pcb-4.3.0/0000775000175000017500000000000014017001277007264 500000000000000pcb-4.3.0/icon-theme-installer0000775000175000017500000001252313773431044013167 00000000000000#!/bin/sh # icon-theme-installer # Copyright (C) 2006 Novell, Inc. # Written by Aaron Bockover # Licensed under the MIT/X11 license # # Modified by Peter Clifton to allow icons with numerals in the filename # # This script is meant to be invoked from within a Makefile/Makefile.am # in the install-data-local and uninstall-data sections. It handles the # task of properly installing icons into the icon theme. It requires a # few arguments to set up its environment, and a list of files to be # installed. The format of the file list is critical: # # , # # apps,music-player-banshee.svg # apps,music-player-banshee-16.png # apps,music-player-banshee-22.png # # is the icon theme category, for instance, apps, devices, # actions, emblems... # # must have a basename in the form of: # # proper-theme-name[-]. # # Where should be either nothing, which will default to scalable # or \-[0-9]{2}, which will expand to x. For example: # # music-player-banshee-16.png # # The here is -16 and will expand to 16x16 per the icon theme spec # # What follows is an example Makefile.am for icon theme installation: # # --------------- # theme=hicolor # themedir=$(datadir)/icons/$(theme) # theme_icons = \ # apps,music-player-banshee.svg \ # apps,music-player-banshee-16.png \ # apps,music-player-banshee-22.png \ # apps,music-player-banshee-24.png \ # apps,music-player-banshee-32.png # # install_icon_exec = $(top_srcdir)/build/icon-theme-installer -t $(theme) -s $(srcdir) -d "x$(DESTDIR)" -b $(themedir) -m "$(mkinstalldirs)" -x "$(INSTALL_DATA)" # install-data-local: # $(install_icon_exec) -i $(theme_icons) # # uninstall-hook: # $(install_icon_exec) -u $(theme_icons) # # MAINTAINERCLEANFILES = Makefile.in # EXTRA_DIST = $(wildcard *.svg *.png) # --------------- # # Arguments to this program: # # -i : Install # -u : Uninstall # -t : Theme name (hicolor) # -b : Theme installation dest directory [x$(DESTDIR)] - Always prefix # this argument with x; it will be stripped but will act as a # placeholder for zero $DESTDIRs (only set by packagers) # -d : Theme installation directory [$(hicolordir)] # -s : Source directory [$(srcdir)] # -m : Command to exec for directory creation [$(mkinstalldirs)] # -x : Command to exec for single file installation [$(INSTALL_DATA)] # : All remainging should be category,filename pairs while getopts "iut:b:d:s:m:x:" flag; do case "$flag" in i) INSTALL=yes ;; u) UNINSTALL=yes ;; t) THEME_NAME=$OPTARG ;; d) INSTALL_DEST_DIR="`echo $OPTARG | sed 's;^x;;'`" ;; b) INSTALL_BASE_DIR=$OPTARG ;; s) SRC_DIR=$OPTARG ;; m) MKINSTALLDIRS_EXEC=$OPTARG ;; x) INSTALL_DATA_EXEC=$OPTARG ;; esac done shift `expr $OPTIND - 1` if test "x$INSTALL" = "xyes" -a "x$UNINSTALL" = "xyes"; then echo "Cannot pass both -i and -u" exit 1 elif test "x$INSTALL" = "x" -a "x$UNINSTALL" = "x"; then echo "Must path either -i or -u" exit 1 fi if test -z "$THEME_NAME"; then echo "Theme name required (-t hicolor)" exit 1 fi if test -z "$INSTALL_BASE_DIR"; then echo "Base theme directory required [-d \$(hicolordir)]" exit 1 fi if test ! -x `echo "$MKINSTALLDIRS_EXEC" | cut -f1 -d' '`; then echo "Cannot find '$MKINSTALLDIRS_EXEC'; You probably want to pass -m \$(mkinstalldirs)" exit 1 fi if test ! -x `echo "$INSTALL_DATA_EXEC" | cut -f1 -d' '`; then echo "Cannot find '$INSTALL_DATA_EXEC'; You probably want to pass -x \$(INSTALL_DATA)" exit 1 fi if test -z "$SRC_DIR"; then SRC_DIR=. fi for icon in $@; do size=`echo $icon | sed -n 's/.*-\([0-9]*\).*/\1/p'` category=`echo $icon | cut -d, -f1` build_name=`echo $icon | cut -d, -f2` install_name=`echo $build_name | sed 's/-[0-9]\+//g'` install_name=`basename $install_name` if test -z $size; then size=scalable; else size=${size}x${size}; fi install_dir=${INSTALL_DEST_DIR}${INSTALL_BASE_DIR}/$size/$category install_path=$install_dir/$install_name if test "x$INSTALL" = "xyes"; then echo "Installing $size $install_name into $THEME_NAME icon theme" $MKINSTALLDIRS_EXEC $install_dir || { echo "Failed to create directory $install_dir" exit 1 } $INSTALL_DATA_EXEC $SRC_DIR/$build_name $install_path || { echo "Failed to install $SRC_DIR/$build_name into $install_path" exit 1 } if test ! -e $install_path; then echo "Failed to install $SRC_DIR/$build_name into $install_path" exit 1 fi else if test -e $install_path; then echo "Removing $size $install_name from $THEME_NAME icon theme" rm $install_path || { echo "Failed to remove $install_path" exit 1 } fi fi done if test "x$INSTALL" = "xyes"; then gtk_update_icon_cache_bin="`(which gtk-update-icon-cache || echo /opt/gnome/bin/gtk-update-icon-cache)2>/dev/null`" gtk_update_icon_cache_bin="${GTK_UPDATE_ICON_CACHE_BIN:-$gtk_update_icon_cache_bin}" gtk_update_icon_cache="$gtk_update_icon_cache_bin -f -t $INSTALL_BASE_DIR" if test -z "$INSTALL_DEST_DIR"; then if test -x $gtk_update_icon_cache_bin; then echo "Updating GTK icon cache" $gtk_update_icon_cache else echo "*** Icon cache not updated. Could not execute $gtk_update_icon_cache_bin" fi else echo "*** Icon cache not updated. After install, run this:" echo "*** $gtk_update_icon_cache" fi fi pcb-4.3.0/ylwrap0000775000175000017500000001405313773431044010462 00000000000000#! /bin/sh # ylwrap - wrapper for lex/yacc invocations. scriptversion=2005-02-02.22 # Copyright (C) 1996, 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2005 # Free Software Foundation, Inc. # # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . case "$1" in '') echo "$0: No files given. Try \`$0 --help' for more information." 1>&2 exit 1 ;; --basedir) basedir=$2 shift 2 ;; -h|--h*) cat <<\EOF Usage: ylwrap [--help|--version] INPUT [OUTPUT DESIRED]... -- PROGRAM [ARGS]... Wrapper for lex/yacc invocations, renaming files as desired. INPUT is the input file OUTPUT is one file PROG generates DESIRED is the file we actually want instead of OUTPUT PROGRAM is program to run ARGS are passed to PROG Any number of OUTPUT,DESIRED pairs may be used. Report bugs to . EOF exit $? ;; -v|--v*) echo "ylwrap $scriptversion" exit $? ;; esac # The input. input="$1" shift case "$input" in [\\/]* | ?:[\\/]*) # Absolute path; do nothing. ;; *) # Relative path. Make it absolute. input="`pwd`/$input" ;; esac pairlist= while test "$#" -ne 0; do if test "$1" = "--"; then shift break fi pairlist="$pairlist $1" shift done # The program to run. prog="$1" shift # Make any relative path in $prog absolute. case "$prog" in [\\/]* | ?:[\\/]*) ;; *[\\/]*) prog="`pwd`/$prog" ;; esac # FIXME: add hostname here for parallel makes that run commands on # other machines. But that might take us over the 14-char limit. dirname=ylwrap$$ trap "cd `pwd`; rm -rf $dirname > /dev/null 2>&1" 1 2 3 15 mkdir $dirname || exit 1 cd $dirname case $# in 0) $prog "$input" ;; *) $prog "$@" "$input" ;; esac ret=$? if test $ret -eq 0; then set X $pairlist shift first=yes # Since DOS filename conventions don't allow two dots, # the DOS version of Bison writes out y_tab.c instead of y.tab.c # and y_tab.h instead of y.tab.h. Test to see if this is the case. y_tab_nodot="no" if test -f y_tab.c || test -f y_tab.h; then y_tab_nodot="yes" fi # The directory holding the input. input_dir=`echo "$input" | sed -e 's,\([\\/]\)[^\\/]*$,\1,'` # Quote $INPUT_DIR so we can use it in a regexp. # FIXME: really we should care about more than `.' and `\'. input_rx=`echo "$input_dir" | sed 's,\\\\,\\\\\\\\,g;s,\\.,\\\\.,g'` while test "$#" -ne 0; do from="$1" # Handle y_tab.c and y_tab.h output by DOS if test $y_tab_nodot = "yes"; then if test $from = "y.tab.c"; then from="y_tab.c" else if test $from = "y.tab.h"; then from="y_tab.h" fi fi fi if test -f "$from"; then # If $2 is an absolute path name, then just use that, # otherwise prepend `../'. case "$2" in [\\/]* | ?:[\\/]*) target="$2";; *) target="../$2";; esac # We do not want to overwrite a header file if it hasn't # changed. This avoid useless recompilations. However the # parser itself (the first file) should always be updated, # because it is the destination of the .y.c rule in the # Makefile. Divert the output of all other files to a temporary # file so we can compare them to existing versions. if test $first = no; then realtarget="$target" target="tmp-`echo $target | sed s/.*[\\/]//g`" fi # Edit out `#line' or `#' directives. # # We don't want the resulting debug information to point at # an absolute srcdir; it is better for it to just mention the # .y file with no path. # # We want to use the real output file name, not yy.lex.c for # instance. # # We want the include guards to be adjusted too. FROM=`echo "$from" | sed \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'\ -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'` TARGET=`echo "$2" | sed \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'\ -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'` sed -e "/^#/!b" -e "s,$input_rx,," -e "s,$from,$2," \ -e "s,$FROM,$TARGET," "$from" >"$target" || ret=$? # Check whether header files must be updated. if test $first = no; then if test -f "$realtarget" && cmp -s "$realtarget" "$target"; then echo "$2" is unchanged rm -f "$target" else echo updating "$2" mv -f "$target" "$realtarget" fi fi else # A missing file is only an error for the first file. This # is a blatant hack to let us support using "yacc -d". If -d # is not specified, we don't want an error when the header # file is "missing". if test $first = yes; then ret=1 fi fi shift shift first=no done else ret=$? fi # Remove the directory. cd .. rm -rf $dirname exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: pcb-4.3.0/README.win320000664000175000017500000000241313773431044011034 00000000000000These are instructions on building a windows installer under cygwin but with mingw toolchain and libraries. The result is an install which does not depend on cygwin. If you are looking for instructions on cross-compiling from linux or other systems, then refer to README.w32 --------------------------------------------------------------------- These instructions were written based on cygwin64. When you install cygwin64 on your system, you will need to ensure that you have installed: - autoconf - automake - bash - bison - flex - gawk - intltool - make - m4 - sed In addition, you will need the mingw cross compilation packages. At the time of writing this, the the list of packages installed which have been shown to work is contained in win32/mings_required_pkgs. That list was obtained via: $ cygcheck -c | grep mingw In addition I have: w32api-headers 4.0.4-1 OK w32api-runtime 4.0.4-1 OK Once these have all been installed then when building from a tarball, extract, cd win32 and run ./build_pcb This will create a windows installer. If you are building from git you will need additional tools to build the documentation which can be skipped using ./build_pcb --disable-doc pcb-4.3.0/configure0000775000175000017500000231636314016777300011137 00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for pcb 4.3.0. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='pcb' PACKAGE_TARNAME='pcb' PACKAGE_VERSION='4.3.0' PACKAGE_STRING='pcb 4.3.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' ac_unique_file="src/draw.c" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" gt_needs= ac_header_list= gl_use_threads_default= ac_func_list= ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS TOPDIRS BTNMOD PCBTREEPATH PCBTREEDIR LIBRARYFILENAME PCBLIBDIR FONTFILENAME CC_OR_CXX DEBUG_BUILD_FALSE DEBUG_BUILD_TRUE PCB BUILD_PCBLIB_NEWLIB_FALSE BUILD_PCBLIB_NEWLIB_TRUE PNG_PREVIEW_FALSE PNG_PREVIEW_TRUE GIF_FALSE GIF_TRUE PNG_FALSE PNG_TRUE GDLIB_CONFIG GDLIB_LIBS GDLIB_CFLAGS GTKGLEXT_LIBS GTKGLEXT_CFLAGS GTK_LIBS GTK_CFLAGS X_EXTRA_LIBS X_LIBS X_PRE_LIBS X_CFLAGS GLIB_LIBS GLIB_CFLAGS HAVE_TEST_TOOLS_FALSE HAVE_TEST_TOOLS_TRUE GERBV XHOST IM_MONTAGE IM_DISPLAY IM_CONVERT IM_COMPOSITE IM_COMPARE IM_ANIMATE MISSING_GSCHEM_FALSE MISSING_GSCHEM_TRUE GSCHEM MISSING_PS2PDF_FALSE MISSING_PS2PDF_TRUE PS2PDF MISSING_TEXI2DVI_FALSE MISSING_TEXI2DVI_TRUE MISSING_PDFLATEX_FALSE MISSING_PDFLATEX_TRUE PDFLATEX GNUM4 WISH M4 GAFDATADIR UPDATE_MIME_DATABASE ENABLE_UPDATE_MIME_DATABASE_FALSE ENABLE_UPDATE_MIME_DATABASE_TRUE UPDATE_DESKTOP_DATABASE ENABLE_UPDATE_DESKTOP_DATABASE_FALSE ENABLE_UPDATE_DESKTOP_DATABASE_TRUE KDEDATADIR XDGDATADIR GTK_UPDATE_ICON_CACHE_BIN SETENV HIDLIBS HIDLIST GLU_LIBS GLU_CFLAGS GL_LIBS GL_CFLAGS PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC ax_pthread_config XMKMF USE_GL_FALSE USE_GL_TRUE DBUS_LIBS DBUS_CFLAGS WITH_DBUS_FALSE WITH_DBUS_TRUE CAIRO_LIBS CAIRO_CFLAGS PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG WITH_TOPOROUTER_FALSE WITH_TOPOROUTER_TRUE WITHGUI KPSEWHICH PERL TEXI2DVI MKINFO CONVERT PPMTOWINICON XPMTOPPM YACC_PATH YFLAGS YACC LEX_PATH LEXLIB LEX_OUTPUT_ROOT LEX ALL_LINGUAS INTLTOOL_PERL INTLTOOL_POLICY_RULE INTLTOOL_SERVICE_RULE INTLTOOL_THEME_RULE INTLTOOL_SCHEMAS_RULE INTLTOOL_CAVES_RULE INTLTOOL_XML_NOMERGE_RULE INTLTOOL_XML_RULE INTLTOOL_KBD_RULE INTLTOOL_XAM_RULE INTLTOOL_UI_RULE INTLTOOL_SOUNDLIST_RULE INTLTOOL_SHEET_RULE INTLTOOL_SERVER_RULE INTLTOOL_PONG_RULE INTLTOOL_OAF_RULE INTLTOOL_PROP_RULE INTLTOOL_KEYS_RULE INTLTOOL_DIRECTORY_RULE INTLTOOL_DESKTOP_RULE intltool__v_merge_options_0 intltool__v_merge_options_ INTLTOOL_V_MERGE_OPTIONS INTLTOOL__v_MERGE_0 INTLTOOL__v_MERGE_ INTLTOOL_V_MERGE INTLTOOL_EXTRACT INTLTOOL_MERGE INTLTOOL_UPDATE POSUB LTLIBINTL LIBINTL INTLLIBS INTL_LIBTOOL_SUFFIX_PREFIX INTLOBJS GENCAT INSTOBJEXT DATADIRNAME CATOBJEXT USE_INCLUDED_LIBINTL BUILD_INCLUDED_LIBINTL LTLIBC WOE32 WOE32DLL HAVE_WPRINTF HAVE_NEWLOCALE HAVE_SNPRINTF HAVE_ASPRINTF HAVE_POSIX_PRINTF INTL_DEFAULT_VERBOSITY INTL_MACOSX_LIBS GLIBC21 INTLBISON LTLIBICONV LIBICONV LTLIBMULTITHREAD LIBMULTITHREAD LTLIBTHREAD LIBTHREAD LIBPTH_PREFIX LTLIBPTH LIBPTH PRI_MACROS_BROKEN ALLOCA HAVE_VISIBILITY CFLAG_VISIBILITY RANLIB GLIBC2 XGETTEXT_EXTRA_OPTIONS MSGMERGE XGETTEXT_015 XGETTEXT GMSGFMT_015 MSGFMT_015 GMSGFMT MSGFMT GETTEXT_MACRO_VERSION USE_NLS SED GETTEXT_PACKAGE WINDRES am__fastdepCXX_FALSE am__fastdepCXX_TRUE CXXDEPMODE ac_ct_CXX CXXFLAGS CXX WIN32_FALSE WIN32_TRUE WIN32 host_os host_vendor host_cpu host build_os build_vendor build_cpu build DOC GIT_OR_CVS_VERSION_FALSE GIT_OR_CVS_VERSION_TRUE CVS_VERSION_FALSE CVS_VERSION_TRUE GIT_VERSION_FALSE GIT_VERSION_TRUE EGREP GREP CPP am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir runstatedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL am__quote' ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules enable_dependency_tracking enable_doc enable_nls enable_threads with_gnu_ld enable_rpath with_libpth_prefix with_libiconv_prefix with_included_gettext with_libintl_prefix with_gui enable_toporouter enable_toporouter_output enable_dbus enable_gl with_x with_printer with_exporters with_xdgdatadir with_kdedatadir enable_update_desktop_database enable_update_mime_database with_gaf_datadir enable_gif enable_jpeg enable_png enable_m4lib_png enable_xrender enable_xinerama enable_dmalloc enable_efence enable_debug enable_coord64 enable_coord32 enable_build_with_cxx ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP CXX CXXFLAGS CCC YACC YFLAGS PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR CAIRO_CFLAGS CAIRO_LIBS DBUS_CFLAGS DBUS_LIBS XMKMF GLIB_CFLAGS GLIB_LIBS GTK_CFLAGS GTK_LIBS GTKGLEXT_CFLAGS GTKGLEXT_LIBS GDLIB_CFLAGS GDLIB_LIBS' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures pcb 4.3.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/pcb] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names X features: --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of pcb 4.3.0:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --enable-doc Build and install the documentation [default=yes] --disable-nls do not use Native Language Support --enable-threads={posix|solaris|pth|windows} specify multithreading API --disable-threads build without multithread safety --disable-rpath do not hardcode runtime library paths --enable-toporouter build toporouter [default=yes] --enable-toporouter-output enable toporouter graphical output [default=no] --enable-dbus Enable DBUS IPC --enable-gl Enable GL drawing (with GTK HID) --disable-update-desktop-database do not update desktop database after installation --disable-update-mime-database do not update mime database after installation --disable-gif Disable support for gif output when the png HID is used [default=include gif support] --disable-jpeg Disable support for JPEG output when the png HID is used [default=include JPEG support] --disable-png Disable support for PNG output when the png HID is used [default=include PNG support] --enable-m4lib-png Enable creating png previews for the m4 library --disable-xrender Compile and link with Xrender default=yes --disable-xinerama Compile and link with Xinerama default=yes --enable-dmalloc Compile and link with dmalloc for malloc debugging default=no --enable-efence Link with ElectricFence for malloc debugging default=no --enable-debug Enable debugging code --enable-coord64 Force 64-bit coordinate types --enable-coord32 Force 32-bit coordinate types --enable-build-with-cxx build with C++ compiler instead of C compiler Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-libpth-prefix[=DIR] search for libpth in DIR/include and DIR/lib --without-libpth-prefix don't search for libpth in includedir and libdir --with-libiconv-prefix[=DIR] search for libiconv in DIR/include and DIR/lib --without-libiconv-prefix don't search for libiconv in includedir and libdir --with-included-gettext use the GNU gettext library included here --with-libintl-prefix[=DIR] search for libintl in DIR/include and DIR/lib --without-libintl-prefix don't search for libintl in includedir and libdir --with-gui= Specify the GUI to use: batch gtk lesstif [default=gtk] --with-x use the X Window System --with-printer= Specify the printer: lpr [default=lpr] --with-exporters= Enable export devices: bom bom_md gerber gcode nelma png ps ipcd356 gsvit [default=bom bom_md gerber gcode nelma png ps ipcd356 gsvit] --with-xdgdatadir=path Change where the theme icons and mime registrations are installed [DATADIR] --with-kdedatadir=path Change where the KDE mime reg istrations are installed [DATADIR] --with-gaf-datadir=DIR install additional gaf scheme into DIR [[DATADIR]] Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor CXX C++ compiler command CXXFLAGS C++ compiler flags YACC The `Yet Another Compiler Compiler' implementation to use. Defaults to the first program found out of: `bison -y', `byacc', `yacc'. YFLAGS The list of arguments that will be passed by default to $YACC. This script will default YFLAGS to the empty string to avoid a default value of `-d' given by some make applications. PKG_CONFIG path to pkg-config utility PKG_CONFIG_PATH directories to add to pkg-config's search path PKG_CONFIG_LIBDIR path overriding pkg-config's built-in search path CAIRO_CFLAGS C compiler flags for CAIRO, overriding pkg-config CAIRO_LIBS linker flags for CAIRO, overriding pkg-config DBUS_CFLAGS C compiler flags for DBUS, overriding pkg-config DBUS_LIBS linker flags for DBUS, overriding pkg-config XMKMF Path to xmkmf, Makefile generator for X Window System GLIB_CFLAGS C compiler flags for GLIB, overriding pkg-config GLIB_LIBS linker flags for GLIB, overriding pkg-config GTK_CFLAGS C compiler flags for GTK, overriding pkg-config GTK_LIBS linker flags for GTK, overriding pkg-config GTKGLEXT_CFLAGS C compiler flags for GTKGLEXT, overriding pkg-config GTKGLEXT_LIBS linker flags for GTKGLEXT, overriding pkg-config GDLIB_CFLAGS C compiler flags for GDLIB, overriding pkg-config GDLIB_LIBS linker flags for GDLIB, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF pcb configure 4.3.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_cxx_try_compile LINENO # ---------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES # --------------------------------------------- # Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR # accordingly. ac_fn_c_check_decl () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack as_decl_name=`echo $2|sed 's/ *(.*//'` as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 $as_echo_n "checking whether $as_decl_name is declared... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { #ifndef $as_decl_name #ifdef __cplusplus (void) $as_decl_use; #else (void) $as_decl_name; #endif #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_decl # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES # -------------------------------------------- # Tries to find the compile-time value of EXPR in a program that includes # INCLUDES, setting VAR accordingly. Returns whether the value could be # computed ac_fn_c_compute_int () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=0 ac_mid=0 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid; break else as_fn_arith $ac_mid + 1 && ac_lo=$as_val if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) < 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=-1 ac_mid=-1 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=$ac_mid; break else as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid else as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in #(( ?*) eval "$3=\$ac_lo"; ac_retval=0 ;; '') ac_retval=1 ;; esac else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 static long int longval () { return $2; } static unsigned long int ulongval () { return $2; } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (($2) < 0) { long int i = longval (); if (i != ($2)) return 1; fprintf (f, "%ld", i); } else { unsigned long int i = ulongval (); if (i != ($2)) return 1; fprintf (f, "%lu", i); } /* Do not output a trailing newline, as this causes \r\n confusion on some platforms. */ return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : echo >>conftest.val; read $3 config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by pcb $as_me 4.3.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi gt_needs="$gt_needs " as_fn_append ac_header_list " stdlib.h" as_fn_append ac_header_list " unistd.h" as_fn_append ac_header_list " sys/param.h" as_fn_append ac_func_list " symlink" # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu am__api_version='1.16' ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='pcb' VERSION='4.3.0' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar pax cpio none' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 $as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; } cat > confinc.mk << 'END' am__doit: @echo this is the am__doit target >confinc.out .PHONY: am__doit END am__include="#" am__quote= # BSD make does it like this. echo '.include "confinc.mk" # ignored' > confmf.BSD # Other make implementations (GNU, Solaris 10, AIX) do it like this. echo 'include confinc.mk # ignored' > confmf.GNU _am_result=no for s in GNU BSD; do { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } case $?:`cat confinc.out 2>/dev/null` in #( '0:this is the am__doit target') : case $s in #( BSD) : am__include='.include' am__quote='"' ;; #( *) : am__include='include' am__quote='' ;; esac ;; #( *) : ;; esac if test "$am__include" != "#"; then _am_result="yes ($s style)" break fi done rm -f confinc.* confmf.* { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 $as_echo "${_am_result}" >&6; } # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 $as_echo_n "checking whether $CC understands -c and -o together... " >&6; } if ${am_cv_prog_cc_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 $as_echo "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default" if test "x$ac_cv_header_minix_config_h" = xyes; then : MINIX=yes else MINIX= fi if test "$MINIX" = yes; then $as_echo "#define _POSIX_SOURCE 1" >>confdefs.h $as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h $as_echo "#define _MINIX 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 $as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } if ${ac_cv_safe_to_define___extensions__+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ # define __EXTENSIONS__ 1 $ac_includes_default int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_safe_to_define___extensions__=yes else ac_cv_safe_to_define___extensions__=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 $as_echo "$ac_cv_safe_to_define___extensions__" >&6; } test $ac_cv_safe_to_define___extensions__ = yes && $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h $as_echo "#define _ALL_SOURCE 1" >>confdefs.h $as_echo "#define _GNU_SOURCE 1" >>confdefs.h $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h ac_config_headers="$ac_config_headers config.h" ########################################################################## # # Try to figure out if we are building from git sources. # If we are then unless building of the documentation has # been disabled then just require the user have all the right # tools. Users building from a tarball won't need latex, makeinfo, # etc. but if you're already downloading development sources, then # it is not unreasonable to require development tools. What motivated # this is that using maintainer mode proved to cause regular confusion. pcb_sources="tarball" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if you are building from a git checkout" >&5 $as_echo_n "checking if you are building from a git checkout... " >&6; } pcb_git_version=no if test -f $srcdir/.gitignore ; then pcb_git_version=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } pcb_sources="GIT" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test x$pcb_git_version = xyes; then GIT_VERSION_TRUE= GIT_VERSION_FALSE='#' else GIT_VERSION_TRUE='#' GIT_VERSION_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if you are building from a anoncvs checkout" >&5 $as_echo_n "checking if you are building from a anoncvs checkout... " >&6; } pcb_cvs_version=no if test -f $srcdir/CVS/Root ; then pcb_cvs_version=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } pcb_sources="CVS" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test x$pcb_cvs_version = xyes; then CVS_VERSION_TRUE= CVS_VERSION_FALSE='#' else CVS_VERSION_TRUE='#' CVS_VERSION_FALSE= fi if test x$pcb_git_version = xyes -o x$pcb_cvs_version = xyes; then GIT_OR_CVS_VERSION_TRUE= GIT_OR_CVS_VERSION_FALSE='#' else GIT_OR_CVS_VERSION_TRUE='#' GIT_OR_CVS_VERSION_FALSE= fi ########################################################################## # # See if we are supposed to build the docs # docs_yesno=yes { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the documentation should be built" >&5 $as_echo_n "checking if the documentation should be built... " >&6; } # Check whether --enable-doc was given. if test "${enable_doc+set}" = set; then : enableval=$enable_doc; if test "X$enable_doc" = "Xno" ; then DOC="" { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } docs_yesno=no else DOC=doc { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } docs_yesno=yes fi else DOC=doc { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } docs_yesno=yes fi # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for windows" >&5 $as_echo_n "checking for windows... " >&6; } PCB_PATH_DELIMETER=":" PCB_DIR_SEPARATOR_S="/" PCB_DIR_SEPARATOR_C='/' case $host in *-*-mingw* ) WIN32=yes CFLAGS="$CFLAGS ${MINGW_CFLAGS:--mms-bitfields -mwindows}" CPPFLAGS="$CPPFLAGS ${MINGW_CPPFLAGS}" ;; * ) WIN32=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WIN32" >&5 $as_echo "$WIN32" >&6; } if test x$WIN32 = xyes; then WIN32_TRUE= WIN32_FALSE='#' else WIN32_TRUE='#' WIN32_FALSE= fi if test "x$WIN32" = "xyes" ; then PCB_PATH_DELIMETER=";" PCB_DIR_SEPARATOR_S="\\\\" PCB_DIR_SEPARATOR_C='\\' fi cat >>confdefs.h <<_ACEOF #define PCB_DIR_SEPARATOR_C '$PCB_DIR_SEPARATOR_C' _ACEOF cat >>confdefs.h <<_ACEOF #define PCB_DIR_SEPARATOR_S "$PCB_DIR_SEPARATOR_S" _ACEOF cat >>confdefs.h <<_ACEOF #define PCB_PATH_DELIMETER "$PCB_PATH_DELIMETER" _ACEOF ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 $as_echo_n "checking whether $CC understands -c and -o together... " >&6; } if ${am_cv_prog_cc_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 $as_echo "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } if ${ac_cv_cxx_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if ${ac_cv_prog_cxx_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes else CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CXX" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CXX_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 $as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi if test "x$WIN32" = "xyes" ; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}windres", so it can be a program name with args. set dummy ${ac_tool_prefix}windres; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_WINDRES+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$WINDRES"; then ac_cv_prog_WINDRES="$WINDRES" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_WINDRES="${ac_tool_prefix}windres" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi WINDRES=$ac_cv_prog_WINDRES if test -n "$WINDRES"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WINDRES" >&5 $as_echo "$WINDRES" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_WINDRES"; then ac_ct_WINDRES=$WINDRES # Extract the first word of "windres", so it can be a program name with args. set dummy windres; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_WINDRES+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_WINDRES"; then ac_cv_prog_ac_ct_WINDRES="$ac_ct_WINDRES" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_WINDRES="windres" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_WINDRES=$ac_cv_prog_ac_ct_WINDRES if test -n "$ac_ct_WINDRES"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_WINDRES" >&5 $as_echo "$ac_ct_WINDRES" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_WINDRES" = x; then WINDRES="no" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac WINDRES=$ac_ct_WINDRES fi else WINDRES="$ac_cv_prog_WINDRES" fi if test "$WINDRES" = "no" ; then as_fn_error $? "*** Could not find an implementation of windres in your PATH." "$LINENO" 5 fi fi # i18n GETTEXT_PACKAGE=$PACKAGE cat >>confdefs.h <<_ACEOF #define GETTEXT_PACKAGE "$GETTEXT_PACKAGE" _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 $as_echo "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5 $as_echo_n "checking whether NLS is requested... " >&6; } # Check whether --enable-nls was given. if test "${enable_nls+set}" = set; then : enableval=$enable_nls; USE_NLS=$enableval else USE_NLS=yes fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5 $as_echo "$USE_NLS" >&6; } GETTEXT_MACRO_VERSION=0.19 # Prepare PATH_SEPARATOR. # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which # contains only /bin. Note that ksh looks also at the FPATH variable, # so we have to set that as well for the test. PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ || PATH_SEPARATOR=';' } fi # Find out how to test for executable files. Don't use a zero-byte file, # as systems may use methods other than mode bits to determine executability. cat >conf$$.file <<_ASEOF #! /bin/sh exit 0 _ASEOF chmod +x conf$$.file if test -x conf$$.file >/dev/null 2>&1; then ac_executable_p="test -x" else ac_executable_p="test -f" fi rm -f conf$$.file # Extract the first word of "msgfmt", so it can be a program name with args. set dummy msgfmt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_MSGFMT+:} false; then : $as_echo_n "(cached) " >&6 else case "$MSGFMT" in [\\/]* | ?:[\\/]*) ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. ;; *) ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$ac_save_IFS" test -z "$ac_dir" && ac_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then echo "$as_me: trying $ac_dir/$ac_word..." >&5 if $ac_dir/$ac_word --statistics /dev/null >&5 2>&1 && (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then ac_cv_path_MSGFMT="$ac_dir/$ac_word$ac_exec_ext" break 2 fi fi done done IFS="$ac_save_IFS" test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT=":" ;; esac fi MSGFMT="$ac_cv_path_MSGFMT" if test "$MSGFMT" != ":"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGFMT" >&5 $as_echo "$MSGFMT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "gmsgfmt", so it can be a program name with args. set dummy gmsgfmt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_GMSGFMT+:} false; then : $as_echo_n "(cached) " >&6 else case $GMSGFMT in [\\/]* | ?:[\\/]*) ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_GMSGFMT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" ;; esac fi GMSGFMT=$ac_cv_path_GMSGFMT if test -n "$GMSGFMT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GMSGFMT" >&5 $as_echo "$GMSGFMT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi case `$MSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) MSGFMT_015=: ;; *) MSGFMT_015=$MSGFMT ;; esac case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;; *) GMSGFMT_015=$GMSGFMT ;; esac # Prepare PATH_SEPARATOR. # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which # contains only /bin. Note that ksh looks also at the FPATH variable, # so we have to set that as well for the test. PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ || PATH_SEPARATOR=';' } fi # Find out how to test for executable files. Don't use a zero-byte file, # as systems may use methods other than mode bits to determine executability. cat >conf$$.file <<_ASEOF #! /bin/sh exit 0 _ASEOF chmod +x conf$$.file if test -x conf$$.file >/dev/null 2>&1; then ac_executable_p="test -x" else ac_executable_p="test -f" fi rm -f conf$$.file # Extract the first word of "xgettext", so it can be a program name with args. set dummy xgettext; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_XGETTEXT+:} false; then : $as_echo_n "(cached) " >&6 else case "$XGETTEXT" in [\\/]* | ?:[\\/]*) ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. ;; *) ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$ac_save_IFS" test -z "$ac_dir" && ac_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then echo "$as_me: trying $ac_dir/$ac_word..." >&5 if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&5 2>&1 && (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then ac_cv_path_XGETTEXT="$ac_dir/$ac_word$ac_exec_ext" break 2 fi fi done done IFS="$ac_save_IFS" test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" ;; esac fi XGETTEXT="$ac_cv_path_XGETTEXT" if test "$XGETTEXT" != ":"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XGETTEXT" >&5 $as_echo "$XGETTEXT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f messages.po case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;; *) XGETTEXT_015=$XGETTEXT ;; esac # Prepare PATH_SEPARATOR. # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which # contains only /bin. Note that ksh looks also at the FPATH variable, # so we have to set that as well for the test. PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ || PATH_SEPARATOR=';' } fi # Find out how to test for executable files. Don't use a zero-byte file, # as systems may use methods other than mode bits to determine executability. cat >conf$$.file <<_ASEOF #! /bin/sh exit 0 _ASEOF chmod +x conf$$.file if test -x conf$$.file >/dev/null 2>&1; then ac_executable_p="test -x" else ac_executable_p="test -f" fi rm -f conf$$.file # Extract the first word of "msgmerge", so it can be a program name with args. set dummy msgmerge; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_MSGMERGE+:} false; then : $as_echo_n "(cached) " >&6 else case "$MSGMERGE" in [\\/]* | ?:[\\/]*) ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a path. ;; *) ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$ac_save_IFS" test -z "$ac_dir" && ac_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then echo "$as_me: trying $ac_dir/$ac_word..." >&5 if $ac_dir/$ac_word --update -q /dev/null /dev/null >&5 2>&1; then ac_cv_path_MSGMERGE="$ac_dir/$ac_word$ac_exec_ext" break 2 fi fi done done IFS="$ac_save_IFS" test -z "$ac_cv_path_MSGMERGE" && ac_cv_path_MSGMERGE=":" ;; esac fi MSGMERGE="$ac_cv_path_MSGMERGE" if test "$MSGMERGE" != ":"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGMERGE" >&5 $as_echo "$MSGMERGE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$localedir" || localedir='${datadir}/locale' test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS= ac_config_commands="$ac_config_commands po-directories" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C Library 2 or newer" >&5 $as_echo_n "checking whether we are using the GNU C Library 2 or newer... " >&6; } if ${ac_cv_gnu_library_2+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifdef __GNU_LIBRARY__ #if (__GLIBC__ >= 2) && !defined __UCLIBC__ Lucky GNU user #endif #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "Lucky GNU user" >/dev/null 2>&1; then : ac_cv_gnu_library_2=yes else ac_cv_gnu_library_2=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gnu_library_2" >&5 $as_echo "$ac_cv_gnu_library_2" >&6; } GLIBC2="$ac_cv_gnu_library_2" if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi CFLAG_VISIBILITY= HAVE_VISIBILITY=0 if test -n "$GCC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the -Werror option is usable" >&5 $as_echo_n "checking whether the -Werror option is usable... " >&6; } if ${gl_cv_cc_vis_werror+:} false; then : $as_echo_n "(cached) " >&6 else gl_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : gl_cv_cc_vis_werror=yes else gl_cv_cc_vis_werror=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$gl_save_CFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_cc_vis_werror" >&5 $as_echo "$gl_cv_cc_vis_werror" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for simple visibility declarations" >&5 $as_echo_n "checking for simple visibility declarations... " >&6; } if ${gl_cv_cc_visibility+:} false; then : $as_echo_n "(cached) " >&6 else gl_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -fvisibility=hidden" if test $gl_cv_cc_vis_werror = yes; then CFLAGS="$CFLAGS -Werror" fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ extern __attribute__((__visibility__("hidden"))) int hiddenvar; extern __attribute__((__visibility__("default"))) int exportedvar; extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void); extern __attribute__((__visibility__("default"))) int exportedfunc (void); void dummyfunc (void) {} int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : gl_cv_cc_visibility=yes else gl_cv_cc_visibility=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$gl_save_CFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_cc_visibility" >&5 $as_echo "$gl_cv_cc_visibility" >&6; } if test $gl_cv_cc_visibility = yes; then CFLAG_VISIBILITY="-fvisibility=hidden" HAVE_VISIBILITY=1 fi fi cat >>confdefs.h <<_ACEOF #define HAVE_VISIBILITY $HAVE_VISIBILITY _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 $as_echo_n "checking for inline... " >&6; } if ${ac_cv_c_inline+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo () {return 0; } $ac_kw foo_t foo () {return 0; } #endif _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_inline=$ac_kw fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_inline" != no && break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 $as_echo "$ac_cv_c_inline" >&6; } case $ac_cv_c_inline in inline | yes) ;; *) case $ac_cv_c_inline in no) ac_val=;; *) ac_val=$ac_cv_c_inline;; esac cat >>confdefs.h <<_ACEOF #ifndef __cplusplus #define inline $ac_val #endif _ACEOF ;; esac ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdint.h" >&5 $as_echo_n "checking for stdint.h... " >&6; } if ${gl_cv_header_stdint_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { uintmax_t i = (uintmax_t) -1; return !i; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : gl_cv_header_stdint_h=yes else gl_cv_header_stdint_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_header_stdint_h" >&5 $as_echo "$gl_cv_header_stdint_h" >&6; } if test $gl_cv_header_stdint_h = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_STDINT_H_WITH_UINTMAX 1 _ACEOF fi # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5 $as_echo_n "checking for working alloca.h... " >&6; } if ${ac_cv_working_alloca_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { char *p = (char *) alloca (2 * sizeof (int)); if (p) return 0; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_working_alloca_h=yes else ac_cv_working_alloca_h=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5 $as_echo "$ac_cv_working_alloca_h" >&6; } if test $ac_cv_working_alloca_h = yes; then $as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5 $as_echo_n "checking for alloca... " >&6; } if ${ac_cv_func_alloca_works+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __GNUC__ # define alloca __builtin_alloca #else # ifdef _MSC_VER # include # define alloca _alloca # else # ifdef HAVE_ALLOCA_H # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ void *alloca (size_t); # endif # endif # endif # endif #endif int main () { char *p = (char *) alloca (1); if (p) return 0; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_func_alloca_works=yes else ac_cv_func_alloca_works=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5 $as_echo "$ac_cv_func_alloca_works" >&6; } if test $ac_cv_func_alloca_works = yes; then $as_echo "#define HAVE_ALLOCA 1" >>confdefs.h else # The SVR3 libPW and SVR4 libucb both contain incompatible functions # that cause trouble. Some versions do not even contain alloca or # contain a buggy version. If you still want to use their alloca, # use ar to extract alloca.o from them instead of compiling alloca.c. ALLOCA=\${LIBOBJDIR}alloca.$ac_objext $as_echo "#define C_ALLOCA 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5 $as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; } if ${ac_cv_os_cray+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if defined CRAY && ! defined CRAY2 webecray #else wenotbecray #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "webecray" >/dev/null 2>&1; then : ac_cv_os_cray=yes else ac_cv_os_cray=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5 $as_echo "$ac_cv_os_cray" >&6; } if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define CRAY_STACKSEG_END $ac_func _ACEOF break fi done fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5 $as_echo_n "checking stack direction for C alloca... " >&6; } if ${ac_cv_c_stack_direction+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_c_stack_direction=0 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int find_stack_direction (int *addr, int depth) { int dir, dummy = 0; if (! addr) addr = &dummy; *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1; dir = depth ? find_stack_direction (addr, depth - 1) : 0; return dir + dummy; } int main (int argc, char **argv) { return find_stack_direction (0, argc + !argv + 20) < 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_c_stack_direction=1 else ac_cv_c_stack_direction=-1 fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5 $as_echo "$ac_cv_c_stack_direction" >&6; } cat >>confdefs.h <<_ACEOF #define STACK_DIRECTION $ac_cv_c_stack_direction _ACEOF fi for ac_header in $ac_header_list do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in getpagesize do : ac_fn_c_check_func "$LINENO" "getpagesize" "ac_cv_func_getpagesize" if test "x$ac_cv_func_getpagesize" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GETPAGESIZE 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working mmap" >&5 $as_echo_n "checking for working mmap... " >&6; } if ${ac_cv_func_mmap_fixed_mapped+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_func_mmap_fixed_mapped=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default /* malloc might have been renamed as rpl_malloc. */ #undef malloc /* Thanks to Mike Haertel and Jim Avera for this test. Here is a matrix of mmap possibilities: mmap private not fixed mmap private fixed at somewhere currently unmapped mmap private fixed at somewhere already mapped mmap shared not fixed mmap shared fixed at somewhere currently unmapped mmap shared fixed at somewhere already mapped For private mappings, we should verify that changes cannot be read() back from the file, nor mmap's back from the file at a different address. (There have been systems where private was not correctly implemented like the infamous i386 svr4.0, and systems where the VM page cache was not coherent with the file system buffer cache like early versions of FreeBSD and possibly contemporary NetBSD.) For shared mappings, we should conversely verify that changes get propagated back to all the places they're supposed to be. Grep wants private fixed already mapped. The main things grep needs to know about mmap are: * does it exist and is it safe to write into the mmap'd area * how to use it (BSD variants) */ #include #include #if !defined STDC_HEADERS && !defined HAVE_STDLIB_H char *malloc (); #endif /* This mess was copied from the GNU getpagesize.h. */ #ifndef HAVE_GETPAGESIZE # ifdef _SC_PAGESIZE # define getpagesize() sysconf(_SC_PAGESIZE) # else /* no _SC_PAGESIZE */ # ifdef HAVE_SYS_PARAM_H # include # ifdef EXEC_PAGESIZE # define getpagesize() EXEC_PAGESIZE # else /* no EXEC_PAGESIZE */ # ifdef NBPG # define getpagesize() NBPG * CLSIZE # ifndef CLSIZE # define CLSIZE 1 # endif /* no CLSIZE */ # else /* no NBPG */ # ifdef NBPC # define getpagesize() NBPC # else /* no NBPC */ # ifdef PAGESIZE # define getpagesize() PAGESIZE # endif /* PAGESIZE */ # endif /* no NBPC */ # endif /* no NBPG */ # endif /* no EXEC_PAGESIZE */ # else /* no HAVE_SYS_PARAM_H */ # define getpagesize() 8192 /* punt totally */ # endif /* no HAVE_SYS_PARAM_H */ # endif /* no _SC_PAGESIZE */ #endif /* no HAVE_GETPAGESIZE */ int main () { char *data, *data2, *data3; const char *cdata2; int i, pagesize; int fd, fd2; pagesize = getpagesize (); /* First, make a file with some known garbage in it. */ data = (char *) malloc (pagesize); if (!data) return 1; for (i = 0; i < pagesize; ++i) *(data + i) = rand (); umask (0); fd = creat ("conftest.mmap", 0600); if (fd < 0) return 2; if (write (fd, data, pagesize) != pagesize) return 3; close (fd); /* Next, check that the tail of a page is zero-filled. File must have non-zero length, otherwise we risk SIGBUS for entire page. */ fd2 = open ("conftest.txt", O_RDWR | O_CREAT | O_TRUNC, 0600); if (fd2 < 0) return 4; cdata2 = ""; if (write (fd2, cdata2, 1) != 1) return 5; data2 = (char *) mmap (0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd2, 0L); if (data2 == MAP_FAILED) return 6; for (i = 0; i < pagesize; ++i) if (*(data2 + i)) return 7; close (fd2); if (munmap (data2, pagesize)) return 8; /* Next, try to mmap the file at a fixed address which already has something else allocated at it. If we can, also make sure that we see the same garbage. */ fd = open ("conftest.mmap", O_RDWR); if (fd < 0) return 9; if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0L)) return 10; for (i = 0; i < pagesize; ++i) if (*(data + i) != *(data2 + i)) return 11; /* Finally, make sure that changes to the mapped area do not percolate back to the file as seen by read(). (This is a bug on some variants of i386 svr4.0.) */ for (i = 0; i < pagesize; ++i) *(data2 + i) = *(data2 + i) + 1; data3 = (char *) malloc (pagesize); if (!data3) return 12; if (read (fd, data3, pagesize) != pagesize) return 13; for (i = 0; i < pagesize; ++i) if (*(data + i) != *(data3 + i)) return 14; close (fd); free (data); free (data3); return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_func_mmap_fixed_mapped=yes else ac_cv_func_mmap_fixed_mapped=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_mmap_fixed_mapped" >&5 $as_echo "$ac_cv_func_mmap_fixed_mapped" >&6; } if test $ac_cv_func_mmap_fixed_mapped = yes; then $as_echo "#define HAVE_MMAP 1" >>confdefs.h fi rm -f conftest.mmap conftest.txt { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether integer division by zero raises SIGFPE" >&5 $as_echo_n "checking whether integer division by zero raises SIGFPE... " >&6; } if ${gt_cv_int_divbyzero_sigfpe+:} false; then : $as_echo_n "(cached) " >&6 else gt_cv_int_divbyzero_sigfpe= case "$host_os" in macos* | darwin[6-9]* | darwin[1-9][0-9]*) # On Mac OS X 10.2 or newer, just assume the same as when cross- # compiling. If we were to perform the real test, 1 Crash Report # dialog window would pop up. case "$host_cpu" in i[34567]86 | x86_64) gt_cv_int_divbyzero_sigfpe="guessing yes" ;; esac ;; esac if test -z "$gt_cv_int_divbyzero_sigfpe"; then if test "$cross_compiling" = yes; then : # Guess based on the CPU. case "$host_cpu" in alpha* | i[34567]86 | x86_64 | m68k | s390*) gt_cv_int_divbyzero_sigfpe="guessing yes";; *) gt_cv_int_divbyzero_sigfpe="guessing no";; esac else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include static void sigfpe_handler (int sig) { /* Exit with code 0 if SIGFPE, with code 1 if any other signal. */ exit (sig != SIGFPE); } int x = 1; int y = 0; int z; int nan; int main () { signal (SIGFPE, sigfpe_handler); /* IRIX and AIX (when "xlc -qcheck" is used) yield signal SIGTRAP. */ #if (defined (__sgi) || defined (_AIX)) && defined (SIGTRAP) signal (SIGTRAP, sigfpe_handler); #endif /* Linux/SPARC yields signal SIGILL. */ #if defined (__sparc__) && defined (__linux__) signal (SIGILL, sigfpe_handler); #endif z = x / y; nan = y / y; exit (2); } _ACEOF if ac_fn_c_try_run "$LINENO"; then : gt_cv_int_divbyzero_sigfpe=yes else gt_cv_int_divbyzero_sigfpe=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_int_divbyzero_sigfpe" >&5 $as_echo "$gt_cv_int_divbyzero_sigfpe" >&6; } case "$gt_cv_int_divbyzero_sigfpe" in *yes) value=1;; *) value=0;; esac cat >>confdefs.h <<_ACEOF #define INTDIV0_RAISES_SIGFPE $value _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inttypes.h" >&5 $as_echo_n "checking for inttypes.h... " >&6; } if ${gl_cv_header_inttypes_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { uintmax_t i = (uintmax_t) -1; return !i; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : gl_cv_header_inttypes_h=yes else gl_cv_header_inttypes_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_header_inttypes_h" >&5 $as_echo "$gl_cv_header_inttypes_h" >&6; } if test $gl_cv_header_inttypes_h = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_INTTYPES_H_WITH_UINTMAX 1 _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for unsigned long long int" >&5 $as_echo_n "checking for unsigned long long int... " >&6; } if ${ac_cv_type_unsigned_long_long_int+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_type_unsigned_long_long_int=yes if test "x${ac_cv_prog_cc_c99-no}" = xno; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* For now, do not test the preprocessor; as of 2007 there are too many implementations with broken preprocessors. Perhaps this can be revisited in 2012. In the meantime, code should not expect #if to work with literals wider than 32 bits. */ /* Test literals. */ long long int ll = 9223372036854775807ll; long long int nll = -9223372036854775807LL; unsigned long long int ull = 18446744073709551615ULL; /* Test constant expressions. */ typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll) ? 1 : -1)]; typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1 ? 1 : -1)]; int i = 63; int main () { /* Test availability of runtime routines for shift and division. */ long long int llmax = 9223372036854775807ll; unsigned long long int ullmax = 18446744073709551615ull; return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i) | (llmax / ll) | (llmax % ll) | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i) | (ullmax / ull) | (ullmax % ull)); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : else ac_cv_type_unsigned_long_long_int=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_unsigned_long_long_int" >&5 $as_echo "$ac_cv_type_unsigned_long_long_int" >&6; } if test $ac_cv_type_unsigned_long_long_int = yes; then $as_echo "#define HAVE_UNSIGNED_LONG_LONG_INT 1" >>confdefs.h fi if test $gl_cv_header_inttypes_h = no && test $gl_cv_header_stdint_h = no; then test $ac_cv_type_unsigned_long_long_int = yes \ && ac_type='unsigned long long' \ || ac_type='unsigned long' cat >>confdefs.h <<_ACEOF #define uintmax_t $ac_type _ACEOF else $as_echo "#define HAVE_UINTMAX_T 1" >>confdefs.h fi for ac_header in inttypes.h do : ac_fn_c_check_header_mongrel "$LINENO" "inttypes.h" "ac_cv_header_inttypes_h" "$ac_includes_default" if test "x$ac_cv_header_inttypes_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_INTTYPES_H 1 _ACEOF fi done if test $ac_cv_header_inttypes_h = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the inttypes.h PRIxNN macros are broken" >&5 $as_echo_n "checking whether the inttypes.h PRIxNN macros are broken... " >&6; } if ${gt_cv_inttypes_pri_broken+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifdef PRId32 char *p = PRId32; #endif int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : gt_cv_inttypes_pri_broken=no else gt_cv_inttypes_pri_broken=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_inttypes_pri_broken" >&5 $as_echo "$gt_cv_inttypes_pri_broken" >&6; } fi if test "$gt_cv_inttypes_pri_broken" = yes; then cat >>confdefs.h <<_ACEOF #define PRI_MACROS_BROKEN 1 _ACEOF PRI_MACROS_BROKEN=1 else PRI_MACROS_BROKEN=0 fi # Check whether --enable-threads was given. if test "${enable_threads+set}" = set; then : enableval=$enable_threads; gl_use_threads=$enableval else if test -n "$gl_use_threads_default"; then gl_use_threads="$gl_use_threads_default" else case "$host_os" in osf*) gl_use_threads=no ;; cygwin*) case `uname -r` in 1.[0-5].*) gl_use_threads=no ;; *) gl_use_threads=yes ;; esac ;; *) gl_use_threads=yes ;; esac fi fi if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then # For using : case "$host_os" in osf*) # On OSF/1, the compiler needs the flag -D_REENTRANT so that it # groks . cc also understands the flag -pthread, but # we don't use it because 1. gcc-2.95 doesn't understand -pthread, # 2. putting a flag into CPPFLAGS that has an effect on the linker # causes the AC_LINK_IFELSE test below to succeed unexpectedly, # leading to wrong values of LIBTHREAD and LTLIBTHREAD. CPPFLAGS="$CPPFLAGS -D_REENTRANT" ;; esac # Some systems optimize for single-threaded programs by default, and # need special flags to disable these optimizations. For example, the # definition of 'errno' in . case "$host_os" in aix* | freebsd*) CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE" ;; solaris*) CPPFLAGS="$CPPFLAGS -D_REENTRANT" ;; esac fi if test "X$prefix" = "XNONE"; then acl_final_prefix="$ac_default_prefix" else acl_final_prefix="$prefix" fi if test "X$exec_prefix" = "XNONE"; then acl_final_exec_prefix='${prefix}' else acl_final_exec_prefix="$exec_prefix" fi acl_save_prefix="$prefix" prefix="$acl_final_prefix" eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" prefix="$acl_save_prefix" # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi # Prepare PATH_SEPARATOR. # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which # contains only /bin. Note that ksh looks also at the FPATH variable, # so we have to set that as well for the test. PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ || PATH_SEPARATOR=';' } fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`echo "$ac_prog"| sed 's%\\\\%/%g'` while echo "$ac_prog" | grep "$re_direlt" > /dev/null 2>&1; do ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${acl_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then acl_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$acl_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then acl_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$acl_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${acl_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$acl_cv_prog_gnu_ld" >&6; } with_gnu_ld=$acl_cv_prog_gnu_ld { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shared library run path origin" >&5 $as_echo_n "checking for shared library run path origin... " >&6; } if ${acl_cv_rpath+:} false; then : $as_echo_n "(cached) " >&6 else CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh . ./conftest.sh rm -f ./conftest.sh acl_cv_rpath=done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_rpath" >&5 $as_echo "$acl_cv_rpath" >&6; } wl="$acl_cv_wl" acl_libext="$acl_cv_libext" acl_shlibext="$acl_cv_shlibext" acl_libname_spec="$acl_cv_libname_spec" acl_library_names_spec="$acl_cv_library_names_spec" acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" acl_hardcode_direct="$acl_cv_hardcode_direct" acl_hardcode_minus_L="$acl_cv_hardcode_minus_L" # Check whether --enable-rpath was given. if test "${enable_rpath+set}" = set; then : enableval=$enable_rpath; : else enable_rpath=yes fi acl_libdirstem=lib acl_libdirstem2= case "$host_os" in solaris*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit host" >&5 $as_echo_n "checking for 64-bit host... " >&6; } if ${gl_cv_solaris_64bit+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef _LP64 sixtyfour bits #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "sixtyfour bits" >/dev/null 2>&1; then : gl_cv_solaris_64bit=yes else gl_cv_solaris_64bit=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_solaris_64bit" >&5 $as_echo "$gl_cv_solaris_64bit" >&6; } if test $gl_cv_solaris_64bit = yes; then acl_libdirstem=lib/64 case "$host_cpu" in sparc*) acl_libdirstem2=lib/sparcv9 ;; i*86 | x86_64) acl_libdirstem2=lib/amd64 ;; esac fi ;; *) searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` if test -n "$searchpath"; then acl_save_IFS="${IFS= }"; IFS=":" for searchdir in $searchpath; do if test -d "$searchdir"; then case "$searchdir" in */lib64/ | */lib64 ) acl_libdirstem=lib64 ;; */../ | */.. ) # Better ignore directories of this form. They are misleading. ;; *) searchdir=`cd "$searchdir" && pwd` case "$searchdir" in */lib64 ) acl_libdirstem=lib64 ;; esac ;; esac fi done IFS="$acl_save_IFS" fi ;; esac test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem" gl_threads_api=none LIBTHREAD= LTLIBTHREAD= LIBMULTITHREAD= LTLIBMULTITHREAD= if test "$gl_use_threads" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether imported symbols can be declared weak" >&5 $as_echo_n "checking whether imported symbols can be declared weak... " >&6; } if ${gl_cv_have_weak+:} false; then : $as_echo_n "(cached) " >&6 else gl_cv_have_weak=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ extern void xyzzy (); #pragma weak xyzzy int main () { xyzzy(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : gl_cv_have_weak=maybe fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test $gl_cv_have_weak = maybe; then if test "$cross_compiling" = yes; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __ELF__ Extensible Linking Format #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "Extensible Linking Format" >/dev/null 2>&1; then : gl_cv_have_weak="guessing yes" else gl_cv_have_weak="guessing no" fi rm -f conftest* else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #pragma weak fputs int main () { return (fputs == NULL); } _ACEOF if ac_fn_c_try_run "$LINENO"; then : gl_cv_have_weak=yes else gl_cv_have_weak=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_have_weak" >&5 $as_echo "$gl_cv_have_weak" >&6; } if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then # On OSF/1, the compiler needs the flag -pthread or -D_REENTRANT so that # it groks . It's added above, in gl_THREADLIB_EARLY_BODY. ac_fn_c_check_header_mongrel "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default" if test "x$ac_cv_header_pthread_h" = xyes; then : gl_have_pthread_h=yes else gl_have_pthread_h=no fi if test "$gl_have_pthread_h" = yes; then # Other possible tests: # -lpthreads (FSU threads, PCthreads) # -lgthreads gl_have_pthread= # Test whether both pthread_mutex_lock and pthread_mutexattr_init exist # in libc. IRIX 6.5 has the first one in both libc and libpthread, but # the second one only in libpthread, and lock.c needs it. # # If -pthread works, prefer it to -lpthread, since Ubuntu 14.04 # needs -pthread for some reason. See: # http://lists.gnu.org/archive/html/bug-gnulib/2014-09/msg00023.html save_LIBS=$LIBS for gl_pthread in '' '-pthread'; do LIBS="$LIBS $gl_pthread" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include pthread_mutex_t m; pthread_mutexattr_t ma; int main () { pthread_mutex_lock (&m); pthread_mutexattr_init (&ma); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : gl_have_pthread=yes LIBTHREAD=$gl_pthread LTLIBTHREAD=$gl_pthread LIBMULTITHREAD=$gl_pthread LTLIBMULTITHREAD=$gl_pthread fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$save_LIBS test -n "$gl_have_pthread" && break done # Test for libpthread by looking for pthread_kill. (Not pthread_self, # since it is defined as a macro on OSF/1.) if test -n "$gl_have_pthread" && test -z "$LIBTHREAD"; then # The program links fine without libpthread. But it may actually # need to link with libpthread in order to create multiple threads. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_kill in -lpthread" >&5 $as_echo_n "checking for pthread_kill in -lpthread... " >&6; } if ${ac_cv_lib_pthread_pthread_kill+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pthread_kill (); int main () { return pthread_kill (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pthread_pthread_kill=yes else ac_cv_lib_pthread_pthread_kill=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_kill" >&5 $as_echo "$ac_cv_lib_pthread_pthread_kill" >&6; } if test "x$ac_cv_lib_pthread_pthread_kill" = xyes; then : LIBMULTITHREAD=-lpthread LTLIBMULTITHREAD=-lpthread # On Solaris and HP-UX, most pthread functions exist also in libc. # Therefore pthread_in_use() needs to actually try to create a # thread: pthread_create from libc will fail, whereas # pthread_create will actually create a thread. case "$host_os" in solaris* | hpux*) $as_echo "#define PTHREAD_IN_USE_DETECTION_HARD 1" >>confdefs.h esac fi elif test -z "$gl_have_pthread"; then # Some library is needed. Try libpthread and libc_r. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_kill in -lpthread" >&5 $as_echo_n "checking for pthread_kill in -lpthread... " >&6; } if ${ac_cv_lib_pthread_pthread_kill+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pthread_kill (); int main () { return pthread_kill (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pthread_pthread_kill=yes else ac_cv_lib_pthread_pthread_kill=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_kill" >&5 $as_echo "$ac_cv_lib_pthread_pthread_kill" >&6; } if test "x$ac_cv_lib_pthread_pthread_kill" = xyes; then : gl_have_pthread=yes LIBTHREAD=-lpthread LTLIBTHREAD=-lpthread LIBMULTITHREAD=-lpthread LTLIBMULTITHREAD=-lpthread fi if test -z "$gl_have_pthread"; then # For FreeBSD 4. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_kill in -lc_r" >&5 $as_echo_n "checking for pthread_kill in -lc_r... " >&6; } if ${ac_cv_lib_c_r_pthread_kill+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc_r $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pthread_kill (); int main () { return pthread_kill (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_c_r_pthread_kill=yes else ac_cv_lib_c_r_pthread_kill=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_r_pthread_kill" >&5 $as_echo "$ac_cv_lib_c_r_pthread_kill" >&6; } if test "x$ac_cv_lib_c_r_pthread_kill" = xyes; then : gl_have_pthread=yes LIBTHREAD=-lc_r LTLIBTHREAD=-lc_r LIBMULTITHREAD=-lc_r LTLIBMULTITHREAD=-lc_r fi fi fi if test -n "$gl_have_pthread"; then gl_threads_api=posix $as_echo "#define USE_POSIX_THREADS 1" >>confdefs.h if test -n "$LIBMULTITHREAD" || test -n "$LTLIBMULTITHREAD"; then if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then $as_echo "#define USE_POSIX_THREADS_WEAK 1" >>confdefs.h LIBTHREAD= LTLIBTHREAD= fi fi fi fi fi if test -z "$gl_have_pthread"; then if test "$gl_use_threads" = yes || test "$gl_use_threads" = solaris; then gl_have_solaristhread= gl_save_LIBS="$LIBS" LIBS="$LIBS -lthread" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { thr_self(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : gl_have_solaristhread=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$gl_save_LIBS" if test -n "$gl_have_solaristhread"; then gl_threads_api=solaris LIBTHREAD=-lthread LTLIBTHREAD=-lthread LIBMULTITHREAD="$LIBTHREAD" LTLIBMULTITHREAD="$LTLIBTHREAD" $as_echo "#define USE_SOLARIS_THREADS 1" >>confdefs.h if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then $as_echo "#define USE_SOLARIS_THREADS_WEAK 1" >>confdefs.h LIBTHREAD= LTLIBTHREAD= fi fi fi fi if test "$gl_use_threads" = pth; then gl_save_CPPFLAGS="$CPPFLAGS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libpth" >&5 $as_echo_n "checking how to link with libpth... " >&6; } if ${ac_cv_libpth_libs+:} false; then : $as_echo_n "(cached) " >&6 else use_additional=yes acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" # Check whether --with-libpth-prefix was given. if test "${with_libpth_prefix+set}" = set; then : withval=$with_libpth_prefix; if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" else additional_includedir="$withval/include" additional_libdir="$withval/$acl_libdirstem" if test "$acl_libdirstem2" != "$acl_libdirstem" \ && ! test -d "$withval/$acl_libdirstem"; then additional_libdir="$withval/$acl_libdirstem2" fi fi fi fi LIBPTH= LTLIBPTH= INCPTH= LIBPTH_PREFIX= HAVE_LIBPTH= rpathdirs= ltrpathdirs= names_already_handled= names_next_round='pth ' while test -n "$names_next_round"; do names_this_round="$names_next_round" names_next_round= for name in $names_this_round; do already_handled= for n in $names_already_handled; do if test "$n" = "$name"; then already_handled=yes break fi done if test -z "$already_handled"; then names_already_handled="$names_already_handled $name" uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'` eval value=\"\$HAVE_LIB$uppername\" if test -n "$value"; then if test "$value" = yes; then eval value=\"\$LIB$uppername\" test -z "$value" || LIBPTH="${LIBPTH}${LIBPTH:+ }$value" eval value=\"\$LTLIB$uppername\" test -z "$value" || LTLIBPTH="${LTLIBPTH}${LTLIBPTH:+ }$value" else : fi else found_dir= found_la= found_so= found_a= eval libname=\"$acl_libname_spec\" # typically: libname=lib$name if test -n "$acl_shlibext"; then shrext=".$acl_shlibext" # typically: shrext=.so else shrext= fi if test $use_additional = yes; then dir="$additional_libdir" if test -n "$acl_shlibext"; then if test -f "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then ver=`(cd "$dir" && \ for f in "$libname$shrext".*; do echo "$f"; done \ | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do if test -f "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break fi done fi fi fi if test "X$found_dir" = "X"; then if test -f "$dir/$libname.$acl_libext"; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi fi if test "X$found_dir" != "X"; then if test -f "$dir/$libname.la"; then found_la="$dir/$libname.la" fi fi fi if test "X$found_dir" = "X"; then for x in $LDFLAGS $LTLIBPTH; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" case "$x" in -L*) dir=`echo "X$x" | sed -e 's/^X-L//'` if test -n "$acl_shlibext"; then if test -f "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then ver=`(cd "$dir" && \ for f in "$libname$shrext".*; do echo "$f"; done \ | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do if test -f "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break fi done fi fi fi if test "X$found_dir" = "X"; then if test -f "$dir/$libname.$acl_libext"; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi fi if test "X$found_dir" != "X"; then if test -f "$dir/$libname.la"; then found_la="$dir/$libname.la" fi fi ;; esac if test "X$found_dir" != "X"; then break fi done fi if test "X$found_dir" != "X"; then LTLIBPTH="${LTLIBPTH}${LTLIBPTH:+ }-L$found_dir -l$name" if test "X$found_so" != "X"; then if test "$enable_rpath" = no \ || test "X$found_dir" = "X/usr/$acl_libdirstem" \ || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then LIBPTH="${LIBPTH}${LIBPTH:+ }$found_so" else haveit= for x in $ltrpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $found_dir" fi if test "$acl_hardcode_direct" = yes; then LIBPTH="${LIBPTH}${LIBPTH:+ }$found_so" else if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then LIBPTH="${LIBPTH}${LIBPTH:+ }$found_so" haveit= for x in $rpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $found_dir" fi else haveit= for x in $LDFLAGS $LIBPTH; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then LIBPTH="${LIBPTH}${LIBPTH:+ }-L$found_dir" fi if test "$acl_hardcode_minus_L" != no; then LIBPTH="${LIBPTH}${LIBPTH:+ }$found_so" else LIBPTH="${LIBPTH}${LIBPTH:+ }-l$name" fi fi fi fi else if test "X$found_a" != "X"; then LIBPTH="${LIBPTH}${LIBPTH:+ }$found_a" else LIBPTH="${LIBPTH}${LIBPTH:+ }-L$found_dir -l$name" fi fi additional_includedir= case "$found_dir" in */$acl_libdirstem | */$acl_libdirstem/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` if test "$name" = 'pth'; then LIBPTH_PREFIX="$basedir" fi additional_includedir="$basedir/include" ;; */$acl_libdirstem2 | */$acl_libdirstem2/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'` if test "$name" = 'pth'; then LIBPTH_PREFIX="$basedir" fi additional_includedir="$basedir/include" ;; esac if test "X$additional_includedir" != "X"; then if test "X$additional_includedir" != "X/usr/include"; then haveit= if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then for x in $CPPFLAGS $INCPTH; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_includedir"; then INCPTH="${INCPTH}${INCPTH:+ }-I$additional_includedir" fi fi fi fi fi if test -n "$found_la"; then save_libdir="$libdir" case "$found_la" in */* | *\\*) . "$found_la" ;; *) . "./$found_la" ;; esac libdir="$save_libdir" for dep in $dependency_libs; do case "$dep" in -L*) additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \ && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then haveit= if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \ || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then haveit= for x in $LDFLAGS $LIBPTH; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LIBPTH="${LIBPTH}${LIBPTH:+ }-L$additional_libdir" fi fi haveit= for x in $LDFLAGS $LTLIBPTH; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LTLIBPTH="${LTLIBPTH}${LTLIBPTH:+ }-L$additional_libdir" fi fi fi fi ;; -R*) dir=`echo "X$dep" | sed -e 's/^X-R//'` if test "$enable_rpath" != no; then haveit= for x in $rpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $dir" fi haveit= for x in $ltrpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $dir" fi fi ;; -l*) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` ;; *.la) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` ;; *) LIBPTH="${LIBPTH}${LIBPTH:+ }$dep" LTLIBPTH="${LTLIBPTH}${LTLIBPTH:+ }$dep" ;; esac done fi else LIBPTH="${LIBPTH}${LIBPTH:+ }-l$name" LTLIBPTH="${LTLIBPTH}${LTLIBPTH:+ }-l$name" fi fi fi done done if test "X$rpathdirs" != "X"; then if test -n "$acl_hardcode_libdir_separator"; then alldirs= for found_dir in $rpathdirs; do alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" done acl_save_libdir="$libdir" libdir="$alldirs" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBPTH="${LIBPTH}${LIBPTH:+ }$flag" else for found_dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$found_dir" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBPTH="${LIBPTH}${LIBPTH:+ }$flag" done fi fi if test "X$ltrpathdirs" != "X"; then for found_dir in $ltrpathdirs; do LTLIBPTH="${LTLIBPTH}${LTLIBPTH:+ }-R$found_dir" done fi ac_cv_libpth_libs="$LIBPTH" ac_cv_libpth_ltlibs="$LTLIBPTH" ac_cv_libpth_cppflags="$INCPTH" ac_cv_libpth_prefix="$LIBPTH_PREFIX" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libpth_libs" >&5 $as_echo "$ac_cv_libpth_libs" >&6; } LIBPTH="$ac_cv_libpth_libs" LTLIBPTH="$ac_cv_libpth_ltlibs" INCPTH="$ac_cv_libpth_cppflags" LIBPTH_PREFIX="$ac_cv_libpth_prefix" for element in $INCPTH; do haveit= for x in $CPPFLAGS; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X$element"; then haveit=yes break fi done if test -z "$haveit"; then CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" fi done HAVE_LIBPTH=yes gl_have_pth= gl_save_LIBS="$LIBS" LIBS="$LIBS $LIBPTH" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { pth_self(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : gl_have_pth=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$gl_save_LIBS" if test -n "$gl_have_pth"; then gl_threads_api=pth LIBTHREAD="$LIBPTH" LTLIBTHREAD="$LTLIBPTH" LIBMULTITHREAD="$LIBTHREAD" LTLIBMULTITHREAD="$LTLIBTHREAD" $as_echo "#define USE_PTH_THREADS 1" >>confdefs.h if test -n "$LIBMULTITHREAD" || test -n "$LTLIBMULTITHREAD"; then if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then $as_echo "#define USE_PTH_THREADS_WEAK 1" >>confdefs.h LIBTHREAD= LTLIBTHREAD= fi fi else CPPFLAGS="$gl_save_CPPFLAGS" fi fi if test -z "$gl_have_pthread"; then case "$gl_use_threads" in yes | windows | win32) # The 'win32' is for backward compatibility. if { case "$host_os" in mingw*) true;; *) false;; esac }; then gl_threads_api=windows $as_echo "#define USE_WINDOWS_THREADS 1" >>confdefs.h fi ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for multithread API to use" >&5 $as_echo_n "checking for multithread API to use... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_threads_api" >&5 $as_echo "$gl_threads_api" >&6; } if test "$gl_threads_api" = posix; then # OSF/1 4.0 and Mac OS X 10.1 lack the pthread_rwlock_t type and the # pthread_rwlock_* functions. ac_fn_c_check_type "$LINENO" "pthread_rwlock_t" "ac_cv_type_pthread_rwlock_t" "#include " if test "x$ac_cv_type_pthread_rwlock_t" = xyes; then : $as_echo "#define HAVE_PTHREAD_RWLOCK 1" >>confdefs.h fi # glibc defines PTHREAD_MUTEX_RECURSIVE as enum, not as a macro. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #if __FreeBSD__ == 4 error "No, in FreeBSD 4.0 recursive mutexes actually don't work." #elif (defined __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ \ && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070) error "No, in Mac OS X < 10.7 recursive mutexes actually don't work." #else int x = (int)PTHREAD_MUTEX_RECURSIVE; return !x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define HAVE_PTHREAD_MUTEX_RECURSIVE 1" >>confdefs.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi : use_additional=yes acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" # Check whether --with-libiconv-prefix was given. if test "${with_libiconv_prefix+set}" = set; then : withval=$with_libiconv_prefix; if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" else additional_includedir="$withval/include" additional_libdir="$withval/$acl_libdirstem" if test "$acl_libdirstem2" != "$acl_libdirstem" \ && ! test -d "$withval/$acl_libdirstem"; then additional_libdir="$withval/$acl_libdirstem2" fi fi fi fi LIBICONV= LTLIBICONV= INCICONV= LIBICONV_PREFIX= HAVE_LIBICONV= rpathdirs= ltrpathdirs= names_already_handled= names_next_round='iconv ' while test -n "$names_next_round"; do names_this_round="$names_next_round" names_next_round= for name in $names_this_round; do already_handled= for n in $names_already_handled; do if test "$n" = "$name"; then already_handled=yes break fi done if test -z "$already_handled"; then names_already_handled="$names_already_handled $name" uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'` eval value=\"\$HAVE_LIB$uppername\" if test -n "$value"; then if test "$value" = yes; then eval value=\"\$LIB$uppername\" test -z "$value" || LIBICONV="${LIBICONV}${LIBICONV:+ }$value" eval value=\"\$LTLIB$uppername\" test -z "$value" || LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$value" else : fi else found_dir= found_la= found_so= found_a= eval libname=\"$acl_libname_spec\" # typically: libname=lib$name if test -n "$acl_shlibext"; then shrext=".$acl_shlibext" # typically: shrext=.so else shrext= fi if test $use_additional = yes; then dir="$additional_libdir" if test -n "$acl_shlibext"; then if test -f "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then ver=`(cd "$dir" && \ for f in "$libname$shrext".*; do echo "$f"; done \ | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do if test -f "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break fi done fi fi fi if test "X$found_dir" = "X"; then if test -f "$dir/$libname.$acl_libext"; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi fi if test "X$found_dir" != "X"; then if test -f "$dir/$libname.la"; then found_la="$dir/$libname.la" fi fi fi if test "X$found_dir" = "X"; then for x in $LDFLAGS $LTLIBICONV; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" case "$x" in -L*) dir=`echo "X$x" | sed -e 's/^X-L//'` if test -n "$acl_shlibext"; then if test -f "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then ver=`(cd "$dir" && \ for f in "$libname$shrext".*; do echo "$f"; done \ | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do if test -f "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break fi done fi fi fi if test "X$found_dir" = "X"; then if test -f "$dir/$libname.$acl_libext"; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi fi if test "X$found_dir" != "X"; then if test -f "$dir/$libname.la"; then found_la="$dir/$libname.la" fi fi ;; esac if test "X$found_dir" != "X"; then break fi done fi if test "X$found_dir" != "X"; then LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$found_dir -l$name" if test "X$found_so" != "X"; then if test "$enable_rpath" = no \ || test "X$found_dir" = "X/usr/$acl_libdirstem" \ || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" else haveit= for x in $ltrpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $found_dir" fi if test "$acl_hardcode_direct" = yes; then LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" else if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" haveit= for x in $rpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $found_dir" fi else haveit= for x in $LDFLAGS $LIBICONV; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir" fi if test "$acl_hardcode_minus_L" != no; then LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" else LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" fi fi fi fi else if test "X$found_a" != "X"; then LIBICONV="${LIBICONV}${LIBICONV:+ }$found_a" else LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir -l$name" fi fi additional_includedir= case "$found_dir" in */$acl_libdirstem | */$acl_libdirstem/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` if test "$name" = 'iconv'; then LIBICONV_PREFIX="$basedir" fi additional_includedir="$basedir/include" ;; */$acl_libdirstem2 | */$acl_libdirstem2/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'` if test "$name" = 'iconv'; then LIBICONV_PREFIX="$basedir" fi additional_includedir="$basedir/include" ;; esac if test "X$additional_includedir" != "X"; then if test "X$additional_includedir" != "X/usr/include"; then haveit= if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then for x in $CPPFLAGS $INCICONV; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_includedir"; then INCICONV="${INCICONV}${INCICONV:+ }-I$additional_includedir" fi fi fi fi fi if test -n "$found_la"; then save_libdir="$libdir" case "$found_la" in */* | *\\*) . "$found_la" ;; *) . "./$found_la" ;; esac libdir="$save_libdir" for dep in $dependency_libs; do case "$dep" in -L*) additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \ && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then haveit= if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \ || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then haveit= for x in $LDFLAGS $LIBICONV; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LIBICONV="${LIBICONV}${LIBICONV:+ }-L$additional_libdir" fi fi haveit= for x in $LDFLAGS $LTLIBICONV; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$additional_libdir" fi fi fi fi ;; -R*) dir=`echo "X$dep" | sed -e 's/^X-R//'` if test "$enable_rpath" != no; then haveit= for x in $rpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $dir" fi haveit= for x in $ltrpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $dir" fi fi ;; -l*) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` ;; *.la) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` ;; *) LIBICONV="${LIBICONV}${LIBICONV:+ }$dep" LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$dep" ;; esac done fi else LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-l$name" fi fi fi done done if test "X$rpathdirs" != "X"; then if test -n "$acl_hardcode_libdir_separator"; then alldirs= for found_dir in $rpathdirs; do alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" done acl_save_libdir="$libdir" libdir="$alldirs" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" else for found_dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$found_dir" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" done fi fi if test "X$ltrpathdirs" != "X"; then for found_dir in $ltrpathdirs; do LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-R$found_dir" done fi am_save_CPPFLAGS="$CPPFLAGS" for element in $INCICONV; do haveit= for x in $CPPFLAGS; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X$element"; then haveit=yes break fi done if test -z "$haveit"; then CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv" >&5 $as_echo_n "checking for iconv... " >&6; } if ${am_cv_func_iconv+:} false; then : $as_echo_n "(cached) " >&6 else am_cv_func_iconv="no, consider installing GNU libiconv" am_cv_lib_iconv=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : am_cv_func_iconv=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "$am_cv_func_iconv" != yes; then am_save_LIBS="$LIBS" LIBS="$LIBS $LIBICONV" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : am_cv_lib_iconv=yes am_cv_func_iconv=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$am_save_LIBS" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv" >&5 $as_echo "$am_cv_func_iconv" >&6; } if test "$am_cv_func_iconv" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working iconv" >&5 $as_echo_n "checking for working iconv... " >&6; } if ${am_cv_func_iconv_works+:} false; then : $as_echo_n "(cached) " >&6 else am_save_LIBS="$LIBS" if test $am_cv_lib_iconv = yes; then LIBS="$LIBS $LIBICONV" fi if test "$cross_compiling" = yes; then : case "$host_os" in aix* | hpux*) am_cv_func_iconv_works="guessing no" ;; *) am_cv_func_iconv_works="guessing yes" ;; esac else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { int result = 0; /* Test against AIX 5.1 bug: Failures are not distinguishable from successful returns. */ { iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8"); if (cd_utf8_to_88591 != (iconv_t)(-1)) { static const char input[] = "\342\202\254"; /* EURO SIGN */ char buf[10]; const char *inptr = input; size_t inbytesleft = strlen (input); char *outptr = buf; size_t outbytesleft = sizeof (buf); size_t res = iconv (cd_utf8_to_88591, (char **) &inptr, &inbytesleft, &outptr, &outbytesleft); if (res == 0) result |= 1; iconv_close (cd_utf8_to_88591); } } /* Test against Solaris 10 bug: Failures are not distinguishable from successful returns. */ { iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646"); if (cd_ascii_to_88591 != (iconv_t)(-1)) { static const char input[] = "\263"; char buf[10]; const char *inptr = input; size_t inbytesleft = strlen (input); char *outptr = buf; size_t outbytesleft = sizeof (buf); size_t res = iconv (cd_ascii_to_88591, (char **) &inptr, &inbytesleft, &outptr, &outbytesleft); if (res == 0) result |= 2; iconv_close (cd_ascii_to_88591); } } /* Test against AIX 6.1..7.1 bug: Buffer overrun. */ { iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1"); if (cd_88591_to_utf8 != (iconv_t)(-1)) { static const char input[] = "\304"; static char buf[2] = { (char)0xDE, (char)0xAD }; const char *inptr = input; size_t inbytesleft = 1; char *outptr = buf; size_t outbytesleft = 1; size_t res = iconv (cd_88591_to_utf8, (char **) &inptr, &inbytesleft, &outptr, &outbytesleft); if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD) result |= 4; iconv_close (cd_88591_to_utf8); } } #if 0 /* This bug could be worked around by the caller. */ /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */ { iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591"); if (cd_88591_to_utf8 != (iconv_t)(-1)) { static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; char buf[50]; const char *inptr = input; size_t inbytesleft = strlen (input); char *outptr = buf; size_t outbytesleft = sizeof (buf); size_t res = iconv (cd_88591_to_utf8, (char **) &inptr, &inbytesleft, &outptr, &outbytesleft); if ((int)res > 0) result |= 8; iconv_close (cd_88591_to_utf8); } } #endif /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is provided. */ if (/* Try standardized names. */ iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1) /* Try IRIX, OSF/1 names. */ && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1) /* Try AIX names. */ && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1) /* Try HP-UX names. */ && iconv_open ("utf8", "eucJP") == (iconv_t)(-1)) result |= 16; return result; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : am_cv_func_iconv_works=yes else am_cv_func_iconv_works=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi LIBS="$am_save_LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv_works" >&5 $as_echo "$am_cv_func_iconv_works" >&6; } case "$am_cv_func_iconv_works" in *no) am_func_iconv=no am_cv_lib_iconv=no ;; *) am_func_iconv=yes ;; esac else am_func_iconv=no am_cv_lib_iconv=no fi if test "$am_func_iconv" = yes; then $as_echo "#define HAVE_ICONV 1" >>confdefs.h fi if test "$am_cv_lib_iconv" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libiconv" >&5 $as_echo_n "checking how to link with libiconv... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBICONV" >&5 $as_echo "$LIBICONV" >&6; } else CPPFLAGS="$am_save_CPPFLAGS" LIBICONV= LTLIBICONV= fi if test "$am_cv_func_iconv" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv declaration" >&5 $as_echo_n "checking for iconv declaration... " >&6; } if ${am_cv_proto_iconv+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include extern #ifdef __cplusplus "C" #endif #if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); #else size_t iconv(); #endif int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : am_cv_proto_iconv_arg1="" else am_cv_proto_iconv_arg1="const" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);" fi am_cv_proto_iconv=`echo "$am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_proto_iconv" >&5 $as_echo " $am_cv_proto_iconv" >&6; } cat >>confdefs.h <<_ACEOF #define ICONV_CONST $am_cv_proto_iconv_arg1 _ACEOF fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (int a) { a = __builtin_expect (a, 10); return a == 10 ? 0 : 1; } int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : $as_echo "#define HAVE_BUILTIN_EXPECT 1" >>confdefs.h fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext for ac_header in argz.h inttypes.h limits.h unistd.h sys/param.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in getcwd getegid geteuid getgid getuid mempcpy munmap \ stpcpy strcasecmp strdup strtoul tsearch uselocale argz_count \ argz_stringify argz_next __fsetlocking do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_c_check_decl "$LINENO" "feof_unlocked" "ac_cv_have_decl_feof_unlocked" "#include " if test "x$ac_cv_have_decl_feof_unlocked" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_FEOF_UNLOCKED $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "fgets_unlocked" "ac_cv_have_decl_fgets_unlocked" "#include " if test "x$ac_cv_have_decl_fgets_unlocked" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_FGETS_UNLOCKED $ac_have_decl _ACEOF for ac_prog in bison do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_INTLBISON+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$INTLBISON"; then ac_cv_prog_INTLBISON="$INTLBISON" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_INTLBISON="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi INTLBISON=$ac_cv_prog_INTLBISON if test -n "$INTLBISON"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLBISON" >&5 $as_echo "$INTLBISON" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$INTLBISON" && break done if test -z "$INTLBISON"; then ac_verc_fail=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: checking version of bison" >&5 $as_echo_n "checking version of bison... " >&6; } ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'` case $ac_prog_version in '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; 2.[7-9]* | [3-9].*) ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_prog_version" >&5 $as_echo "$ac_prog_version" >&6; } fi if test $ac_verc_fail = yes; then INTLBISON=: fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long long int" >&5 $as_echo_n "checking for long long int... " >&6; } if ${ac_cv_type_long_long_int+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_type_long_long_int=yes if test "x${ac_cv_prog_cc_c99-no}" = xno; then ac_cv_type_long_long_int=$ac_cv_type_unsigned_long_long_int if test $ac_cv_type_long_long_int = yes; then if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifndef LLONG_MAX # define HALF \ (1LL << (sizeof (long long int) * CHAR_BIT - 2)) # define LLONG_MAX (HALF - 1 + HALF) #endif int main () { long long int n = 1; int i; for (i = 0; ; i++) { long long int m = n << i; if (m >> i != n) return 1; if (LLONG_MAX / 2 < m) break; } return 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_type_long_long_int=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_long_int" >&5 $as_echo "$ac_cv_type_long_long_int" >&6; } if test $ac_cv_type_long_long_int = yes; then $as_echo "#define HAVE_LONG_LONG_INT 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wchar_t" >&5 $as_echo_n "checking for wchar_t... " >&6; } if ${gt_cv_c_wchar_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include wchar_t foo = (wchar_t)'\0'; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : gt_cv_c_wchar_t=yes else gt_cv_c_wchar_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_c_wchar_t" >&5 $as_echo "$gt_cv_c_wchar_t" >&6; } if test $gt_cv_c_wchar_t = yes; then $as_echo "#define HAVE_WCHAR_T 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wint_t" >&5 $as_echo_n "checking for wint_t... " >&6; } if ${gt_cv_c_wint_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Tru64 with Desktop Toolkit C has a bug: must be included before . BSD/OS 4.0.1 has a bug: , and must be included before . */ #include #include #include #include wint_t foo = (wchar_t)'\0'; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : gt_cv_c_wint_t=yes else gt_cv_c_wint_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_c_wint_t" >&5 $as_echo "$gt_cv_c_wint_t" >&6; } if test $gt_cv_c_wint_t = yes; then $as_echo "#define HAVE_WINT_T 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for intmax_t" >&5 $as_echo_n "checking for intmax_t... " >&6; } if ${gt_cv_c_intmax_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if HAVE_STDINT_H_WITH_UINTMAX #include #endif #if HAVE_INTTYPES_H_WITH_UINTMAX #include #endif int main () { intmax_t x = -1; return !x; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : gt_cv_c_intmax_t=yes else gt_cv_c_intmax_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_c_intmax_t" >&5 $as_echo "$gt_cv_c_intmax_t" >&6; } if test $gt_cv_c_intmax_t = yes; then $as_echo "#define HAVE_INTMAX_T 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether printf() supports POSIX/XSI format strings" >&5 $as_echo_n "checking whether printf() supports POSIX/XSI format strings... " >&6; } if ${gt_cv_func_printf_posix+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if defined __NetBSD__ || defined __BEOS__ || defined _MSC_VER || defined __MINGW32__ || defined __CYGWIN__ notposix #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "notposix" >/dev/null 2>&1; then : gt_cv_func_printf_posix="guessing no" else gt_cv_func_printf_posix="guessing yes" fi rm -f conftest* else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include /* The string "%2$d %1$d", with dollar characters protected from the shell's dollar expansion (possibly an autoconf bug). */ static char format[] = { '%', '2', '$', 'd', ' ', '%', '1', '$', 'd', '\0' }; static char buf[100]; int main () { sprintf (buf, format, 33, 55); return (strcmp (buf, "55 33") != 0); } _ACEOF if ac_fn_c_try_run "$LINENO"; then : gt_cv_func_printf_posix=yes else gt_cv_func_printf_posix=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_printf_posix" >&5 $as_echo "$gt_cv_func_printf_posix" >&6; } case $gt_cv_func_printf_posix in *yes) $as_echo "#define HAVE_POSIX_PRINTF 1" >>confdefs.h ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C Library >= 2.1 or uClibc" >&5 $as_echo_n "checking whether we are using the GNU C Library >= 2.1 or uClibc... " >&6; } if ${ac_cv_gnu_library_2_1+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifdef __GNU_LIBRARY__ #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2) Lucky GNU user #endif #endif #ifdef __UCLIBC__ Lucky user #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "Lucky" >/dev/null 2>&1; then : ac_cv_gnu_library_2_1=yes else ac_cv_gnu_library_2_1=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gnu_library_2_1" >&5 $as_echo "$ac_cv_gnu_library_2_1" >&6; } GLIBC21="$ac_cv_gnu_library_2_1" for ac_header in stdint.h do : ac_fn_c_check_header_mongrel "$LINENO" "stdint.h" "ac_cv_header_stdint_h" "$ac_includes_default" if test "x$ac_cv_header_stdint_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STDINT_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SIZE_MAX" >&5 $as_echo_n "checking for SIZE_MAX... " >&6; } if ${gl_cv_size_max+:} false; then : $as_echo_n "(cached) " >&6 else gl_cv_size_max= cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #if HAVE_STDINT_H #include #endif #ifdef SIZE_MAX Found it #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "Found it" >/dev/null 2>&1; then : gl_cv_size_max=yes fi rm -f conftest* if test -z "$gl_cv_size_max"; then if ac_fn_c_compute_int "$LINENO" "sizeof (size_t) * CHAR_BIT - 1" "size_t_bits_minus_1" "#include #include "; then : else size_t_bits_minus_1= fi if ac_fn_c_compute_int "$LINENO" "sizeof (size_t) <= sizeof (unsigned int)" "fits_in_uint" "#include "; then : else fits_in_uint= fi if test -n "$size_t_bits_minus_1" && test -n "$fits_in_uint"; then if test $fits_in_uint = 1; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include extern size_t foo; extern unsigned long foo; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : fits_in_uint=0 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $fits_in_uint = 1; then gl_cv_size_max="(((1U << $size_t_bits_minus_1) - 1) * 2 + 1)" else gl_cv_size_max="(((1UL << $size_t_bits_minus_1) - 1) * 2 + 1)" fi else gl_cv_size_max='((size_t)~(size_t)0)' fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_size_max" >&5 $as_echo "$gl_cv_size_max" >&6; } if test "$gl_cv_size_max" != yes; then cat >>confdefs.h <<_ACEOF #define SIZE_MAX $gl_cv_size_max _ACEOF fi for ac_header in stdint.h do : ac_fn_c_check_header_mongrel "$LINENO" "stdint.h" "ac_cv_header_stdint_h" "$ac_includes_default" if test "x$ac_cv_header_stdint_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STDINT_H 1 _ACEOF fi done for ac_func in $ac_func_list do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fcntl.h" >&5 $as_echo_n "checking for working fcntl.h... " >&6; } if ${gl_cv_header_working_fcntl_h+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : gl_cv_header_working_fcntl_h=cross-compiling else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if HAVE_UNISTD_H # include #else /* on Windows with MSVC */ # include # include # defined sleep(n) _sleep ((n) * 1000) #endif #include #ifndef O_NOATIME #define O_NOATIME 0 #endif #ifndef O_NOFOLLOW #define O_NOFOLLOW 0 #endif static int const constants[] = { O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC, O_APPEND, O_NONBLOCK, O_SYNC, O_ACCMODE, O_RDONLY, O_RDWR, O_WRONLY }; int main () { int result = !constants; #if HAVE_SYMLINK { static char const sym[] = "conftest.sym"; if (symlink ("/dev/null", sym) != 0) result |= 2; else { int fd = open (sym, O_WRONLY | O_NOFOLLOW | O_CREAT, 0); if (fd >= 0) { close (fd); result |= 4; } } if (unlink (sym) != 0 || symlink (".", sym) != 0) result |= 2; else { int fd = open (sym, O_RDONLY | O_NOFOLLOW); if (fd >= 0) { close (fd); result |= 4; } } unlink (sym); } #endif { static char const file[] = "confdefs.h"; int fd = open (file, O_RDONLY | O_NOATIME); if (fd < 0) result |= 8; else { struct stat st0; if (fstat (fd, &st0) != 0) result |= 16; else { char c; sleep (1); if (read (fd, &c, 1) != 1) result |= 24; else { if (close (fd) != 0) result |= 32; else { struct stat st1; if (stat (file, &st1) != 0) result |= 40; else if (st0.st_atime != st1.st_atime) result |= 64; } } } } } return result; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : gl_cv_header_working_fcntl_h=yes else case $? in #( 4) gl_cv_header_working_fcntl_h='no (bad O_NOFOLLOW)';; #( 64) gl_cv_header_working_fcntl_h='no (bad O_NOATIME)';; #( 68) gl_cv_header_working_fcntl_h='no (bad O_NOATIME, O_NOFOLLOW)';; #( *) gl_cv_header_working_fcntl_h='no';; esac fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_header_working_fcntl_h" >&5 $as_echo "$gl_cv_header_working_fcntl_h" >&6; } case $gl_cv_header_working_fcntl_h in #( *O_NOATIME* | no | cross-compiling) ac_val=0;; #( *) ac_val=1;; esac cat >>confdefs.h <<_ACEOF #define HAVE_WORKING_O_NOATIME $ac_val _ACEOF case $gl_cv_header_working_fcntl_h in #( *O_NOFOLLOW* | no | cross-compiling) ac_val=0;; #( *) ac_val=1;; esac cat >>confdefs.h <<_ACEOF #define HAVE_WORKING_O_NOFOLLOW $ac_val _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CFPreferencesCopyAppValue" >&5 $as_echo_n "checking for CFPreferencesCopyAppValue... " >&6; } if ${gt_cv_func_CFPreferencesCopyAppValue+:} false; then : $as_echo_n "(cached) " >&6 else gt_save_LIBS="$LIBS" LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { CFPreferencesCopyAppValue(NULL, NULL) ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : gt_cv_func_CFPreferencesCopyAppValue=yes else gt_cv_func_CFPreferencesCopyAppValue=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$gt_save_LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_CFPreferencesCopyAppValue" >&5 $as_echo "$gt_cv_func_CFPreferencesCopyAppValue" >&6; } if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then $as_echo "#define HAVE_CFPREFERENCESCOPYAPPVALUE 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CFLocaleCopyCurrent" >&5 $as_echo_n "checking for CFLocaleCopyCurrent... " >&6; } if ${gt_cv_func_CFLocaleCopyCurrent+:} false; then : $as_echo_n "(cached) " >&6 else gt_save_LIBS="$LIBS" LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { CFLocaleCopyCurrent(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : gt_cv_func_CFLocaleCopyCurrent=yes else gt_cv_func_CFLocaleCopyCurrent=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$gt_save_LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_CFLocaleCopyCurrent" >&5 $as_echo "$gt_cv_func_CFLocaleCopyCurrent" >&6; } if test $gt_cv_func_CFLocaleCopyCurrent = yes; then $as_echo "#define HAVE_CFLOCALECOPYCURRENT 1" >>confdefs.h fi INTL_MACOSX_LIBS= if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation" fi case "$enable_silent_rules" in yes) INTL_DEFAULT_VERBOSITY=0;; no) INTL_DEFAULT_VERBOSITY=1;; *) INTL_DEFAULT_VERBOSITY=1;; esac ac_fn_c_check_type "$LINENO" "ptrdiff_t" "ac_cv_type_ptrdiff_t" "$ac_includes_default" if test "x$ac_cv_type_ptrdiff_t" = xyes; then : else $as_echo "#define ptrdiff_t long" >>confdefs.h fi for ac_header in features.h stddef.h stdlib.h string.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in asprintf fwprintf newlocale putenv setenv setlocale \ snprintf strnlen wcslen wcsnlen mbrtowc wcrtomb do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_c_check_decl "$LINENO" "_snprintf" "ac_cv_have_decl__snprintf" "#include " if test "x$ac_cv_have_decl__snprintf" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL__SNPRINTF $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "_snwprintf" "ac_cv_have_decl__snwprintf" "#include " if test "x$ac_cv_have_decl__snwprintf" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL__SNWPRINTF $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "getc_unlocked" "ac_cv_have_decl_getc_unlocked" "#include " if test "x$ac_cv_have_decl_getc_unlocked" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_GETC_UNLOCKED $ac_have_decl _ACEOF case $gt_cv_func_printf_posix in *yes) HAVE_POSIX_PRINTF=1 ;; *) HAVE_POSIX_PRINTF=0 ;; esac if test "$ac_cv_func_asprintf" = yes; then HAVE_ASPRINTF=1 else HAVE_ASPRINTF=0 fi if test "$ac_cv_func_snprintf" = yes; then HAVE_SNPRINTF=1 else HAVE_SNPRINTF=0 fi if test "$ac_cv_func_newlocale" = yes; then HAVE_NEWLOCALE=1 else HAVE_NEWLOCALE=0 fi if test "$ac_cv_func_wprintf" = yes; then HAVE_WPRINTF=1 else HAVE_WPRINTF=0 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_langinfo and CODESET" >&5 $as_echo_n "checking for nl_langinfo and CODESET... " >&6; } if ${am_cv_langinfo_codeset+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { char* cs = nl_langinfo(CODESET); return !cs; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : am_cv_langinfo_codeset=yes else am_cv_langinfo_codeset=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_langinfo_codeset" >&5 $as_echo "$am_cv_langinfo_codeset" >&6; } if test $am_cv_langinfo_codeset = yes; then $as_echo "#define HAVE_LANGINFO_CODESET 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LC_MESSAGES" >&5 $as_echo_n "checking for LC_MESSAGES... " >&6; } if ${gt_cv_val_LC_MESSAGES+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { return LC_MESSAGES ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : gt_cv_val_LC_MESSAGES=yes else gt_cv_val_LC_MESSAGES=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_val_LC_MESSAGES" >&5 $as_echo "$gt_cv_val_LC_MESSAGES" >&6; } if test $gt_cv_val_LC_MESSAGES = yes; then $as_echo "#define HAVE_LC_MESSAGES 1" >>confdefs.h fi if test "$enable_shared" = yes; then case "$host_os" in mingw* | cygwin*) is_woe32dll=yes ;; *) is_woe32dll=no ;; esac else is_woe32dll=no fi WOE32DLL=$is_woe32dll case "$host_os" in mingw* | cygwin*) is_woe32=yes ;; *) is_woe32=no ;; esac WOE32=$is_woe32 if test $WOE32 = yes; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}windres", so it can be a program name with args. set dummy ${ac_tool_prefix}windres; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_WINDRES+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$WINDRES"; then ac_cv_prog_WINDRES="$WINDRES" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_WINDRES="${ac_tool_prefix}windres" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi WINDRES=$ac_cv_prog_WINDRES if test -n "$WINDRES"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WINDRES" >&5 $as_echo "$WINDRES" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_WINDRES"; then ac_ct_WINDRES=$WINDRES # Extract the first word of "windres", so it can be a program name with args. set dummy windres; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_WINDRES+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_WINDRES"; then ac_cv_prog_ac_ct_WINDRES="$ac_ct_WINDRES" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_WINDRES="windres" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_WINDRES=$ac_cv_prog_ac_ct_WINDRES if test -n "$ac_ct_WINDRES"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_WINDRES" >&5 $as_echo "$ac_ct_WINDRES" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_WINDRES" = x; then WINDRES="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac WINDRES=$ac_ct_WINDRES fi else WINDRES="$ac_cv_prog_WINDRES" fi fi case "$host_os" in hpux*) LTLIBC="" ;; *) LTLIBC="-lc" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CFPreferencesCopyAppValue" >&5 $as_echo_n "checking for CFPreferencesCopyAppValue... " >&6; } if ${gt_cv_func_CFPreferencesCopyAppValue+:} false; then : $as_echo_n "(cached) " >&6 else gt_save_LIBS="$LIBS" LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { CFPreferencesCopyAppValue(NULL, NULL) ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : gt_cv_func_CFPreferencesCopyAppValue=yes else gt_cv_func_CFPreferencesCopyAppValue=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$gt_save_LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_CFPreferencesCopyAppValue" >&5 $as_echo "$gt_cv_func_CFPreferencesCopyAppValue" >&6; } if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then $as_echo "#define HAVE_CFPREFERENCESCOPYAPPVALUE 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CFLocaleCopyCurrent" >&5 $as_echo_n "checking for CFLocaleCopyCurrent... " >&6; } if ${gt_cv_func_CFLocaleCopyCurrent+:} false; then : $as_echo_n "(cached) " >&6 else gt_save_LIBS="$LIBS" LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { CFLocaleCopyCurrent(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : gt_cv_func_CFLocaleCopyCurrent=yes else gt_cv_func_CFLocaleCopyCurrent=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$gt_save_LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_CFLocaleCopyCurrent" >&5 $as_echo "$gt_cv_func_CFLocaleCopyCurrent" >&6; } if test $gt_cv_func_CFLocaleCopyCurrent = yes; then $as_echo "#define HAVE_CFLOCALECOPYCURRENT 1" >>confdefs.h fi INTL_MACOSX_LIBS= if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation" fi BUILD_INCLUDED_LIBINTL=no USE_INCLUDED_LIBINTL=no LIBINTL= LTLIBINTL= POSUB= case " $gt_needs " in *" need-formatstring-macros "*) gt_api_version=3 ;; *" need-ngettext "*) gt_api_version=2 ;; *) gt_api_version=1 ;; esac gt_func_gnugettext_libc="gt_cv_func_gnugettext${gt_api_version}_libc" gt_func_gnugettext_libintl="gt_cv_func_gnugettext${gt_api_version}_libintl" if test "$USE_NLS" = "yes"; then gt_use_preinstalled_gnugettext=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether included gettext is requested" >&5 $as_echo_n "checking whether included gettext is requested... " >&6; } # Check whether --with-included-gettext was given. if test "${with_included_gettext+set}" = set; then : withval=$with_included_gettext; nls_cv_force_use_gnu_gettext=$withval else nls_cv_force_use_gnu_gettext=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $nls_cv_force_use_gnu_gettext" >&5 $as_echo "$nls_cv_force_use_gnu_gettext" >&6; } nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" if test "$nls_cv_force_use_gnu_gettext" != "yes"; then if test $gt_api_version -ge 3; then gt_revision_test_code=' #ifndef __GNU_GETTEXT_SUPPORTED_REVISION #define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) #endif typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; ' else gt_revision_test_code= fi if test $gt_api_version -ge 2; then gt_expression_test_code=' + * ngettext ("", "", 0)' else gt_expression_test_code= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU gettext in libc" >&5 $as_echo_n "checking for GNU gettext in libc... " >&6; } if eval \${$gt_func_gnugettext_libc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include $gt_revision_test_code extern int _nl_msg_cat_cntr; extern int *_nl_domain_bindings; int main () { bindtextdomain ("", ""); return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_bindings ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$gt_func_gnugettext_libc=yes" else eval "$gt_func_gnugettext_libc=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$gt_func_gnugettext_libc { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then use_additional=yes acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" # Check whether --with-libintl-prefix was given. if test "${with_libintl_prefix+set}" = set; then : withval=$with_libintl_prefix; if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" else additional_includedir="$withval/include" additional_libdir="$withval/$acl_libdirstem" if test "$acl_libdirstem2" != "$acl_libdirstem" \ && ! test -d "$withval/$acl_libdirstem"; then additional_libdir="$withval/$acl_libdirstem2" fi fi fi fi LIBINTL= LTLIBINTL= INCINTL= LIBINTL_PREFIX= HAVE_LIBINTL= rpathdirs= ltrpathdirs= names_already_handled= names_next_round='intl ' while test -n "$names_next_round"; do names_this_round="$names_next_round" names_next_round= for name in $names_this_round; do already_handled= for n in $names_already_handled; do if test "$n" = "$name"; then already_handled=yes break fi done if test -z "$already_handled"; then names_already_handled="$names_already_handled $name" uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'` eval value=\"\$HAVE_LIB$uppername\" if test -n "$value"; then if test "$value" = yes; then eval value=\"\$LIB$uppername\" test -z "$value" || LIBINTL="${LIBINTL}${LIBINTL:+ }$value" eval value=\"\$LTLIB$uppername\" test -z "$value" || LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$value" else : fi else found_dir= found_la= found_so= found_a= eval libname=\"$acl_libname_spec\" # typically: libname=lib$name if test -n "$acl_shlibext"; then shrext=".$acl_shlibext" # typically: shrext=.so else shrext= fi if test $use_additional = yes; then dir="$additional_libdir" if test -n "$acl_shlibext"; then if test -f "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then ver=`(cd "$dir" && \ for f in "$libname$shrext".*; do echo "$f"; done \ | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do if test -f "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break fi done fi fi fi if test "X$found_dir" = "X"; then if test -f "$dir/$libname.$acl_libext"; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi fi if test "X$found_dir" != "X"; then if test -f "$dir/$libname.la"; then found_la="$dir/$libname.la" fi fi fi if test "X$found_dir" = "X"; then for x in $LDFLAGS $LTLIBINTL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" case "$x" in -L*) dir=`echo "X$x" | sed -e 's/^X-L//'` if test -n "$acl_shlibext"; then if test -f "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then ver=`(cd "$dir" && \ for f in "$libname$shrext".*; do echo "$f"; done \ | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do if test -f "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break fi done fi fi fi if test "X$found_dir" = "X"; then if test -f "$dir/$libname.$acl_libext"; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi fi if test "X$found_dir" != "X"; then if test -f "$dir/$libname.la"; then found_la="$dir/$libname.la" fi fi ;; esac if test "X$found_dir" != "X"; then break fi done fi if test "X$found_dir" != "X"; then LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$found_dir -l$name" if test "X$found_so" != "X"; then if test "$enable_rpath" = no \ || test "X$found_dir" = "X/usr/$acl_libdirstem" \ || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" else haveit= for x in $ltrpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $found_dir" fi if test "$acl_hardcode_direct" = yes; then LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" else if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" haveit= for x in $rpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $found_dir" fi else haveit= for x in $LDFLAGS $LIBINTL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir" fi if test "$acl_hardcode_minus_L" != no; then LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" else LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name" fi fi fi fi else if test "X$found_a" != "X"; then LIBINTL="${LIBINTL}${LIBINTL:+ }$found_a" else LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir -l$name" fi fi additional_includedir= case "$found_dir" in */$acl_libdirstem | */$acl_libdirstem/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` if test "$name" = 'intl'; then LIBINTL_PREFIX="$basedir" fi additional_includedir="$basedir/include" ;; */$acl_libdirstem2 | */$acl_libdirstem2/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'` if test "$name" = 'intl'; then LIBINTL_PREFIX="$basedir" fi additional_includedir="$basedir/include" ;; esac if test "X$additional_includedir" != "X"; then if test "X$additional_includedir" != "X/usr/include"; then haveit= if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then for x in $CPPFLAGS $INCINTL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_includedir"; then INCINTL="${INCINTL}${INCINTL:+ }-I$additional_includedir" fi fi fi fi fi if test -n "$found_la"; then save_libdir="$libdir" case "$found_la" in */* | *\\*) . "$found_la" ;; *) . "./$found_la" ;; esac libdir="$save_libdir" for dep in $dependency_libs; do case "$dep" in -L*) additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \ && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then haveit= if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \ || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then haveit= for x in $LDFLAGS $LIBINTL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LIBINTL="${LIBINTL}${LIBINTL:+ }-L$additional_libdir" fi fi haveit= for x in $LDFLAGS $LTLIBINTL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$additional_libdir" fi fi fi fi ;; -R*) dir=`echo "X$dep" | sed -e 's/^X-R//'` if test "$enable_rpath" != no; then haveit= for x in $rpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $dir" fi haveit= for x in $ltrpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $dir" fi fi ;; -l*) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` ;; *.la) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` ;; *) LIBINTL="${LIBINTL}${LIBINTL:+ }$dep" LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$dep" ;; esac done fi else LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name" LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-l$name" fi fi fi done done if test "X$rpathdirs" != "X"; then if test -n "$acl_hardcode_libdir_separator"; then alldirs= for found_dir in $rpathdirs; do alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" done acl_save_libdir="$libdir" libdir="$alldirs" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBINTL="${LIBINTL}${LIBINTL:+ }$flag" else for found_dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$found_dir" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBINTL="${LIBINTL}${LIBINTL:+ }$flag" done fi fi if test "X$ltrpathdirs" != "X"; then for found_dir in $ltrpathdirs; do LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-R$found_dir" done fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU gettext in libintl" >&5 $as_echo_n "checking for GNU gettext in libintl... " >&6; } if eval \${$gt_func_gnugettext_libintl+:} false; then : $as_echo_n "(cached) " >&6 else gt_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $INCINTL" gt_save_LIBS="$LIBS" LIBS="$LIBS $LIBINTL" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include $gt_revision_test_code extern int _nl_msg_cat_cntr; extern #ifdef __cplusplus "C" #endif const char *_nl_expand_alias (const char *); int main () { bindtextdomain ("", ""); return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("") ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$gt_func_gnugettext_libintl=yes" else eval "$gt_func_gnugettext_libintl=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" != yes; } && test -n "$LIBICONV"; then LIBS="$LIBS $LIBICONV" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include $gt_revision_test_code extern int _nl_msg_cat_cntr; extern #ifdef __cplusplus "C" #endif const char *_nl_expand_alias (const char *); int main () { bindtextdomain ("", ""); return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("") ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : LIBINTL="$LIBINTL $LIBICONV" LTLIBINTL="$LTLIBINTL $LTLIBICONV" eval "$gt_func_gnugettext_libintl=yes" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi CPPFLAGS="$gt_save_CPPFLAGS" LIBS="$gt_save_LIBS" fi eval ac_res=\$$gt_func_gnugettext_libintl { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" = "yes"; } \ || { { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; } \ && test "$PACKAGE" != gettext-runtime \ && test "$PACKAGE" != gettext-tools; }; then gt_use_preinstalled_gnugettext=yes else LIBINTL= LTLIBINTL= INCINTL= fi if test "$gt_use_preinstalled_gnugettext" != "yes"; then nls_cv_use_gnu_gettext=yes fi fi if test "$nls_cv_use_gnu_gettext" = "yes"; then BUILD_INCLUDED_LIBINTL=yes USE_INCLUDED_LIBINTL=yes LIBINTL="\${top_builddir}/intl/libintl.a $LIBICONV $LIBTHREAD" LTLIBINTL="\${top_builddir}/intl/libintl.a $LTLIBICONV $LTLIBTHREAD" LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'` fi CATOBJEXT= if test "$gt_use_preinstalled_gnugettext" = "yes" \ || test "$nls_cv_use_gnu_gettext" = "yes"; then CATOBJEXT=.gmo fi if test -n "$INTL_MACOSX_LIBS"; then if test "$gt_use_preinstalled_gnugettext" = "yes" \ || test "$nls_cv_use_gnu_gettext" = "yes"; then LIBINTL="$LIBINTL $INTL_MACOSX_LIBS" LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS" fi fi if test "$gt_use_preinstalled_gnugettext" = "yes" \ || test "$nls_cv_use_gnu_gettext" = "yes"; then $as_echo "#define ENABLE_NLS 1" >>confdefs.h else USE_NLS=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use NLS" >&5 $as_echo_n "checking whether to use NLS... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5 $as_echo "$USE_NLS" >&6; } if test "$USE_NLS" = "yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking where the gettext function comes from" >&5 $as_echo_n "checking where the gettext function comes from... " >&6; } if test "$gt_use_preinstalled_gnugettext" = "yes"; then if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then gt_source="external libintl" else gt_source="libc" fi else gt_source="included intl directory" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_source" >&5 $as_echo "$gt_source" >&6; } fi if test "$USE_NLS" = "yes"; then if test "$gt_use_preinstalled_gnugettext" = "yes"; then if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libintl" >&5 $as_echo_n "checking how to link with libintl... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBINTL" >&5 $as_echo "$LIBINTL" >&6; } for element in $INCINTL; do haveit= for x in $CPPFLAGS; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X$element"; then haveit=yes break fi done if test -z "$haveit"; then CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" fi done fi $as_echo "#define HAVE_GETTEXT 1" >>confdefs.h $as_echo "#define HAVE_DCGETTEXT 1" >>confdefs.h fi POSUB=po fi if test "$PACKAGE" = gettext-runtime || test "$PACKAGE" = gettext-tools; then BUILD_INCLUDED_LIBINTL=yes fi nls_cv_header_intl= nls_cv_header_libgt= DATADIRNAME=share INSTOBJEXT=.mo GENCAT=gencat INTLOBJS= if test "$USE_INCLUDED_LIBINTL" = yes; then INTLOBJS="\$(GETTOBJS)" fi INTL_LIBTOOL_SUFFIX_PREFIX= INTLLIBS="$LIBINTL" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MSGFMT understands msgctxt (message context)" >&5 $as_echo_n "checking if $MSGFMT understands msgctxt (message context)... " >&6; } cat > conftest.po </dev/null; exit) 2>&5 then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "It appears that your gettext tools ($MSGFMT) is too old. You should install a newer gettext tools (>= 0.19.3 suggested). You may specify the location of the msgfmt executible with MSGFMT=/path/to/msgfmt on the configure command line. " "$LINENO" 5 fi rm -f conftest.po conftest.gmo case "$am__api_version" in 1.01234) as_fn_error $? "Automake 1.5 or newer is required to use intltool" "$LINENO" 5 ;; *) ;; esac INTLTOOL_REQUIRED_VERSION_AS_INT=`echo 0.35.0 | awk -F. '{ print $ 1 * 1000 + $ 2 * 100 + $ 3; }'` INTLTOOL_APPLIED_VERSION=`intltool-update --version | head -1 | cut -d" " -f3` INTLTOOL_APPLIED_VERSION_AS_INT=`echo $INTLTOOL_APPLIED_VERSION | awk -F. '{ print $ 1 * 1000 + $ 2 * 100 + $ 3; }'` if test -n "0.35.0"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for intltool >= 0.35.0" >&5 $as_echo_n "checking for intltool >= 0.35.0... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_APPLIED_VERSION found" >&5 $as_echo "$INTLTOOL_APPLIED_VERSION found" >&6; } test "$INTLTOOL_APPLIED_VERSION_AS_INT" -ge "$INTLTOOL_REQUIRED_VERSION_AS_INT" || as_fn_error $? "Your intltool is too old. You need intltool 0.35.0 or later." "$LINENO" 5 fi # Extract the first word of "intltool-update", so it can be a program name with args. set dummy intltool-update; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_INTLTOOL_UPDATE+:} false; then : $as_echo_n "(cached) " >&6 else case $INTLTOOL_UPDATE in [\\/]* | ?:[\\/]*) ac_cv_path_INTLTOOL_UPDATE="$INTLTOOL_UPDATE" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_INTLTOOL_UPDATE="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi INTLTOOL_UPDATE=$ac_cv_path_INTLTOOL_UPDATE if test -n "$INTLTOOL_UPDATE"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_UPDATE" >&5 $as_echo "$INTLTOOL_UPDATE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "intltool-merge", so it can be a program name with args. set dummy intltool-merge; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_INTLTOOL_MERGE+:} false; then : $as_echo_n "(cached) " >&6 else case $INTLTOOL_MERGE in [\\/]* | ?:[\\/]*) ac_cv_path_INTLTOOL_MERGE="$INTLTOOL_MERGE" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_INTLTOOL_MERGE="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi INTLTOOL_MERGE=$ac_cv_path_INTLTOOL_MERGE if test -n "$INTLTOOL_MERGE"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_MERGE" >&5 $as_echo "$INTLTOOL_MERGE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "intltool-extract", so it can be a program name with args. set dummy intltool-extract; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_INTLTOOL_EXTRACT+:} false; then : $as_echo_n "(cached) " >&6 else case $INTLTOOL_EXTRACT in [\\/]* | ?:[\\/]*) ac_cv_path_INTLTOOL_EXTRACT="$INTLTOOL_EXTRACT" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_INTLTOOL_EXTRACT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi INTLTOOL_EXTRACT=$ac_cv_path_INTLTOOL_EXTRACT if test -n "$INTLTOOL_EXTRACT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_EXTRACT" >&5 $as_echo "$INTLTOOL_EXTRACT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$INTLTOOL_UPDATE" -o -z "$INTLTOOL_MERGE" -o -z "$INTLTOOL_EXTRACT"; then as_fn_error $? "The intltool scripts were not found. Please install intltool." "$LINENO" 5 fi if test -z "$AM_DEFAULT_VERBOSITY"; then AM_DEFAULT_VERBOSITY=1 fi INTLTOOL_V_MERGE='$(INTLTOOL__v_MERGE_$(V))' INTLTOOL__v_MERGE_='$(INTLTOOL__v_MERGE_$(AM_DEFAULT_VERBOSITY))' INTLTOOL__v_MERGE_0='@echo " ITMRG " $@;' INTLTOOL_V_MERGE_OPTIONS='$(intltool__v_merge_options_$(V))' intltool__v_merge_options_='$(intltool__v_merge_options_$(AM_DEFAULT_VERBOSITY))' intltool__v_merge_options_0='-q' INTLTOOL_DESKTOP_RULE='%.desktop: %.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' INTLTOOL_DIRECTORY_RULE='%.directory: %.directory.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' INTLTOOL_KEYS_RULE='%.keys: %.keys.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -k -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' INTLTOOL_PROP_RULE='%.prop: %.prop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' INTLTOOL_OAF_RULE='%.oaf: %.oaf.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -o -p $(top_srcdir)/po $< $@' INTLTOOL_PONG_RULE='%.pong: %.pong.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' INTLTOOL_SERVER_RULE='%.server: %.server.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -o -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' INTLTOOL_SHEET_RULE='%.sheet: %.sheet.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' INTLTOOL_SOUNDLIST_RULE='%.soundlist: %.soundlist.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' INTLTOOL_UI_RULE='%.ui: %.ui.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' INTLTOOL_XML_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' if test "$INTLTOOL_APPLIED_VERSION_AS_INT" -ge 5000; then INTLTOOL_XML_NOMERGE_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u --no-translations $< $@' else INTLTOOL_XML_NOMERGE_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) ; $(INTLTOOL_V_MERGE)_it_tmp_dir=tmp.intltool.$$RANDOM && mkdir $$_it_tmp_dir && LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u $$_it_tmp_dir $< $@ && rmdir $$_it_tmp_dir' fi INTLTOOL_XAM_RULE='%.xam: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' INTLTOOL_KBD_RULE='%.kbd: %.kbd.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -m -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' INTLTOOL_CAVES_RULE='%.caves: %.caves.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' INTLTOOL_SCHEMAS_RULE='%.schemas: %.schemas.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -s -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' INTLTOOL_THEME_RULE='%.theme: %.theme.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' INTLTOOL_SERVICE_RULE='%.service: %.service.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' INTLTOOL_POLICY_RULE='%.policy: %.policy.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' # Check the gettext tools to make sure they are GNU # Extract the first word of "xgettext", so it can be a program name with args. set dummy xgettext; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_XGETTEXT+:} false; then : $as_echo_n "(cached) " >&6 else case $XGETTEXT in [\\/]* | ?:[\\/]*) ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_XGETTEXT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi XGETTEXT=$ac_cv_path_XGETTEXT if test -n "$XGETTEXT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XGETTEXT" >&5 $as_echo "$XGETTEXT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "msgmerge", so it can be a program name with args. set dummy msgmerge; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_MSGMERGE+:} false; then : $as_echo_n "(cached) " >&6 else case $MSGMERGE in [\\/]* | ?:[\\/]*) ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_MSGMERGE="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi MSGMERGE=$ac_cv_path_MSGMERGE if test -n "$MSGMERGE"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGMERGE" >&5 $as_echo "$MSGMERGE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "msgfmt", so it can be a program name with args. set dummy msgfmt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_MSGFMT+:} false; then : $as_echo_n "(cached) " >&6 else case $MSGFMT in [\\/]* | ?:[\\/]*) ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_MSGFMT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi MSGFMT=$ac_cv_path_MSGFMT if test -n "$MSGFMT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGFMT" >&5 $as_echo "$MSGFMT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "gmsgfmt", so it can be a program name with args. set dummy gmsgfmt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_GMSGFMT+:} false; then : $as_echo_n "(cached) " >&6 else case $GMSGFMT in [\\/]* | ?:[\\/]*) ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_GMSGFMT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" ;; esac fi GMSGFMT=$ac_cv_path_GMSGFMT if test -n "$GMSGFMT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GMSGFMT" >&5 $as_echo "$GMSGFMT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$XGETTEXT" -o -z "$MSGMERGE" -o -z "$MSGFMT"; then as_fn_error $? "GNU gettext tools not found; required for intltool" "$LINENO" 5 fi xgversion="`$XGETTEXT --version|grep '(GNU ' 2> /dev/null`" mmversion="`$MSGMERGE --version|grep '(GNU ' 2> /dev/null`" mfversion="`$MSGFMT --version|grep '(GNU ' 2> /dev/null`" if test -z "$xgversion" -o -z "$mmversion" -o -z "$mfversion"; then as_fn_error $? "GNU gettext tools not found; required for intltool" "$LINENO" 5 fi # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_INTLTOOL_PERL+:} false; then : $as_echo_n "(cached) " >&6 else case $INTLTOOL_PERL in [\\/]* | ?:[\\/]*) ac_cv_path_INTLTOOL_PERL="$INTLTOOL_PERL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_INTLTOOL_PERL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi INTLTOOL_PERL=$ac_cv_path_INTLTOOL_PERL if test -n "$INTLTOOL_PERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_PERL" >&5 $as_echo "$INTLTOOL_PERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$INTLTOOL_PERL"; then as_fn_error $? "perl not found" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for perl >= 5.8.1" >&5 $as_echo_n "checking for perl >= 5.8.1... " >&6; } $INTLTOOL_PERL -e "use 5.8.1;" > /dev/null 2>&1 if test $? -ne 0; then as_fn_error $? "perl 5.8.1 is required for intltool" "$LINENO" 5 else IT_PERL_VERSION=`$INTLTOOL_PERL -e "printf '%vd', $^V"` { $as_echo "$as_me:${as_lineno-$LINENO}: result: $IT_PERL_VERSION" >&5 $as_echo "$IT_PERL_VERSION" >&6; } fi if test "x" != "xno-xml"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XML::Parser" >&5 $as_echo_n "checking for XML::Parser... " >&6; } if `$INTLTOOL_PERL -e "require XML::Parser" 2>/dev/null`; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } else as_fn_error $? "XML::Parser perl module is required for intltool" "$LINENO" 5 fi fi # Substitute ALL_LINGUAS so we can use it in po/Makefile { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 $as_echo_n "checking for inline... " >&6; } if ${ac_cv_c_inline+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo () {return 0; } $ac_kw foo_t foo () {return 0; } #endif _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_inline=$ac_kw fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_inline" != no && break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 $as_echo "$ac_cv_c_inline" >&6; } case $ac_cv_c_inline in inline | yes) ;; *) case $ac_cv_c_inline in no) ac_val=;; *) ac_val=$ac_cv_c_inline;; esac cat >>confdefs.h <<_ACEOF #ifndef __cplusplus #define inline $ac_val #endif _ACEOF ;; esac case $ac_cv_prog_cc_stdc in #( no) : ac_cv_prog_cc_c99=no; ac_cv_prog_cc_c89=no ;; #( *) : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5 $as_echo_n "checking for $CC option to accept ISO C99... " >&6; } if ${ac_cv_prog_cc_c99+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c99=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include #include // Check varargs macros. These examples are taken from C99 6.10.3.5. #define debug(...) fprintf (stderr, __VA_ARGS__) #define showlist(...) puts (#__VA_ARGS__) #define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) static void test_varargs_macros (void) { int x = 1234; int y = 5678; debug ("Flag"); debug ("X = %d\n", x); showlist (The first, second, and third items.); report (x>y, "x is %d but y is %d", x, y); } // Check long long types. #define BIG64 18446744073709551615ull #define BIG32 4294967295ul #define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) #if !BIG_OK your preprocessor is broken; #endif #if BIG_OK #else your preprocessor is broken; #endif static long long int bignum = -9223372036854775807LL; static unsigned long long int ubignum = BIG64; struct incomplete_array { int datasize; double data[]; }; struct named_init { int number; const wchar_t *name; double average; }; typedef const char *ccp; static inline int test_restrict (ccp restrict text) { // See if C++-style comments work. // Iterate through items via the restricted pointer. // Also check for declarations in for loops. for (unsigned int i = 0; *(text+i) != '\0'; ++i) continue; return 0; } // Check varargs and va_copy. static void test_varargs (const char *format, ...) { va_list args; va_start (args, format); va_list args_copy; va_copy (args_copy, args); const char *str; int number; float fnumber; while (*format) { switch (*format++) { case 's': // string str = va_arg (args_copy, const char *); break; case 'd': // int number = va_arg (args_copy, int); break; case 'f': // float fnumber = va_arg (args_copy, double); break; default: break; } } va_end (args_copy); va_end (args); } int main () { // Check bool. _Bool success = false; // Check restrict. if (test_restrict ("String literal") == 0) success = true; char *restrict newvar = "Another string"; // Check varargs. test_varargs ("s, d' f .", "string", 65, 34.234); test_varargs_macros (); // Check flexible array members. struct incomplete_array *ia = malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); ia->datasize = 10; for (int i = 0; i < ia->datasize; ++i) ia->data[i] = i * 1.234; // Check named initializers. struct named_init ni = { .number = 34, .name = L"Test wide string", .average = 543.34343, }; ni.number = 58; int dynamic_array[ni.number]; dynamic_array[ni.number - 1] = 543; // work around unused variable warnings return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x' || dynamic_array[ni.number - 1] != 543); ; return 0; } _ACEOF for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99 do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c99=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c99" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c99" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c99" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 $as_echo "$ac_cv_prog_cc_c99" >&6; } ;; esac if test "x$ac_cv_prog_cc_c99" != xno; then : ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 else ac_cv_prog_cc_stdc=no fi fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO Standard C" >&5 $as_echo_n "checking for $CC option to accept ISO Standard C... " >&6; } if ${ac_cv_prog_cc_stdc+:} false; then : $as_echo_n "(cached) " >&6 fi case $ac_cv_prog_cc_stdc in #( no) : { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; #( '') : { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; #( *) : { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_stdc" >&5 $as_echo "$ac_cv_prog_cc_stdc" >&6; } ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5 $as_echo_n "checking for $CC option to accept ISO C99... " >&6; } if ${ac_cv_prog_cc_c99+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c99=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include #include // Check varargs macros. These examples are taken from C99 6.10.3.5. #define debug(...) fprintf (stderr, __VA_ARGS__) #define showlist(...) puts (#__VA_ARGS__) #define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) static void test_varargs_macros (void) { int x = 1234; int y = 5678; debug ("Flag"); debug ("X = %d\n", x); showlist (The first, second, and third items.); report (x>y, "x is %d but y is %d", x, y); } // Check long long types. #define BIG64 18446744073709551615ull #define BIG32 4294967295ul #define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) #if !BIG_OK your preprocessor is broken; #endif #if BIG_OK #else your preprocessor is broken; #endif static long long int bignum = -9223372036854775807LL; static unsigned long long int ubignum = BIG64; struct incomplete_array { int datasize; double data[]; }; struct named_init { int number; const wchar_t *name; double average; }; typedef const char *ccp; static inline int test_restrict (ccp restrict text) { // See if C++-style comments work. // Iterate through items via the restricted pointer. // Also check for declarations in for loops. for (unsigned int i = 0; *(text+i) != '\0'; ++i) continue; return 0; } // Check varargs and va_copy. static void test_varargs (const char *format, ...) { va_list args; va_start (args, format); va_list args_copy; va_copy (args_copy, args); const char *str; int number; float fnumber; while (*format) { switch (*format++) { case 's': // string str = va_arg (args_copy, const char *); break; case 'd': // int number = va_arg (args_copy, int); break; case 'f': // float fnumber = va_arg (args_copy, double); break; default: break; } } va_end (args_copy); va_end (args); } int main () { // Check bool. _Bool success = false; // Check restrict. if (test_restrict ("String literal") == 0) success = true; char *restrict newvar = "Another string"; // Check varargs. test_varargs ("s, d' f .", "string", 65, 34.234); test_varargs_macros (); // Check flexible array members. struct incomplete_array *ia = malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); ia->datasize = 10; for (int i = 0; i < ia->datasize; ++i) ia->data[i] = i * 1.234; // Check named initializers. struct named_init ni = { .number = 34, .name = L"Test wide string", .average = 543.34343, }; ni.number = 58; int dynamic_array[ni.number]; dynamic_array[ni.number - 1] = 543; // work around unused variable warnings return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x' || dynamic_array[ni.number - 1] != 543); ; return 0; } _ACEOF for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99 do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c99=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c99" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c99" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c99" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 $as_echo "$ac_cv_prog_cc_c99" >&6; } ;; esac if test "x$ac_cv_prog_cc_c99" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking that C compiler supports C99" >&5 $as_echo_n "checking that C compiler supports C99... " >&6; } if test "X$ac_cv_prog_cc_c99" = "Xno"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "A C99-compliant compiler is requred" "$LINENO" 5 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done for ac_prog in flex lex do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LEX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LEX"; then ac_cv_prog_LEX="$LEX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LEX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LEX=$ac_cv_prog_LEX if test -n "$LEX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LEX" >&5 $as_echo "$LEX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$LEX" && break done test -n "$LEX" || LEX=":" if test "x$LEX" != "x:"; then cat >conftest.l <<_ACEOF %% a { ECHO; } b { REJECT; } c { yymore (); } d { yyless (1); } e { /* IRIX 6.5 flex 2.5.4 underquotes its yyless argument. */ yyless ((input () != 0)); } f { unput (yytext[0]); } . { BEGIN INITIAL; } %% #ifdef YYTEXT_POINTER extern char *yytext; #endif int main (void) { return ! yylex () + ! yywrap (); } _ACEOF { { ac_try="$LEX conftest.l" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$LEX conftest.l") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking lex output file root" >&5 $as_echo_n "checking lex output file root... " >&6; } if ${ac_cv_prog_lex_root+:} false; then : $as_echo_n "(cached) " >&6 else if test -f lex.yy.c; then ac_cv_prog_lex_root=lex.yy elif test -f lexyy.c; then ac_cv_prog_lex_root=lexyy else as_fn_error $? "cannot find output from $LEX; giving up" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_root" >&5 $as_echo "$ac_cv_prog_lex_root" >&6; } LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root if test -z "${LEXLIB+set}"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking lex library" >&5 $as_echo_n "checking lex library... " >&6; } if ${ac_cv_lib_lex+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_LIBS=$LIBS ac_cv_lib_lex='none needed' for ac_lib in '' -lfl -ll; do LIBS="$ac_lib $ac_save_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ `cat $LEX_OUTPUT_ROOT.c` _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_lex=$ac_lib fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext test "$ac_cv_lib_lex" != 'none needed' && break done LIBS=$ac_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lex" >&5 $as_echo "$ac_cv_lib_lex" >&6; } test "$ac_cv_lib_lex" != 'none needed' && LEXLIB=$ac_cv_lib_lex fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether yytext is a pointer" >&5 $as_echo_n "checking whether yytext is a pointer... " >&6; } if ${ac_cv_prog_lex_yytext_pointer+:} false; then : $as_echo_n "(cached) " >&6 else # POSIX says lex can declare yytext either as a pointer or an array; the # default is implementation-dependent. Figure out which it is, since # not all implementations provide the %pointer and %array declarations. ac_cv_prog_lex_yytext_pointer=no ac_save_LIBS=$LIBS LIBS="$LEXLIB $ac_save_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define YYTEXT_POINTER 1 `cat $LEX_OUTPUT_ROOT.c` _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_prog_lex_yytext_pointer=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_yytext_pointer" >&5 $as_echo "$ac_cv_prog_lex_yytext_pointer" >&6; } if test $ac_cv_prog_lex_yytext_pointer = yes; then $as_echo "#define YYTEXT_POINTER 1" >>confdefs.h fi rm -f conftest.l $LEX_OUTPUT_ROOT.c fi if test "$LEX" = :; then LEX=${am_missing_run}flex fi # Extract the first word of "$LEX", so it can be a program name with args. set dummy $LEX; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_LEX_PATH+:} false; then : $as_echo_n "(cached) " >&6 else case $LEX_PATH in [\\/]* | ?:[\\/]*) ac_cv_path_LEX_PATH="$LEX_PATH" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_LEX_PATH="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_LEX_PATH" && ac_cv_path_LEX_PATH="notfound" ;; esac fi LEX_PATH=$ac_cv_path_LEX_PATH if test -n "$LEX_PATH"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LEX_PATH" >&5 $as_echo "$LEX_PATH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$LEX_PATH" = "notfound" ; then as_fn_error $? "Couldn't find a usable lex program. Please install flex which is available from ftp://ftp.gnu.org/pub/non-gnu/flex/ " "$LINENO" 5 fi for ac_prog in 'bison -y' byacc do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_YACC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$YACC"; then ac_cv_prog_YACC="$YACC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_YACC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi YACC=$ac_cv_prog_YACC if test -n "$YACC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $YACC" >&5 $as_echo "$YACC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$YACC" && break done test -n "$YACC" || YACC="yacc" # Extract the first word of "$YACC", so it can be a program name with args. set dummy $YACC; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_YACC_PATH+:} false; then : $as_echo_n "(cached) " >&6 else case $YACC_PATH in [\\/]* | ?:[\\/]*) ac_cv_path_YACC_PATH="$YACC_PATH" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_YACC_PATH="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_YACC_PATH" && ac_cv_path_YACC_PATH="notfound" ;; esac fi YACC_PATH=$ac_cv_path_YACC_PATH if test -n "$YACC_PATH"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $YACC_PATH" >&5 $as_echo "$YACC_PATH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$YACC_PATH" = "notfound" ; then as_fn_error $? "Couldn't find a usable yacc program. Please install bison which is available from ftp://ftp.gnu.org/pub/gnu/bison/ " "$LINENO" 5 fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi # # Used for building the icons # # Extract the first word of "xpmtoppm", so it can be a program name with args. set dummy xpmtoppm; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_XPMTOPPM+:} false; then : $as_echo_n "(cached) " >&6 else case $XPMTOPPM in [\\/]* | ?:[\\/]*) ac_cv_path_XPMTOPPM="$XPMTOPPM" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_XPMTOPPM="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_XPMTOPPM" && ac_cv_path_XPMTOPPM="notfound" ;; esac fi XPMTOPPM=$ac_cv_path_XPMTOPPM if test -n "$XPMTOPPM"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XPMTOPPM" >&5 $as_echo "$XPMTOPPM" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "ppmtowinicon", so it can be a program name with args. set dummy ppmtowinicon; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PPMTOWINICON+:} false; then : $as_echo_n "(cached) " >&6 else case $PPMTOWINICON in [\\/]* | ?:[\\/]*) ac_cv_path_PPMTOWINICON="$PPMTOWINICON" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PPMTOWINICON="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PPMTOWINICON" && ac_cv_path_PPMTOWINICON="notfound" ;; esac fi PPMTOWINICON=$ac_cv_path_PPMTOWINICON if test -n "$PPMTOWINICON"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PPMTOWINICON" >&5 $as_echo "$PPMTOWINICON" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "convert", so it can be a program name with args. set dummy convert; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_CONVERT+:} false; then : $as_echo_n "(cached) " >&6 else case $CONVERT in [\\/]* | ?:[\\/]*) ac_cv_path_CONVERT="$CONVERT" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_CONVERT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_CONVERT" && ac_cv_path_CONVERT="notfound" ;; esac fi CONVERT=$ac_cv_path_CONVERT if test -n "$CONVERT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CONVERT" >&5 $as_echo "$CONVERT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ########################################################################## # # if test "X$docs_yesno" = "Xyes" -a "X$pcb_git_version" = "Xyes" ; then # Extract the first word of "makeinfo", so it can be a program name with args. set dummy makeinfo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_MKINFO+:} false; then : $as_echo_n "(cached) " >&6 else case $MKINFO in [\\/]* | ?:[\\/]*) ac_cv_path_MKINFO="$MKINFO" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_MKINFO="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_MKINFO" && ac_cv_path_MKINFO="no" ;; esac fi MKINFO=$ac_cv_path_MKINFO if test -n "$MKINFO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKINFO" >&5 $as_echo "$MKINFO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "X$MKINFO" != "Xno"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU makeinfo version >= 4.6" >&5 $as_echo_n "checking for GNU makeinfo version >= 4.6... " >&6; } v=`$MKINFO --version | grep "GNU texinfo"` if test $? -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: non-GNU" >&5 $as_echo "non-GNU" >&6; } MKINFO="no" fi fi if test "X$MKINFO" != "Xno"; then vmajor=`echo "$v" | sed 's/.* \([0-9]*\)\.\([0-9]*\)$/\1/'` vminor=`echo "$v" | sed 's/.* \([0-9]*\)\.\([0-9]*\)$/\2/'` { $as_echo "$as_me:${as_lineno-$LINENO}: result: $vmajor.$vminor" >&5 $as_echo "$vmajor.$vminor" >&6; } if test "$vmajor" -lt 4 \ || (test "$vmajor" -eq 4 && test "$vminor" -lt 6); then MKINFO=no fi fi if test "X$MKINFO" = "Xno"; then as_fn_error $? "You have requested a build of the documentation. For this to work, you must have version 4.6 or newer of the GNU texinfo package. You seem to have $v Please update to a newer version of texinfo or disable building of the documentation with --disable-doc " "$LINENO" 5 fi # Extract the first word of "texi2dvi", so it can be a program name with args. set dummy texi2dvi; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_TEXI2DVI+:} false; then : $as_echo_n "(cached) " >&6 else case $TEXI2DVI in [\\/]* | ?:[\\/]*) ac_cv_path_TEXI2DVI="$TEXI2DVI" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_TEXI2DVI="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_TEXI2DVI" && ac_cv_path_TEXI2DVI="no" ;; esac fi TEXI2DVI=$ac_cv_path_TEXI2DVI if test -n "$TEXI2DVI"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TEXI2DVI" >&5 $as_echo "$TEXI2DVI" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "X$TEXI2DVI" = "Xno"; then as_fn_error $? "You have requested a build of the documentation. For this to work, you must have the texi2dvi program installed. Alternatively, you can disable building the documentation with --disable-doc." "$LINENO" 5 fi # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PERL+:} false; then : $as_echo_n "(cached) " >&6 else case $PERL in [\\/]* | ?:[\\/]*) ac_cv_path_PERL="$PERL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PERL" && ac_cv_path_PERL="notfound" ;; esac fi PERL=$ac_cv_path_PERL if test -n "$PERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5 $as_echo "$PERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "X$PERL" = "Xnotfound"; then as_fn_error $? "You have requested a build of the documentation. For this to work, you must have perl installed. Alternatively, you can disable building the documentation with --disable-doc. " "$LINENO" 5 fi # Extract the first word of "kpsewhich", so it can be a program name with args. set dummy kpsewhich; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_KPSEWHICH+:} false; then : $as_echo_n "(cached) " >&6 else case $KPSEWHICH in [\\/]* | ?:[\\/]*) ac_cv_path_KPSEWHICH="$KPSEWHICH" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_KPSEWHICH="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_KPSEWHICH" && ac_cv_path_KPSEWHICH="no" ;; esac fi KPSEWHICH=$ac_cv_path_KPSEWHICH if test -n "$KPSEWHICH"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $KPSEWHICH" >&5 $as_echo "$KPSEWHICH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "X$KPSEWHICH" = "Xno"; then as_fn_error $? "You have requested a build of the documentation. For this to work, you must have a functional install of TeX and LaTeX. kpsewhich is part of TeX. Alternatively, you can disable building the documentation with --disable-doc." "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking If your TeX installation contains epsf.tex" >&5 $as_echo_n "checking If your TeX installation contains epsf.tex... " >&6; } f=`$KPSEWHICH epsf.tex` if test $? -eq 0 ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes ($f)" >&5 $as_echo "yes ($f)" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "You have requested a build of the documentation. For this to work, you must have a functional install of TeX and LaTeX that includes epsf.tex. On some linux distributions this is part of the texlive-generic-recommended package. On NetBSD this is is part of the tex-epsf package. Alternatively, you can disable building the documentation with --disable-doc." "$LINENO" 5 fi fi ########################################################################## # # # FIXME: for now, only try to add -rdynamic if we're using gcc. We really # need to figure out what the correct test is here. In the mean time, this # should let things build with SunPRO again. if test "x$GCC" = "xyes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking If the compiler accepts -rdynamic" >&5 $as_echo_n "checking If the compiler accepts -rdynamic... " >&6; } old_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -rdynamic" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else LDFLAGS="$old_LDFLAGS" { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi # ------------- HID config ------------------- hid_guis="" hid_printers="" hid_exporters="" hid_always="" for hid in `cd $srcdir/src/hid; echo *`; do F=$srcdir/src/hid/$hid/hid.conf if test -f $F then echo checking $F . $F case $type in gui ) hid_guis="$hid_guis $hid" ;; printer ) hid_printers="$hid_printers $hid" ;; export ) hid_exporters="$hid_exporters $hid" ;; always ) hid_always="$hid_always $hid" ;; esac fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for which gui to use" >&5 $as_echo_n "checking for which gui to use... " >&6; } # Check whether --with-gui was given. if test "${with_gui+set}" = set; then : withval=$with_gui; else with_gui=gtk fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_gui" >&5 $as_echo "$with_gui" >&6; } case " $hid_guis no none " in *\ $with_gui\ * ) HIDLIST="$with_gui" ;; * ) as_fn_error $? "$with_gui is not a valid gui" "$LINENO" 5 ;; esac WITHGUI="$with_gui" if test x"$with_gui" = x"none" -o x"$with_gui" = x"no" then HIDLIST= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable toporouter" >&5 $as_echo_n "checking whether to enable toporouter... " >&6; } # Check whether --enable-toporouter was given. if test "${enable_toporouter+set}" = set; then : enableval=$enable_toporouter; fi case "x$enable_toporouter" in #( xyes | xno) : ;; #( *) : enable_toporouter=yes ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_toporouter" >&5 $as_echo "$enable_toporouter" >&6; } if test $enable_toporouter != no; then WITH_TOPOROUTER_TRUE= WITH_TOPOROUTER_FALSE='#' else WITH_TOPOROUTER_TRUE='#' WITH_TOPOROUTER_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable toporouter output" >&5 $as_echo_n "checking whether to enable toporouter output... " >&6; } # Check whether --enable-toporouter-output was given. if test "${enable_toporouter_output+set}" = set; then : enableval=$enable_toporouter_output; fi case "z$enable_toporouter_output" in #( zyes | zno) : ;; #( *) : enable_toporouter_output=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_toporouter_output" >&5 $as_echo "$enable_toporouter_output" >&6; } case $enable_toporouter_output in #( yes) : topo_output_enabled=1 ;; #( *) : topo_output_enabled=0 ;; esac cat >>confdefs.h <<_ACEOF #define TOPO_OUTPUT_ENABLED $topo_output_enabled _ACEOF if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_PKG_CONFIG"; then ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 $as_echo "$ac_pt_PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then PKG_CONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKG_CONFIG=$ac_pt_PKG_CONFIG fi else PKG_CONFIG="$ac_cv_path_PKG_CONFIG" fi fi if test -n "$PKG_CONFIG"; then _pkg_min_version=0.9.0 { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 $as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } PKG_CONFIG="" fi fi if test "x$enable_toporouter_output" = "xyes"; then pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CAIRO" >&5 $as_echo_n "checking for CAIRO... " >&6; } if test -n "$CAIRO_CFLAGS"; then pkg_cv_CAIRO_CFLAGS="$CAIRO_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"cairo\""; } >&5 ($PKG_CONFIG --exists --print-errors "cairo") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_CAIRO_CFLAGS=`$PKG_CONFIG --cflags "cairo" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$CAIRO_LIBS"; then pkg_cv_CAIRO_LIBS="$CAIRO_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"cairo\""; } >&5 ($PKG_CONFIG --exists --print-errors "cairo") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_CAIRO_LIBS=`$PKG_CONFIG --libs "cairo" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then CAIRO_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "cairo" 2>&1` else CAIRO_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "cairo" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$CAIRO_PKG_ERRORS" >&5 as_fn_error $? "Cannot find cairo, needed by the toporouter Please review the following errors: $CAIRO_PKG_ERRORS" "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Cannot find cairo, needed by the toporouter Please review the following errors: $CAIRO_PKG_ERRORS" "$LINENO" 5 else CAIRO_CFLAGS=$pkg_cv_CAIRO_CFLAGS CAIRO_LIBS=$pkg_cv_CAIRO_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for whether to use DBUS" >&5 $as_echo_n "checking for whether to use DBUS... " >&6; } # Check whether --enable-dbus was given. if test "${enable_dbus+set}" = set; then : enableval=$enable_dbus; else case " $with_gui " in *\ gtk\ *) enable_dbus=yes ;; *\ lesstif\ *) enable_dbus=yes ;; * ) enable_dbus=no ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_dbus" >&5 $as_echo "$enable_dbus" >&6; } if test x$enable_dbus = xyes; then WITH_DBUS_TRUE= WITH_DBUS_FALSE='#' else WITH_DBUS_TRUE='#' WITH_DBUS_FALSE= fi if test "x$enable_dbus" = "xyes"; then case " $with_gui " in *\ gtk\ *) ;; *\ lesstif\ *) ;; * ) as_fn_error $? "DBUS enabled but only works with a mainloop capable GUI HID. Either do not use --enable-dbus or enable the gtk or lesstif GUI HID." "$LINENO" 5 esac pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DBUS" >&5 $as_echo_n "checking for DBUS... " >&6; } if test -n "$DBUS_CFLAGS"; then pkg_cv_DBUS_CFLAGS="$DBUS_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dbus-1 >= 0.61\""; } >&5 ($PKG_CONFIG --exists --print-errors "dbus-1 >= 0.61") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_DBUS_CFLAGS=`$PKG_CONFIG --cflags "dbus-1 >= 0.61" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$DBUS_LIBS"; then pkg_cv_DBUS_LIBS="$DBUS_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dbus-1 >= 0.61\""; } >&5 ($PKG_CONFIG --exists --print-errors "dbus-1 >= 0.61") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_DBUS_LIBS=`$PKG_CONFIG --libs "dbus-1 >= 0.61" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then DBUS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "dbus-1 >= 0.61" 2>&1` else DBUS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "dbus-1 >= 0.61" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$DBUS_PKG_ERRORS" >&5 as_fn_error $? "Cannot find dbus-1 >= 0.61, install it and rerun ./configure Please review the following errors: $DBUS_PKG_ERRORS" "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Cannot find dbus-1 >= 0.61, install it and rerun ./configure Please review the following errors: $DBUS_PKG_ERRORS" "$LINENO" 5 else DBUS_CFLAGS=$pkg_cv_DBUS_CFLAGS DBUS_LIBS=$pkg_cv_DBUS_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } saved_LIBS="$LIBS" LIBS="$LIBS $DBUS_LIBS" for ac_func in dbus_watch_get_unix_fd do : ac_fn_c_check_func "$LINENO" "dbus_watch_get_unix_fd" "ac_cv_func_dbus_watch_get_unix_fd" if test "x$ac_cv_func_dbus_watch_get_unix_fd" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DBUS_WATCH_GET_UNIX_FD 1 _ACEOF fi done LIBS="$saved_LIBS" fi DBUS_VERSION=`$PKG_CONFIG dbus-1 --modversion` $as_echo "#define HAVE_DBUS 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for whether to use GL drawing" >&5 $as_echo_n "checking for whether to use GL drawing... " >&6; } # Check whether --enable-gl was given. if test "${enable_gl+set}" = set; then : enableval=$enable_gl; else case " $with_gui " in *\ gtk\ *) enable_gl=yes;; * ) enable_gl=no;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_gl" >&5 $as_echo "$enable_gl" >&6; } if test x$enable_gl = xyes; then USE_GL_TRUE= USE_GL_FALSE='#' else USE_GL_TRUE='#' USE_GL_FALSE= fi if test "x$enable_gl" = "xyes"; then case " $with_gui " in *\ gtk\ *) ;; * ) as_fn_error $? "GL drawing enabled but only works with the GTK HID. Either do not use --enable-gl or enable the gtk HID." "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for X" >&5 $as_echo_n "checking for X... " >&6; } # Check whether --with-x was given. if test "${with_x+set}" = set; then : withval=$with_x; fi # $have_x is `yes', `no', `disabled', or empty when we do not yet know. if test "x$with_x" = xno; then # The user explicitly disabled X. have_x=disabled else case $x_includes,$x_libraries in #( *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #( *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then : $as_echo_n "(cached) " >&6 else # One or both of the vars are not set, and there is no cached value. ac_x_includes=no ac_x_libraries=no rm -f -r conftest.dir if mkdir conftest.dir; then cd conftest.dir cat >Imakefile <<'_ACEOF' incroot: @echo incroot='${INCROOT}' usrlibdir: @echo usrlibdir='${USRLIBDIR}' libdir: @echo libdir='${LIBDIR}' _ACEOF if (export CC; ${XMKMF-xmkmf}) >/dev/null 2>/dev/null && test -f Makefile; then # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. for ac_var in incroot usrlibdir libdir; do eval "ac_im_$ac_var=\`\${MAKE-make} $ac_var 2>/dev/null | sed -n 's/^$ac_var=//p'\`" done # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. for ac_extension in a so sl dylib la dll; do if test ! -f "$ac_im_usrlibdir/libX11.$ac_extension" && test -f "$ac_im_libdir/libX11.$ac_extension"; then ac_im_usrlibdir=$ac_im_libdir; break fi done # Screen out bogus values from the imake configuration. They are # bogus both because they are the default anyway, and because # using them would break gcc on systems where it needs fixed includes. case $ac_im_incroot in /usr/include) ac_x_includes= ;; *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;; esac case $ac_im_usrlibdir in /usr/lib | /usr/lib64 | /lib | /lib64) ;; *) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;; esac fi cd .. rm -f -r conftest.dir fi # Standard set of common directories for X headers. # Check X11 before X11Rn because it is often a symlink to the current release. ac_x_header_dirs=' /usr/X11/include /usr/X11R7/include /usr/X11R6/include /usr/X11R5/include /usr/X11R4/include /usr/include/X11 /usr/include/X11R7 /usr/include/X11R6 /usr/include/X11R5 /usr/include/X11R4 /usr/local/X11/include /usr/local/X11R7/include /usr/local/X11R6/include /usr/local/X11R5/include /usr/local/X11R4/include /usr/local/include/X11 /usr/local/include/X11R7 /usr/local/include/X11R6 /usr/local/include/X11R5 /usr/local/include/X11R4 /usr/X386/include /usr/x386/include /usr/XFree86/include/X11 /usr/include /usr/local/include /usr/unsupported/include /usr/athena/include /usr/local/x11r5/include /usr/lpp/Xamples/include /usr/openwin/include /usr/openwin/share/include' if test "$ac_x_includes" = no; then # Guess where to find include files, by looking for Xlib.h. # First, try using that file with no special directory specified. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # We can compile using X headers with no special include directory. ac_x_includes= else for ac_dir in $ac_x_header_dirs; do if test -r "$ac_dir/X11/Xlib.h"; then ac_x_includes=$ac_dir break fi done fi rm -f conftest.err conftest.i conftest.$ac_ext fi # $ac_x_includes = no if test "$ac_x_libraries" = no; then # Check for the libraries. # See if we find them without any special options. # Don't add to $LIBS permanently. ac_save_LIBS=$LIBS LIBS="-lX11 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { XrmInitialize () ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : LIBS=$ac_save_LIBS # We can link X programs with no special library path. ac_x_libraries= else LIBS=$ac_save_LIBS for ac_dir in `$as_echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g` do # Don't even attempt the hair of trying to link an X program! for ac_extension in a so sl dylib la dll; do if test -r "$ac_dir/libX11.$ac_extension"; then ac_x_libraries=$ac_dir break 2 fi done done fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi # $ac_x_libraries = no case $ac_x_includes,$ac_x_libraries in #( no,* | *,no | *\'*) # Didn't find X, or a directory has "'" in its name. ac_cv_have_x="have_x=no";; #( *) # Record where we found X for the cache. ac_cv_have_x="have_x=yes\ ac_x_includes='$ac_x_includes'\ ac_x_libraries='$ac_x_libraries'" esac fi ;; #( *) have_x=yes;; esac eval "$ac_cv_have_x" fi # $with_x != no if test "$have_x" != yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_x" >&5 $as_echo "$have_x" >&6; } no_x=yes else # If each of the values was on the command line, it overrides each guess. test "x$x_includes" = xNONE && x_includes=$ac_x_includes test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries # Update the cache value to reflect the command line values. ac_cv_have_x="have_x=yes\ ac_x_includes='$x_includes'\ ac_x_libraries='$x_libraries'" { $as_echo "$as_me:${as_lineno-$LINENO}: result: libraries $x_libraries, headers $x_includes" >&5 $as_echo "libraries $x_libraries, headers $x_includes" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ax_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h # requires special compiler flags (e.g. on True64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5 $as_echo_n "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pthread_join (); int main () { return pthread_join (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ax_pthread_ok=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5 $as_echo "$ax_pthread_ok" >&6; } if test x"$ax_pthread_ok" = xno; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" fi # We must check for the threads library under a number of different # names; the ordering is very important because some systems # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). # Create a list of thread flags to try. Items starting with a "-" are # C compiler flags, and other items are library names, except for "none" # which indicates that we try without any flags at all, and "pthread-config" # which is a program returning the flags for the Pth emulation library. ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # pthreads: AIX (must check this before -lpthread) # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) # -pthreads: Solaris/gcc # -mthreads: Mingw32/gcc, Lynx/gcc # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads too; # also defines -D_REENTRANT) # ... -mt is also the pthreads flag for HP/aCC # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) case "${host_cpu}-${host_os}" in *solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (We need to link with -pthreads/-mt/ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather # a function called by this macro, so we could check for that, but # who knows whether they'll stub that too in a future libc.) So, # we'll just look for -pthreads and -lpthread first: ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" ;; esac if test x"$ax_pthread_ok" = xno; then for flag in $ax_pthread_flags; do case $flag in none) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5 $as_echo_n "checking whether pthreads work without any flags... " >&6; } ;; -*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $flag" >&5 $as_echo_n "checking whether pthreads work with $flag... " >&6; } PTHREAD_CFLAGS="$flag" ;; pthread-config) # Extract the first word of "pthread-config", so it can be a program name with args. set dummy pthread-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ax_pthread_config+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ax_pthread_config"; then ac_cv_prog_ax_pthread_config="$ax_pthread_config" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ax_pthread_config="yes" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_ax_pthread_config" && ac_cv_prog_ax_pthread_config="no" fi fi ax_pthread_config=$ac_cv_prog_ax_pthread_config if test -n "$ax_pthread_config"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_config" >&5 $as_echo "$ax_pthread_config" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test x"$ax_pthread_config" = xno; then continue; fi PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$flag" >&5 $as_echo_n "checking for the pthreads library -l$flag... " >&6; } PTHREAD_LIBS="-l$flag" ;; esac save_LIBS="$LIBS" save_CFLAGS="$CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we # need a special flag -Kthread to make this header compile.) # We check for pthread_join because it is in -lpthread on IRIX # while pthread_create is in libc. We check for pthread_attr_init # due to DEC craziness with -lpthreads. We check for # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include static void routine(void* a) {a=0;} static void* start_routine(void* a) {return a;} int main () { pthread_t th; pthread_attr_t attr; pthread_join(th, 0); pthread_attr_init(&attr); pthread_cleanup_push(routine, 0); pthread_create(&th,0,start_routine,0); pthread_cleanup_pop(0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ax_pthread_ok=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5 $as_echo "$ax_pthread_ok" >&6; } if test "x$ax_pthread_ok" = xyes; then break; fi PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi # Various other checks: if test "x$ax_pthread_ok" = xyes; then save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5 $as_echo_n "checking for joinable pthread attribute... " >&6; } attr_name=unknown for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int attr=$attr; return attr; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : attr_name=$attr; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done { $as_echo "$as_me:${as_lineno-$LINENO}: result: $attr_name" >&5 $as_echo "$attr_name" >&6; } if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then cat >>confdefs.h <<_ACEOF #define PTHREAD_CREATE_JOINABLE $attr_name _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if more special flags are required for pthreads" >&5 $as_echo_n "checking if more special flags are required for pthreads... " >&6; } flag=no case "${host_cpu}-${host_os}" in *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${flag}" >&5 $as_echo "${flag}" >&6; } if test "x$flag" != xno; then PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" # More AIX lossage: must compile with xlc_r or cc_r if test x"$GCC" != xyes; then for ac_prog in xlc_r cc_r do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_PTHREAD_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$PTHREAD_CC"; then ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_PTHREAD_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi PTHREAD_CC=$ac_cv_prog_PTHREAD_CC if test -n "$PTHREAD_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5 $as_echo "$PTHREAD_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$PTHREAD_CC" && break done test -n "$PTHREAD_CC" || PTHREAD_CC="${CC}" else PTHREAD_CC=$CC fi else PTHREAD_CC="$CC" fi # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test x"$ax_pthread_ok" = xyes; then $as_echo "#define HAVE_PTHREAD 1" >>confdefs.h : else ax_pthread_ok=no fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the Microsoft C compiler" >&5 $as_echo_n "checking whether we are using the Microsoft C compiler... " >&6; } if ${ax_cv_c_compiler_ms+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef _MSC_VER choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ax_compiler_ms=yes else ax_compiler_ms=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ax_cv_c_compiler_ms=$ax_compiler_ms fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_c_compiler_ms" >&5 $as_echo "$ax_cv_c_compiler_ms" >&6; } if test X$ax_compiler_ms = Xno; then : GL_CFLAGS="${PTHREAD_CFLAGS}"; GL_LIBS="${PTHREAD_LIBS}" fi # # Use x_includes and x_libraries if they have been set (presumably by # AC_PATH_X). # if test X$no_x != Xyes -a -n "$x_includes"; then : GL_CFLAGS="-I$x_includes $GL_CFLAGS" fi for ac_header in windows.h do : ac_fn_c_check_header_mongrel "$LINENO" "windows.h" "ac_cv_header_windows_h" "$ac_includes_default" if test "x$ac_cv_header_windows_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_WINDOWS_H 1 _ACEOF fi done ax_save_CPPFLAGS=$CPPFLAGS CPPFLAGS="$GL_CFLAGS $CPPFLAGS" for ac_header in GL/gl.h OpenGL/gl.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" " # if defined(HAVE_WINDOWS_H) && defined(_WIN32) # include # endif " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done CPPFLAGS=$ax_save_CPPFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenGL library" >&5 $as_echo_n "checking for OpenGL library... " >&6; } if ${ax_cv_check_gl_libgl+:} false; then : $as_echo_n "(cached) " >&6 else ax_cv_check_gl_libgl=no case $host_cpu in x86_64) ax_check_gl_libdir=lib64 ;; *) ax_check_gl_libdir=lib ;; esac ax_save_CPPFLAGS=$CPPFLAGS CPPFLAGS="$CPPFLAGS $GL_CFLAGS" if test X$no_x != Xyes -a -n "$x_libraries"; then : LDFLAGS="$LDFLAGS -L$x_libraries" fi ax_save_LDFLAGS=$LDFLAGS ax_save_LIBS=$LIBS ax_check_libs="-lopengl32 -lGL" for ax_lib in $ax_check_libs; do if test X$ax_compiler_ms = Xyes; then : ax_try_lib=`echo $ax_lib | $SED -e 's/^-l//' -e 's/$/.lib/'` else ax_try_lib=$ax_lib fi LDFLAGS="$ax_save_LDFLAGS $GL_LIBS" LIBS="$ax_try_lib $ax_save_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ # if defined(HAVE_WINDOWS_H) && defined(_WIN32) # include # endif # ifdef HAVE_GL_GL_H # include # elif defined(HAVE_OPENGL_GL_H) # include # else # error no gl.h # endif int main () { glBegin(0) ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ax_cv_check_gl_libgl=$ax_try_lib; break else ax_check_gl_nvidia_flags="-L/usr/$ax_check_gl_libdir/nvidia" LDFLAGS="$ax_save_LDFLAGS $GL_LIBS $ax_check_gl_nvidia_flags" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ # if defined(HAVE_WINDOWS_H) && defined(_WIN32) # include # endif # ifdef HAVE_GL_GL_H # include # elif defined(HAVE_OPENGL_GL_H) # include # else # error no gl.h # endif int main () { glBegin(0) ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ax_cv_check_gl_libgl="$ax_check_gl_nvidia_flags $ax_try_lib"; break else ax_check_gl_dylib_flag='-dylib_file /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib:/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib' LDFLAGS="$ax_save_LDFLAGS $GL_LIBS $ax_check_gl_dylib_flag" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ # if defined(HAVE_WINDOWS_H) && defined(_WIN32) # include # endif # ifdef HAVE_GL_GL_H # include # elif defined(HAVE_OPENGL_GL_H) # include # else # error no gl.h # endif int main () { glBegin(0) ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ax_cv_check_gl_libgl="$ax_check_gl_dylib_flag $ax_try_lib"; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done # # If no_x is "yes", we don't want to wind up using a libGL that is # linked with X11. Test to see if the found libGL includes GLX # functions. If it does and no_x is "yes", we want to reset # ax_cv_check_gl_libgl back to "no". # # Note that LDFLAGS and LIBS should still have whatever values they # had when we broke out of the test loop above; use that. # if test "X$ax_cv_check_gl_libgl" != Xno; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ # if defined(HAVE_WINDOWS_H) && defined(_WIN32) # include # endif # ifdef HAVE_GL_GL_H # include # elif defined(HAVE_OPENGL_GL_H) # include # else # error no gl.h # endif int main () { glXQueryVersion(0, 0, 0) ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : if test X$no_x = Xyes; then : ax_cv_check_gl_libgl=no fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi LIBS=$ax_save_LIBS if test "X$ax_cv_check_gl_libgl" = Xno -a X$no_x = Xyes; then : LDFLAGS="$ax_save_LDFLAGS -framework OpenGL" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ # if defined(HAVE_WINDOWS_H) && defined(_WIN32) # include # endif # ifdef HAVE_GL_GL_H # include # elif defined(HAVE_OPENGL_GL_H) # include # else # error no gl.h # endif int main () { glBegin(0) ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ax_cv_check_gl_libgl='-framework OpenGL' fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi LDFLAGS=$ax_save_LDFLAGS CPPFLAGS=$ax_save_CPPFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_gl_libgl" >&5 $as_echo "$ax_cv_check_gl_libgl" >&6; } if test "X$ax_cv_check_gl_libgl" = Xno; then : no_gl=yes; GL_CFLAGS=""; GL_LIBS="" else GL_LIBS="$ax_cv_check_gl_libgl $GL_LIBS" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test X$no_gl = Xyes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "OpenGL is required. See \`config.log' for more details" "$LINENO" 5; } fi GLU_CFLAGS=$GL_CFLAGS ax_save_CPPFLAGS=$CPPFLAGS CPPFLAGS="$GL_CFLAGS $CPPFLAGS" for ac_header in GL/glu.h OpenGL/glu.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" " # if defined(HAVE_WINDOWS_H) && defined(_WIN32) # include # endif " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done CPPFLAGS=$ax_save_CPPFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenGL Utility library" >&5 $as_echo_n "checking for OpenGL Utility library... " >&6; } if ${ax_cv_check_glu_libglu+:} false; then : $as_echo_n "(cached) " >&6 else ax_cv_check_glu_libglu=no ax_save_CPPFLAGS=$CPPFLAGS CPPFLAGS="$GL_CFLAGS $CPPFLAGS" ax_save_LDFLAGS=$LDFLAGS ax_save_LIBS=$LIBS # # First, check for the possibility that everything we need is already in # GL_LIBS. # LDFLAGS="$ax_save_LDFLAGS $GL_LIBS" # # libGLU typically links with libstdc++ on POSIX platforms. # However, setting the language to C++ means that test program # source is named "conftest.cc"; and Microsoft cl doesn't know what # to do with such a file. # ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test X$ax_compiler_ms = Xyes; then : ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ # if defined(HAVE_WINDOWS_H) && defined(_WIN32) # include # endif # ifdef HAVE_GL_GLU_H # include # elif defined(HAVE_OPENGL_GLU_H) # include # else # error no glu.h # endif int main () { gluBeginCurve(0) ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ax_cv_check_glu_libglu=yes else LIBS="" ax_check_libs="-lglu32 -lGLU" for ax_lib in ${ax_check_libs}; do if test X$ax_compiler_ms = Xyes; then : ax_try_lib=`echo $ax_lib | $SED -e 's/^-l//' -e 's/$/.lib/'` else ax_try_lib=$ax_lib fi LIBS="$ax_try_lib $ax_save_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ # if defined(HAVE_WINDOWS_H) && defined(_WIN32) # include # endif # ifdef HAVE_GL_GLU_H # include # elif defined(HAVE_OPENGL_GLU_H) # include # else # error no glu.h # endif int main () { gluBeginCurve(0) ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ax_cv_check_glu_libglu=$ax_try_lib; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test X$ax_compiler_ms = Xyes; then : ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu LIBS=$ax_save_LIBS LDFLAGS=$ax_save_LDFLAGS CPPFLAGS=$ax_save_CPPFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_glu_libglu" >&5 $as_echo "$ax_cv_check_glu_libglu" >&6; } if test "X$ax_cv_check_glu_libglu" = Xno; then : no_glu=yes; GLU_CFLAGS=""; GLU_LIBS="" else if test "X$ax_cv_check_glu_libglu" = Xyes; then : GLU_LIBS="" else GLU_LIBS="$ax_cv_check_glu_libglu" fi fi # # Some versions of Mac OS X include a broken interpretation of the GLU # tesselation callback function signature when using the C++ compiler. # if test "X$ax_cv_check_glu_libglu" != Xno; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for varargs GLU tesselator callback function type" >&5 $as_echo_n "checking for varargs GLU tesselator callback function type... " >&6; } if ${ax_cv_varargs_glu_tesscb+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ax_cv_varargs_glu_tesscb=no ax_save_CXXFLAGS=$CXXFLAGS CXXFLAGS="$GL_CFLAGS $CXXFLAGS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ # ifdef HAVE_GL_GLU_H # include # else # include # endif int main () { GLvoid (*func)(...); gluTessCallback(0, 0, func) ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ax_cv_varargs_glu_tesscb=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CXXFLAGS=$ax_save_CXXFLAGS ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_varargs_glu_tesscb" >&5 $as_echo "$ax_cv_varargs_glu_tesscb" >&6; } if test X$ax_cv_varargs_glu_tesscb = Xyes; then : $as_echo "#define HAVE_VARARGS_GLU_TESSCB 1" >>confdefs.h fi fi if test X$no_glu = Xyes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The OpenGL GLU library is required. See \`config.log' for more details" "$LINENO" 5; } fi $as_echo "#define ENABLE_GL 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for which printer to use" >&5 $as_echo_n "checking for which printer to use... " >&6; } # Check whether --with-printer was given. if test "${with_printer+set}" = set; then : withval=$with_printer; else with_printer=lpr fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_printer" >&5 $as_echo "$with_printer" >&6; } case " $hid_printers " in *\ $with_printer\ * ) HIDLIST="$HIDLIST $with_printer" ;; * ) as_fn_error $? "$with_printer is not a valid printer" "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for which exporters to use" >&5 $as_echo_n "checking for which exporters to use... " >&6; } # Check whether --with-exporters was given. if test "${with_exporters+set}" = set; then : withval=$with_exporters; else with_exporters=$hid_exporters fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_exporters" >&5 $as_echo "$with_exporters" >&6; } for e in `echo $with_exporters | sed 's/,/ /g'`; do case " $hid_exporters " in *\ $e\ * ) HIDLIST="$HIDLIST $e" ;; * ) as_fn_error $? "$e is not a valid exporter" "$LINENO" 5 ;; esac done if test "X$enable_jpeg" = "Xno" -a "X$enable_gif" = "Xno" -a "X$enable_png" = "Xno" ; then case " ${HIDLIST} " in *\ png\ *) as_fn_error $? "you have requested the png HID but turned off all output formats! If you do not want gif/jpeg/png output, use --with-exporters to list which exporters you want and do not list png there." "$LINENO" 5 ;; *) ;; esac fi for hid in $HIDLIST; do F=$srcdir/src/hid/$hid/hid.conf if test -f $F ; then echo checking $hid dependencies deps= . $F for dep in $deps; do if test "X`echo $HIDLIST | grep $dep`" = "X"; then as_fn_error $? "you have requested the $hid HID but not the $dep HID, which it depends on" "$LINENO" 5 fi done fi done for e in $HIDLIST; do HIDLIBS="$HIDLIBS lib$e.a" done # ------------- end HID config ------------------- ###################################################################### # # desktop integration # # Extract the first word of "env", so it can be a program name with args. set dummy env; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_SETENV+:} false; then : $as_echo_n "(cached) " >&6 else case $SETENV in [\\/]* | ?:[\\/]*) ac_cv_path_SETENV="$SETENV" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_SETENV="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi SETENV=$ac_cv_path_SETENV if test -n "$SETENV"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SETENV" >&5 $as_echo "$SETENV" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "gtk-update-icon-path", so it can be a program name with args. set dummy gtk-update-icon-path; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_GTK_UPDATE_ICON_CACHE_BIN+:} false; then : $as_echo_n "(cached) " >&6 else case $GTK_UPDATE_ICON_CACHE_BIN in [\\/]* | ?:[\\/]*) ac_cv_path_GTK_UPDATE_ICON_CACHE_BIN="$GTK_UPDATE_ICON_CACHE_BIN" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_GTK_UPDATE_ICON_CACHE_BIN="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_GTK_UPDATE_ICON_CACHE_BIN" && ac_cv_path_GTK_UPDATE_ICON_CACHE_BIN="true" ;; esac fi GTK_UPDATE_ICON_CACHE_BIN=$ac_cv_path_GTK_UPDATE_ICON_CACHE_BIN if test -n "$GTK_UPDATE_ICON_CACHE_BIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GTK_UPDATE_ICON_CACHE_BIN" >&5 $as_echo "$GTK_UPDATE_ICON_CACHE_BIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Change default location for XDG files (MIME and Icons) # Check whether --with-xdgdatadir was given. if test "${with_xdgdatadir+set}" = set; then : withval=$with_xdgdatadir; opt_xdgdatadir=$withval fi # Change default location for KDE data files (KDE MIME registrations) # Check whether --with-kdedatadir was given. if test "${with_kdedatadir+set}" = set; then : withval=$with_kdedatadir; opt_kdedatadir=$withval fi if test x$opt_xdgdatadir = x; then # path was not specified with --with-xdgdatadir XDGDATADIR='${datadir}' else # path WAS specified with --with-xdgdatadir XDGDATADIR="$opt_xdgdatadir" fi if test x$opt_kdedatadir = x; then # path was not specified with --with-kdedatadir KDEDATADIR='${datadir}' else # path WAS specified with --with-kdedatadir KDEDATADIR="$opt_kdedatadir" fi # Check whether --enable-update-desktop-database was given. if test "${enable_update_desktop_database+set}" = set; then : enableval=$enable_update_desktop_database; else enable_update_desktop_database=yes fi if test x$enable_update_desktop_database = xyes; then ENABLE_UPDATE_DESKTOP_DATABASE_TRUE= ENABLE_UPDATE_DESKTOP_DATABASE_FALSE='#' else ENABLE_UPDATE_DESKTOP_DATABASE_TRUE='#' ENABLE_UPDATE_DESKTOP_DATABASE_FALSE= fi if test x$enable_update_desktop_database = xyes ; then # Extract the first word of "update-desktop-database", so it can be a program name with args. set dummy update-desktop-database; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_UPDATE_DESKTOP_DATABASE+:} false; then : $as_echo_n "(cached) " >&6 else case $UPDATE_DESKTOP_DATABASE in [\\/]* | ?:[\\/]*) ac_cv_path_UPDATE_DESKTOP_DATABASE="$UPDATE_DESKTOP_DATABASE" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_UPDATE_DESKTOP_DATABASE="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_UPDATE_DESKTOP_DATABASE" && ac_cv_path_UPDATE_DESKTOP_DATABASE="no" ;; esac fi UPDATE_DESKTOP_DATABASE=$ac_cv_path_UPDATE_DESKTOP_DATABASE if test -n "$UPDATE_DESKTOP_DATABASE"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $UPDATE_DESKTOP_DATABASE" >&5 $as_echo "$UPDATE_DESKTOP_DATABASE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test $UPDATE_DESKTOP_DATABASE = no; then as_fn_error $? "Cannot find update-desktop-database, make sure it is installed and in your PATH, or configure with --disable-update-desktop-database" "$LINENO" 5 fi fi # Check whether --enable-update-mime-database was given. if test "${enable_update_mime_database+set}" = set; then : enableval=$enable_update_mime_database; else enable_update_mime_database=yes fi if test x$enable_update_mime_database = xyes; then ENABLE_UPDATE_MIME_DATABASE_TRUE= ENABLE_UPDATE_MIME_DATABASE_FALSE='#' else ENABLE_UPDATE_MIME_DATABASE_TRUE='#' ENABLE_UPDATE_MIME_DATABASE_FALSE= fi if test x$enable_update_mime_database = xyes ; then # Extract the first word of "update-mime-database", so it can be a program name with args. set dummy update-mime-database; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_UPDATE_MIME_DATABASE+:} false; then : $as_echo_n "(cached) " >&6 else case $UPDATE_MIME_DATABASE in [\\/]* | ?:[\\/]*) ac_cv_path_UPDATE_MIME_DATABASE="$UPDATE_MIME_DATABASE" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_UPDATE_MIME_DATABASE="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_UPDATE_MIME_DATABASE" && ac_cv_path_UPDATE_MIME_DATABASE="no" ;; esac fi UPDATE_MIME_DATABASE=$ac_cv_path_UPDATE_MIME_DATABASE if test -n "$UPDATE_MIME_DATABASE"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $UPDATE_MIME_DATABASE" >&5 $as_echo "$UPDATE_MIME_DATABASE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test $UPDATE_MIME_DATABASE = no; then as_fn_error $? "Cannot find update-mime-database, make sure it is installed and in your PATH, or configure with --disable-update-mime-database" "$LINENO" 5 fi fi # ###################################################################### # ------------- Non-standard gaf install location ----------------- { $as_echo "$as_me:${as_lineno-$LINENO}: checking where to install gaf scheme additions" >&5 $as_echo_n "checking where to install gaf scheme additions... " >&6; } GAFDATADIR="${datadir}" # Check whether --with-gaf-datadir was given. if test "${with_gaf_datadir+set}" = set; then : withval=$with_gaf_datadir; if (test "X$with_gaf_datadir" != "Xno" && test "X$with_gaf_datadir" != "Xyes"); then GAFDATADIR="$with_gaf_datadir" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GAFDATADIR" >&5 $as_echo "$GAFDATADIR" >&6; } for ac_prog in gm4 m4 do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_M4+:} false; then : $as_echo_n "(cached) " >&6 else case $M4 in [\\/]* | ?:[\\/]*) ac_cv_path_M4="$M4" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_M4="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi M4=$ac_cv_path_M4 if test -n "$M4"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $M4" >&5 $as_echo "$M4" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$M4" && break done test -n "$M4" || M4="none" if test "X$M4" = "Xnone" ; then as_fn_error $? "Did not find a m4 executible. You need to make sure that m4 is installed on your system and that m4 is in your path" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $M4 has the division involving negative numbers bug" >&5 $as_echo_n "checking if $M4 has the division involving negative numbers bug... " >&6; } pcb_m4_r=`echo "eval(-2/2)" | $M4` if test "$pcb_m4_r" != "-1" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } as_fn_error $? "It appears that $M4 has a bug involving division with negative numbers. In particular it just returned the result that -2/2 = $pcb_m4_r instead of -1. This is a known bug in GNU m4-1.4.9. Please install a non-broken m4." "$LINENO" 5 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi for ac_prog in wish wish85 wish8.5 wish83 wish8.3 wish80 wish8.0 cygwish83 cygwish80 do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_WISH+:} false; then : $as_echo_n "(cached) " >&6 else case $WISH in [\\/]* | ?:[\\/]*) ac_cv_path_WISH="$WISH" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_WISH="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi WISH=$ac_cv_path_WISH if test -n "$WISH"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WISH" >&5 $as_echo "$WISH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$WISH" && break done test -n "$WISH" || WISH="none" if test "X$WISH" = "Xnone" ; then as_fn_error $? "Did not find the wish executible. You need to make sure that tcl is installed on your system and that wish is in your path" "$LINENO" 5 fi cat >>confdefs.h <<_ACEOF #define M4 $M4 _ACEOF GNUM4=$M4 cat >>confdefs.h <<_ACEOF #define GNUM4 "$M4" _ACEOF # Extract the first word of "pdflatex", so it can be a program name with args. set dummy pdflatex; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PDFLATEX+:} false; then : $as_echo_n "(cached) " >&6 else case $PDFLATEX in [\\/]* | ?:[\\/]*) ac_cv_path_PDFLATEX="$PDFLATEX" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PDFLATEX="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PDFLATEX" && ac_cv_path_PDFLATEX="notfound" ;; esac fi PDFLATEX=$ac_cv_path_PDFLATEX if test -n "$PDFLATEX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PDFLATEX" >&5 $as_echo "$PDFLATEX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test x$PDFLATEX = xnotfound; then MISSING_PDFLATEX_TRUE= MISSING_PDFLATEX_FALSE='#' else MISSING_PDFLATEX_TRUE='#' MISSING_PDFLATEX_FALSE= fi # Extract the first word of "texi2dvi", so it can be a program name with args. set dummy texi2dvi; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_TEXI2DVI+:} false; then : $as_echo_n "(cached) " >&6 else case $TEXI2DVI in [\\/]* | ?:[\\/]*) ac_cv_path_TEXI2DVI="$TEXI2DVI" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_TEXI2DVI="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_TEXI2DVI" && ac_cv_path_TEXI2DVI="notfound" ;; esac fi TEXI2DVI=$ac_cv_path_TEXI2DVI if test -n "$TEXI2DVI"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TEXI2DVI" >&5 $as_echo "$TEXI2DVI" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test x$TEXI2DVI = xnotfound; then MISSING_TEXI2DVI_TRUE= MISSING_TEXI2DVI_FALSE='#' else MISSING_TEXI2DVI_TRUE='#' MISSING_TEXI2DVI_FALSE= fi # Extract the first word of "ps2pdf", so it can be a program name with args. set dummy ps2pdf; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PS2PDF+:} false; then : $as_echo_n "(cached) " >&6 else case $PS2PDF in [\\/]* | ?:[\\/]*) ac_cv_path_PS2PDF="$PS2PDF" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PS2PDF="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PS2PDF" && ac_cv_path_PS2PDF="notfound" ;; esac fi PS2PDF=$ac_cv_path_PS2PDF if test -n "$PS2PDF"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PS2PDF" >&5 $as_echo "$PS2PDF" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test x$PS2PDF = xnotfound; then MISSING_PS2PDF_TRUE= MISSING_PS2PDF_FALSE='#' else MISSING_PS2PDF_TRUE='#' MISSING_PS2PDF_FALSE= fi # used to build some of the getting started guide # Extract the first word of "gschem", so it can be a program name with args. set dummy gschem; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_GSCHEM+:} false; then : $as_echo_n "(cached) " >&6 else case $GSCHEM in [\\/]* | ?:[\\/]*) ac_cv_path_GSCHEM="$GSCHEM" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_GSCHEM="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_GSCHEM" && ac_cv_path_GSCHEM="notfound" ;; esac fi GSCHEM=$ac_cv_path_GSCHEM if test -n "$GSCHEM"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GSCHEM" >&5 $as_echo "$GSCHEM" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test x$GSCHEM = xnotfound; then MISSING_GSCHEM_TRUE= MISSING_GSCHEM_FALSE='#' else MISSING_GSCHEM_TRUE='#' MISSING_GSCHEM_FALSE= fi if test "X$docs_yesno" = "Xyes" -a "X$pcb_git_version" = "Xyes" ; then if test "$PDFLATEX" = "notfound" -o "$TEXI2DVI" = "notfound" -o "$PS2PDF" = "notfound" ; then as_fn_error $? "It appears that you are building from a source tree obtained via git but you do not have the required tools installed to build the documentation. Here is a list of tools and the detected values: PDFLATEX: $PDFLATEX TEXI2DVI: $TEXI2DVI PS2PDF: $PS2PDF GSCHEM: $GSCHEM Either make sure these tools are installed or disable building and installing the documentation by using the --disable-doc configure option. " "$LINENO" 5 fi fi ############################################################################ # # These checks are for tools used by the testsuite. It will not be fatal # if these are missing because this is primarily for developer use. It is # possible that we might add some --enable flag in the future that forces # full tools for development work. # Check for ImageMagick tools used by the testsuite # Extract the first word of "animate", so it can be a program name with args. set dummy animate; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_IM_ANIMATE+:} false; then : $as_echo_n "(cached) " >&6 else case $IM_ANIMATE in [\\/]* | ?:[\\/]*) ac_cv_path_IM_ANIMATE="$IM_ANIMATE" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_IM_ANIMATE="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_IM_ANIMATE" && ac_cv_path_IM_ANIMATE="notfound" ;; esac fi IM_ANIMATE=$ac_cv_path_IM_ANIMATE if test -n "$IM_ANIMATE"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $IM_ANIMATE" >&5 $as_echo "$IM_ANIMATE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "compare", so it can be a program name with args. set dummy compare; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_IM_COMPARE+:} false; then : $as_echo_n "(cached) " >&6 else case $IM_COMPARE in [\\/]* | ?:[\\/]*) ac_cv_path_IM_COMPARE="$IM_COMPARE" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_IM_COMPARE="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_IM_COMPARE" && ac_cv_path_IM_COMPARE="notfound" ;; esac fi IM_COMPARE=$ac_cv_path_IM_COMPARE if test -n "$IM_COMPARE"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $IM_COMPARE" >&5 $as_echo "$IM_COMPARE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "composite", so it can be a program name with args. set dummy composite; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_IM_COMPOSITE+:} false; then : $as_echo_n "(cached) " >&6 else case $IM_COMPOSITE in [\\/]* | ?:[\\/]*) ac_cv_path_IM_COMPOSITE="$IM_COMPOSITE" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_IM_COMPOSITE="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_IM_COMPOSITE" && ac_cv_path_IM_COMPOSITE="notfound" ;; esac fi IM_COMPOSITE=$ac_cv_path_IM_COMPOSITE if test -n "$IM_COMPOSITE"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $IM_COMPOSITE" >&5 $as_echo "$IM_COMPOSITE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "convert", so it can be a program name with args. set dummy convert; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_IM_CONVERT+:} false; then : $as_echo_n "(cached) " >&6 else case $IM_CONVERT in [\\/]* | ?:[\\/]*) ac_cv_path_IM_CONVERT="$IM_CONVERT" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_IM_CONVERT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_IM_CONVERT" && ac_cv_path_IM_CONVERT="notfound" ;; esac fi IM_CONVERT=$ac_cv_path_IM_CONVERT if test -n "$IM_CONVERT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $IM_CONVERT" >&5 $as_echo "$IM_CONVERT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "display", so it can be a program name with args. set dummy display; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_IM_DISPLAY+:} false; then : $as_echo_n "(cached) " >&6 else case $IM_DISPLAY in [\\/]* | ?:[\\/]*) ac_cv_path_IM_DISPLAY="$IM_DISPLAY" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_IM_DISPLAY="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_IM_DISPLAY" && ac_cv_path_IM_DISPLAY="notfound" ;; esac fi IM_DISPLAY=$ac_cv_path_IM_DISPLAY if test -n "$IM_DISPLAY"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $IM_DISPLAY" >&5 $as_echo "$IM_DISPLAY" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "montage", so it can be a program name with args. set dummy montage; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_IM_MONTAGE+:} false; then : $as_echo_n "(cached) " >&6 else case $IM_MONTAGE in [\\/]* | ?:[\\/]*) ac_cv_path_IM_MONTAGE="$IM_MONTAGE" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_IM_MONTAGE="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_IM_MONTAGE" && ac_cv_path_IM_MONTAGE="notfound" ;; esac fi IM_MONTAGE=$ac_cv_path_IM_MONTAGE if test -n "$IM_MONTAGE"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $IM_MONTAGE" >&5 $as_echo "$IM_MONTAGE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "xhost", so it can be a program name with args. set dummy xhost; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_XHOST+:} false; then : $as_echo_n "(cached) " >&6 else case $XHOST in [\\/]* | ?:[\\/]*) ac_cv_path_XHOST="$XHOST" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_XHOST="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_XHOST" && ac_cv_path_XHOST="notfound" ;; esac fi XHOST=$ac_cv_path_XHOST if test -n "$XHOST"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XHOST" >&5 $as_echo "$XHOST" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi missing_magick="" test "${IM_ANIMATE}" != "notfound" || missing_magick="${missing_magick} animate" test "${IM_COMPARE}" != "notfound" || missing_magick="${missing_magick} compare" test "${IM_COMPOSITE}" != "notfound" || missing_magick="${missing_magick} composite" test "${IM_CONVERT}" != "notfound" || missing_magick="${missing_magick} convert" test "${IM_DISPLAY}" != "notfound" || missing_magick="${missing_magick} display" test "${IM_MONTAGE}" != "notfound" || missing_magick="${missing_magick} montage" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if all ImageMagick tools needed for the testsuite were found" >&5 $as_echo_n "checking if all ImageMagick tools needed for the testsuite were found... " >&6; } if test "X${missing_magick}" != "X" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no. The testsuite will be disabled because the following tools from the ImageMagick suite were not found: ${missing_magick} No loss in pcb functionality should be experienced, you just will not be able to run the full regression testsuite. " >&5 $as_echo "no. The testsuite will be disabled because the following tools from the ImageMagick suite were not found: ${missing_magick} No loss in pcb functionality should be experienced, you just will not be able to run the full regression testsuite. " >&6; } have_magick=no else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } have_magick=yes fi have_test_tools=yes test $have_magick = yes || have_test_tools=no # the RS274-X export HID is partially checked by looking at the result with # gerbv # Extract the first word of "gerbv", so it can be a program name with args. set dummy gerbv; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_GERBV+:} false; then : $as_echo_n "(cached) " >&6 else case $GERBV in [\\/]* | ?:[\\/]*) ac_cv_path_GERBV="$GERBV" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_GERBV="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_GERBV" && ac_cv_path_GERBV="notfound" ;; esac fi GERBV=$ac_cv_path_GERBV if test -n "$GERBV"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GERBV" >&5 $as_echo "$GERBV" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test $GERBV != notfound || have_test_tools=no if test x$have_test_tools = xyes; then HAVE_TEST_TOOLS_TRUE= HAVE_TEST_TOOLS_FALSE='#' else HAVE_TEST_TOOLS_TRUE='#' HAVE_TEST_TOOLS_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if all the required testsuite tools were found" >&5 $as_echo_n "checking if all the required testsuite tools were found... " >&6; } if test x$have_test_tools = xyes ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no -- the testsuite will be disabled" >&5 $as_echo "no -- the testsuite will be disabled" >&6; } fi # ############################################################################ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqrt in -lm" >&5 $as_echo_n "checking for sqrt in -lm... " >&6; } if ${ac_cv_lib_m_sqrt+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char sqrt (); int main () { return sqrt (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_sqrt=yes else ac_cv_lib_m_sqrt=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sqrt" >&5 $as_echo "$ac_cv_lib_m_sqrt" >&6; } if test "x$ac_cv_lib_m_sqrt" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBDL 1 _ACEOF LIBS="-ldl $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lxnet" >&5 $as_echo_n "checking for gethostbyname in -lxnet... " >&6; } if ${ac_cv_lib_xnet_gethostbyname+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lxnet $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethostbyname (); int main () { return gethostbyname (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_xnet_gethostbyname=yes else ac_cv_lib_xnet_gethostbyname=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xnet_gethostbyname" >&5 $as_echo "$ac_cv_lib_xnet_gethostbyname" >&6; } if test "x$ac_cv_lib_xnet_gethostbyname" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBXNET 1 _ACEOF LIBS="-lxnet $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for yywrap in -lfl" >&5 $as_echo_n "checking for yywrap in -lfl... " >&6; } if ${ac_cv_lib_fl_yywrap+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lfl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char yywrap (); int main () { return yywrap (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_fl_yywrap=yes else ac_cv_lib_fl_yywrap=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_fl_yywrap" >&5 $as_echo "$ac_cv_lib_fl_yywrap" >&6; } if test "x$ac_cv_lib_fl_yywrap" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBFL 1 _ACEOF LIBS="-lfl $LIBS" fi for ac_func in getline do : ac_fn_c_check_func "$LINENO" "getline" "ac_cv_func_getline" if test "x$ac_cv_func_getline" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GETLINE 1 _ACEOF fi done for ac_func in strcasestr do : ac_fn_c_check_func "$LINENO" "strcasestr" "ac_cv_func_strcasestr" if test "x$ac_cv_func_strcasestr" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRCASESTR 1 _ACEOF fi done for ac_func in strerror do : ac_fn_c_check_func "$LINENO" "strerror" "ac_cv_func_strerror" if test "x$ac_cv_func_strerror" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRERROR 1 _ACEOF fi done for ac_func in regcomp re_comp do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in logf expf rint do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in vsnprintf do : ac_fn_c_check_func "$LINENO" "vsnprintf" "ac_cv_func_vsnprintf" if test "x$ac_cv_func_vsnprintf" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_VSNPRINTF 1 _ACEOF fi done for ac_func in getpwuid getcwd do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in rand random do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in stat do : ac_fn_c_check_func "$LINENO" "stat" "ac_cv_func_stat" if test "x$ac_cv_func_stat" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STAT 1 _ACEOF fi done for ac_func in mkdtemp do : ac_fn_c_check_func "$LINENO" "mkdtemp" "ac_cv_func_mkdtemp" if test "x$ac_cv_func_mkdtemp" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_MKDTEMP 1 _ACEOF fi done # normally used for all file i/o for ac_func in popen do : ac_fn_c_check_func "$LINENO" "popen" "ac_cv_func_popen" if test "x$ac_cv_func_popen" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_POPEN 1 _ACEOF fi done # for lrealpath.c for ac_func in realpath canonicalize_file_name do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether canonicalize_file_name must be declared" >&5 $as_echo_n "checking whether canonicalize_file_name must be declared... " >&6; } if ${libiberty_cv_decl_needed_canonicalize_file_name+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "confdefs.h" #include #ifdef HAVE_STRING_H #include #else #ifdef HAVE_STRINGS_H #include #endif #endif #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif int main () { char *(*pfn) = (char *(*)) canonicalize_file_name ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : libiberty_cv_decl_needed_canonicalize_file_name=no else libiberty_cv_decl_needed_canonicalize_file_name=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $libiberty_cv_decl_needed_canonicalize_file_name" >&5 $as_echo "$libiberty_cv_decl_needed_canonicalize_file_name" >&6; } if test $libiberty_cv_decl_needed_canonicalize_file_name = yes; then $as_echo "#define NEED_DECLARATION_CANONICALIZE_FILE_NAME 1" >>confdefs.h fi # for pcb_spawnvp in action.c on Windows for ac_func in _spawnvp do : ac_fn_c_check_func "$LINENO" "_spawnvp" "ac_cv_func__spawnvp" if test "x$ac_cv_func__spawnvp" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE__SPAWNVP 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi for ac_header in limits.h locale.h string.h sys/types.h regex.h pwd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in sys/socket.h netinet/in.h netdb.h sys/param.h sys/times.h sys/wait.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in dlfcn.h do : ac_fn_c_check_header_mongrel "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default" if test "x$ac_cv_header_dlfcn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF fi done if test "x${WIN32}" = "xyes" ; then for ac_header in windows.h do : ac_fn_c_check_header_mongrel "$LINENO" "windows.h" "ac_cv_header_windows_h" "$ac_includes_default" if test "x$ac_cv_header_windows_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_WINDOWS_H 1 _ACEOF fi done fi # Search for glib pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GLIB" >&5 $as_echo_n "checking for GLIB... " >&6; } if test -n "$GLIB_CFLAGS"; then pkg_cv_GLIB_CFLAGS="$GLIB_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"glib-2.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "glib-2.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GLIB_CFLAGS=`$PKG_CONFIG --cflags "glib-2.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$GLIB_LIBS"; then pkg_cv_GLIB_LIBS="$GLIB_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"glib-2.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "glib-2.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GLIB_LIBS=`$PKG_CONFIG --libs "glib-2.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then GLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "glib-2.0" 2>&1` else GLIB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "glib-2.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$GLIB_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: Note: cannot find glib-2.0. You may want to review the following errors: $GLIB_PKG_ERRORS" >&5 $as_echo "Note: cannot find glib-2.0. You may want to review the following errors: $GLIB_PKG_ERRORS" >&6; } elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: Note: cannot find glib-2.0. You may want to review the following errors: $GLIB_PKG_ERRORS" >&5 $as_echo "Note: cannot find glib-2.0. You may want to review the following errors: $GLIB_PKG_ERRORS" >&6; } else GLIB_CFLAGS=$pkg_cv_GLIB_CFLAGS GLIB_LIBS=$pkg_cv_GLIB_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi need_gdlib=no with_gif=no with_png=no with_jpeg=no for e in $HIDLIST; do case $e in lesstif ) if test "$no_x" = yes; then # Not all programs may use this symbol, but it does not hurt to define it. $as_echo "#define X_DISPLAY_MISSING 1" >>confdefs.h X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS= else if test -n "$x_includes"; then X_CFLAGS="$X_CFLAGS -I$x_includes" fi # It would also be nice to do this for all -L options, not just this one. if test -n "$x_libraries"; then X_LIBS="$X_LIBS -L$x_libraries" # For Solaris; some versions of Sun CC require a space after -R and # others require no space. Words are not sufficient . . . . { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -R must be followed by a space" >&5 $as_echo_n "checking whether -R must be followed by a space... " >&6; } ac_xsave_LIBS=$LIBS; LIBS="$LIBS -R$x_libraries" ac_xsave_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } X_LIBS="$X_LIBS -R$x_libraries" else LIBS="$ac_xsave_LIBS -R $x_libraries" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } X_LIBS="$X_LIBS -R $x_libraries" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: neither works" >&5 $as_echo "neither works" >&6; } fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_c_werror_flag=$ac_xsave_c_werror_flag LIBS=$ac_xsave_LIBS fi # Check for system-dependent libraries X programs must link with. # Do this before checking for the system-independent R6 libraries # (-lICE), since we may need -lsocket or whatever for X linking. if test "$ISC" = yes; then X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet" else # Martyn Johnson says this is needed for Ultrix, if the X # libraries were built with DECnet support. And Karl Berry says # the Alpha needs dnet_stub (dnet does not exist). ac_xsave_LIBS="$LIBS"; LIBS="$LIBS $X_LIBS -lX11" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XOpenDisplay (); int main () { return XOpenDisplay (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet" >&5 $as_echo_n "checking for dnet_ntoa in -ldnet... " >&6; } if ${ac_cv_lib_dnet_dnet_ntoa+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldnet $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dnet_ntoa (); int main () { return dnet_ntoa (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dnet_dnet_ntoa=yes else ac_cv_lib_dnet_dnet_ntoa=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_dnet_ntoa" >&5 $as_echo "$ac_cv_lib_dnet_dnet_ntoa" >&6; } if test "x$ac_cv_lib_dnet_dnet_ntoa" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet" fi if test $ac_cv_lib_dnet_dnet_ntoa = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet_stub" >&5 $as_echo_n "checking for dnet_ntoa in -ldnet_stub... " >&6; } if ${ac_cv_lib_dnet_stub_dnet_ntoa+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldnet_stub $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dnet_ntoa (); int main () { return dnet_ntoa (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dnet_stub_dnet_ntoa=yes else ac_cv_lib_dnet_stub_dnet_ntoa=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5 $as_echo "$ac_cv_lib_dnet_stub_dnet_ntoa" >&6; } if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub" fi fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$ac_xsave_LIBS" # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT, # to get the SysV transport functions. # Chad R. Larson says the Pyramis MIS-ES running DC/OSx (SVR4) # needs -lnsl. # The nsl library prevents programs from opening the X display # on Irix 5.2, according to T.E. Dickey. # The functions gethostbyname, getservbyname, and inet_addr are # in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking. ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname" if test "x$ac_cv_func_gethostbyname" = xyes; then : fi if test $ac_cv_func_gethostbyname = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 $as_echo_n "checking for gethostbyname in -lnsl... " >&6; } if ${ac_cv_lib_nsl_gethostbyname+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethostbyname (); int main () { return gethostbyname (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nsl_gethostbyname=yes else ac_cv_lib_nsl_gethostbyname=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 $as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl" fi if test $ac_cv_lib_nsl_gethostbyname = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lbsd" >&5 $as_echo_n "checking for gethostbyname in -lbsd... " >&6; } if ${ac_cv_lib_bsd_gethostbyname+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lbsd $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethostbyname (); int main () { return gethostbyname (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_bsd_gethostbyname=yes else ac_cv_lib_bsd_gethostbyname=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_gethostbyname" >&5 $as_echo "$ac_cv_lib_bsd_gethostbyname" >&6; } if test "x$ac_cv_lib_bsd_gethostbyname" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd" fi fi fi # lieder@skyler.mavd.honeywell.com says without -lsocket, # socket/setsockopt and other routines are undefined under SCO ODT # 2.0. But -lsocket is broken on IRIX 5.2 (and is not necessary # on later versions), says Simon Leinen: it contains gethostby* # variants that don't use the name server (or something). -lsocket # must be given before -lnsl if both are needed. We assume that # if connect needs -lnsl, so does gethostbyname. ac_fn_c_check_func "$LINENO" "connect" "ac_cv_func_connect" if test "x$ac_cv_func_connect" = xyes; then : fi if test $ac_cv_func_connect = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5 $as_echo_n "checking for connect in -lsocket... " >&6; } if ${ac_cv_lib_socket_connect+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $X_EXTRA_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char connect (); int main () { return connect (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_socket_connect=yes else ac_cv_lib_socket_connect=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5 $as_echo "$ac_cv_lib_socket_connect" >&6; } if test "x$ac_cv_lib_socket_connect" = xyes; then : X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS" fi fi # Guillermo Gomez says -lposix is necessary on A/UX. ac_fn_c_check_func "$LINENO" "remove" "ac_cv_func_remove" if test "x$ac_cv_func_remove" = xyes; then : fi if test $ac_cv_func_remove = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for remove in -lposix" >&5 $as_echo_n "checking for remove in -lposix... " >&6; } if ${ac_cv_lib_posix_remove+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lposix $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char remove (); int main () { return remove (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_posix_remove=yes else ac_cv_lib_posix_remove=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_posix_remove" >&5 $as_echo "$ac_cv_lib_posix_remove" >&6; } if test "x$ac_cv_lib_posix_remove" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix" fi fi # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. ac_fn_c_check_func "$LINENO" "shmat" "ac_cv_func_shmat" if test "x$ac_cv_func_shmat" = xyes; then : fi if test $ac_cv_func_shmat = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shmat in -lipc" >&5 $as_echo_n "checking for shmat in -lipc... " >&6; } if ${ac_cv_lib_ipc_shmat+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lipc $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shmat (); int main () { return shmat (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_ipc_shmat=yes else ac_cv_lib_ipc_shmat=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ipc_shmat" >&5 $as_echo "$ac_cv_lib_ipc_shmat" >&6; } if test "x$ac_cv_lib_ipc_shmat" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc" fi fi fi # Check for libraries that X11R6 Xt/Xaw programs need. ac_save_LDFLAGS=$LDFLAGS test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries" # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to # check for ICE first), but we must link in the order -lSM -lICE or # we get undefined symbols. So assume we have SM if we have ICE. # These have to be linked with before -lX11, unlike the other # libraries we check for below, so use a different variable. # John Interrante, Karl Berry { $as_echo "$as_me:${as_lineno-$LINENO}: checking for IceConnectionNumber in -lICE" >&5 $as_echo_n "checking for IceConnectionNumber in -lICE... " >&6; } if ${ac_cv_lib_ICE_IceConnectionNumber+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lICE $X_EXTRA_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char IceConnectionNumber (); int main () { return IceConnectionNumber (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_ICE_IceConnectionNumber=yes else ac_cv_lib_ICE_IceConnectionNumber=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5 $as_echo "$ac_cv_lib_ICE_IceConnectionNumber" >&6; } if test "x$ac_cv_lib_ICE_IceConnectionNumber" = xyes; then : X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE" fi LDFLAGS=$ac_save_LDFLAGS fi save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$X_CFLAGS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XOpenDisplay in -lX11" >&5 $as_echo_n "checking for XOpenDisplay in -lX11... " >&6; } if ${ac_cv_lib_X11_XOpenDisplay+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lX11 $X_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XOpenDisplay (); int main () { return XOpenDisplay (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_X11_XOpenDisplay=yes else ac_cv_lib_X11_XOpenDisplay=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_X11_XOpenDisplay" >&5 $as_echo "$ac_cv_lib_X11_XOpenDisplay" >&6; } if test "x$ac_cv_lib_X11_XOpenDisplay" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBX11 1 _ACEOF LIBS="-lX11 $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lICE" >&5 $as_echo_n "checking for main in -lICE... " >&6; } if ${ac_cv_lib_ICE_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lICE $X_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_ICE_main=yes else ac_cv_lib_ICE_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ICE_main" >&5 $as_echo "$ac_cv_lib_ICE_main" >&6; } if test "x$ac_cv_lib_ICE_main" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBICE 1 _ACEOF LIBS="-lICE $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lSM" >&5 $as_echo_n "checking for main in -lSM... " >&6; } if ${ac_cv_lib_SM_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lSM $X_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_SM_main=yes else ac_cv_lib_SM_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_SM_main" >&5 $as_echo "$ac_cv_lib_SM_main" >&6; } if test "x$ac_cv_lib_SM_main" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBSM 1 _ACEOF LIBS="-lSM $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lXext" >&5 $as_echo_n "checking for main in -lXext... " >&6; } if ${ac_cv_lib_Xext_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXext $X_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xext_main=yes else ac_cv_lib_Xext_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xext_main" >&5 $as_echo "$ac_cv_lib_Xext_main" >&6; } if test "x$ac_cv_lib_Xext_main" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBXEXT 1 _ACEOF LIBS="-lXext $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XtOpenDisplay in -lXt" >&5 $as_echo_n "checking for XtOpenDisplay in -lXt... " >&6; } if ${ac_cv_lib_Xt_XtOpenDisplay+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXt $X_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XtOpenDisplay (); int main () { return XtOpenDisplay (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xt_XtOpenDisplay=yes else ac_cv_lib_Xt_XtOpenDisplay=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xt_XtOpenDisplay" >&5 $as_echo "$ac_cv_lib_Xt_XtOpenDisplay" >&6; } if test "x$ac_cv_lib_Xt_XtOpenDisplay" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBXT 1 _ACEOF LIBS="-lXt $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lXmu" >&5 $as_echo_n "checking for main in -lXmu... " >&6; } if ${ac_cv_lib_Xmu_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXmu $X_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xmu_main=yes else ac_cv_lib_Xmu_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xmu_main" >&5 $as_echo "$ac_cv_lib_Xmu_main" >&6; } if test "x$ac_cv_lib_Xmu_main" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBXMU 1 _ACEOF LIBS="-lXmu $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lXpm" >&5 $as_echo_n "checking for main in -lXpm... " >&6; } if ${ac_cv_lib_Xpm_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXpm $X_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xpm_main=yes else ac_cv_lib_Xpm_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xpm_main" >&5 $as_echo "$ac_cv_lib_Xpm_main" >&6; } if test "x$ac_cv_lib_Xpm_main" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBXPM 1 _ACEOF LIBS="-lXpm $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XmCreateMainWindow in -lXm" >&5 $as_echo_n "checking for XmCreateMainWindow in -lXm... " >&6; } if ${ac_cv_lib_Xm_XmCreateMainWindow+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXm $X_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XmCreateMainWindow (); int main () { return XmCreateMainWindow (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xm_XmCreateMainWindow=yes else ac_cv_lib_Xm_XmCreateMainWindow=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xm_XmCreateMainWindow" >&5 $as_echo "$ac_cv_lib_Xm_XmCreateMainWindow" >&6; } if test "x$ac_cv_lib_Xm_XmCreateMainWindow" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBXM 1 _ACEOF LIBS="-lXm $LIBS" fi CPPFLAGS="$save_CPPFLAGS" case $ac_cv_lib_Xm_XmCreateMainWindow in no ) as_fn_error $? "You don't seem to have the Lesstif development environment installed." "$LINENO" 5 ;; * ) ;; esac for ac_header in Xm/Xm.h do : ac_fn_c_check_header_mongrel "$LINENO" "Xm/Xm.h" "ac_cv_header_Xm_Xm_h" "$ac_includes_default" if test "x$ac_cv_header_Xm_Xm_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_XM_XM_H 1 _ACEOF fi done case $ac_cv_header_Xm_Xm_h in no ) as_fn_error $? "You don't seem to have the Lesstif development environment installed." "$LINENO" 5 ;; * ) ;; esac ;; gtk ) # Check for pkg-config if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_PKG_CONFIG"; then ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 $as_echo "$ac_pt_PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then PKG_CONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKG_CONFIG=$ac_pt_PKG_CONFIG fi else PKG_CONFIG="$ac_cv_path_PKG_CONFIG" fi fi if test -n "$PKG_CONFIG"; then _pkg_min_version=0.9.0 { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 $as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } PKG_CONFIG="" fi fi if test -z "$PKG_CONFIG"; then as_fn_error $? "Cannot find pkg-config, make sure it is installed and in your PATH" "$LINENO" 5 fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTK" >&5 $as_echo_n "checking for GTK... " >&6; } if test -n "$GTK_CFLAGS"; then pkg_cv_GTK_CFLAGS="$GTK_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-2.0 >= 2.18.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "gtk+-2.0 >= 2.18.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GTK_CFLAGS=`$PKG_CONFIG --cflags "gtk+-2.0 >= 2.18.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$GTK_LIBS"; then pkg_cv_GTK_LIBS="$GTK_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-2.0 >= 2.18.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "gtk+-2.0 >= 2.18.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GTK_LIBS=`$PKG_CONFIG --libs "gtk+-2.0 >= 2.18.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then GTK_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gtk+-2.0 >= 2.18.0" 2>&1` else GTK_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gtk+-2.0 >= 2.18.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$GTK_PKG_ERRORS" >&5 as_fn_error $? "Cannot find gtk+ >= 2.18.0, install it and rerun ./configure Please review the following errors: $GTK_PKG_ERRORS" "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Cannot find gtk+ >= 2.18.0, install it and rerun ./configure Please review the following errors: $GTK_PKG_ERRORS" "$LINENO" 5 else GTK_CFLAGS=$pkg_cv_GTK_CFLAGS GTK_LIBS=$pkg_cv_GTK_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi GTK_VERSION=`$PKG_CONFIG gtk+-2.0 --modversion` GLIB_VERSION=`$PKG_CONFIG glib-2.0 --modversion` if test "x$enable_gl" = "xyes"; then # Check for GtkGLExt pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTKGLEXT" >&5 $as_echo_n "checking for GTKGLEXT... " >&6; } if test -n "$GTKGLEXT_CFLAGS"; then pkg_cv_GTKGLEXT_CFLAGS="$GTKGLEXT_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtkglext-1.0 >= 1.0.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "gtkglext-1.0 >= 1.0.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GTKGLEXT_CFLAGS=`$PKG_CONFIG --cflags "gtkglext-1.0 >= 1.0.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$GTKGLEXT_LIBS"; then pkg_cv_GTKGLEXT_LIBS="$GTKGLEXT_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtkglext-1.0 >= 1.0.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "gtkglext-1.0 >= 1.0.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GTKGLEXT_LIBS=`$PKG_CONFIG --libs "gtkglext-1.0 >= 1.0.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then GTKGLEXT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gtkglext-1.0 >= 1.0.0" 2>&1` else GTKGLEXT_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gtkglext-1.0 >= 1.0.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$GTKGLEXT_PKG_ERRORS" >&5 as_fn_error $? " *** Required version of gtkglext is not installed - please install first *** Please review the following errors: $GTKGLEXT_PKG_ERRORS" "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? " *** Required version of gtkglext is not installed - please install first *** Please review the following errors: $GTKGLEXT_PKG_ERRORS" "$LINENO" 5 else GTKGLEXT_CFLAGS=$pkg_cv_GTKGLEXT_CFLAGS GTKGLEXT_LIBS=$pkg_cv_GTKGLEXT_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi GTKGLEXT_VER=`$PKG_CONFIG gtkglext-1.0 --modversion` fi ;; png) need_gdlib=yes { $as_echo "$as_me:${as_lineno-$LINENO}: checking if GIF output from the png HID is desired" >&5 $as_echo_n "checking if GIF output from the png HID is desired... " >&6; } # Check whether --enable-gif was given. if test "${enable_gif+set}" = set; then : enableval=$enable_gif; if test "X$enable_gif" != "Xno" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } with_gif=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } with_gif=yes fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if JPEG output from the png HID is desired" >&5 $as_echo_n "checking if JPEG output from the png HID is desired... " >&6; } # Check whether --enable-jpeg was given. if test "${enable_jpeg+set}" = set; then : enableval=$enable_jpeg; if test "X$enable_jpeg" != "Xno" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } with_jpeg=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } with_jpeg=yes fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if PNG output from the png HID is desired" >&5 $as_echo_n "checking if PNG output from the png HID is desired... " >&6; } # Check whether --enable-png was given. if test "${enable_png+set}" = set; then : enableval=$enable_png; if test "X$enable_png" != "Xno" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } with_png=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } with_png=yes fi ;; gcode|nelma) need_gdlib=yes with_png=yes ;; esac done if test "$need_gdlib" = "yes"; then # Search for glib pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GDLIB" >&5 $as_echo_n "checking for GDLIB... " >&6; } if test -n "$GDLIB_CFLAGS"; then pkg_cv_GDLIB_CFLAGS="$GDLIB_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gdlib\""; } >&5 ($PKG_CONFIG --exists --print-errors "gdlib") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GDLIB_CFLAGS=`$PKG_CONFIG --cflags "gdlib" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$GDLIB_LIBS"; then pkg_cv_GDLIB_LIBS="$GDLIB_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gdlib\""; } >&5 ($PKG_CONFIG --exists --print-errors "gdlib") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GDLIB_LIBS=`$PKG_CONFIG --libs "gdlib" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then GDLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gdlib" 2>&1` else GDLIB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gdlib" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$GDLIB_PKG_ERRORS" >&5 found_gdlib=no elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } found_gdlib=no else GDLIB_CFLAGS=$pkg_cv_GDLIB_CFLAGS GDLIB_LIBS=$pkg_cv_GDLIB_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } found_gdlib=yes fi if test "X$found_gdlib" = "Xno"; then # older installs came with gdlib-config and not the .pc file # to work with pkg-config # Extract the first word of "gdlib-config", so it can be a program name with args. set dummy gdlib-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_GDLIB_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $GDLIB_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_GDLIB_CONFIG="$GDLIB_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_GDLIB_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_GDLIB_CONFIG" && ac_cv_path_GDLIB_CONFIG="notfound" ;; esac fi GDLIB_CONFIG=$ac_cv_path_GDLIB_CONFIG if test -n "$GDLIB_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GDLIB_CONFIG" >&5 $as_echo "$GDLIB_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$GDLIB_CONFIG" = "notfound" ; then as_fn_error $? "cannot find gdlib-config. gdlib is required for gcode, nelma, png HIDs You may want to review the following errors from $PKG_CONFIG: $GDLIB_PKG_ERRORS" "$LINENO" 5 else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gdlib cflags" >&5 $as_echo_n "checking for gdlib cflags... " >&6; } GDLIB_CFLAGS=`${GDLIB_CONFIG} --cflags` { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GDLIB_CFLAGS" >&5 $as_echo "$GDLIB_CFLAGS" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gdlib libraries" >&5 $as_echo_n "checking for gdlib libraries... " >&6; } GDLIB_LIBS=`${GDLIB_CONFIG} --libs` { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GDLIB_LIBS" >&5 $as_echo "$GDLIB_LIBS" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gdlib ldflags" >&5 $as_echo_n "checking for gdlib ldflags... " >&6; } GDLIB_LDFLAGS=`${GDLIB_CONFIG} --ldflags` { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GDLIB_LDFLAGS" >&5 $as_echo "$GDLIB_LDFLAGS" >&6; } fi fi save_LIBS="$LIBS" LIBS="$LIBS $GDLIB_LDFLAGS $GDLIB_LIBS" # some older installs, Ubuntu Precise for example, leave off the "-lgd" part. # try to see if it needs to be added. However this is currently broken # under cygwin cross building for mingw because of interactions with # __imp__ prefix added in the libgd.a static library. Look at the declspec # stuff in the mingw gd.h file. if test "x$WIN32" = "xno" ; then before_LIBS="$LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gdImageCreate" >&5 $as_echo_n "checking for library containing gdImageCreate... " >&6; } if ${ac_cv_search_gdImageCreate+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gdImageCreate (); int main () { return gdImageCreate (); ; return 0; } _ACEOF for ac_lib in '' gd; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_gdImageCreate=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_gdImageCreate+:} false; then : break fi done if ${ac_cv_search_gdImageCreate+:} false; then : else ac_cv_search_gdImageCreate=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_gdImageCreate" >&5 $as_echo "$ac_cv_search_gdImageCreate" >&6; } ac_res=$ac_cv_search_gdImageCreate if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" else as_fn_error $? "Unable to figure out how to link gd applications. It is likely that your system has a broken gdlib-config or gdlib.pc file used by pkg-config. " "$LINENO" 5 fi if test "$LIBS" != "${before_LIBS}" ; then GDLIB_LIBS="${GDLIB_LIBS} -lgd" fi fi if test "X$with_gif" = "Xyes" ; then for ac_func in gdImageGif do : ac_fn_c_check_func "$LINENO" "gdImageGif" "ac_cv_func_gdImageGif" if test "x$ac_cv_func_gdImageGif" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GDIMAGEGIF 1 _ACEOF fi done if test "$ac_cv_func_gdImageGif" != "yes"; then as_fn_error $? "Your gd installation does not appear to include gif support. You may need to update your installation of gd or disable gif export with --disable-gif" "$LINENO" 5 fi fi if test "X$with_jpeg" = "Xyes" ; then for ac_func in gdImageJpeg do : ac_fn_c_check_func "$LINENO" "gdImageJpeg" "ac_cv_func_gdImageJpeg" if test "x$ac_cv_func_gdImageJpeg" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GDIMAGEJPEG 1 _ACEOF fi done if test "$ac_cv_func_gdImageJpeg" != "yes"; then as_fn_error $? "Your gd installation does not appear to include JPEG support. You may need to update your installation of gd or disable JPEG export with --disable-jpeg" "$LINENO" 5 fi fi if test "X$with_png" = "Xyes" ; then for ac_func in gdImagePng do : ac_fn_c_check_func "$LINENO" "gdImagePng" "ac_cv_func_gdImagePng" if test "x$ac_cv_func_gdImagePng" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GDIMAGEPNG 1 _ACEOF fi done if test "$ac_cv_func_gdImagePng" != "yes"; then as_fn_error $? "Your gd installation does not appear to include PNG support. You may need to update your installation of gd or disable PNG export with --disable-png" "$LINENO" 5 fi fi LIBS="$save_LIBS" fi if test x$with_png = xyes; then PNG_TRUE= PNG_FALSE='#' else PNG_TRUE='#' PNG_FALSE= fi if test x$with_gif = xyes; then GIF_TRUE= GIF_FALSE='#' else GIF_TRUE='#' GIF_FALSE= fi # ------------- check if png previews should be built for pcblib-newlib { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the m4lib to newlib export should create png previews" >&5 $as_echo_n "checking if the m4lib to newlib export should create png previews... " >&6; } # Check whether --enable-m4lib-png was given. if test "${enable_m4lib_png+set}" = set; then : enableval=$enable_m4lib_png; else enable_m4lib_png=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_m4lib_png" >&5 $as_echo "$enable_m4lib_png" >&6; } if test x$enable_m4lib_png = xyes; then PNG_PREVIEW_TRUE= PNG_PREVIEW_FALSE='#' else PNG_PREVIEW_TRUE='#' PNG_PREVIEW_FALSE= fi # Run away.... more ugly stuff here. By default we don't actually build # pcblib-newlib from pcblib unless we are building from cvs or git sources. # The reason is it takes a while and requires the png HID. The problem is, # what if someone wants to use --enable-m4lib-png but the tarball was built # without the previews. Or, what if someone does not want the PNG previews # but the person building the tarball included them. Ugh! So what the following # code attempts to do is detect that mismatch situation. Note that we only # want to kick this code in when *not* building from git or cvs sources. build_pcblib_newlib=no if test "$pcb_sources" = "tarball" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking If pcblib-newlib was built with png previews" >&5 $as_echo_n "checking If pcblib-newlib was built with png previews... " >&6; } stamp=$srcdir/lib/pcblib-newlib.stamp if test ! -f ${stamp} ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: unknown, missing ${stamp}" >&5 $as_echo "unknown, missing ${stamp}" >&6; } build_pcblib_newlib=yes else if test "`cat ${stamp}`" = "png-preview=yes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # lib exists and built with preview. # if we don't want the preview, than rebuild if test x$enable_m4lib_png != xyes ; then build_pcblib_newlib=yes fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } # lib exists and built without preview. # if we want the preview, than rebuild if test x$enable_m4lib_png = xyes ; then build_pcblib_newlib=yes fi fi fi else build_pcblib_newlib=yes fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking If pcblib-newlib needs to be rebuilt" >&5 $as_echo_n "checking If pcblib-newlib needs to be rebuilt... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $build_pcblib_newlib" >&5 $as_echo "$build_pcblib_newlib" >&6; } if test x$build_pcblib_newlib = xyes; then BUILD_PCBLIB_NEWLIB_TRUE= BUILD_PCBLIB_NEWLIB_FALSE='#' else BUILD_PCBLIB_NEWLIB_TRUE='#' BUILD_PCBLIB_NEWLIB_FALSE= fi if test "X$cross_compiling" = "Xyes" ; then # we are cross compiling so we will need a build host binary for pcb # Extract the first word of "pcb", so it can be a program name with args. set dummy pcb; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PCB+:} false; then : $as_echo_n "(cached) " >&6 else case $PCB in [\\/]* | ?:[\\/]*) ac_cv_path_PCB="$PCB" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PCB="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PCB" && ac_cv_path_PCB="notfound" ;; esac fi PCB=$ac_cv_path_PCB if test -n "$PCB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PCB" >&5 $as_echo "$PCB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else PCB="\${top_builddir}/src/pcb" fi # now make see how essential it was that we have a pcb executable for the build # host if test "X$pcb_git_version" = "Xyes" ; then if test "X$docs_yesno" = "Xyes" -o "X$enable_m4lib_png" = "Xyes" ; then if test "$PCB" = "notfound" ; then as_fn_error $? "You have selected a build with m4lib png previews enabled and/or with building the documentation enabled but you also appear to be cross-compiling. For this to work, you must have a pcb installed that can run on this machine (the build machine) because it is needed for generating library footprint png previews as well as some of the figures in the documentation. If you wish to skip building the documentation and the footprint previews then add --disable-doc --disable-m4lib-png This will allow your cross build to work." "$LINENO" 5 fi fi fi # ------------- Xrender ------------------- have_xrender=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XRenderQueryExtension in -lXrender" >&5 $as_echo_n "checking for XRenderQueryExtension in -lXrender... " >&6; } if ${ac_cv_lib_Xrender_XRenderQueryExtension+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXrender $X_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XRenderQueryExtension (); int main () { return XRenderQueryExtension (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xrender_XRenderQueryExtension=yes else ac_cv_lib_Xrender_XRenderQueryExtension=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xrender_XRenderQueryExtension" >&5 $as_echo "$ac_cv_lib_Xrender_XRenderQueryExtension" >&6; } if test "x$ac_cv_lib_Xrender_XRenderQueryExtension" = xyes; then : have_xrender=yes else have_xrender=no fi # Check whether --enable-xrender was given. if test "${enable_xrender+set}" = set; then : enableval=$enable_xrender; fi case "$have_xrender:$enable_xrender" in no:* ) ;; *:no ) ;; * ) X_LIBS="-lXrender $X_LIBS" $as_echo "#define HAVE_XRENDER 1" >>confdefs.h ;; esac # ------------- Xinerama ------------------- have_xinerama=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XineramaQueryExtension in -lXinerama" >&5 $as_echo_n "checking for XineramaQueryExtension in -lXinerama... " >&6; } if ${ac_cv_lib_Xinerama_XineramaQueryExtension+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lXinerama $X_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XineramaQueryExtension (); int main () { return XineramaQueryExtension (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Xinerama_XineramaQueryExtension=yes else ac_cv_lib_Xinerama_XineramaQueryExtension=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xinerama_XineramaQueryExtension" >&5 $as_echo "$ac_cv_lib_Xinerama_XineramaQueryExtension" >&6; } if test "x$ac_cv_lib_Xinerama_XineramaQueryExtension" = xyes; then : have_xinerama=yes else have_xinerama=no fi # Check whether --enable-xinerama was given. if test "${enable_xinerama+set}" = set; then : enableval=$enable_xinerama; fi case "$have_xinerama:$enable_xinerama" in no:* ) ;; *:no ) ;; * ) X_LIBS="-lXinerama $X_LIBS" $as_echo "#define HAVE_XINERAMA 1" >>confdefs.h ;; esac # ------------- dmalloc ------------------- with_dmalloc=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking if dmalloc debugging should be enabled" >&5 $as_echo_n "checking if dmalloc debugging should be enabled... " >&6; } # Check whether --enable-dmalloc was given. if test "${enable_dmalloc+set}" = set; then : enableval=$enable_dmalloc; if test "X$enable_dmalloc" != "Xno" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ac_fn_c_check_header_mongrel "$LINENO" "dmalloc.h" "ac_cv_header_dmalloc_h" "$ac_includes_default" if test "x$ac_cv_header_dmalloc_h" = xyes; then : else as_fn_error $? "You have requested dmalloc debugging but dmalloc.h could not be found" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -ldmalloc" >&5 $as_echo_n "checking for main in -ldmalloc... " >&6; } if ${ac_cv_lib_dmalloc_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldmalloc $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dmalloc_main=yes else ac_cv_lib_dmalloc_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dmalloc_main" >&5 $as_echo "$ac_cv_lib_dmalloc_main" >&6; } if test "x$ac_cv_lib_dmalloc_main" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBDMALLOC 1 _ACEOF LIBS="-ldmalloc $LIBS" else as_fn_error $? "You have requested dmalloc debugging but -ldmalloc could not be found" "$LINENO" 5 fi DMALLOC_LIBS="-ldmalloc" with_dmalloc=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } DMALLOC_LIBS="" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } DMALLOC_LIBS="" fi # ------------- ElectricFence ------------------- with_efence=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ElectricFence debugging should be enabled" >&5 $as_echo_n "checking if ElectricFence debugging should be enabled... " >&6; } # Check whether --enable-efence was given. if test "${enable_efence+set}" = set; then : enableval=$enable_efence; if test "X$enable_efence" != "Xno" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lefence" >&5 $as_echo_n "checking for main in -lefence... " >&6; } if ${ac_cv_lib_efence_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lefence $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_efence_main=yes else ac_cv_lib_efence_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_efence_main" >&5 $as_echo "$ac_cv_lib_efence_main" >&6; } if test "x$ac_cv_lib_efence_main" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBEFENCE 1 _ACEOF LIBS="-lefence $LIBS" else as_fn_error $? "You have requested ElectricFence debugging but -lefence could not be found" "$LINENO" 5 fi with_efence=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # ------------- Enable Debug code ------------------- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for whether to enable debugging code" >&5 $as_echo_n "checking for whether to enable debugging code... " >&6; } # Check whether --enable-debug was given. if test "${enable_debug+set}" = set; then : enableval=$enable_debug; else enable_debug=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_debug" >&5 $as_echo "$enable_debug" >&6; } if test x$enable_debug = xyes; then DEBUG_BUILD_TRUE= DEBUG_BUILD_FALSE='#' else DEBUG_BUILD_TRUE='#' DEBUG_BUILD_FALSE= fi # ------------- mkdir required for win32 compatibility ------------ # WIN32 mkdir takes only one argument, POSIX takes two. # #include "misc.h" where mkdir is required. # =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_func_mkdir.html # =========================================================================== # # SYNOPSIS # # AX_FUNC_MKDIR # # DESCRIPTION # # Check whether mkdir() is mkdir or _mkdir, and whether it takes one or # two arguments. # # This macro can define HAVE_MKDIR, HAVE__MKDIR, and MKDIR_TAKES_ONE_ARG, # which are expected to be used as follows: # # #if HAVE_MKDIR # # if MKDIR_TAKES_ONE_ARG # /* MinGW32 */ # # define mkdir(a, b) mkdir(a) # # endif # #else # # if HAVE__MKDIR # /* plain Windows 32 */ # # define mkdir(a, b) _mkdir(a) # # else # # error "Don't know how to create a directory on this system." # # endif # #endif # # LICENSE # # Copyright (c) 2008 Alexandre Duret-Lutz # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 2 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 4 # This is what autoupdate's m4 run will expand. It fires # the warning (with _au_warn_XXX), outputs it into the # updated configure.ac (with AC_DIAGNOSE), and then outputs # the replacement expansion. # This is an auxiliary macro that is also run when # autoupdate runs m4. It simply calls m4_warning, but # we need a wrapper so that each warning is emitted only # once. We break the quoting in m4_warning's argument in # order to expand this macro's arguments, not AU_DEFUN's. # Finally, this is the expansion that is picked up by # autoconf. It tells the user to run autoupdate, and # then outputs the replacement expansion. We do not care # about autoupdate's warning because that contains # information on what to do *after* running autoupdate. for ac_func in mkdir _mkdir do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mkdir takes one argument" >&5 $as_echo_n "checking whether mkdir takes one argument... " >&6; } if ${ac_cv_mkdir_takes_one_arg+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #if HAVE_UNISTD_H # include #endif int main () { mkdir ("."); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_mkdir_takes_one_arg=yes else ac_cv_mkdir_takes_one_arg=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_mkdir_takes_one_arg" >&5 $as_echo "$ac_cv_mkdir_takes_one_arg" >&6; } if test x"$ac_cv_mkdir_takes_one_arg" = xyes; then $as_echo "#define MKDIR_TAKES_ONE_ARG 1" >>confdefs.h fi # ------------- Type used for "Coord" type ------------------- for ac_header in stdint.h do : ac_fn_c_check_header_mongrel "$LINENO" "stdint.h" "ac_cv_header_stdint_h" "$ac_includes_default" if test "x$ac_cv_header_stdint_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STDINT_H 1 _ACEOF fi done # Check whether --enable-coord64 was given. if test "${enable_coord64+set}" = set; then : enableval=$enable_coord64; else enable_coord64=no fi # Check whether --enable-coord32 was given. if test "${enable_coord32+set}" = set; then : enableval=$enable_coord32; else enable_coord32=no fi COORDTYPE="long" echo "$enable_coord32:$enable_coord64:$ac_cv_header_stdint_h" case "$enable_coord32:$enable_coord64:$ac_cv_header_stdint_h" in yes:no:yes ) COORD_TYPE="int32_t" COORD_MAX="INT32_MAX" ;; no:yes:yes ) COORD_TYPE="int64_t" COORD_MAX="INT64_MAX" ;; yes:no:no ) COORD_TYPE="int" COORD_MAX="INT_MAX" ;; no:yes:no ) COORD_TYPE="long long" COORD_MAX="LLONG_MAX" ;; yes:yes:* ) as_fn_error $? "\"*** cannot require both 32 and 64 bit coordinates\"" "$LINENO" 5 ;; *:*:* ) COORD_TYPE="long" COORD_MAX="LONG_MAX" ;; esac cat >>confdefs.h <<_ACEOF #define COORD_TYPE $COORD_TYPE _ACEOF cat >>confdefs.h <<_ACEOF #define COORD_MAX $COORD_MAX _ACEOF # ------------- Complete set of CPPFLAGS and LIBS ------------------- CPPFLAGS="$CPPFLAGS $X_CFLAGS $DBUS_CFLAGS $GDLIB_CFLAGS $GLIB_CFLAGS $GTK_CFLAGS $GD_CFLAGS $CAIRO_CFLAGS $GTKGLEXT_CFLAGS $GLU_CFLAGS $GL_CFLAGS" LIBS="$LIBS $XM_LIBS $DBUS_LIBS $X_LIBS $GDLIB_LDFLAGS $GDLIB_LIBS $GLIB_LIBS $GTK_LIBS $DMALLOC_LIBS $GD_LIBS $INTLLIBS $CAIRO_LIBS $GTKGLEXT_LIBS $GLU_LIBS $GL_LIBS" # if we have gcc then add -Wall if test "x$GCC" = "xyes"; then # see about adding some extra checks if the compiler takes them for flag in -Wall ; do case " ${CFLAGS} " in *\ ${flag}\ *) # flag is already present ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the compiler accepts ${flag}" >&5 $as_echo_n "checking if the compiler accepts ${flag}... " >&6; } ac_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS ${flag}" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$ac_save_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ;; esac done fi CXXFLAGS="$CFLAGS" # Now add C-specific flags if test "x$GCC" = "xyes"; then # see about adding some extra checks if the compiler takes them for flag in -Wdeclaration-after-statement ; do case " ${CFLAGS} " in *\ ${flag}\ *) # flag is already present ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the compiler accepts ${flag}" >&5 $as_echo_n "checking if the compiler accepts ${flag}... " >&6; } ac_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS ${flag}" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$ac_save_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ;; esac done fi # See if we are building gcc with C++. # Check whether --enable-build-with-cxx was given. if test "${enable_build_with_cxx+set}" = set; then : enableval=$enable_build_with_cxx; ENABLE_BUILD_WITH_CXX=$enableval else ENABLE_BUILD_WITH_CXX=no fi case "$ENABLE_BUILD_WITH_CXX" in yes) CC_OR_CXX="$CXX" ;; no) CC_OR_CXX="$CC" ;; esac # font filename FONTFILENAME=${FONTFILENAME:-"default_font"} cat >>confdefs.h <<_ACEOF #define FONTFILENAME "$FONTFILENAME" _ACEOF # standard autoconf variables CPPFLAGS="$CPPFLAGS -DPREFIXDIR=\\\"\${prefix}\\\"" CPPFLAGS="$CPPFLAGS -DBINDIR=\\\"\${bindir}\\\"" CPPFLAGS="$CPPFLAGS -DHOST=\\\"\${host}\\\"" # directory for old-style library and for fonts PCBLIBDIR=${datadir}/pcb #AC_DEFINE_UNQUOTED(PCBLIBDIR,"$PCBLIBDIR",[Library directory]) CPPFLAGS="$CPPFLAGS -DPCBLIBDIR=\\\"$PCBLIBDIR\\\"" # name for old-style library LIBRARYFILENAME=pcblib cat >>confdefs.h <<_ACEOF #define LIBRARYFILENAME "$LIBRARYFILENAME" _ACEOF # directory for new library PCBTREEDIR=${datadir}/pcb/newlib PCBTREEPATH=${PCBTREEDIR}:${PCBLIBDIR}/pcblib-newlib PCBTREEDIR=${PCBTREEDIR:-"$PCBTREEDIR"} #AC_DEFINE_UNQUOTED(PCBTREEDIR,"$PCBLIB",[top directory for new style pcb library]) CPPFLAGS="$CPPFLAGS -DPCBTREEDIR=\\\"$PCBTREEDIR\\\"" CPPFLAGS="$CPPFLAGS -DPCBTREEPATH=\\\"$PCBTREEPATH\\\"" # Figure out relative paths { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the bindir to pcblibdir relative path" >&5 $as_echo_n "checking for the bindir to pcblibdir relative path... " >&6; } for _lcl_i in bindir:PCBLIBDIR:bindir_to_pcblibdir; do _lcl_from=\$`echo "$_lcl_i" | sed 's,:.*$,,'` _lcl_to=\$`echo "$_lcl_i" | sed 's,^[^:]*:,,' | sed 's,:[^:]*$,,'` _lcl_result_var=`echo "$_lcl_i" | sed 's,^.*:,,'` _lcl_receval="$_lcl_from" _lcl_from=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" _lcl_receval_old='' while test "$_lcl_receval_old" != "$_lcl_receval"; do _lcl_receval_old="$_lcl_receval" eval _lcl_receval="\"$_lcl_receval\"" done echo "$_lcl_receval")` _lcl_receval="$_lcl_to" _lcl_to=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" _lcl_receval_old='' while test "$_lcl_receval_old" != "$_lcl_receval"; do _lcl_receval_old="$_lcl_receval" eval _lcl_receval="\"$_lcl_receval\"" done echo "$_lcl_receval")` _lcl_notation="$_lcl_from$_lcl_to" case ":$_lcl_from:" in # change empty paths to '.' ::) _lcl_from='.' ;; # strip trailing slashes :*[\\/]:) _lcl_from=`echo "$_lcl_from" | sed 's,[\\/]*$,,'` ;; :*:) ;; esac # squeze repeated slashes case '/' in # if the path contains any backslashes, turn slashes into backslashes *\\*) _lcl_from=`echo "$_lcl_from" | sed 's,\(.\)[\\/][\\/]*,\1\\\\\\\\,g'` ;; # if the path contains slashes, also turn backslashes into slashes *) _lcl_from=`echo "$_lcl_from" | sed 's,\(.\)[\\/][\\/]*,\1/,g'` ;; esac case ":$_lcl_to:" in # change empty paths to '.' ::) _lcl_to='.' ;; # strip trailing slashes :*[\\/]:) _lcl_to=`echo "$_lcl_to" | sed 's,[\\/]*$,,'` ;; :*:) ;; esac # squeze repeated slashes case '/' in # if the path contains any backslashes, turn slashes into backslashes *\\*) _lcl_to=`echo "$_lcl_to" | sed 's,\(.\)[\\/][\\/]*,\1\\\\\\\\,g'` ;; # if the path contains slashes, also turn backslashes into slashes *) _lcl_to=`echo "$_lcl_to" | sed 's,\(.\)[\\/][\\/]*,\1/,g'` ;; esac _lcl_common_prefix='' _lcl_second_prefix_match='' while test "$_lcl_second_prefix_match" != 0; do _lcl_first_prefix=`expr "x$_lcl_from" : "x\($_lcl_common_prefix/*[^/]*\)"` _lcl_second_prefix_match=`expr "x$_lcl_to" : "x$_lcl_first_prefix"` if test "$_lcl_second_prefix_match" != 0; then if test "$_lcl_first_prefix" != "$_lcl_common_prefix"; then _lcl_common_prefix="$_lcl_first_prefix" else _lcl_second_prefix_match=0 fi fi done _lcl_first_suffix=`expr "x$_lcl_from" : "x$_lcl_common_prefix/*\(.*\)"` _lcl_first_rel='' _lcl_tmp='xxx' while test "$_lcl_tmp" != ''; do _lcl_tmp=`expr "x$_lcl_first_suffix" : "x[^/]*/*\(.*\)"` if test "$_lcl_first_suffix" != ''; then _lcl_first_suffix="$_lcl_tmp" _lcl_first_rel="../$_lcl_first_rel" fi done _lcl_second_suffix=`expr "x$_lcl_to" : "x$_lcl_common_prefix/*\(.*\)"` _lcl_result_tmp="$_lcl_first_rel$_lcl_second_suffix" case ":$_lcl_result_tmp:" in # change empty paths to '.' ::) _lcl_result_tmp='.' ;; # strip trailing slashes :*[\\/]:) _lcl_result_tmp=`echo "$_lcl_result_tmp" | sed 's,[\\/]*$,,'` ;; :*:) ;; esac # squeze repeated slashes case "$_lcl_notation" in # if the path contains any backslashes, turn slashes into backslashes *\\*) _lcl_result_tmp=`echo "$_lcl_result_tmp" | sed 's,\(.\)[\\/][\\/]*,\1\\\\\\\\,g'` ;; # if the path contains slashes, also turn backslashes into slashes *) _lcl_result_tmp=`echo "$_lcl_result_tmp" | sed 's,\(.\)[\\/][\\/]*,\1/,g'` ;; esac eval $_lcl_result_var='$_lcl_result_tmp' done case ":$bindir_to_pcblibdir:" in # change empty paths to '.' ::) bindir_to_pcblibdir='.' ;; # strip trailing slashes :*[\\/]:) bindir_to_pcblibdir=`echo "$bindir_to_pcblibdir" | sed 's,[\\/]*$,,'` ;; :*:) ;; esac # squeze repeated slashes case $PCB_DIR_SEPARATOR_S in # if the path contains any backslashes, turn slashes into backslashes *\\*) bindir_to_pcblibdir=`echo "$bindir_to_pcblibdir" | sed 's,\(.\)[\\/][\\/]*,\1\\\\\\\\,g'` ;; # if the path contains slashes, also turn backslashes into slashes *) bindir_to_pcblibdir=`echo "$bindir_to_pcblibdir" | sed 's,\(.\)[\\/][\\/]*,\1/,g'` ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $bindir_to_pcblibdir" >&5 $as_echo "$bindir_to_pcblibdir" >&6; } cat >>confdefs.h <<_ACEOF #define BINDIR_TO_PCBLIBDIR "$bindir_to_pcblibdir" _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the bindir to pcbtreedir relative path" >&5 $as_echo_n "checking for the bindir to pcbtreedir relative path... " >&6; } for _lcl_i in bindir:PCBTREEDIR:bindir_to_pcbtreedir; do _lcl_from=\$`echo "$_lcl_i" | sed 's,:.*$,,'` _lcl_to=\$`echo "$_lcl_i" | sed 's,^[^:]*:,,' | sed 's,:[^:]*$,,'` _lcl_result_var=`echo "$_lcl_i" | sed 's,^.*:,,'` _lcl_receval="$_lcl_from" _lcl_from=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" _lcl_receval_old='' while test "$_lcl_receval_old" != "$_lcl_receval"; do _lcl_receval_old="$_lcl_receval" eval _lcl_receval="\"$_lcl_receval\"" done echo "$_lcl_receval")` _lcl_receval="$_lcl_to" _lcl_to=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" _lcl_receval_old='' while test "$_lcl_receval_old" != "$_lcl_receval"; do _lcl_receval_old="$_lcl_receval" eval _lcl_receval="\"$_lcl_receval\"" done echo "$_lcl_receval")` _lcl_notation="$_lcl_from$_lcl_to" case ":$_lcl_from:" in # change empty paths to '.' ::) _lcl_from='.' ;; # strip trailing slashes :*[\\/]:) _lcl_from=`echo "$_lcl_from" | sed 's,[\\/]*$,,'` ;; :*:) ;; esac # squeze repeated slashes case '/' in # if the path contains any backslashes, turn slashes into backslashes *\\*) _lcl_from=`echo "$_lcl_from" | sed 's,\(.\)[\\/][\\/]*,\1\\\\\\\\,g'` ;; # if the path contains slashes, also turn backslashes into slashes *) _lcl_from=`echo "$_lcl_from" | sed 's,\(.\)[\\/][\\/]*,\1/,g'` ;; esac case ":$_lcl_to:" in # change empty paths to '.' ::) _lcl_to='.' ;; # strip trailing slashes :*[\\/]:) _lcl_to=`echo "$_lcl_to" | sed 's,[\\/]*$,,'` ;; :*:) ;; esac # squeze repeated slashes case '/' in # if the path contains any backslashes, turn slashes into backslashes *\\*) _lcl_to=`echo "$_lcl_to" | sed 's,\(.\)[\\/][\\/]*,\1\\\\\\\\,g'` ;; # if the path contains slashes, also turn backslashes into slashes *) _lcl_to=`echo "$_lcl_to" | sed 's,\(.\)[\\/][\\/]*,\1/,g'` ;; esac _lcl_common_prefix='' _lcl_second_prefix_match='' while test "$_lcl_second_prefix_match" != 0; do _lcl_first_prefix=`expr "x$_lcl_from" : "x\($_lcl_common_prefix/*[^/]*\)"` _lcl_second_prefix_match=`expr "x$_lcl_to" : "x$_lcl_first_prefix"` if test "$_lcl_second_prefix_match" != 0; then if test "$_lcl_first_prefix" != "$_lcl_common_prefix"; then _lcl_common_prefix="$_lcl_first_prefix" else _lcl_second_prefix_match=0 fi fi done _lcl_first_suffix=`expr "x$_lcl_from" : "x$_lcl_common_prefix/*\(.*\)"` _lcl_first_rel='' _lcl_tmp='xxx' while test "$_lcl_tmp" != ''; do _lcl_tmp=`expr "x$_lcl_first_suffix" : "x[^/]*/*\(.*\)"` if test "$_lcl_first_suffix" != ''; then _lcl_first_suffix="$_lcl_tmp" _lcl_first_rel="../$_lcl_first_rel" fi done _lcl_second_suffix=`expr "x$_lcl_to" : "x$_lcl_common_prefix/*\(.*\)"` _lcl_result_tmp="$_lcl_first_rel$_lcl_second_suffix" case ":$_lcl_result_tmp:" in # change empty paths to '.' ::) _lcl_result_tmp='.' ;; # strip trailing slashes :*[\\/]:) _lcl_result_tmp=`echo "$_lcl_result_tmp" | sed 's,[\\/]*$,,'` ;; :*:) ;; esac # squeze repeated slashes case "$_lcl_notation" in # if the path contains any backslashes, turn slashes into backslashes *\\*) _lcl_result_tmp=`echo "$_lcl_result_tmp" | sed 's,\(.\)[\\/][\\/]*,\1\\\\\\\\,g'` ;; # if the path contains slashes, also turn backslashes into slashes *) _lcl_result_tmp=`echo "$_lcl_result_tmp" | sed 's,\(.\)[\\/][\\/]*,\1/,g'` ;; esac eval $_lcl_result_var='$_lcl_result_tmp' done case ":$bindir_to_pcbtreedir:" in # change empty paths to '.' ::) bindir_to_pcbtreedir='.' ;; # strip trailing slashes :*[\\/]:) bindir_to_pcbtreedir=`echo "$bindir_to_pcbtreedir" | sed 's,[\\/]*$,,'` ;; :*:) ;; esac # squeze repeated slashes case $PCB_DIR_SEPARATOR_S in # if the path contains any backslashes, turn slashes into backslashes *\\*) bindir_to_pcbtreedir=`echo "$bindir_to_pcbtreedir" | sed 's,\(.\)[\\/][\\/]*,\1\\\\\\\\,g'` ;; # if the path contains slashes, also turn backslashes into slashes *) bindir_to_pcbtreedir=`echo "$bindir_to_pcbtreedir" | sed 's,\(.\)[\\/][\\/]*,\1/,g'` ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $bindir_to_pcbtreedir" >&5 $as_echo "$bindir_to_pcbtreedir" >&6; } cat >>confdefs.h <<_ACEOF #define BINDIR_TO_PCBTREEDIR "$bindir_to_pcbtreedir" _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the bindir to exec_prefix relative path" >&5 $as_echo_n "checking for the bindir to exec_prefix relative path... " >&6; } for _lcl_i in bindir:exec_prefix:bindir_to_execprefix; do _lcl_from=\$`echo "$_lcl_i" | sed 's,:.*$,,'` _lcl_to=\$`echo "$_lcl_i" | sed 's,^[^:]*:,,' | sed 's,:[^:]*$,,'` _lcl_result_var=`echo "$_lcl_i" | sed 's,^.*:,,'` _lcl_receval="$_lcl_from" _lcl_from=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" _lcl_receval_old='' while test "$_lcl_receval_old" != "$_lcl_receval"; do _lcl_receval_old="$_lcl_receval" eval _lcl_receval="\"$_lcl_receval\"" done echo "$_lcl_receval")` _lcl_receval="$_lcl_to" _lcl_to=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" _lcl_receval_old='' while test "$_lcl_receval_old" != "$_lcl_receval"; do _lcl_receval_old="$_lcl_receval" eval _lcl_receval="\"$_lcl_receval\"" done echo "$_lcl_receval")` _lcl_notation="$_lcl_from$_lcl_to" case ":$_lcl_from:" in # change empty paths to '.' ::) _lcl_from='.' ;; # strip trailing slashes :*[\\/]:) _lcl_from=`echo "$_lcl_from" | sed 's,[\\/]*$,,'` ;; :*:) ;; esac # squeze repeated slashes case '/' in # if the path contains any backslashes, turn slashes into backslashes *\\*) _lcl_from=`echo "$_lcl_from" | sed 's,\(.\)[\\/][\\/]*,\1\\\\\\\\,g'` ;; # if the path contains slashes, also turn backslashes into slashes *) _lcl_from=`echo "$_lcl_from" | sed 's,\(.\)[\\/][\\/]*,\1/,g'` ;; esac case ":$_lcl_to:" in # change empty paths to '.' ::) _lcl_to='.' ;; # strip trailing slashes :*[\\/]:) _lcl_to=`echo "$_lcl_to" | sed 's,[\\/]*$,,'` ;; :*:) ;; esac # squeze repeated slashes case '/' in # if the path contains any backslashes, turn slashes into backslashes *\\*) _lcl_to=`echo "$_lcl_to" | sed 's,\(.\)[\\/][\\/]*,\1\\\\\\\\,g'` ;; # if the path contains slashes, also turn backslashes into slashes *) _lcl_to=`echo "$_lcl_to" | sed 's,\(.\)[\\/][\\/]*,\1/,g'` ;; esac _lcl_common_prefix='' _lcl_second_prefix_match='' while test "$_lcl_second_prefix_match" != 0; do _lcl_first_prefix=`expr "x$_lcl_from" : "x\($_lcl_common_prefix/*[^/]*\)"` _lcl_second_prefix_match=`expr "x$_lcl_to" : "x$_lcl_first_prefix"` if test "$_lcl_second_prefix_match" != 0; then if test "$_lcl_first_prefix" != "$_lcl_common_prefix"; then _lcl_common_prefix="$_lcl_first_prefix" else _lcl_second_prefix_match=0 fi fi done _lcl_first_suffix=`expr "x$_lcl_from" : "x$_lcl_common_prefix/*\(.*\)"` _lcl_first_rel='' _lcl_tmp='xxx' while test "$_lcl_tmp" != ''; do _lcl_tmp=`expr "x$_lcl_first_suffix" : "x[^/]*/*\(.*\)"` if test "$_lcl_first_suffix" != ''; then _lcl_first_suffix="$_lcl_tmp" _lcl_first_rel="../$_lcl_first_rel" fi done _lcl_second_suffix=`expr "x$_lcl_to" : "x$_lcl_common_prefix/*\(.*\)"` _lcl_result_tmp="$_lcl_first_rel$_lcl_second_suffix" case ":$_lcl_result_tmp:" in # change empty paths to '.' ::) _lcl_result_tmp='.' ;; # strip trailing slashes :*[\\/]:) _lcl_result_tmp=`echo "$_lcl_result_tmp" | sed 's,[\\/]*$,,'` ;; :*:) ;; esac # squeze repeated slashes case "$_lcl_notation" in # if the path contains any backslashes, turn slashes into backslashes *\\*) _lcl_result_tmp=`echo "$_lcl_result_tmp" | sed 's,\(.\)[\\/][\\/]*,\1\\\\\\\\,g'` ;; # if the path contains slashes, also turn backslashes into slashes *) _lcl_result_tmp=`echo "$_lcl_result_tmp" | sed 's,\(.\)[\\/][\\/]*,\1/,g'` ;; esac eval $_lcl_result_var='$_lcl_result_tmp' done case ":$bindir_to_execprefix:" in # change empty paths to '.' ::) bindir_to_execprefix='.' ;; # strip trailing slashes :*[\\/]:) bindir_to_execprefix=`echo "$bindir_to_execprefix" | sed 's,[\\/]*$,,'` ;; :*:) ;; esac # squeze repeated slashes case $PCB_DIR_SEPARATOR_S in # if the path contains any backslashes, turn slashes into backslashes *\\*) bindir_to_execprefix=`echo "$bindir_to_execprefix" | sed 's,\(.\)[\\/][\\/]*,\1\\\\\\\\,g'` ;; # if the path contains slashes, also turn backslashes into slashes *) bindir_to_execprefix=`echo "$bindir_to_execprefix" | sed 's,\(.\)[\\/][\\/]*,\1/,g'` ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $bindir_to_execprefix" >&5 $as_echo "$bindir_to_execprefix" >&6; } cat >>confdefs.h <<_ACEOF #define BINDIR_TO_EXECPREFIX "$bindir_to_execprefix" _ACEOF BTNMOD=${BTNMOD:-"Mod1"} TOPDIRS= for dir in src lib newlib doc example tools tutorial README_FILES do test -d $dir/. && TOPDIRS="$TOPDIRS $dir" done ac_config_files="$ac_config_files Makefile data/Makefile intl/Makefile po/Makefile.in" if test -d $srcdir/README_FILES; then ac_config_files="$ac_config_files README_FILES/Makefile" fi if test -d $srcdir/doc; then ac_config_files="$ac_config_files doc/Makefile" fi if test -d $srcdir/doc/gs; then ac_config_files="$ac_config_files doc/gs/Makefile" ac_config_files="$ac_config_files doc/gs/gafrc" ac_config_files="$ac_config_files doc/gs/gschemrc" fi if test -d $srcdir/example; then ac_config_files="$ac_config_files example/Makefile" ac_config_files="$ac_config_files example/libraries/Makefile" fi if test -d $srcdir/lib; then ac_config_files="$ac_config_files lib/CreateLibraryContents.sh" ac_config_files="$ac_config_files lib/CreateLibrary.sh" ac_config_files="$ac_config_files lib/ListLibraryContents.sh" ac_config_files="$ac_config_files lib/Makefile" ac_config_files="$ac_config_files lib/QueryLibrary.sh" ac_config_files="$ac_config_files lib/qfp-ui" fi if test -d $srcdir/newlib; then ac_config_files="$ac_config_files newlib/2_pin_thru-hole_packages/Makefile" ac_config_files="$ac_config_files newlib/Makefile" ac_config_files="$ac_config_files newlib/connectors/Makefile" ac_config_files="$ac_config_files newlib/crystal/Makefile" ac_config_files="$ac_config_files newlib/electro-optics/Makefile" ac_config_files="$ac_config_files newlib/headers/Makefile" ac_config_files="$ac_config_files newlib/keystone/Makefile" ac_config_files="$ac_config_files newlib/msp430/Makefile" ac_config_files="$ac_config_files newlib/not_vetted_ingo/Makefile" ac_config_files="$ac_config_files newlib/sockets/Makefile" ac_config_files="$ac_config_files newlib/tests/Makefile" fi ac_config_files="$ac_config_files src/Makefile" ac_config_files="$ac_config_files src/icons/Makefile" if test -d $srcdir/tools; then ac_config_files="$ac_config_files tools/Makefile" fi if test -d $srcdir/tutorial; then ac_config_files="$ac_config_files tutorial/Makefile" fi ac_config_files="$ac_config_files tests/Makefile" ac_config_files="$ac_config_files gts/Makefile" ac_config_files="$ac_config_files w32/Makefile" ac_config_files="$ac_config_files win32/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 $as_echo_n "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${GIT_VERSION_TRUE}" && test -z "${GIT_VERSION_FALSE}"; then as_fn_error $? "conditional \"GIT_VERSION\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${CVS_VERSION_TRUE}" && test -z "${CVS_VERSION_FALSE}"; then as_fn_error $? "conditional \"CVS_VERSION\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${GIT_OR_CVS_VERSION_TRUE}" && test -z "${GIT_OR_CVS_VERSION_FALSE}"; then as_fn_error $? "conditional \"GIT_OR_CVS_VERSION\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WIN32_TRUE}" && test -z "${WIN32_FALSE}"; then as_fn_error $? "conditional \"WIN32\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi ac_config_commands="$ac_config_commands po/stamp-it" if test -z "${WITH_TOPOROUTER_TRUE}" && test -z "${WITH_TOPOROUTER_FALSE}"; then as_fn_error $? "conditional \"WITH_TOPOROUTER\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_DBUS_TRUE}" && test -z "${WITH_DBUS_FALSE}"; then as_fn_error $? "conditional \"WITH_DBUS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${USE_GL_TRUE}" && test -z "${USE_GL_FALSE}"; then as_fn_error $? "conditional \"USE_GL\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ENABLE_UPDATE_DESKTOP_DATABASE_TRUE}" && test -z "${ENABLE_UPDATE_DESKTOP_DATABASE_FALSE}"; then as_fn_error $? "conditional \"ENABLE_UPDATE_DESKTOP_DATABASE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ENABLE_UPDATE_MIME_DATABASE_TRUE}" && test -z "${ENABLE_UPDATE_MIME_DATABASE_FALSE}"; then as_fn_error $? "conditional \"ENABLE_UPDATE_MIME_DATABASE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${MISSING_PDFLATEX_TRUE}" && test -z "${MISSING_PDFLATEX_FALSE}"; then as_fn_error $? "conditional \"MISSING_PDFLATEX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${MISSING_TEXI2DVI_TRUE}" && test -z "${MISSING_TEXI2DVI_FALSE}"; then as_fn_error $? "conditional \"MISSING_TEXI2DVI\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${MISSING_PS2PDF_TRUE}" && test -z "${MISSING_PS2PDF_FALSE}"; then as_fn_error $? "conditional \"MISSING_PS2PDF\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${MISSING_GSCHEM_TRUE}" && test -z "${MISSING_GSCHEM_FALSE}"; then as_fn_error $? "conditional \"MISSING_GSCHEM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_TEST_TOOLS_TRUE}" && test -z "${HAVE_TEST_TOOLS_FALSE}"; then as_fn_error $? "conditional \"HAVE_TEST_TOOLS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${PNG_TRUE}" && test -z "${PNG_FALSE}"; then as_fn_error $? "conditional \"PNG\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${GIF_TRUE}" && test -z "${GIF_FALSE}"; then as_fn_error $? "conditional \"GIF\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${PNG_PREVIEW_TRUE}" && test -z "${PNG_PREVIEW_FALSE}"; then as_fn_error $? "conditional \"PNG_PREVIEW\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_PCBLIB_NEWLIB_TRUE}" && test -z "${BUILD_PCBLIB_NEWLIB_FALSE}"; then as_fn_error $? "conditional \"BUILD_PCBLIB_NEWLIB\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${DEBUG_BUILD_TRUE}" && test -z "${DEBUG_BUILD_FALSE}"; then as_fn_error $? "conditional \"DEBUG_BUILD\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by pcb $as_me 4.3.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ pcb config.status 4.3.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" # Capture the value of obsolete ALL_LINGUAS because we need it to compute # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it # from automake < 1.5. eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"' # Capture the value of LINGUAS because we need it to compute CATALOGS. LINGUAS="${LINGUAS-%UNSET%}" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "po-directories") CONFIG_COMMANDS="$CONFIG_COMMANDS po-directories" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "data/Makefile") CONFIG_FILES="$CONFIG_FILES data/Makefile" ;; "intl/Makefile") CONFIG_FILES="$CONFIG_FILES intl/Makefile" ;; "po/Makefile.in") CONFIG_FILES="$CONFIG_FILES po/Makefile.in" ;; "README_FILES/Makefile") CONFIG_FILES="$CONFIG_FILES README_FILES/Makefile" ;; "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; "doc/gs/Makefile") CONFIG_FILES="$CONFIG_FILES doc/gs/Makefile" ;; "doc/gs/gafrc") CONFIG_FILES="$CONFIG_FILES doc/gs/gafrc" ;; "doc/gs/gschemrc") CONFIG_FILES="$CONFIG_FILES doc/gs/gschemrc" ;; "example/Makefile") CONFIG_FILES="$CONFIG_FILES example/Makefile" ;; "example/libraries/Makefile") CONFIG_FILES="$CONFIG_FILES example/libraries/Makefile" ;; "lib/CreateLibraryContents.sh") CONFIG_FILES="$CONFIG_FILES lib/CreateLibraryContents.sh" ;; "lib/CreateLibrary.sh") CONFIG_FILES="$CONFIG_FILES lib/CreateLibrary.sh" ;; "lib/ListLibraryContents.sh") CONFIG_FILES="$CONFIG_FILES lib/ListLibraryContents.sh" ;; "lib/Makefile") CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;; "lib/QueryLibrary.sh") CONFIG_FILES="$CONFIG_FILES lib/QueryLibrary.sh" ;; "lib/qfp-ui") CONFIG_FILES="$CONFIG_FILES lib/qfp-ui" ;; "newlib/2_pin_thru-hole_packages/Makefile") CONFIG_FILES="$CONFIG_FILES newlib/2_pin_thru-hole_packages/Makefile" ;; "newlib/Makefile") CONFIG_FILES="$CONFIG_FILES newlib/Makefile" ;; "newlib/connectors/Makefile") CONFIG_FILES="$CONFIG_FILES newlib/connectors/Makefile" ;; "newlib/crystal/Makefile") CONFIG_FILES="$CONFIG_FILES newlib/crystal/Makefile" ;; "newlib/electro-optics/Makefile") CONFIG_FILES="$CONFIG_FILES newlib/electro-optics/Makefile" ;; "newlib/headers/Makefile") CONFIG_FILES="$CONFIG_FILES newlib/headers/Makefile" ;; "newlib/keystone/Makefile") CONFIG_FILES="$CONFIG_FILES newlib/keystone/Makefile" ;; "newlib/msp430/Makefile") CONFIG_FILES="$CONFIG_FILES newlib/msp430/Makefile" ;; "newlib/not_vetted_ingo/Makefile") CONFIG_FILES="$CONFIG_FILES newlib/not_vetted_ingo/Makefile" ;; "newlib/sockets/Makefile") CONFIG_FILES="$CONFIG_FILES newlib/sockets/Makefile" ;; "newlib/tests/Makefile") CONFIG_FILES="$CONFIG_FILES newlib/tests/Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "src/icons/Makefile") CONFIG_FILES="$CONFIG_FILES src/icons/Makefile" ;; "tools/Makefile") CONFIG_FILES="$CONFIG_FILES tools/Makefile" ;; "tutorial/Makefile") CONFIG_FILES="$CONFIG_FILES tutorial/Makefile" ;; "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; "gts/Makefile") CONFIG_FILES="$CONFIG_FILES gts/Makefile" ;; "w32/Makefile") CONFIG_FILES="$CONFIG_FILES w32/Makefile" ;; "win32/Makefile") CONFIG_FILES="$CONFIG_FILES win32/Makefile" ;; "po/stamp-it") CONFIG_COMMANDS="$CONFIG_COMMANDS po/stamp-it" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. # TODO: see whether this extra hack can be removed once we start # requiring Autoconf 2.70 or later. case $CONFIG_FILES in #( *\'*) : eval set x "$CONFIG_FILES" ;; #( *) : set x $CONFIG_FILES ;; #( *) : ;; esac shift # Used to flag and report bootstrapping failures. am_rc=0 for am_mf do # Strip MF so we end up with the name of the file. am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile which includes # dependency-tracking related rules and includes. # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ || continue am_dirpart=`$as_dirname -- "$am_mf" || $as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$am_mf" : 'X\(//\)[^/]' \| \ X"$am_mf" : 'X\(//\)$' \| \ X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$am_mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` am_filepart=`$as_basename -- "$am_mf" || $as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ X"$am_mf" : 'X\(//\)$' \| \ X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$am_mf" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` { echo "$as_me:$LINENO: cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles" >&5 (cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } || am_rc=$? done if test $am_rc -ne 0; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "Something went wrong bootstrapping makefile fragments for automatic dependency tracking. Try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking). See \`config.log' for more details" "$LINENO" 5; } fi { am_dirpart=; unset am_dirpart;} { am_filepart=; unset am_filepart;} { am_mf=; unset am_mf;} { am_rc=; unset am_rc;} rm -f conftest-deps.mk } ;; "po-directories":C) for ac_file in $CONFIG_FILES; do # Support "outfile[:infile[:infile...]]" case "$ac_file" in *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; esac # PO directories have a Makefile.in generated from Makefile.in.in. case "$ac_file" in */Makefile.in) # Adjust a relative srcdir. ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'` ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` # In autoconf-2.13 it is called $ac_given_srcdir. # In autoconf-2.50 it is called $srcdir. test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" case "$ac_given_srcdir" in .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; /*) top_srcdir="$ac_given_srcdir" ;; *) top_srcdir="$ac_dots$ac_given_srcdir" ;; esac # Treat a directory as a PO directory if and only if it has a # POTFILES.in file. This allows packages to have multiple PO # directories under different names or in different locations. if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then rm -f "$ac_dir/POTFILES" test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" gt_tab=`printf '\t'` cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ${gt_tab}]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" POMAKEFILEDEPS="POTFILES.in" # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend # on $ac_dir but don't depend on user-specified configuration # parameters. if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then # The LINGUAS file contains the set of available languages. if test -n "$OBSOLETE_ALL_LINGUAS"; then test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" fi ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` # Hide the ALL_LINGUAS assignment from automake < 1.5. eval 'ALL_LINGUAS''=$ALL_LINGUAS_' POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" else # The set of available languages was given in configure.in. # Hide the ALL_LINGUAS assignment from automake < 1.5. eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS' fi # Compute POFILES # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) # Compute UPDATEPOFILES # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) # Compute DUMMYPOFILES # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) # Compute GMOFILES # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) case "$ac_given_srcdir" in .) srcdirpre= ;; *) srcdirpre='$(srcdir)/' ;; esac POFILES= UPDATEPOFILES= DUMMYPOFILES= GMOFILES= for lang in $ALL_LINGUAS; do POFILES="$POFILES $srcdirpre$lang.po" UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" DUMMYPOFILES="$DUMMYPOFILES $lang.nop" GMOFILES="$GMOFILES $srcdirpre$lang.gmo" done # CATALOGS depends on both $ac_dir and the user's LINGUAS # environment variable. INST_LINGUAS= if test -n "$ALL_LINGUAS"; then for presentlang in $ALL_LINGUAS; do useit=no if test "%UNSET%" != "$LINGUAS"; then desiredlanguages="$LINGUAS" else desiredlanguages="$ALL_LINGUAS" fi for desiredlang in $desiredlanguages; do # Use the presentlang catalog if desiredlang is # a. equal to presentlang, or # b. a variant of presentlang (because in this case, # presentlang can be used as a fallback for messages # which are not translated in the desiredlang catalog). case "$desiredlang" in "$presentlang"*) useit=yes;; esac done if test $useit = yes; then INST_LINGUAS="$INST_LINGUAS $presentlang" fi done fi CATALOGS= if test -n "$INST_LINGUAS"; then for lang in $INST_LINGUAS; do CATALOGS="$CATALOGS $lang.gmo" done fi test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do if test -f "$f"; then case "$f" in *.orig | *.bak | *~) ;; *) cat "$f" >> "$ac_dir/Makefile" ;; esac fi done fi ;; esac done ;; "po/stamp-it":C) if ! grep "^# INTLTOOL_MAKEFILE$" "po/Makefile.in" > /dev/null ; then as_fn_error $? "po/Makefile.in.in was not created by intltoolize." "$LINENO" 5 fi rm -f "po/stamp-it" "po/stamp-it.tmp" "po/POTFILES" "po/Makefile.tmp" >"po/stamp-it.tmp" sed '/^#/d s/^[[].*] *// /^[ ]*$/d '"s|^| $ac_top_srcdir/|" \ "$srcdir/po/POTFILES.in" | sed '$!s/$/ \\/' >"po/POTFILES" sed '/^POTFILES =/,/[^\\]$/ { /^POTFILES =/!d r po/POTFILES } ' "po/Makefile.in" >"po/Makefile" rm -f "po/Makefile.tmp" mv "po/stamp-it.tmp" "po/stamp-it" ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi with_gui=`echo $with_gui` with_printer=`echo $with_printer` with_exporters=`echo $with_exporters | sed 's/,/ /g'` expandedXDGDATADIR=`eval "echo $XDGDATADIR"` expandedKDEDATADIR=`eval "echo $KDEDATADIR"` expandedGAFDATADIR=`eval "echo $GAFDATADIR"` { $as_echo "$as_me:${as_lineno-$LINENO}: result: ** Configuration summary for $PACKAGE $VERSION: Cross Compiling: $cross_compiling CC: $CC CXX: $CXX CPPFLAGS: $CPPFLAGS CFLAGS: $CFLAGS CXXFLAGS: $CXXFLAGS LIBS: $LIBS PCB: $PCB GUI: $with_gui Printer: $with_printer Exporters: $with_exporters Coordinate type: $COORD_TYPE Source tree distribution: $pcb_sources Build documentation: $docs_yesno Build toporouter: $enable_toporouter Enable toporouter output: $enable_toporouter_output xdg data directory: $expandedXDGDATADIR KDE data directory: $expandedKDEDATADIR gaf data directory: $expandedGAFDATADIR dmalloc debugging: $with_dmalloc ElectricFence debugging: $with_efence Regression tests enabled: $have_test_tools " >&5 $as_echo " ** Configuration summary for $PACKAGE $VERSION: Cross Compiling: $cross_compiling CC: $CC CXX: $CXX CPPFLAGS: $CPPFLAGS CFLAGS: $CFLAGS CXXFLAGS: $CXXFLAGS LIBS: $LIBS PCB: $PCB GUI: $with_gui Printer: $with_printer Exporters: $with_exporters Coordinate type: $COORD_TYPE Source tree distribution: $pcb_sources Build documentation: $docs_yesno Build toporouter: $enable_toporouter Enable toporouter output: $enable_toporouter_output xdg data directory: $expandedXDGDATADIR KDE data directory: $expandedKDEDATADIR gaf data directory: $expandedGAFDATADIR dmalloc debugging: $with_dmalloc ElectricFence debugging: $with_efence Regression tests enabled: $have_test_tools " >&6; } pcb-4.3.0/src/0000775000175000017500000000000014017001275010051 500000000000000pcb-4.3.0/src/rats.h0000664000175000017500000000322513773431044011126 00000000000000/*! * \file src/rats.h * * \brief Prototypes for rats routines. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * Copyright (C) 1997, harry eaton * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * * Thomas.Nau@rz.uni-ulm.de */ #ifndef PCB_RATS_H #define PCB_RATS_H #include "global.h" /* This one is actually in netlist.h, but it's used by rats.c */ LibraryMenuType * netnode_to_netname (char *nodename); LibraryMenuType * netname_to_netname (char *netname); RatType * AddNet (void); char *ConnectionName (int, void *, void *); bool AddAllRats (bool, void (*)(register ConnectionType *, register ConnectionType *, register RouteStyleType *)); bool SeekPad (LibraryEntryType *, ConnectionType *, bool); NetListType * ProcNetlist (LibraryType *); NetListListType CollectSubnets (bool); #endif pcb-4.3.0/src/gpcb-menu.res.in0000664000175000017500000005144413773431044013007 00000000000000# -*- c -*- # Note - gpcb-menu.res is used to build gpcb-menu.h # Note - parameters are sensitive to extra spaces around the commas Mouse = { Left = { Mode(Notify) ctrl = { Mode(Save) Mode(None) Mode(Restore) Mode(Notify) } shift-ctrl = { Mode(Save) Mode(Remove) Mode(Notify) Mode(Restore) } up = Mode(Release) } Right = { Pan(1) up = Pan(0) shift = Popup(Popup1) ctrl = Display(CycleCrosshair) } Middle = { Mode(Stroke) up = Mode(Release) ctrl = { Mode(Save) Mode(Copy) Mode(Notify) } up-ctrl = { Mode(Notify) Mode(Restore) } shift-ctrl = { Display(ToggleRubberbandMode) Mode(Save) Mode(Move) Mode(Notify) } up-shift-ctrl = { Mode(Notify) Mode(Restore) Display(ToggleRubberbandMode) } } Up = { Zoom(0.8) shift = Scroll(up) ctrl = Scroll(left) } Down = { Zoom(1.25) shift = Scroll(down) ctrl = Scroll(right) } # If you want zoom to center, do this instead. #Up = { {Zoom(0.8) Center()} } #Down = { {Zoom(1.25) Center()} } scroll-left = { Scroll(left) } scroll-right = { Scroll(right) } } MainMenu = { # # File Menu # {"File" m=F {"New" New() a={"Ctrl-N" "Ctrln"}} {"Open..." Load(Layout) tip="Load a layout from a file"} - {"Save" Save(Layout) tip="Saves current layout" m=S a={"Ctrl-S" "Ctrls"}} {"Save As..." Save(LayoutAs) tip="Saves current layout into a new file" m=A a={"Shift Ctrl-S" "Shift Ctrls"}} {"Revert" Load(Revert,none) tip="Revert to the layout stored on disk"} - {"Import Schematics" {"gschem" Import() } {"TinyCAD" ImportTinyCAD() } } {"Load element to buffer" PasteBuffer(Clear) Load(ElementTobuffer)} {"Load layout to buffer" PasteBuffer(Clear) Load(LayoutTobuffer)} {"Load netlist" Load(Netlist)} {"Load vendor resource file" LoadVendorFrom()} - {"Save connection data of" {" a single element" GetXY(Click to set the element mark <>) Save(ElementConnections)} {" all elements" Save(AllConnections)} {" unused pins" Save(AllUnusedPins)} } {"Export..." Export()} - {"Calibrate Printer..." PrintCalibrate()} {"Print..." Print()} - {"Preferences..." DoWindows(Preferences)} - {"Quit" Quit() a={"Ctrl-Q" "Ctrlq"}} } # # Edit Menu # {"Edit" m=E {"Undo" Undo() a={"U" "u"}} {"Redo" Redo() a={"Shift-R" "Shiftr"}} #{"Clear undo-buffer" Undo(ClearList) a={"Shift-Ctrl-U" "Shift Ctrlu"}} - {"Cut to buffer" GetXY(Click to set the snap point for this buffer) PasteBuffer(Clear) PasteBuffer(AddSelected) RemoveSelected() Mode(PasteBuffer) a={"Ctrl-X" "Ctrlx"}} {"Copy to buffer" GetXY(Click to set the snap point for this buffer) PasteBuffer(Clear) PasteBuffer(AddSelected) Unselect(All) Mode(PasteBuffer) a={"Ctrl-C" "Ctrlc"}} {"Paste buffer" Mode(PasteBuffer) a={"Ctrl-V" "Ctrlv"}} - {"Unselect all" Unselect(All) a={"Shift-Ctrl-A" "Shift Ctrla"}} {"Select all visible" Select(All) a={"Ctrl-A" "Ctrla"}} - {"Edit name of" {"text on layout" ChangeName(Object) a={"N" "n"}} {"layout" ChangeName(Layout)} {"active layer" ChangeName(Layer)} } {"Edit attributes of" {"Layout" Attributes(Layout)} {"CurrentLayer" Attributes(Layer)} {"Element" Attributes(Element)} } - {"Route Styles" @routestyles - {"Edit..." AdjustStyle(0)} } - {"Via type" {"Through-hole" a={"Xtrl-Shift-P" "Ctrl Shiftp"} SetViaLayers(Object,th)} {"Buried from" a={"Xtrl-Shift-F" "Ctrl Shiftf"} SetViaLayers(Object,c,-)} {"Buried to" a={"Xtrl-Shift-T" "Ctrl Shiftt"} SetViaLayers(Object,-,c)} } } # # View Menu # {"View" m=V {"Enable visible grid" checked=drawgrid Display(Grid)} {"Grid units" {"mil" checked=grid_units_mil,1 SetUnits(mil)} {"mm" checked=grid_units_mm,1 SetUnits(mm)} } {"Grid size" {"No Grid" checked=grid,0 SetValue(Grid,1)} - { "0.1 mil" checked=gridsize,0.1mil SetUnits(mil) SetValue(Grid,0.1mil)} { "1 mil" checked=gridsize,1mil SetUnits(mil) SetValue(Grid,1mil)} { "5 mil" checked=gridsize,5mil SetUnits(mil) SetValue(Grid,5mil)} { "10 mil" checked=gridsize,10mil SetUnits(mil) SetValue(Grid,10mil)} { "25 mil" checked=gridsize,25mil SetUnits(mil) SetValue(Grid,25mil)} { "50 mil" checked=gridsize,50mil SetUnits(mil) SetValue(Grid,50mil)} {"100 mil" checked=gridsize,100mil SetUnits(mil) SetValue(Grid,100mil)} - {"0.01 mm" checked=gridsize,0.01mm SetUnits(mm) SetValue(Grid,0.01mm)} {"0.05 mm" checked=gridsize,0.05mm SetUnits(mm) SetValue(Grid,0.05mm)} {"0.1 mm" checked=gridsize,0.10mm SetUnits(mm) SetValue(Grid,0.1mm)} {"0.25 mm" checked=gridsize,0.25mm SetUnits(mm) SetValue(Grid,0.25mm)} {"0.5 mm" checked=gridsize,0.50mm SetUnits(mm) SetValue(Grid,0.5mm)} {"1 mm" checked=gridsize,1mm SetUnits(mm) SetValue(Grid,1mm)} - {"Grid -" SetValue(Grid,-) a={"Shift-G" "Shiftg"}} {"Grid +" SetValue(Grid,+) a={"G" "g"}} } {"Realign grid" GetXY(Click to set the grid origin) Display(ToggleGrid)} - {"Displayed element name" {"Description" Display(Description) checked=elementname,1} {"Reference Designator" Display(NameOnPCB) checked=elementname,2} {"Value" Display(Value) checked=elementname,3} } {"Enable Pinout shows number" checked=shownumber Display(ToggleName)} {"Pins/Via show Name/Number" Display(PinOrPadName) a={"D" "d"}} - {"Zoom In 20%" Zoom(-1.2) m=Z a={"Z" "z"}} {"Zoom Out 20%" Zoom(+1.2) m=O a={"Shift-Z" "Shiftz"}} {"More zooms and view changes" {"Zoom Max" Zoom() m=M a={"V" "v"}} {"Zoom In 2X" Zoom(-2)} {"Zoom Out 2X" Zoom(+2)} {"Zoom to 0.1mil/px" Zoom(=0.1mil)} {"Zoom to 0.01mm/px" Zoom(=0.01mm)} {"Zoom to 1mil/px" Zoom(=1mil)} {"Zoom to 0.05mm/px" Zoom(=0.05mm)} {"Zoom to 2.5mil/px" Zoom(=2.5mil)} {"Zoom to 0.1mm/px" Zoom(=0.1mm)} {"Zoom to 10mil/px" Zoom(=10mil)} {"Zoom In 20% and center" Zoom(-1.2) Center() m=Z } {"Zoom Out 20% and center" Zoom(+1.2) Center() m=O } {"Flip up/down" checked=flip_y SwapSides(V) a={"Tab" "Tab"}} {"Flip left/right" checked=flip_x SwapSides(H) a={"Shift-Tab" "ShiftTab"}} {"Spin 180 degrees" SwapSides(R) a={"Ctrl-Tab" "CtrlTab"}} {"Swap Sides" SwapSides() a={"Ctrl-Shift-Tab" "Ctrl ShiftTab"}} {"Center cursor" Center() a={"C" "c"}} } - {"Shown Layers" @layerview - {"Edit Layer Groups" EditLayerGroups()} } {"Current Layer" @layerpick - {"Delete current layer" MoveLayer(c,-1)} {"Add new layer" MoveLayer(-1,c)} {"Move current layer up" MoveLayer(c,up)} {"Move current layer down" MoveLayer(c,down)} } } # # Settings menu # {"Settings" m=S {"'All-direction' lines" checked=alldirection Display(Toggle45Degree) a={"." "."}} {"Auto swap line start angle" checked=swapstartdir Display(ToggleStartDirection)} {"Orthogonal moves" checked=orthomove Display(ToggleOrthoMove)} {"Crosshair snaps to pins and pads" checked=snappin Display(ToggleSnapPin)} {"Crosshair shows DRC clearance" checked=showdrc Display(ToggleShowDRC)} {"Auto enforce DRC clearance" checked=autodrc Display(ToggleAutoDRC)} {"Lock Names" checked=locknames Display(ToggleLockNames)} {"Only Names" checked=onlynames Display(ToggleOnlyNames)} {"Hide Names" checked=hidenames Display(ToggleHideNames)} - {"Rubber band mode" checked=rubberband Display(ToggleRubberBandMode)} {"Require unique element names" checked=uniquename Display(ToggleUniqueNames)} {"Auto-zero delta measurements" checked=localref Display(ToggleLocalRef)} {"New lines, arcs clear polygons" checked=clearnew Display(ToggleClearLine)} {"New polygons are full ones" checked=newfullpoly Display(ToggleFullPoly)} {"Show autorouter trials" checked=liveroute Display(ToggleLiveRoute)} {"Thin draw" checked=thindraw Display(ToggleThindraw) a={"|" "|"}} {"Thin draw poly" checked=thindrawpoly Display(ToggleThindrawPoly) a={"Ctrl-Shift-P" "Ctrl Shiftp"}} {"Check polygons" checked=checkplanes Display(ToggleCheckPlanes)} {"Auto buried vias" checked=autoburiedvias Display(ToggleAutoBuriedVias)} {"Vendor drill mapping" ToggleVendor() checked=VendorMapOn} {"Import New Elements at" m=I {" Center" Import(setnewpoint,center) m=C} {" Mark" Import(setnewpoint,mark) m=M} {" Crosshair" Import(setnewpoint) m=h} - {"Set Dispersion" Import(setdisperse) m=D} } } # # Select menu # {"Select" m=l {"Select all visible" Select(All)} {"Select all found" Select(Found)} {"Select all connected" Select(Connection)} {"Select all buried vias" Select(BuriedVias)} - {"Unselect all" Unselect(All)} {"Unselect all found" Unselect(Found)} {"Unselect all connected" Unselect(Connection)} - {"Select by name" {"All objects" Select(ObjectByName) active=have_regex} {"Elements" Select(ElementByName) active=have_regex} {"Pads" Select(PadByName) active=have_regex} {"Pins" Select(PinByName) active=have_regex} {"Text" Select(TextByName) active=have_regex} {"Vias" Select(ViaByName) active=have_regex} } - {"Auto-place selected elements" AutoPlaceSelected() a={"Ctrl-P" "Ctrlp"}} {"Disperse all elements" DisperseElements(All)} {"Disperse selected elements" DisperseElements(Selected)} - {"Move selected elements to other side" Flip(SelectedElements) a={"Shift-B" "Shiftb"}} {"Move selected to current layer" MoveToCurrentLayer(Selected) a={"Shift-M" "Shiftm"}} {"Remove selected objects" RemoveSelected() a={"Shift-Delete" "ShiftDelete"}} {"Convert selection to element" Select(Convert)} - {"Optimize selected rats" DeleteRats(SelectedRats) AddRats(SelectedRats)} {"Auto-route selected rats" AutoRoute(SelectedRats) a={"Alt-R" "Altr"}} {"Rip up selected auto-routed tracks" RipUp(Selected)} - {"Change size of selected objects" {"Lines -10 mil" ChangeSize(SelectedLines,-10,mil) ChangeSize(SelectedArcs,-10,mil)} {"Lines +10 mil" ChangeSize(SelectedLines,+10,mil) ChangeSize(SelectedArcs,+10,mil)} {"Pads -10 mil" ChangeSize(SelectedPads,-10,mil)} {"Pads +10 mil" ChangeSize(SelectedPads,+10,mil)} {"Pins -10 mil" ChangeSize(SelectedPins,-10,mil)} {"Pins +10 mil" ChangeSize(SelectedPins,+10,mil)} {"Texts -10 mil" ChangeSize(SelectedTexts,-10,mil)} {"Texts +10 mil" ChangeSize(SelectedTexts,+10,mil)} {"Vias -10 mil" ChangeSize(SelectedVias,-10,mil)} {"Vias +10 mil" ChangeSize(SelectedVias,+10,mil)} } - {"Change drilling hole of selected objects" {"Vias -10 mil" ChangeDrillSize(SelectedVias,-10,mil)} {"Vias +10 mil" ChangeDrillSize(SelectedVias,+10,mil)} {"Pins -10 mil" ChangeDrillSize(SelectedPins,-10,mil)} {"Pins +10 mil" ChangeDrillSize(SelectedPins,+10,mil)} } - {"Change square-flag of selected objects" {"Elements" ChangeSquare(SelectedElements)} {"Pins" ChangeSquare(SelectedPins)} } - {"Change type of selected vias" {"Through-hole" SetViaLayers(selected,th)} {"Buried from current layer" SetViaLayers(selected,c,-)} {"Buried to current layer" SetViaLayers(selected,-,c)} } } # # Buffer menu # {"Buffer" m=B {"Cut to buffer" GetXY(Click to set the snap point for this buffer) PasteBuffer(Clear) PasteBuffer(AddSelected) RemoveSelected() Mode(PasteBuffer)} {"Paste buffer" Mode(PasteBuffer)} - {"Rotate buffer 90 deg CCW" Mode(PasteBuffer) PasteBuffer(Rotate,1) a={"Shift-F7" "ShiftF7"}} {"Rotate buffer 90 deg CW" Mode(PasteBuffer) PasteBuffer(Rotate,3)} {"Arbitrarily Rotate Buffer" Mode(PasteBuffer) FreeRotateBuffer()} {"Mirror buffer (up/down)" Mode(PasteBuffer) PasteBuffer(Mirror)} {"Mirror buffer (left/right)" Mode(PasteBuffer) PasteBuffer(Rotate,1) PasteBuffer(Mirror) PasteBuffer(Rotate,3)} - {"Clear buffer" PasteBuffer(Clear)} {"Convert buffer to element" PasteBuffer(Convert)} {"Break buffer elements to pieces" PasteBuffer(Restore)} {"Save buffer elements to file" Save(PasteBuffer)} - {"Select Buffer #1" checked=buffer,1 PasteBuffer(1) m=1 a={"Shift-1" "Shift1"}} {"Select Buffer #2" checked=buffer,2 PasteBuffer(2) m=2 a={"Shift-2" "Shift2"}} {"Select Buffer #3" checked=buffer,3 PasteBuffer(3) m=3 a={"Shift-3" "Shift3"}} {"Select Buffer #4" checked=buffer,4 PasteBuffer(4) m=4 a={"Shift-4" "Shift4"}} {"Select Buffer #5" checked=buffer,5 PasteBuffer(5) m=5 a={"Shift-5" "Shift5"}} } # # Connects menu # {"Connects" m=C {"Lookup connection" GetXY(Click on the object) Connection(Find) a={"Ctrl-F" "Ctrlf"}} {"Reset scanned pads/pins/vias" Connection(ResetPinsViasAndPads) Display(Redraw)} {"Reset scanned lines/polygons" Connection(ResetLinesAndPolygons) Display(Redraw)} {"Reset all connections" Connection(Reset) Display(Redraw) a={"Shift-F" "Shiftf"}} - {"Optimize rats nest" Atomic(Save) DeleteRats(AllRats) Atomic(Restore) AddRats(AllRats) Atomic(Block) a={"O" "o"}} {"Erase rats nest" DeleteRats(AllRats) a={"E" "e"}} {"Erase selected rats" DeleteRats(SelectedRats) a={"Shift-E" "Shifte"}} - {"Auto-route selected rats" AutoRoute(Selected)} {"Auto-route all rats" AutoRoute(AllRats)} {"Toporouter" Toporouter()} {"Rip up all auto-routed tracks" RipUp(All)} - {"Optimize routed tracks" {"Auto-Optimize" djopt(auto) a={"Shift-=" "Shift="}} {"Debumpify" djopt(debumpify) } {"Unjaggy" djopt(unjaggy) } {"Vianudge" djopt(vianudge) } {"Viatrim" djopt(viatrim) } {"Ortho pull" djopt(orthopull) } {"Simple optimization" djopt(simple) a={"=" "="}} {"Miter" djopt(miter) } {"Puller" a={"Y" "y"} Puller() } {"Global Puller" {"Selected" GlobalPuller(selected) } {"Found" GlobalPuller(found) } {"All" GlobalPuller() } } - {"Only autorouted nets" OptAutoOnly() checked=optautoonly} } - {"Design Rule Checker" DRC()} - {"Apply vendor drill mapping" ApplyVendor()} } # # Info Menu # {"Info" m=I {"Generate object report" ReportObject() a={"Ctrl-R" "Ctrlr"}} {"Generate drill summary" Report(DrillReport)} {"Report found pins/pads" Report(FoundPins)} {"Report net length" Report(NetLength) a={"R" "r"}} {"Key Bindings" {"Remove" a={"Delete" "Delete"} Mode(Save) Mode(Remove) Mode(Notify) Mode(Restore) } {"Remove Selected" a={"Backspace" "BackSpace"} RemoveSelected() } {"Remove Connected" a={"Shift-Backspace" "ShiftBackSpace"} Atomic(Save) Connection(Reset) Atomic(Restore) Unselect(All) Atomic(Restore) Connection(Find) Atomic(Restore) Select(Connection) Atomic(Restore) RemoveSelected() Atomic(Restore) Connection(Reset) Atomic(Restore) Unselect(All) Atomic(Block) } {"Set Same" a={"A" "a"} SetSame()} {"Flip Object" a={"B" "b"} Flip(Object)} {"Find Connections" a={"F" "f"} Connection(Reset) Connection(Find)} {"ToggleHideName Object" a={"H" "h"} ToggleHideName(Object)} {"ToggleHideName SelectedElement" a={"Shift-H" "Shifth"} ToggleHideName(SelectedElements)} {"ChangeHole Object" a={"Ctrl-H" "Ctrlh"} ChangeHole(Object)} {"ChangeJoin Object" a={"J" "j"} ChangeJoin(Object)} {"ChangeJoin SelectedObject" a={"Shift-J" "Shiftj"} ChangeJoin(SelectedObjects)} {"Clear Object +" a={"K" "k"} ChangeClearSize(Object,+)} {"Clear Object -" a={"Shift-K" "Shiftk"} ChangeClearSize(Object,-)} {"Clear Selected +" a={"Ctrl-K" "Ctrlk"} ChangeClearSize(SelectedObjects,+)} {"Clear Selected -" a={"Shift-Ctrl-K" "Shift Ctrlk"} ChangeClearSize(SelectedObjects,-)} {"Line Tool size +" a={"L" "l"} SetValue(LineSize,+)} {"Line Tool size -" a={"Shift-L" "Shiftl"} SetValue(LineSize,-)} {"Move Object to current layer" a={"M" "m"} MoveToCurrentLayer(Object)} {"MarkCrosshair" a={"Ctrl-M" "Ctrlm"} MarkCrosshair()} {"Select shortest rat" a={"Shift-N" "Shiftn"} AddRats(Close)} {"AddRats to selected pins" a={"Shift-O" "Shifto"} Atomic(Save) DeleteRats(AllRats) Atomic(Restore) AddRats(SelectedRats) Atomic(Block) } {"ChangeOctagon Object" a={"Ctrl-O" "Ctrlo"} ChangeOctagon(Object)} {"Polygon PreviousPoint" a={"P" "p"} Polygon(PreviousPoint)} {"Polygon Close" a={"Shift-P" "Shiftp"} Polygon(Close)} {"ChangeSquare Object" a={"Q" "q"} ChangeSquare(ToggleObject)} {"ChangeSize +" a={"S" "s"} ChangeSize(Object,+)} {"ChangeSize -" a={"Shift-S" "Shifts"} ChangeSize(Object,-)} {"ChangeDrill +5 mil" a={"Ctrl-D" "Ctrld"} ChangeDrillSize(Object,+5,mil)} {"ChangeDrill -5 mil" a={"Ctrl-Shift-D" "Ctrl Shiftd"} ChangeDrillSize(Object,-5,mil)} {"Text Tool scale +10 mil" a={"T" "t"} SetValue(TextScale,+10,mil)} {"Text Tool scale -10 mil" a={"Shift-T" "Shiftt"} SetValue(TextScale,-10,mil)} {"Via Tool size +5 mil" a={"Shift-V" "Shiftv"} SetValue(ViaSize,+5,mil)} {"Via Tool size -5 mil" a={"Shift-Ctrl-V" "Shift Ctrlv"} SetValue(ViaSize,-5,mil)} {"Via Tool drill +5 mil" a={"Ctrl-L" "Ctrll"} SetValue(ViaDrillingHole,+5,mil)} {"Via Tool drill -5 mil" a={"Ctrl-Shift-L" "Ctrl Shiftl"} SetValue(ViaDrillingHole,-5,mil)} {"AddRats Selected" a={"Shift-W" "Shiftw"} AddRats(SelectedRats)} {"Add All Rats" a={"W" "w"} AddRats(AllRats)} {"Cycle Clip" a={"/" "/"} Display(CycleClip)} {"Arrow Mode" a={"Space" "space"} Mode(Arrow) checked=arrowmode,1} {"Temp Arrow ON" a={"[" "["} Mode(Save) Mode(Arrow) Mode(Notify)} {"Temp Arrow OFF" a={"]" "]"} Mode(Release) Mode(Restore)} - {"Step Up" a={"Up" "Up"} Cursor(Warp,0,1,grid)} {"Step Down" a={"Down" "Down"} Cursor(Warp,0,-1,grid)} {"Step Left" a={"Left" "Left"} Cursor(Warp,-1,0,grid)} {"Step Right" a={"Right" "Right"} Cursor(Warp,1,0,grid)} {"Step +Up" a={"Up" "ShiftUp"} Cursor(Pan,0,50,view)} {"Step +Down" a={"Down" "ShiftDown"} Cursor(Pan,0,-50,view)} {"Step +Left" a={"Left" "ShiftLeft"} Cursor(Pan,-50,0,view)} {"Step +Right" a={"Right" "ShiftRight"} Cursor(Pan,50,0,view)} {'"Click"' a={"Enter" "Enter"} Mode(Notify) Mode(Release)} - } } # # Window Menu # {"Window" m=W {"Library" DoWindows(Library) a={"i" "i"}} {"Message Log" DoWindows(Log)} {"DRC Check" DoWindows(DRC)} {"Netlist" DoWindows(Netlist)} {"Command Entry" Command() a={":" ":"}} {"Pinout" Display(Pinout) a={"Shift-D" "Shiftd"}} - {"About..." About()} } } PopupMenus = { Popup1 = { {"Operations on selections" {"Unselect all objects" Unselect(All)} {"Remove selected objects" RemoveSelected()} {"Copy selection to buffer" GetXY(Click to set the snap point for this buffer) PasteBuffer(Clear) PasteBuffer(AddSelected) Mode(PasteBuffer) } {"Cut selection to buffer" GetXY(Click to set the snap point for this buffer) PasteBuffer(Clear) PasteBuffer(AddSelected) RemoveSelected() Mode(PasteBuffer) } {"Convert selection to element" Select(Convert)} {"Auto place selected elements" AutoPlaceSelected()} {"Autoroute selected elements" AutoRoute(SelectedRats)} {"Rip up selected auto-routed tracks" RipUp(Selected)} } {"Operations on this location" {"Generate object report" GetXY(Click on the object) Report(Object)} } - {"Undo last operation" Undo()} {"Redo last undone operation" Redo()} - {Tools {"None" checked=nomode,1 Mode(None)} {"Via" checked=viamode,1 Mode(Via) a={"F1" "F1"}} {"Line" checked=linemode,1 Mode(Line) a={"F2" "F2"}} {"Arc" checked=arcmode,1 Mode(Arc) a={"F3" "F3"}} {"Text" checked=textmode,1 Mode(Text) a={"F4" "F4"}} {"Rectangle" checked=rectanglemode,1 Mode(Rectangle) a={"F5" "F5"}} {"Polygon" checked=polygonmode,1 Mode(Polygon) a={"F6" "F6"}} {"Polygon Hole" checked=polygonholemode,1 Mode(PolygonHole)} {"Buffer" checked=pastebuffermode,1 Mode(PasteBuffer) a={"F7" "F7"}} {"Remove" checked=removemode,1 Mode(Remove) a={"F8" "F8"}} {"Rotate" checked=rotatemode,1 Mode(Rotate) a={"F9" "F9"}} {"Thermal" checked=thermalmode,1 Mode(Thermal) a={"F10" "F10"}} {"Arrow" checked=arrowmode,1 Mode(Arrow) a={"F11" "F11"}} {"Insert Point" checked=insertpointmode,1 Mode(InsertPoint) a={"Insert" "Insert"}} {"Move" checked=movemode,1 Mode(Move)} {"Copy" checked=copymode,1 Mode(Copy)} {"Lock" checked=lockmode,1 Mode(Lock) a={"F12" "F12"}} {"Cancel" Mode(Escape) a={"Esc" "Escape"}} } } } pcb-4.3.0/src/object_list.h0000664000175000017500000001316613773431044012463 00000000000000/*! * \file src/object_list.h * * \brief object_list header * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 2018 Charles Parker * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *
* * This is a container class for keeping lists of any type of object. It uses * two allocations of memory. The first keeps track of the list info, e.g. * number of objects in the list, number of objects the list can hold, size of * each object, etc. The second allocation contains the object data themselves. * * When an object is added to the list, the list makes its own copy of the data. * The list does not take ownership of the original data, so, the caller is * still responsible for the original object. Providing an option where the list * takes ownership of the original object is perhaps an improvement for the * future. * * For complex objects, objects that don't contain all of their data in one * place, but have pointers to other areas of memory, it is necessary to create * object operation functions. At a minimum, the copy_object and clear_object * functions, as these are used to make the list's copy of the object and move * its copies around. * * To do: * * Allow the list to store objects anywhere instead of forcing a * contiguous memory allocation. * * The list would store pointers to the objects which could reside * anywhere in memory. This would remove a lot of the reallocating of * memory since we'd basically have a list of pointers, which are much * smaller. * * This should be an option that can be specified, but not required. * * * Allow the list to take ownership of objects. * * The list would not allocate memory and copy the object in this case, * but it would free the objects memory when removed from the list. * * A fun case would be the mixed case in which the list owned some objects * but not others. Let's not go there for a while. * */ #ifndef object_list_h #define object_list_h /*! * \brief Object operations structure. * * This is a virtuial function table of functions that operate on whatever type * of object the list happens to contain. They must be written for any complex * object type this class stores. */ typedef struct object_operations { void (*copy_object)(void * a, void * b); /*!< Create a new copy of the object. * If the object contains its own memory allocations, then this function * needs to make a copy of those also. */ void (*clear_object)(void * a); /*!< Clear an object. * This doesn't free the memory for the object itself, but, it should free any * memory that the object owns. */ int (*compare_objects)(void *a, void *b); /*!< Compare objects * Return 0 if the objects are "equal", < 0 if the first object is "less" * than the second object and > 0 if the first object is "greater" than * the second object. */ } object_operations; /*! * \brief Object list structure. * * This is the metadata structure. The actual data is stored in a block of * memory somewhere outside of this structure. */ typedef struct object_list { int count; /*!< number of items in the list. */ int size; /*!< number of items the list can hold. */ int item_size; /*!< the size of the items the list contains. */ void ** items; /*!< array of pointers to objects. */ void * data; /*!< pointer to the memory where the objects are stored. */ object_operations * ops; /*!< pointer to the function table of object ops. */ } object_list; /* * Constructors, destructors, etc. */ /* Create a new object list with n items of size item_size */ object_list * object_list_new(int n, unsigned item_size); /* Copy constructor, copies data too. */ object_list * object_list_duplicate(object_list * list); /* Delete an object list */ void object_list_delete(object_list * list); /* * Functions that change the list itself */ /* Delete the data in an object list */ int object_list_clear(object_list * list); /* Make the object list bigger by n items */ int object_list_expand(object_list * list, int n); /* Print the list information */ void object_list_describe(object_list * list); /* * Functions that manipulate the data stored in the list */ /* Insert an object into the list at position n */ int object_list_insert(object_list * list, int n, void * item); /* Remove the object at position n from the list */ int object_list_remove(object_list * list, int n); /* Add an objet to the end of the list */ int object_list_append(object_list * list, void * item); /* Get a pointer to the object at position n in the list */ void * object_list_get_item(object_list * list, int n); /* Search the list for something equal to item * Note: This returns the first match. * */ void * object_list_find_item(object_list * list, void * item); /* * Unit test */ #ifdef PCB_UNIT_TEST void object_list_register_tests(void); void object_list_test(void); #endif /* PCB_UNIT_TEST */ #endif /* object_list_h */ pcb-4.3.0/src/find.h0000664000175000017500000000503613773431044011077 00000000000000/*! * \file src/find.h * * \brief Prototypes for connection search routines. * *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * Thomas.Nau@rz.uni-ulm.de */ #ifndef PCB_FIND_H #define PCB_FIND_H #include /* needed to define 'FILE *' */ #include "global.h" /* --------------------------------------------------------------------------- * some local defines */ #define LOOKUP_FIRST \ (PIN_TYPE | PAD_TYPE) #define LOOKUP_MORE \ (VIA_TYPE | LINE_TYPE | RATLINE_TYPE | POLYGON_TYPE | ARC_TYPE) #define SILK_TYPE \ (LINE_TYPE | ARC_TYPE | POLYGON_TYPE) bool LineLineIntersect (LineType *, LineType *); bool LineArcIntersect (LineType *, ArcType *); bool PinLineIntersect (PinType *, LineType *); bool LinePadIntersect (LineType *, PadType *); bool ArcPadIntersect (ArcType *, PadType *); void LookupElementConnections (ElementType *, FILE *); void LookupConnectionsToAllElements (FILE *); void LookupConnection (Coord, Coord, bool, Coord, int, bool AndRats); void LookupUnusedPins (FILE *); void InitConnectionLookup (void); void FreeConnectionLookupMemory (void); void RatFindHook (int, void *, void *, void *, bool, int flag, bool); void LookupConnectionByPin (int , void *); /* remove these prototypes later */ bool ListStart(int, void*, void*, void*, int); bool DoIt(int, Coord, bool, bool, bool); void DumpList(void); void start_do_it_and_dump(int, void*, void*, void*, int, bool, Coord, bool); bool IsArcInPolygon (ArcType *, PolygonType *); bool IsLineInPolygon (LineType *, PolygonType *); bool IsPadInPolygon (PadType *, PolygonType *); bool IsPinInPolygon (PinType *, PolygonType *); bool IsPolygonInPolygon (PolygonType *, PolygonType *); #endif pcb-4.3.0/src/polygon1.c0000664000175000017500000026754313773431044011737 00000000000000/*! * \file src/polygon1.c * * \brief Polygon clipping functions. * * harry eaton implemented the algorithm described in "A Closed Set of * Algorithms for Performing Set Operations on Polygonal Regions in the * Plane" which the original code did not do. * * I also modified it for integer coordinates and faster computation. * * The license for this modified copy was switched to the GPL per term * (3) of the original LGPL license. * *
* *

Copyright.

\n * * Copyright (C) 2006 harry eaton * * based on: * * poly_Boolean: a polygon clip library * * Copyright (C) 1997 Alexey Nikitin, Michael Leonov * * (also the authors of the paper describing the actual algorithm) * * leonov@propro.iis.nsk.su * * in turn based on: * * nclip: a polygon clip library * * Copyright (C) 1993 Klamer Schutte * * All cases where original (Klamer Schutte) code is present are marked. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *
* * \note How about expanding polygons so that edges can be arcs rather * than lines.\n * Consider using the third coordinate to store the radius of the arc.\n * The arc would pass through the vertex points.\n * Positive radius would indicate the arc bows left (center on right of * P1-P2 path).\n * Negative radius would put the center on the other side.\n * 0 radius would mean the edge is a line instead of arc.\n * The intersections of the two circles centered at the vertex points * would determine the two possible arc centers.\n * If P2.x > P1.x then the center with smaller Y is selected for * positive r.\n * If P2.y > P1.y then the center with greate X is selected for * positive r.\n * The vec_inters2() routine would then need to handle line-line * line-arc and arc-arc intersections.\n * Perhaps reverse tracing the arc would require look-ahead to check * for arcs */ #include #include #include #include #include #include #include "global.h" #include "pcb-printf.h" #include "rtree.h" #include "heap.h" #define ROUND(a) (long)((a) > 0 ? ((a) + 0.5) : ((a) - 0.5)) #define EPSILON (1E-8) #define IsZero(a, b) (fabs((a) - (b)) < EPSILON) /* L o n g V e c t o r S t u f f */ #define Vcopy(a,b) {(a)[0]=(b)[0];(a)[1]=(b)[1];} int vect_equal (Vector v1, Vector v2); void vect_init (Vector v, double x, double y); void vect_sub (Vector res, Vector v2, Vector v3); void vect_min (Vector res, Vector v2, Vector v3); void vect_max (Vector res, Vector v2, Vector v3); double vect_dist2 (Vector v1, Vector v2); double vect_det2 (Vector v1, Vector v2); double vect_len2 (Vector v1); int vect_inters2 (Vector A, Vector B, Vector C, Vector D, Vector S1, Vector S2); /* note that a vertex v's Flags.status represents the edge defined by * v to v->next (i.e. the edge is forward of v) */ #define ISECTED 3 #define UNKNWN 0 #define INSIDE 1 #define OUTSIDE 2 #define SHARED 3 #define SHARED2 4 #define TOUCHES 99 #define NODE_LABEL(n) ((n)->Flags.status) #define LABEL_NODE(n,l) ((n)->Flags.status = (l)) #define error(code) longjmp(*(e), code) #define MemGet(ptr, type) \ if (UNLIKELY (((ptr) = (type *)malloc(sizeof(type))) == NULL)) \ error(err_no_memory); #undef DEBUG_LABEL #undef DEBUG_ALL_LABELS #undef DEBUG_JUMP #undef DEBUG_GATHER #undef DEBUG_ANGLE #undef DEBUG #ifdef DEBUG #define DEBUGP(...) pcb_fprintf(stderr, ## __VA_ARGS__) #else #define DEBUGP(...) #endif /* 2-Dimentional stuff */ #define Vsub2(r,a,b) {(r)[0] = (a)[0] - (b)[0]; (r)[1] = (a)[1] - (b)[1];} #define Vadd2(r,a,b) {(r)[0] = (a)[0] + (b)[0]; (r)[1] = (a)[1] + (b)[1];} #define Vsca2(r,a,s) {(r)[0] = (a)[0] * (s); (r)[1] = (a)[1] * (s);} #define Vcpy2(r,a) {(r)[0] = (a)[0]; (r)[1] = (a)[1];} #define Vequ2(a,b) ((a)[0] == (b)[0] && (a)[1] == (b)[1]) #define Vadds(r,a,b,s) {(r)[0] = ((a)[0] + (b)[0]) * (s); (r)[1] = ((a)[1] + (b)[1]) * (s);} #define Vswp2(a,b) { long t; \ t = (a)[0], (a)[0] = (b)[0], (b)[0] = t; \ t = (a)[1], (a)[1] = (b)[1], (b)[1] = t; \ } #ifdef DEBUG static char *theState (VNODE * v); static void pline_dump (VNODE * v) { VNODE *s, *n; s = v; do { n = v->next; pcb_fprintf (stderr, "Line [%#mS %#mS %#mS %#mS 10 10 \"%s\"]\n", v->point[0], v->point[1], n->point[0], n->point[1], theState (v)); } while ((v = v->next) != s); } static void poly_dump (POLYAREA * p) { POLYAREA *f = p; PLINE *pl; do { pl = p->contours; do { pline_dump (&pl->head); fprintf (stderr, "NEXT PLINE\n"); } while ((pl = pl->next) != NULL); fprintf (stderr, "NEXT POLY\n"); } while ((p = p->f) != f); } #endif /* routines for processing intersections */ /*! * \brief node_add. * * (C) 1993 Klamer Schutte. * * (C) 1997 Alexey Nikitin, Michael Leonov. * * (C) 2006 harry eaton. * * \return a bit field in new_point that indicates where the point was. * 1 means a new node was created and inserted. * 4 means the intersection was not on the dest point. */ static VNODE * node_add_single (VNODE * dest, Vector po) { VNODE *p; /* If the new point is one of the segment end points, we don't need to * create a new node. */ if (vect_equal (po, dest->point)) return dest; if (vect_equal (po, dest->next->point)) return dest->next; /* Create a new one. */ p = poly_CreateNode (po); if (p == NULL) return NULL; /* couldn't allocate memory */ p->cvc_prev = p->cvc_next = NULL; p->Flags.status = UNKNWN; return p; } /* node_add */ #define ISECT_BAD_PARAM (-1) #define ISECT_NO_MEMORY (-2) /*! * \brief new_descriptor. * * (C) 2006 harry eaton. */ static CVCList * new_descriptor (VNODE * a, char poly, char side) { CVCList *l = (CVCList *) malloc (sizeof (CVCList)); Vector v; register double ang, dx, dy; if (!l) return NULL; l->head = NULL; l->parent = a; l->poly = poly; l->side = side; l->next = l->prev = l; if (side == 'P') /* previous */ vect_sub (v, a->prev->point, a->point); else /* next */ vect_sub (v, a->next->point, a->point); /* Uses slope/(slope+1) in quadrant 1 as a proxy for the angle. * It still has the same monotonic sort result * and is far less expensive to compute than the real angle. */ if (vect_equal (v, vect_zero)) { if (side == 'P') { if (a->prev->cvc_prev == (CVCList *) - 1) a->prev->cvc_prev = a->prev->cvc_next = NULL; poly_ExclVertex (a->prev); vect_sub (v, a->prev->point, a->point); } else { if (a->next->cvc_prev == (CVCList *) - 1) a->next->cvc_prev = a->next->cvc_next = NULL; poly_ExclVertex (a->next); vect_sub (v, a->next->point, a->point); } } assert (!vect_equal (v, vect_zero)); dx = fabs ((double) v[0]); dy = fabs ((double) v[1]); ang = dy / (dy + dx); /* now move to the actual quadrant */ if (v[0] < 0 && v[1] >= 0) ang = 2.0 - ang; /* 2nd quadrant */ else if (v[0] < 0 && v[1] < 0) ang += 2.0; /* 3rd quadrant */ else if (v[0] >= 0 && v[1] < 0) ang = 4.0 - ang; /* 4th quadrant */ l->angle = ang; assert (ang >= 0.0 && ang <= 4.0); #ifdef DEBUG_ANGLE DEBUGP ("node on %c at %#mD assigned angle %g on side %c\n", poly, a->point[0], a->point[1], ang, side); #endif return l; } /*! * \brief insert_descriptor. * * (C) 2006 harry eaton. * * \param a is a cross-vertex node. * \param poly is the polygon it comes from ('A' or 'B'). * \param side is the side this descriptor goes on ('P' for * previous 'N' for next). * \param start is the head of the list of cvclists. */ static CVCList * insert_descriptor (VNODE * a, char poly, char side, CVCList * start) { CVCList *l, *newone, *big, *small; if (!(newone = new_descriptor (a, poly, side))) return NULL; /* search for the CVCList for this point */ if (!start) { start = newone; /* return is also new, so we know where start is */ start->head = newone; /* circular list */ return newone; } else { l = start; do { assert (l->head); if (l->parent->point[0] == a->point[0] && l->parent->point[1] == a->point[1]) { /* this CVCList is at our point */ start = l; newone->head = l->head; break; } if (l->head->parent->point[0] == start->parent->point[0] && l->head->parent->point[1] == start->parent->point[1]) { /* this seems to be a new point */ /* link this cvclist to the list of all cvclists */ for (; l->head != newone; l = l->next) l->head = newone; newone->head = start; return newone; } l = l->head; } while (1); } assert (start); l = big = small = start; do { if (l->next->angle < l->angle) /* find start/end of list */ { small = l->next; big = l; } else if (newone->angle >= l->angle && newone->angle <= l->next->angle) { /* insert new cvc if it lies between existing points */ newone->prev = l; newone->next = l->next; l->next = l->next->prev = newone; return newone; } } while ((l = l->next) != start); /* didn't find it between points, it must go on an end */ if (big->angle <= newone->angle) { newone->prev = big; newone->next = big->next; big->next = big->next->prev = newone; return newone; } assert (small->angle >= newone->angle); newone->next = small; newone->prev = small->prev; small->prev = small->prev->next = newone; return newone; } /*! * \brief node_add_point. * * (C) 1993 Klamer Schutte. * * (C) 1997 Alexey Nikitin, Michael Leonov. * * \return 1 if new node in b, 2 if new node in a and 3 if new node in * both. */ static VNODE * node_add_single_point (VNODE * a, Vector p) { VNODE *next_a, *new_node; next_a = a->next; /* create a new VNODE. We get one of the existing VNODEs returned if p * points to a or a->next */ new_node = node_add_single (a, p); assert (new_node != NULL); /* presumably -1 is used to indicate "uninitialized" */ new_node->cvc_prev = new_node->cvc_next = (CVCList *) - 1; /* we might have gotten one of our existing nodes back, in which case we * didn't create anything. */ if (new_node == a || new_node == next_a) return NULL; return new_node; } /* node_add_point */ /*! * \brief node_label. * * (C) 2006 harry eaton. */ static unsigned int node_label (VNODE * pn) { CVCList *first_l, *l; char this_poly; int region = UNKNWN; assert (pn); assert (pn->cvc_next); this_poly = pn->cvc_next->poly; /* search counter-clockwise in the cross vertex connectivity (CVC) list * * check for shared edges (that could be prev or next in the list since the angles are equal) * and check if this edge (pn -> pn->next) is found between the other poly's entry and exit */ if (pn->cvc_next->angle == pn->cvc_next->prev->angle) l = pn->cvc_next->prev; else l = pn->cvc_next->next; first_l = l; while ((l->poly == this_poly) && (l != first_l->prev)) l = l->next; assert (l->poly != this_poly); assert (l && l->angle >= 0 && l->angle <= 4.0); if (l->poly != this_poly) { if (l->side == 'P') { if (l->parent->prev->point[0] == pn->next->point[0] && l->parent->prev->point[1] == pn->next->point[1]) { region = SHARED2; pn->shared = l->parent->prev; } else region = INSIDE; } else { if (l->angle == pn->cvc_next->angle) { assert (l->parent->next->point[0] == pn->next->point[0] && l->parent->next->point[1] == pn->next->point[1]); region = SHARED; pn->shared = l->parent; } else region = OUTSIDE; } } if (region == UNKNWN) { for (l = l->next; l != pn->cvc_next; l = l->next) { if (l->poly != this_poly) { if (l->side == 'P') region = INSIDE; else region = OUTSIDE; break; } } } assert (region != UNKNWN); assert (NODE_LABEL (pn) == UNKNWN || NODE_LABEL (pn) == region); LABEL_NODE (pn, region); if (region == SHARED || region == SHARED2) return UNKNWN; return region; } /* node_label */ /*! * \brief add_descriptors. * * (C) 2006 harry eaton. */ static CVCList * add_descriptors (PLINE * pl, char poly, CVCList * list) { VNODE *node = &pl->head; do { if (node->cvc_prev) { assert (node->cvc_prev == (CVCList *) - 1 && node->cvc_next == (CVCList *) - 1); list = node->cvc_prev = insert_descriptor (node, poly, 'P', list); if (!node->cvc_prev) return NULL; list = node->cvc_next = insert_descriptor (node, poly, 'N', list); if (!node->cvc_next) return NULL; } } while ((node = node->next) != &pl->head); return list; } static inline void cntrbox_adjust (PLINE * c, Vector p) { c->xmin = min (c->xmin, p[0]); c->xmax = max (c->xmax, p[0] + 1); c->ymin = min (c->ymin, p[1]); c->ymax = max (c->ymax, p[1] + 1); } /* some structures for handling segment intersections using the rtrees */ typedef struct seg { BoxType box; VNODE *v; PLINE *p; int intersected; } seg; typedef struct _insert_node_task insert_node_task; struct _insert_node_task { insert_node_task *next; seg * node_seg; VNODE *new_node; }; typedef struct info { double m, b; rtree_t *tree; VNODE *v; struct seg *s; jmp_buf *env, sego, *touch; int need_restart; insert_node_task *node_insert_list; } info; typedef struct contour_info { PLINE *pa; jmp_buf restart; jmp_buf *getout; int need_restart; insert_node_task *node_insert_list; } contour_info; /*! * \brief adjust_tree(). * * (C) 2006 harry eaton. * * This replaces the segment in the tree with the two new segments after * a vertex has been added. */ static int adjust_tree (rtree_t * tree, struct seg *s) { struct seg *q; q = (seg *)malloc (sizeof (struct seg)); if (!q) return 1; q->intersected = 0; q->v = s->v; q->p = s->p; q->box.X1 = min (q->v->point[0], q->v->next->point[0]); q->box.X2 = max (q->v->point[0], q->v->next->point[0]) + 1; q->box.Y1 = min (q->v->point[1], q->v->next->point[1]); q->box.Y2 = max (q->v->point[1], q->v->next->point[1]) + 1; r_insert_entry (tree, (const BoxType *) q, 1); q = (seg *)malloc (sizeof (struct seg)); if (!q) return 1; q->intersected = 0; q->v = s->v->next; q->p = s->p; q->box.X1 = min (q->v->point[0], q->v->next->point[0]); q->box.X2 = max (q->v->point[0], q->v->next->point[0]) + 1; q->box.Y1 = min (q->v->point[1], q->v->next->point[1]); q->box.Y2 = max (q->v->point[1], q->v->next->point[1]) + 1; r_insert_entry (tree, (const BoxType *) q, 1); r_delete_entry (tree, (const BoxType *) s); return 0; } /*! * \brief seg_in_region(). * * (C) 2006, harry eaton. * * This prunes the search for boxes that don't intersect the segment. */ static int seg_in_region (const BoxType * b, void *cl) { struct info *i = (struct info *) cl; double y1, y2; /* for zero slope the search is aligned on the axis so it is already pruned */ if (i->m == 0.) return 1; /* Earlier we computed the parameters of the line on which our search * segment falls. Here, we compute the y coordinates of that line for the * extreme X values of the overlapping box we found with the r_search. * If there isn't some overlap, the segments can't overlap, and we can * skip this segment. * * This is equivalent to enforcing that the bounding box of the found * segment overlaps with the original segment. The r_search only tells * us that the bounding boxes of the two segments overlap, so, this applies * a more restrictive condition. * */ y1 = i->m * b->X1 + i->b; y2 = i->m * b->X2 + i->b; if (min (y1, y2) >= b->Y2) return 0; if (max (y1, y2) < b->Y1) return 0; return 1; /* might intersect */ } /*! * \brief Prepend a deferred node-insersion task to a list. */ static insert_node_task * prepend_insert_node_task (insert_node_task *list, seg *seg, VNODE *new_node) { insert_node_task *task = (insert_node_task *)malloc (sizeof (*task)); task->node_seg = seg; task->new_node = new_node; task->next = list; return task; } /*! * \brief seg_in_seg(). * * (C) 2006 harry eaton. * * This routine checks if the segment in the tree intersect the search * segment. * If it does, the plines are marked as intersected and the point is * marked for the cvclist. * If the point is not already a vertex, a new vertex is inserted and * the search for intersections starts over at the beginning. * That is potentially a significant time penalty, but it does solve the * snap rounding problem. * * \todo There are efficient algorithms for finding intersections with * snap rounding, but I don't have time to implement them right now. */ static int seg_in_seg (const BoxType * b, void *cl) { struct info *i = (struct info *) cl; struct seg *s = (struct seg *) b; Vector s1, s2; int cnt; VNODE *new_node; /* When new nodes are added at the end of a pass due to an intersection * the segments may be altered. If either segment we're looking at has * already been intersected this pass, skip it until the next pass. */ if (s->intersected || i->s->intersected) return 0; /* returns the number of intersecting points, 0, 1, or 2... I think. */ /* While it *looks* like s1 and s2 are used uninitialized here, they're actually * pointers because the Vector type is a Coord[2]. We get the intersection points * returned in these variables. */ cnt = vect_inters2 (s->v->point, s->v->next->point, i->v->point, i->v->next->point, s1, s2); if (!cnt) return 0; /* We found an intersection. */ if (i->touch) /* if checking touches one find and we're done */ longjmp (*i->touch, TOUCHES); /* Mark the segments are intersecting. */ i->s->p->Flags.status = ISECTED; s->p->Flags.status = ISECTED; for (; cnt; cnt--) /* for each intersection... */ { bool done_insert_on_i = false; /* create a new node at the intersection point. */ new_node = node_add_single_point (i->v, cnt > 1 ? s2 : s1); /* new_node could be NULL if the new point is at one of the segment * endpoints */ if (new_node != NULL) { #ifdef DEBUG_INTERSECT DEBUGP ("new intersection on segment \"i\" at %#mD\n", cnt > 1 ? s2[0] : s1[0], cnt > 1 ? s2[1] : s1[1]); #endif /* We created a node, but it's not yet associated with any contour. * We'll do that later. This list keeps track of the nodes we need to * add. * */ i->node_insert_list = prepend_insert_node_task (i->node_insert_list, i->s, new_node); i->s->intersected = 1; done_insert_on_i = true; } /* Now create one associated with the other segment.*/ new_node = node_add_single_point (s->v, cnt > 1 ? s2 : s1); if (new_node != NULL) { #ifdef DEBUG_INTERSECT DEBUGP ("new intersection on segment \"s\" at %#mD\n", cnt > 1 ? s2[0] : s1[0], cnt > 1 ? s2[1] : s1[1]); #endif i->node_insert_list = prepend_insert_node_task (i->node_insert_list, s, new_node); s->intersected = 1; return 0; /* Keep looking for intersections with segment "i" */ } /* Skip any remaining r_search hits against segment i, as any futher * intersections will be rejected until the next pass anyway. */ if (done_insert_on_i) longjmp (*i->env, 1); } return 0; } /*! * \brief Generate an r-tree structure for the edges of a PLINE contour. * */ static void * make_edge_tree (PLINE * pb) { struct seg *s; VNODE *bv; rtree_t *ans = r_create_tree (NULL, 0, 0); bv = &pb->head; do { s = (seg *)malloc (sizeof (struct seg)); s->intersected = 0; /* Generate a bounding box for the current segment */ if (bv->point[0] < bv->next->point[0]) { s->box.X1 = bv->point[0]; s->box.X2 = bv->next->point[0] + 1; } else { s->box.X2 = bv->point[0] + 1; s->box.X1 = bv->next->point[0]; } if (bv->point[1] < bv->next->point[1]) { s->box.Y1 = bv->point[1]; s->box.Y2 = bv->next->point[1] + 1; } else { s->box.Y2 = bv->point[1] + 1; s->box.Y1 = bv->next->point[1]; } /* Add references to the current point, and the parent contour. We * only need the current point because the segment will always be * defined as being between this point and the next point in the * chain. * */ s->v = bv; s->p = pb; /* Add the segment to the rtree. */ r_insert_entry (ans, (const BoxType *) s, 1); } /* Move to the next point in the contour. */ while ((bv = bv->next) != &pb->head); return (void *) ans; } static int get_seg (const BoxType * b, void *cl) { struct info *i = (struct info *) cl; struct seg *s = (struct seg *) b; if (i->v == s->v) { i->s = s; longjmp (i->sego, 1); } return 0; } /*! * \brief intersect() (and helpers). * * (C) 2006, harry eaton. * * This uses an rtree to find A-B intersections. * Whenever a new vertex is added, the search for intersections is * re-started because the rounding could alter the topology otherwise. * This should use a faster algorithm for snap rounding intersection * finding. * The best algorthim is probably found in: * * "Improved output-sensitive snap rounding," John Hershberger, * Proceedings of the 22nd annual symposium on Computational geomerty, * 2006, pp 357-366. * * http://doi.acm.org/10.1145/1137856.1137909 * * Algorithms described by de Berg, or Goodrich or Halperin, or Hobby * would probably work as well. */ static int contour_bounds_touch (const BoxType * b, void *cl) { contour_info *c_info = (contour_info *) cl; PLINE *pa = c_info->pa; PLINE *pb = (PLINE *) b; PLINE *rtree_over; PLINE *looping_over; VNODE *av; /* node iterators */ struct info info; BoxType box; jmp_buf restart; /* If we're here, it means that we have found that the bounding boxes of * two different contours overlap. Our goal now is to determine if any of * the segments of those contours intersect. */ /* Have seg_in_seg return to our desired location if it touches */ info.env = &restart; info.touch = c_info->getout; info.need_restart = 0; info.node_insert_list = c_info->node_insert_list; /* Pick which contour has the fewer points, and do the loop * over that. The r_tree makes hit-testing against a contour * faster, so we want to do that on the bigger contour. */ if (pa->Count < pb->Count) { rtree_over = pb; looping_over = pa; } else { rtree_over = pa; looping_over = pb; } av = &looping_over->head; /* First VNODE of a contour */ do /* Loop over the nodes in the smaller contour */ { /* check this edge for any insertions */ double dx; info.v = av; /* compute the slant for region trimming */ dx = av->next->point[0] - av->point[0]; if (dx == 0) /* line is vertical */ info.m = 0; else { /* compute the parameters of the line this segment falls on*/ info.m = (av->next->point[1] - av->point[1]) / dx; info.b = av->point[1] - info.m * av->point[0]; } /* This search box is 1 nm x 1 nm at the location of our VNODE */ box.X2 = (box.X1 = av->point[0]) + 1; box.Y2 = (box.Y1 = av->point[1]) + 1; /* fill in the segment in info corresponding to this node */ if (setjmp (info.sego) == 0) { /* we put seg structs into the rtree, we want to find our struct * for this VNODE. Once we find it, it gets stored in info.s and * we longjmp back here and continue. * */ r_search (looping_over->tree, &box, NULL, get_seg, &info); assert (0); } /* If we're going to have another pass anyway, skip this */ if (info.s->intersected && info.node_insert_list != NULL) continue; if (setjmp (restart)) continue; /* NB: If this actually hits anything, we are teleported back to the beginning */ info.tree = rtree_over->tree; if (info.tree) if (UNLIKELY (r_search (info.tree, &info.s->box, seg_in_region, seg_in_seg, &info))) assert (0); /* XXX: Memory allocation failure */ } while ((av = av->next) != &looping_over->head); c_info->node_insert_list = info.node_insert_list; if (info.need_restart) c_info->need_restart = 1; return 0; } /*! * \brief Determine if two polyareas touch each other * */ static int intersect_impl (jmp_buf * jb, POLYAREA * b, POLYAREA * a, int add) { POLYAREA *t; PLINE *pa; contour_info c_info; int need_restart = 0; insert_node_task *task; c_info.need_restart = 0; c_info.node_insert_list = NULL; /* Search the r-tree of the object with most contours * We loop over the contours of "a". Swap if necessary. */ if (a->contour_tree->size > b->contour_tree->size) { t = b; b = a; a = t; } /* Loop over the contours of POLYAREA "a" */ for (pa = a->contours; pa; pa = pa->next) { BoxType sb; /* search box */ jmp_buf out; int retval; c_info.getout = NULL; c_info.pa = pa; if (!add) { retval = setjmp (out); if (retval) { /* The intersection test short-circuited back here, * we need to clean up, then longjmp to jb */ longjmp (*jb, retval); } c_info.getout = &out; } sb.X1 = pa->xmin; sb.Y1 = pa->ymin; sb.X2 = pa->xmax + 1; sb.Y2 = pa->ymax + 1; /* search the contours of b for a bounding box that overlaps with this * contour of a's bounding box. * */ r_search (b->contour_tree, &sb, NULL, contour_bounds_touch, &c_info); if (c_info.need_restart) need_restart = 1; } /* Process any deferred node insersions */ task = c_info.node_insert_list; while (task != NULL) { insert_node_task *next = task->next; /* Do insersion */ task->new_node->prev = task->node_seg->v; task->new_node->next = task->node_seg->v->next; task->node_seg->v->next->prev = task->new_node; task->node_seg->v->next = task->new_node; task->node_seg->p->Count++; cntrbox_adjust (task->node_seg->p, task->new_node->point); if (adjust_tree (task->node_seg->p->tree, task->node_seg)) assert (0); /* XXX: Memory allocation failure */ need_restart = 1; /* Any new nodes could intersect */ free (task); task = next; } return need_restart; } static int intersect (jmp_buf * jb, POLYAREA * b, POLYAREA * a, int add) { int call_count = 1; while (intersect_impl (jb, b, a, add)) call_count++; return 0; } static void M_POLYAREA_intersect (jmp_buf * e, POLYAREA * afst, POLYAREA * bfst, int add) { POLYAREA *a = afst, *b = bfst; PLINE *curcA, *curcB; CVCList *the_list = NULL; if (a == NULL || b == NULL) error (err_bad_parm); do { do { /* If the bounding box of A intersects bounding box of B */ if (a->contours->xmax >= b->contours->xmin && a->contours->ymax >= b->contours->ymin && a->contours->xmin <= b->contours->xmax && a->contours->ymin <= b->contours->ymax) { /* BBs intersect */ if (UNLIKELY (intersect (e, a, b, add))) error (err_no_memory); } } while (add && (a = a->f) != afst); for (curcB = b->contours; curcB != NULL; curcB = curcB->next) if (curcB->Flags.status == ISECTED) { the_list = add_descriptors (curcB, 'B', the_list); if (UNLIKELY (the_list == NULL)) error (err_no_memory); } } while (add && (b = b->f) != bfst); do { for (curcA = a->contours; curcA != NULL; curcA = curcA->next) if (curcA->Flags.status == ISECTED) { the_list = add_descriptors (curcA, 'A', the_list); if (UNLIKELY (the_list == NULL)) error (err_no_memory); } } while (add && (a = a->f) != afst); } /* M_POLYAREA_intersect */ static inline int cntrbox_inside (PLINE * c1, PLINE * c2) { assert (c1 != NULL && c2 != NULL); return ((c1->xmin >= c2->xmin) && (c1->ymin >= c2->ymin) && (c1->xmax <= c2->xmax) && (c1->ymax <= c2->ymax)); } /* Routines for making labels */ static int count_contours_i_am_inside (const BoxType * b, void *cl) { PLINE *me = (PLINE *) cl; PLINE *check = (PLINE *) b; if (poly_ContourInContour (check, me)) return 1; return 0; } /*! * \brief cntr_in_M_POLYAREA. * * \return poly is inside outfst ? TRUE : FALSE. */ static int cntr_in_M_POLYAREA (PLINE * poly, POLYAREA * outfst, BOOLp test) { POLYAREA *outer = outfst; heap_t *heap; assert (poly != NULL); assert (outer != NULL); heap = heap_create (); do { if (cntrbox_inside (poly, outer->contours)) heap_insert (heap, outer->contours->area, (void *) outer); } /* if checking touching, use only the first polygon */ while (!test && (outer = outer->f) != outfst); /* we need only check the smallest poly container * but we must loop in case the box containter is not * the poly container */ do { if (heap_is_empty (heap)) break; outer = (POLYAREA *) heap_remove_smallest (heap); switch (r_search (outer->contour_tree, (BoxType *) poly, NULL, count_contours_i_am_inside, poly)) { case 0: /* Didn't find anything in this piece, Keep looking */ break; case 1: /* Found we are inside this piece, and not any of its holes */ heap_destroy (&heap); return TRUE; case 2: /* Found inside a hole in the smallest polygon so far. No need to check the other polygons */ heap_destroy (&heap); return FALSE; default: printf ("Something strange here\n"); break; } } while (1); heap_destroy (&heap); return FALSE; } /* cntr_in_M_POLYAREA */ #ifdef DEBUG static char * theState (VNODE * v) { static char u[] = "UNKNOWN"; static char i[] = "INSIDE"; static char o[] = "OUTSIDE"; static char s[] = "SHARED"; static char s2[] = "SHARED2"; switch (NODE_LABEL (v)) { case INSIDE: return i; case OUTSIDE: return o; case SHARED: return s; case SHARED2: return s2; default: return u; } } #ifdef DEBUG_ALL_LABELS static void print_labels (PLINE * a) { VNODE *c = &a->head; do { DEBUGP ("%#mD->%#mD labeled %s\n", c->point[0], c->point[1], c->next->point[0], c->next->point[1], theState (c)); } while ((c = c->next) != &a->head); } #endif #endif /*! * \brief label_contour. * * (C) 2006 harry eaton. * * (C) 1993 Klamer Schutte. * * (C) 1997 Alexey Nikitin, Michael Leonov. */ static BOOLp label_contour (PLINE * a) { VNODE *cur = &a->head; VNODE *first_labelled = NULL; int label = UNKNWN; do { if (cur->cvc_next) /* examine cross vertex */ { label = node_label (cur); if (first_labelled == NULL) first_labelled = cur; continue; } if (first_labelled == NULL) continue; /* This labels nodes which aren't cross-connected */ assert (label == INSIDE || label == OUTSIDE); LABEL_NODE (cur, label); } while ((cur = cur->next) != first_labelled); #ifdef DEBUG_ALL_LABELS print_labels (a); DEBUGP ("\n\n"); #endif return FALSE; } /* label_contour */ static BOOLp cntr_label_POLYAREA (PLINE * poly, POLYAREA * ppl, BOOLp test) { assert (ppl != NULL && ppl->contours != NULL); if (poly->Flags.status == ISECTED) { label_contour (poly); /* should never get here when BOOLp is true */ } else if (cntr_in_M_POLYAREA (poly, ppl, test)) { if (test) return TRUE; poly->Flags.status = INSIDE; } else { if (test) return false; poly->Flags.status = OUTSIDE; } return FALSE; } /* cntr_label_POLYAREA */ static BOOLp M_POLYAREA_label_separated (PLINE * afst, POLYAREA * b, BOOLp touch) { PLINE *curc = afst; for (curc = afst; curc != NULL; curc = curc->next) { if (cntr_label_POLYAREA (curc, b, touch) && touch) return TRUE; } return FALSE; } static BOOLp M_POLYAREA_label (POLYAREA * afst, POLYAREA * b, BOOLp touch) { POLYAREA *a = afst; PLINE *curc; assert (a != NULL); do { for (curc = a->contours; curc != NULL; curc = curc->next) if (cntr_label_POLYAREA (curc, b, touch)) { if (touch) return TRUE; } } while (!touch && (a = a->f) != afst); return FALSE; } /*! * \brief Routines for temporary storing resulting contours. */ static void InsCntr (jmp_buf * e, PLINE * c, POLYAREA ** dst) { POLYAREA *newp; if (*dst == NULL) { MemGet (*dst, POLYAREA); (*dst)->f = (*dst)->b = *dst; newp = *dst; } else { MemGet (newp, POLYAREA); newp->f = *dst; newp->b = (*dst)->b; newp->f->b = newp->b->f = newp; } newp->contours = c; newp->contour_tree = r_create_tree (NULL, 0, 0); r_insert_entry (newp->contour_tree, (BoxType *) c, 0); c->next = NULL; } /* InsCntr */ static void PutContour (jmp_buf * e, PLINE * cntr, POLYAREA ** contours, PLINE ** holes, POLYAREA * owner, POLYAREA * parent, PLINE * parent_contour) { assert (cntr != NULL); assert (cntr->Count > 2); cntr->next = NULL; if (cntr->Flags.orient == PLF_DIR) { if (owner != NULL) r_delete_entry (owner->contour_tree, (BoxType *) cntr); InsCntr (e, cntr, contours); } /* put hole into temporary list */ else { /* if we know this belongs inside the parent, put it there now */ if (parent_contour) { cntr->next = parent_contour->next; parent_contour->next = cntr; if (owner != parent) { if (owner != NULL) r_delete_entry (owner->contour_tree, (BoxType *) cntr); r_insert_entry (parent->contour_tree, (BoxType *) cntr, 0); } } else { cntr->next = *holes; *holes = cntr; /* let cntr be 1st hole in list */ /* We don't insert the holes into an r-tree, * they just form a linked list */ if (owner != NULL) r_delete_entry (owner->contour_tree, (BoxType *) cntr); } } } /* PutContour */ static inline void remove_contour (POLYAREA * piece, PLINE * prev_contour, PLINE * contour, int remove_rtree_entry) { if (piece->contours == contour) piece->contours = contour->next; else if (prev_contour != NULL) { assert (prev_contour->next == contour); prev_contour->next = contour->next; } contour->next = NULL; if (remove_rtree_entry) r_delete_entry (piece->contour_tree, (BoxType *) contour); } struct polyarea_info { BoxType BoundingBox; POLYAREA *pa; }; static int heap_it (const BoxType * b, void *cl) { heap_t *heap = (heap_t *) cl; struct polyarea_info *pa_info = (struct polyarea_info *) b; PLINE *p = pa_info->pa->contours; if (p->Count == 0) return 0; /* how did this happen? */ heap_insert (heap, p->area, pa_info); return 1; } struct find_inside_info { jmp_buf jb; PLINE *want_inside; PLINE *result; }; static int find_inside (const BoxType * b, void *cl) { struct find_inside_info *info = (struct find_inside_info *) cl; PLINE *check = (PLINE *) b; /* Do test on check to see if it inside info->want_inside */ /* If it is: */ if (check->Flags.orient == PLF_DIR) { return 0; } if (poly_ContourInContour (info->want_inside, check)) { info->result = check; longjmp (info->jb, 1); } return 0; } static void InsertHoles (jmp_buf * e, POLYAREA * dest, PLINE ** src) { POLYAREA *curc; PLINE *curh, *container; heap_t *heap; rtree_t *tree; int i; int num_polyareas = 0; struct polyarea_info *all_pa_info, *pa_info; if (*src == NULL) return; /* empty hole list */ if (dest == NULL) error (err_bad_parm); /* empty contour list */ /* Count dest polyareas */ curc = dest; do { num_polyareas++; } while ((curc = curc->f) != dest); /* make a polyarea info table */ /* make an rtree of polyarea info table */ all_pa_info = (struct polyarea_info *) malloc (sizeof (struct polyarea_info) * num_polyareas); tree = r_create_tree (NULL, 0, 0); i = 0; curc = dest; do { all_pa_info[i].BoundingBox.X1 = curc->contours->xmin; all_pa_info[i].BoundingBox.Y1 = curc->contours->ymin; all_pa_info[i].BoundingBox.X2 = curc->contours->xmax; all_pa_info[i].BoundingBox.Y2 = curc->contours->ymax; all_pa_info[i].pa = curc; r_insert_entry (tree, (const BoxType *) &all_pa_info[i], 0); i++; } while ((curc = curc->f) != dest); /* loop through the holes and put them where they belong */ while ((curh = *src) != NULL) { *src = curh->next; container = NULL; /* build a heap of all of the polys that the hole is inside its bounding box */ heap = heap_create (); r_search (tree, (BoxType *) curh, NULL, heap_it, heap); if (heap_is_empty (heap)) { #ifndef NDEBUG #ifdef DEBUG poly_dump (dest); #endif #endif poly_DelContour (&curh); error (err_bad_parm); } /* Now search the heap for the container. If there was only one item * in the heap, assume it is the container without the expense of * proving it. */ pa_info = (struct polyarea_info *) heap_remove_smallest (heap); if (heap_is_empty (heap)) { /* only one possibility it must be the right one */ assert (poly_ContourInContour (pa_info->pa->contours, curh)); container = pa_info->pa->contours; } else { do { if (poly_ContourInContour (pa_info->pa->contours, curh)) { container = pa_info->pa->contours; break; } if (heap_is_empty (heap)) break; pa_info = (struct polyarea_info *) heap_remove_smallest (heap); } while (1); } heap_destroy (&heap); if (container == NULL) { /* bad input polygons were given */ #ifndef NDEBUG #ifdef DEBUG poly_dump (dest); #endif #endif curh->next = NULL; poly_DelContour (&curh); error (err_bad_parm); } else { /* Need to check if this new hole means we need to kick out any old ones for reprocessing */ while (1) { struct find_inside_info info; PLINE *prev; info.want_inside = curh; /* Set jump return */ if (setjmp (info.jb)) { /* Returned here! */ } else { info.result = NULL; /* Rtree search, calling back a routine to longjmp back with data about any hole inside the added one */ /* Be sure not to bother jumping back to report the main contour! */ r_search (pa_info->pa->contour_tree, (BoxType *) curh, NULL, find_inside, &info); /* Nothing found? */ break; } /* We need to find the contour before it, so we can update its next pointer */ prev = container; while (prev->next != info.result) { prev = prev->next; } /* Remove hole from the contour */ remove_contour (pa_info->pa, prev, info.result, TRUE); /* Add hole as the next on the list to be processed in this very function */ info.result->next = *src; *src = info.result; } /* End check for kicked out holes */ /* link at front of hole list */ curh->next = container->next; container->next = curh; r_insert_entry (pa_info->pa->contour_tree, (BoxType *) curh, 0); } } r_destroy_tree (&tree); free (all_pa_info); } /* InsertHoles */ /* routines for collecting result */ typedef enum { FORW, BACKW } DIRECTION; /*! * \brief Start Rule. */ typedef int (*S_Rule) (VNODE *, DIRECTION *); /*! * \brief Jump Rule. */ typedef int (*J_Rule) (char, VNODE *, DIRECTION *); static int UniteS_Rule (VNODE * cur, DIRECTION * initdir) { *initdir = FORW; return (NODE_LABEL (cur) == OUTSIDE) || (NODE_LABEL (cur) == SHARED); } static int IsectS_Rule (VNODE * cur, DIRECTION * initdir) { *initdir = FORW; return (NODE_LABEL (cur) == INSIDE) || (NODE_LABEL (cur) == SHARED); } static int SubS_Rule (VNODE * cur, DIRECTION * initdir) { *initdir = FORW; return (NODE_LABEL (cur) == OUTSIDE) || (NODE_LABEL (cur) == SHARED2); } static int XorS_Rule (VNODE * cur, DIRECTION * initdir) { if (cur->Flags.status == INSIDE) { *initdir = BACKW; return TRUE; } if (cur->Flags.status == OUTSIDE) { *initdir = FORW; return TRUE; } return FALSE; } static int IsectJ_Rule (char p, VNODE * v, DIRECTION * cdir) { assert (*cdir == FORW); return (v->Flags.status == INSIDE || v->Flags.status == SHARED); } static int UniteJ_Rule (char p, VNODE * v, DIRECTION * cdir) { assert (*cdir == FORW); return (v->Flags.status == OUTSIDE || v->Flags.status == SHARED); } static int XorJ_Rule (char p, VNODE * v, DIRECTION * cdir) { if (v->Flags.status == INSIDE) { *cdir = BACKW; return TRUE; } if (v->Flags.status == OUTSIDE) { *cdir = FORW; return TRUE; } return FALSE; } static int SubJ_Rule (char p, VNODE * v, DIRECTION * cdir) { if (p == 'B' && v->Flags.status == INSIDE) { *cdir = BACKW; return TRUE; } if (p == 'A' && v->Flags.status == OUTSIDE) { *cdir = FORW; return TRUE; } if (v->Flags.status == SHARED2) { if (p == 'A') *cdir = FORW; else *cdir = BACKW; return TRUE; } return FALSE; } /*! * \brief Return the edge that comes next. * * If the direction is BACKW, then we return the next vertex so that * prev vertex has the flags for the edge. * * \return true if an edge is found, false otherwise. */ static int jump (VNODE ** cur, DIRECTION * cdir, J_Rule rule) { CVCList *d, *start; VNODE *e; DIRECTION newone; if (!(*cur)->cvc_prev) /* not a cross-vertex */ { if (*cdir == FORW ? (*cur)->Flags.mark : (*cur)->prev->Flags.mark) return FALSE; return TRUE; } #ifdef DEBUG_JUMP DEBUGP ("jump entering node at %$mD\n", (*cur)->point[0], (*cur)->point[1]); #endif if (*cdir == FORW) d = (*cur)->cvc_prev->prev; else d = (*cur)->cvc_next->prev; start = d; do { e = d->parent; if (d->side == 'P') e = e->prev; newone = *cdir; if (!e->Flags.mark && rule (d->poly, e, &newone)) { if ((d->side == 'N' && newone == FORW) || (d->side == 'P' && newone == BACKW)) { #ifdef DEBUG_JUMP if (newone == FORW) DEBUGP ("jump leaving node at %#mD\n", e->next->point[0], e->next->point[1]); else DEBUGP ("jump leaving node at %#mD\n", e->point[0], e->point[1]); #endif *cur = d->parent; *cdir = newone; return TRUE; } } } while ((d = d->prev) != start); return FALSE; } static int Gather (VNODE * start, PLINE ** result, J_Rule v_rule, DIRECTION initdir) { VNODE *cur = start, *newn; DIRECTION dir = initdir; #ifdef DEBUG_GATHER DEBUGP ("gather direction = %d\n", dir); #endif assert (*result == NULL); do { /* see where to go next */ if (!jump (&cur, &dir, v_rule)) break; /* add edge to polygon */ if (!*result) { *result = poly_NewContour (cur->point); if (*result == NULL) return err_no_memory; } else { if ((newn = poly_CreateNode (cur->point)) == NULL) return err_no_memory; poly_InclVertex ((*result)->head.prev, newn); } #ifdef DEBUG_GATHER DEBUGP ("gather vertex at %#mD\n", cur->point[0], cur->point[1]); #endif /* Now mark the edge as included. */ newn = (dir == FORW ? cur : cur->prev); newn->Flags.mark = 1; /* for SHARED edge mark both */ if (newn->shared) newn->shared->Flags.mark = 1; /* Advance to the next edge. */ cur = (dir == FORW ? cur->next : cur->prev); } while (1); return err_ok; } /* Gather */ static void Collect1 (jmp_buf * e, VNODE * cur, DIRECTION dir, POLYAREA ** contours, PLINE ** holes, J_Rule j_rule) { PLINE *p = NULL; /* start making contour */ int errc = err_ok; if ((errc = Gather (cur, &p, j_rule, dir)) != err_ok) { if (p != NULL) poly_DelContour (&p); error (errc); } if (!p) return; poly_PreContour (p, TRUE); if (p->Count > 2) { #ifdef DEBUG_GATHER DEBUGP ("adding contour with %d verticies and direction %c\n", p->Count, p->Flags.orient ? 'F' : 'B'); #endif PutContour (e, p, contours, holes, NULL, NULL, NULL); } else { /* some sort of computation error ? */ #ifdef DEBUG_GATHER DEBUGP ("Bad contour! Not enough points!!\n"); #endif poly_DelContour (&p); } } static void Collect (jmp_buf * e, PLINE * a, POLYAREA ** contours, PLINE ** holes, S_Rule s_rule, J_Rule j_rule) { VNODE *cur, *other; DIRECTION dir; cur = &a->head; do { dir = FORW; /* avoid uninitialized variable with XOR rule (side note: XOR not used in PCB anyway) */ if (s_rule (cur, &dir) && cur->Flags.mark == 0) Collect1 (e, dir == FORW ? cur : cur->next, dir, contours, holes, j_rule); /* Note: when the direction is not FORW, move to the vertex, Gather() should actually start from. */ other = cur; if ((other->cvc_prev && jump (&other, &dir, j_rule))) Collect1 (e, other, dir, contours, holes, j_rule); } while ((cur = cur->next) != &a->head); } /* Collect */ static int cntr_Collect (jmp_buf * e, PLINE ** A, POLYAREA ** contours, PLINE ** holes, int action, POLYAREA * owner, POLYAREA * parent, PLINE * parent_contour) { PLINE *tmprev; if ((*A)->Flags.status == ISECTED) { switch (action) { case PBO_UNITE: Collect (e, *A, contours, holes, UniteS_Rule, UniteJ_Rule); break; case PBO_ISECT: Collect (e, *A, contours, holes, IsectS_Rule, IsectJ_Rule); break; case PBO_XOR: Collect (e, *A, contours, holes, XorS_Rule, XorJ_Rule); break; case PBO_SUB: Collect (e, *A, contours, holes, SubS_Rule, SubJ_Rule); break; }; } else { switch (action) { case PBO_ISECT: if ((*A)->Flags.status == INSIDE) { tmprev = *A; /* disappear this contour (rtree entry removed in PutContour) */ *A = tmprev->next; tmprev->next = NULL; PutContour (e, tmprev, contours, holes, owner, NULL, NULL); return TRUE; } break; case PBO_XOR: if ((*A)->Flags.status == INSIDE) { tmprev = *A; /* disappear this contour (rtree entry removed in PutContour) */ *A = tmprev->next; tmprev->next = NULL; poly_InvContour (tmprev); PutContour (e, tmprev, contours, holes, owner, NULL, NULL); return TRUE; } /* break; *//* Fall through (I think this is correct! pcjc2) */ case PBO_UNITE: case PBO_SUB: if ((*A)->Flags.status == OUTSIDE) { tmprev = *A; /* disappear this contour (rtree entry removed in PutContour) */ *A = tmprev->next; tmprev->next = NULL; PutContour (e, tmprev, contours, holes, owner, parent, parent_contour); return TRUE; } break; } } return FALSE; } /* cntr_Collect */ static void M_B_AREA_Collect (jmp_buf * e, POLYAREA * bfst, POLYAREA ** contours, PLINE ** holes, int action) { POLYAREA *b = bfst; PLINE **cur, **next, *tmp; assert (b != NULL); do { for (cur = &b->contours; *cur != NULL; cur = next) { next = &((*cur)->next); if ((*cur)->Flags.status == ISECTED) continue; if ((*cur)->Flags.status == INSIDE) switch (action) { case PBO_XOR: case PBO_SUB: poly_InvContour (*cur); case PBO_ISECT: tmp = *cur; *cur = tmp->next; next = cur; tmp->next = NULL; tmp->Flags.status = UNKNWN; PutContour (e, tmp, contours, holes, b, NULL, NULL); break; case PBO_UNITE: break; /* nothing to do - already included */ } else if ((*cur)->Flags.status == OUTSIDE) switch (action) { case PBO_XOR: case PBO_UNITE: /* include */ tmp = *cur; *cur = tmp->next; next = cur; tmp->next = NULL; tmp->Flags.status = UNKNWN; PutContour (e, tmp, contours, holes, b, NULL, NULL); break; case PBO_ISECT: case PBO_SUB: break; /* do nothing, not included */ } } } while ((b = b->f) != bfst); } static inline int contour_is_first (POLYAREA * a, PLINE * cur) { return (a->contours == cur); } static inline int contour_is_last (PLINE * cur) { return (cur->next == NULL); } static inline void remove_polyarea (POLYAREA ** list, POLYAREA * piece) { /* If this item was the start of the list, advance that pointer */ if (*list == piece) *list = (*list)->f; /* But reset it to NULL if it wraps around and hits us again */ if (*list == piece) *list = NULL; piece->b->f = piece->f; piece->f->b = piece->b; piece->f = piece->b = piece; } static void M_POLYAREA_separate_isected (jmp_buf * e, POLYAREA ** pieces, PLINE ** holes, PLINE ** isected) { POLYAREA *a = *pieces; POLYAREA *anext; PLINE *curc, *next, *prev; int finished; if (a == NULL) return; /* TODO: STASH ENOUGH INFORMATION EARLIER ON, SO WE CAN REMOVE THE INTERSECTED CONTOURS WITHOUT HAVING TO WALK THE FULL DATA-STRUCTURE LOOKING FOR THEM. */ do { int hole_contour = 0; int is_outline = 1; anext = a->f; finished = (anext == *pieces); prev = NULL; for (curc = a->contours; curc != NULL; curc = next, is_outline = 0) { int is_first = contour_is_first (a, curc); int is_last = contour_is_last (curc); int isect_contour = (curc->Flags.status == ISECTED); next = curc->next; if (isect_contour || hole_contour) { /* Reset the intersection flags, since we keep these pieces */ if (curc->Flags.status != ISECTED) curc->Flags.status = UNKNWN; remove_contour (a, prev, curc, !(is_first && is_last)); if (isect_contour) { /* Link into the list of intersected contours */ curc->next = *isected; *isected = curc; } else if (hole_contour) { /* Link into the list of holes */ curc->next = *holes; *holes = curc; } else { assert (0); } if (is_first && is_last) { remove_polyarea (pieces, a); poly_Free (&a); /* NB: Sets a to NULL */ } } else { /* Note the item we just didn't delete as the next candidate for having its "next" pointer adjusted. Saves walking the contour list when we delete one. */ prev = curc; } /* If we move or delete an outer contour, we need to move any holes we wish to keep within that contour to the holes list. */ if (is_outline && isect_contour) hole_contour = 1; } /* If we deleted all the pieces of the polyarea, *pieces is NULL */ } while ((a = anext), *pieces != NULL && !finished); } struct find_inside_m_pa_info { jmp_buf jb; POLYAREA *want_inside; PLINE *result; }; static int find_inside_m_pa (const BoxType * b, void *cl) { struct find_inside_m_pa_info *info = (struct find_inside_m_pa_info *) cl; PLINE *check = (PLINE *) b; /* Don't report for the main contour */ if (check->Flags.orient == PLF_DIR) return 0; /* Don't look at contours marked as being intersected */ if (check->Flags.status == ISECTED) return 0; if (cntr_in_M_POLYAREA (check, info->want_inside, FALSE)) { info->result = check; longjmp (info->jb, 1); } return 0; } static void M_POLYAREA_update_primary (jmp_buf * e, POLYAREA ** pieces, PLINE ** holes, int action, POLYAREA * bpa) { POLYAREA *a = *pieces; POLYAREA *b; POLYAREA *anext; PLINE *curc, *next, *prev; BoxType box; /* int inv_inside = 0; */ int del_inside = 0; int del_outside = 0; int finished; if (a == NULL) return; switch (action) { case PBO_ISECT: del_outside = 1; break; case PBO_UNITE: case PBO_SUB: del_inside = 1; break; case PBO_XOR: /* NOT IMPLEMENTED OR USED */ /* inv_inside = 1; */ assert (0); break; } box = *((BoxType *) bpa->contours); b = bpa; while ((b = b->f) != bpa) { BoxType *b_box = (BoxType *) b->contours; MAKEMIN (box.X1, b_box->X1); MAKEMIN (box.Y1, b_box->Y1); MAKEMAX (box.X2, b_box->X2); MAKEMAX (box.Y2, b_box->Y2); } if (del_inside) { do { anext = a->f; finished = (anext == *pieces); /* Test the outer contour first, as we may need to remove all children */ /* We've not yet split intersected contours out, just ignore them */ if (a->contours->Flags.status != ISECTED && /* Pre-filter on bounding box */ ((a->contours->xmin >= box.X1) && (a->contours->ymin >= box.Y1) && (a->contours->xmax <= box.X2) && (a->contours->ymax <= box.Y2)) && /* Then test properly */ cntr_in_M_POLYAREA (a->contours, bpa, FALSE)) { /* Delete this contour, all children -> holes queue */ /* Delete the outer contour */ curc = a->contours; remove_contour (a, NULL, curc, FALSE); /* Rtree deleted in poly_Free below */ /* a->contours now points to the remaining holes */ poly_DelContour (&curc); if (a->contours != NULL) { /* Find the end of the list of holes */ curc = a->contours; while (curc->next != NULL) curc = curc->next; /* Take the holes and prepend to the holes queue */ curc->next = *holes; *holes = a->contours; a->contours = NULL; } remove_polyarea (pieces, a); poly_Free (&a); /* NB: Sets a to NULL */ continue; } /* Loop whilst we find INSIDE contours to delete */ while (1) { struct find_inside_m_pa_info info; PLINE *prev; info.want_inside = bpa; /* Set jump return */ if (setjmp (info.jb)) { /* Returned here! */ } else { info.result = NULL; /* r-tree search, calling back a routine to longjmp back with * data about any hole inside the B polygon. * NB: Does not jump back to report the main contour! */ r_search (a->contour_tree, &box, NULL, find_inside_m_pa, &info); /* Nothing found? */ break; } /* We need to find the contour before it, so we can update its next pointer */ prev = a->contours; while (prev->next != info.result) { prev = prev->next; } /* Remove hole from the contour */ remove_contour (a, prev, info.result, TRUE); poly_DelContour (&info.result); } /* End check for deleted holes */ /* If we deleted all the pieces of the polyarea, *pieces is NULL */ } while ((a = anext), *pieces != NULL && !finished); return; } else { /* This path isn't optimised for speed */ } do { int hole_contour = 0; int is_outline = 1; anext = a->f; finished = (anext == *pieces); prev = NULL; for (curc = a->contours; curc != NULL; curc = next, is_outline = 0) { int is_first = contour_is_first (a, curc); int is_last = contour_is_last (curc); int del_contour = 0; next = curc->next; if (del_outside) del_contour = curc->Flags.status != ISECTED && !cntr_in_M_POLYAREA (curc, bpa, FALSE); /* Skip intersected contours */ if (curc->Flags.status == ISECTED) { prev = curc; continue; } /* Reset the intersection flags, since we keep these pieces */ curc->Flags.status = UNKNWN; if (del_contour || hole_contour) { remove_contour (a, prev, curc, !(is_first && is_last)); if (del_contour) { /* Delete the contour */ poly_DelContour (&curc); /* NB: Sets curc to NULL */ } else if (hole_contour) { /* Link into the list of holes */ curc->next = *holes; *holes = curc; } else { assert (0); } if (is_first && is_last) { remove_polyarea (pieces, a); poly_Free (&a); /* NB: Sets a to NULL */ } } else { /* Note the item we just didn't delete as the next candidate for having its "next" pointer adjusted. Saves walking the contour list when we delete one. */ prev = curc; } /* If we move or delete an outer contour, we need to move any holes we wish to keep within that contour to the holes list. */ if (is_outline && del_contour) hole_contour = 1; } /* If we deleted all the pieces of the polyarea, *pieces is NULL */ } while ((a = anext), *pieces != NULL && !finished); } static void M_POLYAREA_Collect_separated (jmp_buf * e, PLINE * afst, POLYAREA ** contours, PLINE ** holes, int action, BOOLp maybe) { PLINE **cur, **next; for (cur = &afst; *cur != NULL; cur = next) { next = &((*cur)->next); /* if we disappear a contour, don't advance twice */ if (cntr_Collect (e, cur, contours, holes, action, NULL, NULL, NULL)) next = cur; } } static void M_POLYAREA_Collect (jmp_buf * e, POLYAREA * afst, POLYAREA ** contours, PLINE ** holes, int action, BOOLp maybe) { POLYAREA *a = afst; POLYAREA *parent = NULL; /* Quiet compiler warning */ PLINE **cur, **next, *parent_contour; assert (a != NULL); while ((a = a->f) != afst); /* now the non-intersect parts are collected in temp/holes */ do { if (maybe && a->contours->Flags.status != ISECTED) parent_contour = a->contours; else parent_contour = NULL; /* Take care of the first contour - so we know if we * can shortcut reparenting some of its children */ cur = &a->contours; if (*cur != NULL) { next = &((*cur)->next); /* if we disappear a contour, don't advance twice */ if (cntr_Collect (e, cur, contours, holes, action, a, NULL, NULL)) { parent = (*contours)->b; /* InsCntr inserts behind the head */ next = cur; } else parent = a; cur = next; } for (; *cur != NULL; cur = next) { next = &((*cur)->next); /* if we disappear a contour, don't advance twice */ if (cntr_Collect (e, cur, contours, holes, action, a, parent, parent_contour)) next = cur; } } while ((a = a->f) != afst); } /*! * \brief Determine if two polygons touch or overlap. */ BOOLp Touching (POLYAREA * a, POLYAREA * b) { jmp_buf e; int code; if ((code = setjmp (e)) == 0) { #ifdef DEBUG if (!poly_Valid (a)) return -1; if (!poly_Valid (b)) return -1; #endif M_POLYAREA_intersect (&e, a, b, false); if (M_POLYAREA_label (a, b, TRUE)) return TRUE; if (M_POLYAREA_label (b, a, TRUE)) return TRUE; } else if (code == TOUCHES) return TRUE; return FALSE; } /*! * \brief The main clipping routines. */ int poly_Boolean (const POLYAREA * a_org, const POLYAREA * b_org, POLYAREA ** res, int action) { POLYAREA *a = NULL, *b = NULL; if (!poly_M_Copy0 (&a, a_org) || !poly_M_Copy0 (&b, b_org)) return err_no_memory; return poly_Boolean_free (a, b, res, action); } /* poly_Boolean */ /*! * \brief Just like poly_Boolean but frees the input polys. */ int poly_Boolean_free (POLYAREA * ai, POLYAREA * bi, POLYAREA ** res, int action) { POLYAREA *a = ai, *b = bi; PLINE *a_isected = NULL; PLINE *p, *holes = NULL; jmp_buf e; int code; *res = NULL; if (!a) { switch (action) { case PBO_XOR: case PBO_UNITE: /* if a was null, then the union or xor with b is b. */ *res = bi; return err_ok; case PBO_SUB: case PBO_ISECT: /* can't do these with out two operands. */ if (b != NULL) poly_Free (&b); return err_ok; } } if (!b) { switch (action) { case PBO_SUB: case PBO_XOR: case PBO_UNITE: /* if b was null, the result of these operations is just a. */ *res = ai; return err_ok; case PBO_ISECT: /* can't do this without two operands. */ if (a != NULL) poly_Free (&a); return err_ok; } } if ((code = setjmp (e)) == 0) { #ifdef DEBUG assert (poly_Valid (a)); assert (poly_Valid (b)); #endif /* intersect needs to make a list of the contours in a and b which are intersected */ M_POLYAREA_intersect (&e, a, b, TRUE); /* We could speed things up a lot here if we only processed the relevant contours */ /* NB: Relevant parts of a are labeled below */ M_POLYAREA_label (b, a, FALSE); *res = a; M_POLYAREA_update_primary (&e, res, &holes, action, b); M_POLYAREA_separate_isected (&e, res, &holes, &a_isected); M_POLYAREA_label_separated (a_isected, b, FALSE); M_POLYAREA_Collect_separated (&e, a_isected, res, &holes, action, FALSE); M_B_AREA_Collect (&e, b, res, &holes, action); poly_Free (&b); /* free a_isected */ while ((p = a_isected) != NULL) { a_isected = p->next; poly_DelContour (&p); } InsertHoles (&e, *res, &holes); } /* delete holes if any left */ while ((p = holes) != NULL) { holes = p->next; poly_DelContour (&p); } if (code) { poly_Free (res); return code; } assert (!*res || poly_Valid (*res)); return code; } /* poly_Boolean_free */ static void clear_marks (POLYAREA * p) { POLYAREA *n = p; PLINE *c; VNODE *v; do { for (c = n->contours; c; c = c->next) { v = &c->head; do { v->Flags.mark = 0; } while ((v = v->next) != &c->head); } } while ((n = n->f) != p); } /*! * \brief Compute the intersection and subtraction (divides "a" into two * pieces) and frees the input polys. * * This assumes that bi is a single simple polygon. */ int poly_AndSubtract_free (POLYAREA * ai, POLYAREA * bi, POLYAREA ** aandb, POLYAREA ** aminusb) { POLYAREA *a = ai, *b = bi; PLINE *p, *holes = NULL; jmp_buf e; int code; *aandb = NULL; *aminusb = NULL; if ((code = setjmp (e)) == 0) { #ifdef DEBUG if (!poly_Valid (a)) return -1; if (!poly_Valid (b)) return -1; #endif M_POLYAREA_intersect (&e, a, b, TRUE); M_POLYAREA_label (a, b, FALSE); M_POLYAREA_label (b, a, FALSE); M_POLYAREA_Collect (&e, a, aandb, &holes, PBO_ISECT, FALSE); InsertHoles (&e, *aandb, &holes); assert (poly_Valid (*aandb)); /* delete holes if any left */ while ((p = holes) != NULL) { holes = p->next; poly_DelContour (&p); } holes = NULL; clear_marks (a); clear_marks (b); M_POLYAREA_Collect (&e, a, aminusb, &holes, PBO_SUB, FALSE); InsertHoles (&e, *aminusb, &holes); poly_Free (&a); poly_Free (&b); assert (poly_Valid (*aminusb)); } /* delete holes if any left */ while ((p = holes) != NULL) { holes = p->next; poly_DelContour (&p); } if (code) { poly_Free (aandb); poly_Free (aminusb); return code; } assert (!*aandb || poly_Valid (*aandb)); assert (!*aminusb || poly_Valid (*aminusb)); return code; } /* poly_AndSubtract_free */ static inline int cntrbox_pointin (PLINE * c, Vector p) { return (p[0] >= c->xmin && p[1] >= c->ymin && p[0] <= c->xmax && p[1] <= c->ymax); } static inline int node_neighbours (VNODE * a, VNODE * b) { return (a == b) || (a->next == b) || (b->next == a) || (a->next == b->next); } /*! * \brief Create a new VNODE at the end of v * */ VNODE * poly_CreateNode (Vector v) { VNODE *res; Coord *c; assert (v); res = (VNODE *) calloc (1, sizeof (VNODE)); if (res == NULL) /* Couldn't allocate memory */ return NULL; // bzero (res, sizeof (VNODE) - sizeof(Vector)); c = res->point; /* type(res->point) = Vector = vertex = Coord [2]*/ *c++ = *v++; /* Copy the first Coord and point to the second of each */ *c = *v; /* Copy the second Coord*/ return res; } /*! * \brief Initialize a PLINE contour. * */ void poly_IniContour (PLINE * c) { if (c == NULL) return; /* bzero (c, sizeof(PLINE)); */ /* Set up the linked list. This is the first object so we point to * ourselves. * */ c->head.next = c->head.prev = &c->head; /* Set up the bounding box. */ c->xmin = c->ymin = COORD_MAX; c->xmax = c->ymax = -COORD_MAX - 1; /* Other parameters */ c->is_round = FALSE; c->cx = 0; c->cy = 0; c->radius = 0; } /*! * \brief Create a new PLINE with an initial point at v * */ PLINE * poly_NewContour (Vector v) { PLINE *res; res = (PLINE *) calloc (1, sizeof (PLINE)); if (res == NULL) /* Failed to allocate memory */ return NULL; /* Initialize the list pointers and variables. */ poly_IniContour (res); if (v != NULL) { /* Copy Coords in v to res->head.point */ Vcopy (res->head.point, v); /* Update the contour box (bounding box) to include the new point */ cntrbox_adjust (res, v); } return res; } void poly_ClrContour (PLINE * c) { VNODE *cur; assert (c != NULL); while ((cur = c->head.next) != &c->head) { poly_ExclVertex (cur); free (cur); } poly_IniContour (c); } void poly_DelContour (PLINE ** c) { VNODE *cur, *prev; if (*c == NULL) return; for (cur = (*c)->head.prev; cur != &(*c)->head; cur = prev) { prev = cur->prev; if (cur->cvc_next != NULL) { free (cur->cvc_next); free (cur->cvc_prev); } free (cur); } if ((*c)->head.cvc_next != NULL) { free ((*c)->head.cvc_next); free ((*c)->head.cvc_prev); } /*! \todo FIXME -- strict aliasing violation. */ if ((*c)->tree) { rtree_t *r = (*c)->tree; r_destroy_tree (&r); } free (*c), *c = NULL; } /*! * \brief Prepare (?) an initialized PLINE contour. * * If optimize is true, points that line on a line connected the previous * and next points are removed. * */ void poly_PreContour (PLINE * C, BOOLp optimize) { double area = 0; VNODE *p, *c; Vector p1, p2; assert (C != NULL); if (optimize) { for (c = (p = &C->head)->next; c != &C->head; c = (p = c)->next) { /* if the previous node is on the same line with this one, * we should remove it. If the vector cross-product of the vectors * connecting this point to the next and previous points is zero, the * points are on the same line and we can remove point c. * */ Vsub2 (p1, c->point, p->point); Vsub2 (p2, c->next->point, c->point); if (vect_det2 (p1, p2) == 0) { poly_ExclVertex (c); free (c); c = p; } } /* for (each vertex) */ } /* optimize */ C->Count = 0; C->xmin = C->xmax = C->head.point[0]; C->ymin = C->ymax = C->head.point[1]; p = (c = &C->head)->prev; if (c != p) { do { /* calculate area for orientation */ /* I don't understand how this part works. This is a funny area that * is the difference in x with the sum in y. In pcb all coordinates are * positive. So, dx = p.x - c.x, and therefore the area, is negative * if the current point (c) is further to the right than the previous * point (p). The sum of the ys is greater when we're further from the * axis, so, if we're going clockwise, we'll be adding larger numbers * when the next point is to the left than when going to the right, * and at the end we should have a positive number (remember that * pcb's positive y-axis points down). If we're going CCW, then we'll * be moving to the right a y coordinate that's greater than when * we're moving to the left, and so the net area will be negative. * * However if this is the case, why do we save the absolute value of * the area? I'm not sure how this value is meaningful... * */ area += (double) (p->point[0] - c->point[0]) * (p->point[1] + c->point[1]); /* expand the contour box to include the current vertex */ cntrbox_adjust (C, c->point); C->Count++; } while ((c = (p = c)->next) != &C->head); } C->area = ABS (area); if (C->Count > 2) C->Flags.orient = ((area < 0) ? PLF_INV : PLF_DIR); /* Generate an rtree for the contour. */ C->tree = (rtree_t *)make_edge_tree (C); } /* poly_PreContour */ static int flip_cb (const BoxType * b, void *cl) { struct seg *s = (struct seg *) b; /* Adjust the node pointer so that the previous segment becomes the * current segment. Note that this doesn't change the orientation, just * which edge of the contour the segment points to. */ s->v = s->v->prev; return 1; } /*! * \brief Invert the orientation of a contour. * * If the contour is positive (CW?) we reverse it to be negative (CCW?) and * vice versa. Positive contours are the perimeters of polygons, negative * contours are holes in polygons. * */ void poly_InvContour (PLINE * c) { VNODE *cur, *next; #ifndef NDEBUG int r; #endif assert (c != NULL); cur = &c->head; do { /* Swap the next and prev pointers to reverse the direction of the * segment. * */ next = cur->next; cur->next = cur->prev; cur->prev = next; /* fix the segment tree */ } while ((cur = next) != &c->head); c->Flags.orient ^= 1; if (c->tree) { #ifndef NDEBUG r = #endif r_search (c->tree, NULL, NULL, flip_cb, NULL); #ifndef NDEBUG assert (r == c->Count); #endif } } void poly_ExclVertex (VNODE * node) { assert (node != NULL); if (node->cvc_next) { free (node->cvc_next); free (node->cvc_prev); } node->prev->next = node->next; node->next->prev = node->prev; } void poly_InclVertex (VNODE * after, VNODE * node) { double a, b; assert (after != NULL); assert (node != NULL); node->prev = after; node->next = after->next; after->next = after->next->prev = node; /* remove points on same line */ if (node->prev->prev == node) return; /* we don't have 3 points in the poly yet */ a = (node->point[1] - node->prev->prev->point[1]); a *= (node->prev->point[0] - node->prev->prev->point[0]); b = (node->point[0] - node->prev->prev->point[0]); b *= (node->prev->point[1] - node->prev->prev->point[1]); if (fabs (a - b) < EPSILON) { VNODE *t = node->prev; t->prev->next = node; node->prev = t->prev; free (t); } } BOOLp poly_CopyContour (PLINE ** dst, PLINE * src) { VNODE *cur, *newnode; assert (src != NULL); *dst = NULL; *dst = poly_NewContour (src->head.point); if (*dst == NULL) return FALSE; (*dst)->Count = src->Count; (*dst)->Flags.orient = src->Flags.orient; (*dst)->xmin = src->xmin, (*dst)->xmax = src->xmax; (*dst)->ymin = src->ymin, (*dst)->ymax = src->ymax; (*dst)->area = src->area; for (cur = src->head.next; cur != &src->head; cur = cur->next) { if ((newnode = poly_CreateNode (cur->point)) == NULL) return FALSE; // newnode->Flags = cur->Flags; poly_InclVertex ((*dst)->head.prev, newnode); } (*dst)->tree = (rtree_t *)make_edge_tree (*dst); return TRUE; } /* polygon routines */ BOOLp poly_Copy0 (POLYAREA ** dst, const POLYAREA * src) { *dst = NULL; if (src != NULL) *dst = (POLYAREA *)calloc (1, sizeof (POLYAREA)); if (*dst == NULL) return FALSE; (*dst)->contour_tree = r_create_tree (NULL, 0, 0); return poly_Copy1 (*dst, src); } BOOLp poly_Copy1 (POLYAREA * dst, const POLYAREA * src) { PLINE *cur, **last = &dst->contours; *last = NULL; dst->f = dst->b = dst; for (cur = src->contours; cur != NULL; cur = cur->next) { if (!poly_CopyContour (last, cur)) return FALSE; r_insert_entry (dst->contour_tree, (BoxType *) * last, 0); last = &(*last)->next; } return TRUE; } void poly_M_Incl (POLYAREA ** list, POLYAREA * a) { if (*list == NULL) a->f = a->b = a, *list = a; else { a->f = *list; a->b = (*list)->b; (*list)->b = (*list)->b->f = a; } } BOOLp poly_M_Copy0 (POLYAREA ** dst, const POLYAREA * srcfst) { const POLYAREA *src = srcfst; POLYAREA *di; *dst = NULL; if (src == NULL) return FALSE; do { if ((di = poly_Create ()) == NULL || !poly_Copy1 (di, src)) return FALSE; poly_M_Incl (dst, di); } while ((src = src->f) != srcfst); return TRUE; } /*! * \brief Insert a PLINE contour in a POLYAREA. * */ BOOLp poly_InclContour (POLYAREA * p, PLINE * c) { PLINE *tmp; if ((c == NULL) || (p == NULL)) return FALSE; if (c->Flags.orient == PLF_DIR) { /* c is a positive contour (perimeter) */ /* Only the first contour may be positive. */ if (p->contours != NULL) return FALSE; p->contours = c; } else { /* c is a negative contour (hole) */ /* Only subsequent contours may be negative */ if (p->contours == NULL) return FALSE; /* link at front of hole list */ tmp = p->contours->next; p->contours->next = c; c->next = tmp; } /* Add the contour to the POLYAREAs contour rtree */ r_insert_entry (p->contour_tree, (BoxType *) c, 0); return TRUE; } typedef struct pip { int f; Vector p; jmp_buf env; } pip; /*! * \brief Callback to determine if a point is inside a polygon. * * A "bounding box" is generated from the point to the greatest X coordinate * possible, and this function is called for each segment bounding box that * overlaps with the "ray" bounding box. * * If the ray intersects a segment that is going away from y=0, we add 1 to * a counter, and if it intersects a segment that is going towards y=0 we * subtract 1. If a point is inside the polygon, the net result must be * non-zero. * */ static int crossing (const BoxType * b, void *cl) { /* The contour segment our ray touches the bounding box of. */ struct seg *s = (struct seg *) b; /* Contains our point in question */ struct pip *p = (struct pip *) cl; if (s->v->point[1] <= p->p[1]) /* First segment point is closer to y=0 than the point in question. */ { if (s->v->next->point[1] > p->p[1]) /* Second segment point is further from zero than the point in question. */ { /* The y coord of our point is between those of the segment end * points, and our segment is directed towards increasing y. */ Vector v1, v2; long long cross; /* Segment vector */ Vsub2 (v1, s->v->next->point, s->v->point); /* Vector from first end point of the segment to the point in question */ Vsub2 (v2, p->p, s->v->point); /* Compute the cross product */ cross = (long long) v1[0] * v2[1] - (long long) v2[0] * v1[1]; if (cross == 0) { /* vectors are parallel, intersection not possible */ p->f = 1; longjmp (p->env, 1); } /* A positive cross product means that the point is to the left of * the segment (remember positive y is down, so positive z is into * the screen, and we know that the segment is directed away towards * increasing y), and therefore intersects. Add one to the count since * this is edge is going towards increasing y. * */ if (cross > 0) p->f += 1; } } else /* First segment point is further from y=0 than the point in question. */ { if (s->v->next->point[1] <= p->p[1]) /* Second segment point is closer to zero that the point in question. */ { /* The y coord of our point is between those of the segment end * points, and our segment is directed towards decreasing y. */ Vector v1, v2; long long cross; /* vector along the segment */ Vsub2 (v1, s->v->next->point, s->v->point); /* vector from the first point of the segment to the point in question. */ Vsub2 (v2, p->p, s->v->point); /* Compute the cross product*/ cross = (long long) v1[0] * v2[1] - (long long) v2[0] * v1[1]; if (cross == 0) { /* vectors are parallel. */ p->f = 1; longjmp (p->env, 1); } /* A negative cross product means the point is to the left of the * segment (see above). Since the ray is moving right, it must * intersect. Subtract one from the count since this segment is going * towards decreasing y. * */ if (cross < 0) p->f -= 1; } } return 1; } /*! * \brief Determine if a point is inside a contour * * Generate a vector from the specified point to the maximum x coordinate, * and see what segments are intersected. If we intersect as many "positive * going" segments as "negative going" segments (y direction), then we must * not be inside the polygon. * * Return 0 if the point is outside, otherwise the net count of intersected * segments (crossing a positive segment = +1, crossing a negative segment = * -1). * */ int poly_InsideContour (PLINE * c, Vector p) { struct pip info; BoxType ray; /* Quick bounding box check */ if (!cntrbox_pointin (c, p)) return FALSE; /* Create a ray (bounding box) one nm tall that goes from the point to the * furthest edge possible. * */ info.f = 0; info.p[0] = ray.X1 = p[0]; info.p[1] = ray.Y1 = p[1]; ray.X2 = COORD_MAX; ray.Y2 = p[1] + 1; /* Call the crossing callback for any segment for which this ray touches * the bounding box * */ if (setjmp (info.env) == 0) r_search (c->tree, &ray, NULL, crossing, &info); /* if info.f != 0, the specified point is inside the polygon */ return info.f; } /*! * \brief Check if a point is inside a POLYAREA, but not one of its holes. * */ BOOLp poly_CheckInside (POLYAREA * p, Vector v0) { PLINE *cur; if ((p == NULL) || (v0 == NULL) || (p->contours == NULL)) return FALSE; /* first contour is the polygon perimeter*/ cur = p->contours; if (poly_InsideContour (cur, v0)) /* Inside the perimeter of the polygon */ { /* loop over each hole */ for (cur = cur->next; cur != NULL; cur = cur->next) /* If inside any hole, then false */ if (poly_InsideContour (cur, v0)) return FALSE; /* Inside the polygon perimeter, but not a hole. */ return TRUE; } /* if inside perimeter */ /* wasn't inside the perimeter */ return FALSE; } /*! * \brief Check if a point is inside this polyarea or any that it's linked to. * */ BOOLp poly_M_CheckInside (POLYAREA * p, Vector v0) { POLYAREA *cur; if ((p == NULL) || (v0 == NULL)) return FALSE; /* bad input */ cur = p; do { /* If we're inside any POLYAREA, return true. */ if (poly_CheckInside (cur, v0)) return TRUE; } /* check the next POLYAREA until we get back to the start */ while ((cur = cur->f) != p); return FALSE; } static double dot (Vector A, Vector B) { return (double)A[0] * (double)B[0] + (double)A[1] * (double)B[1]; } /*! * \brief Compute whether point is inside a triangle formed by 3 other * points. * * Algorithm from http://www.blackpawn.com/texts/pointinpoly/default.html. */ static int point_in_triangle (Vector A, Vector B, Vector C, Vector P) { Vector v0, v1, v2; double dot00, dot01, dot02, dot11, dot12; double invDenom; double u, v; /* Compute vectors */ v0[0] = C[0] - A[0]; v0[1] = C[1] - A[1]; v1[0] = B[0] - A[0]; v1[1] = B[1] - A[1]; v2[0] = P[0] - A[0]; v2[1] = P[1] - A[1]; /* Compute dot products */ dot00 = dot (v0, v0); dot01 = dot (v0, v1); dot02 = dot (v0, v2); dot11 = dot (v1, v1); dot12 = dot (v1, v2); /* Compute barycentric coordinates */ invDenom = 1. / (dot00 * dot11 - dot01 * dot01); u = (dot11 * dot02 - dot01 * dot12) * invDenom; v = (dot00 * dot12 - dot01 * dot02) * invDenom; /* Check if point is in triangle */ return (u > 0.0) && (v > 0.0) && (u + v < 1.0); } /*! * \brief Returns the dot product of Vector A->B, and a vector * orthogonal to Vector C->D. * * The result is not normalisd, so will be weighted by the magnitude of * the C->D vector. */ static double dot_orthogonal_to_direction (Vector A, Vector B, Vector C, Vector D) { Vector l1, l2, l3; l1[0] = B[0] - A[0]; l1[1] = B[1] - A[1]; l2[0] = D[0] - C[0]; l2[1] = D[1] - C[1]; l3[0] = -l2[1]; l3[1] = l2[0]; return dot (l1, l3); } /*! * \brief Algorithm from http://www.exaflop.org/docs/cgafaq/cga2.html. * * "Given a simple polygon, find some point inside it. * * Here is a method based on the proof that there exists an internal * diagonal, in [O'Rourke, 13-14]. * * The idea is that the midpoint of a diagonal is interior to the * polygon. * *
    *
  1. Identify a convex vertex v; let its adjacent vertices be a and b.
  2. *
  3. For each other vertex q do:
  4. *
      *
    1. If q is inside avb, compute distance to v (orthogonal to ab).
    2. *
    3. Save point q if distance is a new min.
    4. *
    *
  5. If no point is inside, return midpoint of ab, or centroid of avb.
  6. *
  7. Else if some point inside, qv is internal: return its midpoint."
  8. *
* * [O'Rourke]: Computational Geometry in C (2nd Ed.) * * Joseph O'Rourke, Cambridge University Press 1998, * ISBN 0-521-64010-5 Pbk, ISBN 0-521-64976-5 Hbk. */ static void poly_ComputeInteriorPoint (PLINE *poly, Vector v) { VNODE *pt1, *pt2, *pt3, *q; VNODE *min_q = NULL; double dist; double min_dist = 0.0; double dir = (poly->Flags.orient == PLF_DIR) ? 1. : -1; /* Find a convex node on the polygon */ pt1 = &poly->head; do { double dot_product; pt2 = pt1->next; pt3 = pt2->next; dot_product = dot_orthogonal_to_direction (pt1->point, pt2->point, pt3->point, pt2->point); if (dot_product * dir > 0.) break; } while ((pt1 = pt1->next) != &poly->head); /* Loop over remaining vertices */ q = pt3; do { /* Is current vertex "q" outside pt1 pt2 pt3 triangle? */ if (!point_in_triangle (pt1->point, pt2->point, pt3->point, q->point)) continue; /* NO: compute distance to pt2 (v) orthogonal to pt1 - pt3) */ /* Record minimum */ dist = dot_orthogonal_to_direction (q->point, pt2->point, pt1->point, pt3->point); if (min_q == NULL || dist < min_dist) { min_dist = dist; min_q = q; } } while ((q = q->next) != pt2); /* Were any "q" found inside pt1 pt2 pt3? */ if (min_q == NULL) { /* NOT FOUND: Return midpoint of pt1 pt3 */ v[0] = (pt1->point[0] + pt3->point[0]) / 2; v[1] = (pt1->point[1] + pt3->point[1]) / 2; } else { /* FOUND: Return mid point of min_q, pt2 */ v[0] = (pt2->point[0] + min_q->point[0]) / 2; v[1] = (pt2->point[1] + min_q->point[1]) / 2; } } /*! * \brief . * * \note This function assumes the caller _knows_ the contours do not * intersect. If the contours intersect, the result is undefined. * It will return the correct result if the two contours share * common points beteween their contours. (Identical contours * are treated as being inside each other). */ int poly_ContourInContour (PLINE * poly, PLINE * inner) { Vector point; assert (poly != NULL); assert (inner != NULL); if (cntrbox_inside (inner, poly)) { /* We need to prove the "inner" contour is not outside * "poly" contour. If it is outside, we can return. */ if (!poly_InsideContour (poly, inner->head.point)) return 0; poly_ComputeInteriorPoint (inner, point); return poly_InsideContour (poly, point); } return 0; } void poly_Init (POLYAREA * p) { p->f = p->b = p; p->contours = NULL; p->contour_tree = r_create_tree (NULL, 0, 0); } POLYAREA * poly_Create (void) { POLYAREA *res; if ((res = (POLYAREA *)malloc (sizeof (POLYAREA))) != NULL) poly_Init (res); return res; } void poly_FreeContours (PLINE ** pline) { PLINE *pl; while ((pl = *pline) != NULL) { *pline = pl->next; poly_DelContour (&pl); } } void poly_Free (POLYAREA ** p) { POLYAREA *cur; if (*p == NULL) return; for (cur = (*p)->f; cur != *p; cur = (*p)->f) { poly_FreeContours (&cur->contours); r_destroy_tree (&cur->contour_tree); cur->f->b = cur->b; cur->b->f = cur->f; free (cur); } poly_FreeContours (&cur->contours); r_destroy_tree (&cur->contour_tree); free (*p), *p = NULL; } static BOOLp inside_sector (VNODE * pn, Vector p2) { Vector cdir, ndir, pdir; int p_c, n_c, p_n; assert (pn != NULL); vect_sub (cdir, p2, pn->point); vect_sub (pdir, pn->point, pn->prev->point); vect_sub (ndir, pn->next->point, pn->point); p_c = vect_det2 (pdir, cdir) >= 0; n_c = vect_det2 (ndir, cdir) >= 0; p_n = vect_det2 (pdir, ndir) >= 0; if ((p_n && p_c && n_c) || ((!p_n) && (p_c || n_c))) return TRUE; else return FALSE; } /* inside_sector */ /*! * \brief . * * \return TRUE if bad contour. */ BOOLp poly_ChkContour (PLINE * a) { VNODE *a1, *a2, *hit1, *hit2; Vector i1, i2; int icnt; assert (a != NULL); a1 = &a->head; do { a2 = a1; do { if (!node_neighbours (a1, a2) && (icnt = vect_inters2 (a1->point, a1->next->point, a2->point, a2->next->point, i1, i2)) > 0) { if (icnt > 1) return TRUE; if (vect_dist2 (i1, a1->point) < EPSILON) hit1 = a1; else if (vect_dist2 (i1, a1->next->point) < EPSILON) hit1 = a1->next; else hit1 = NULL; if (vect_dist2 (i1, a2->point) < EPSILON) hit2 = a2; else if (vect_dist2 (i1, a2->next->point) < EPSILON) hit2 = a2->next; else hit2 = NULL; if ((hit1 == NULL) && (hit2 == NULL)) { /* If the intersection didn't land on an end-point of either * line, we know the lines cross and we return TRUE. */ return TRUE; } else if (hit1 == NULL) { /* An end-point of the second line touched somewhere along the length of the first line. Check where the second line leads. */ if (inside_sector (hit2, a1->point) != inside_sector (hit2, a1->next->point)) return TRUE; } else if (hit2 == NULL) { /* An end-point of the first line touched somewhere along the length of the second line. Check where the first line leads. */ if (inside_sector (hit1, a2->point) != inside_sector (hit1, a2->next->point)) return TRUE; } else { /* Both lines intersect at an end-point. Check where they lead. */ if (inside_sector (hit1, hit2->prev->point) != inside_sector (hit1, hit2->next->point)) return TRUE; } } } while ((a2 = a2->next) != &a->head); } while ((a1 = a1->next) != &a->head); return FALSE; } BOOLp poly_Valid (POLYAREA * p) { PLINE *c; if ((p == NULL) || (p->contours == NULL)) return FALSE; if (p->contours->Flags.orient == PLF_INV || poly_ChkContour (p->contours)) { #ifndef NDEBUG VNODE *v, *n; DEBUGP ("Invalid Outer PLINE\n"); if (p->contours->Flags.orient == PLF_INV) DEBUGP ("failed orient\n"); if (poly_ChkContour (p->contours)) DEBUGP ("failed self-intersection\n"); v = &p->contours->head; do { n = v->next; pcb_fprintf (stderr, "Line [%#mS %#mS %#mS %#mS 100 100 \"\"]\n", v->point[0], v->point[1], n->point[0], n->point[1]); } while ((v = v->next) != &p->contours->head); #endif return FALSE; } for (c = p->contours->next; c != NULL; c = c->next) { if (c->Flags.orient == PLF_DIR || poly_ChkContour (c) || !poly_ContourInContour (p->contours, c)) { #ifndef NDEBUG VNODE *v, *n; DEBUGP ("Invalid Inner PLINE orient = %d\n", c->Flags.orient); if (c->Flags.orient == PLF_DIR) DEBUGP ("failed orient\n"); if (poly_ChkContour (c)) DEBUGP ("failed self-intersection\n"); if (!poly_ContourInContour (p->contours, c)) DEBUGP ("failed containment\n"); v = &c->head; do { n = v->next; pcb_fprintf (stderr, "Line [%#mS %#mS %#mS %#mS 100 100 \"\"]\n", v->point[0], v->point[1], n->point[0], n->point[1]); } while ((v = v->next) != &c->head); #endif return FALSE; } } return TRUE; } Vector vect_zero = { (long) 0, (long) 0 }; /* L o n g V e c t o r S t u f f */ void vect_init (Vector v, double x, double y) { v[0] = (long) x; v[1] = (long) y; } /* vect_init */ #define Vzero(a) ((a)[0] == 0. && (a)[1] == 0.) #define Vsub(a,b,c) {(a)[0]=(b)[0]-(c)[0];(a)[1]=(b)[1]-(c)[1];} int vect_equal (Vector v1, Vector v2) { return (v1[0] == v2[0] && v1[1] == v2[1]); } /* vect_equal */ void vect_sub (Vector res, Vector v1, Vector v2) { Vsub (res, v1, v2)} /* vect_sub */ void vect_min (Vector v1, Vector v2, Vector v3) { v1[0] = (v2[0] < v3[0]) ? v2[0] : v3[0]; v1[1] = (v2[1] < v3[1]) ? v2[1] : v3[1]; } /* vect_min */ void vect_max (Vector v1, Vector v2, Vector v3) { v1[0] = (v2[0] > v3[0]) ? v2[0] : v3[0]; v1[1] = (v2[1] > v3[1]) ? v2[1] : v3[1]; } /* vect_max */ double vect_len2 (Vector v) { return ((double) v[0] * v[0] + (double) v[1] * v[1]); /* why sqrt? only used for compares */ } double vect_dist2 (Vector v1, Vector v2) { double dx = v1[0] - v2[0]; double dy = v1[1] - v2[1]; return (dx * dx + dy * dy); /* why sqrt */ } /*! * \brief Value has sign of angle between vectors. */ double vect_det2 (Vector v1, Vector v2) { return (((double) v1[0] * v2[1]) - ((double) v2[0] * v1[1])); } static double vect_m_dist (Vector v1, Vector v2) { double dx = v1[0] - v2[0]; double dy = v1[1] - v2[1]; double dd = (dx * dx + dy * dy); /* sqrt */ if (dx > 0) return +dd; if (dx < 0) return -dd; if (dy > 0) return +dd; return -dd; } /* vect_m_dist */ /*! * \brief vect_inters2. * * (C) 1993 Klamer Schutte. * * (C) 1997 Michael Leonov, Alexey Nikitin. * * Returns the number of intersecting points: * 0 - no intersection * 1 - segments cross, or are parallel and end to end * 2 - segments are parallel and overlap each other */ int vect_inters2 (Vector p1, Vector p2, Vector q1, Vector q2, Vector S1, Vector S2) { double s, t, deel; double rpx, rpy, rqx, rqy; if (max (p1[0], p2[0]) < min (q1[0], q2[0]) || max (q1[0], q2[0]) < min (p1[0], p2[0]) || max (p1[1], p2[1]) < min (q1[1], q2[1]) || max (q1[1], q2[1]) < min (p1[1], p2[1])) return 0; /* vec(rpx, rpy) points from p1 to p2, and vec(rqx, rqy) points * from q1 to q2 * */ rpx = p2[0] - p1[0]; rpy = p2[1] - p1[1]; rqx = q2[0] - q1[0]; rqy = q2[1] - q1[1]; deel = rpy * rqx - rpx * rqy; /* -vect_det(rp,rq); */ /* coordinates are 30-bit integers so deel will be exactly zero * if the lines are parallel */ if (deel == 0) /* parallel */ { double dc1, dc2, d1, d2, h; /* Check to see whether p1-p2 and q1-q2 are on the same line */ Vector hp1, hq1, hp2, hq2, q1p1, q1q2; Vsub2 (q1p1, q1, p1); Vsub2 (q1q2, q1, q2); /* If this product is not zero then p1-p2 and q1-q2 are not on same line! */ if (vect_det2 (q1p1, q1q2) != 0) return 0; dc1 = 0; /* m_len(p1 - p1) */ dc2 = vect_m_dist (p1, p2); /* signed dist^2 */ d1 = vect_m_dist (p1, q1); d2 = vect_m_dist (p1, q2); /* Sorting the independent points from small to large */ Vcpy2 (hp1, p1); Vcpy2 (hp2, p2); Vcpy2 (hq1, q1); Vcpy2 (hq2, q2); if (dc1 > dc2) { /* hv and h are used as help-variable. */ Vswp2 (hp1, hp2); h = dc1, dc1 = dc2, dc2 = h; } if (d1 > d2) { Vswp2 (hq1, hq2); h = d1, d1 = d2, d2 = h; } /* Now the line-pieces are compared */ if (dc1 < d1) { if (dc2 < d1) return 0; if (dc2 < d2) { Vcpy2 (S1, hp2); Vcpy2 (S2, hq1); } else { Vcpy2 (S1, hq1); Vcpy2 (S2, hq2); }; } else { if (dc1 > d2) return 0; if (dc2 < d2) { Vcpy2 (S1, hp1); Vcpy2 (S2, hp2); } else { Vcpy2 (S1, hp1); Vcpy2 (S2, hq2); }; } return (Vequ2 (S1, S2) ? 1 : 2); } else { /* not parallel */ /* * We have the lines: * l1: p1 + s(p2 - p1) * l2: q1 + t(q2 - q1) * And we want to know the intersection point. * Calculate t: * p1 + s(p2-p1) = q1 + t(q2-q1) * which is similar to the two equations: * p1x + s * rpx = q1x + t * rqx * p1y + s * rpy = q1y + t * rqy * Multiplying these by rpy resp. rpx gives: * rpy * p1x + s * rpx * rpy = rpy * q1x + t * rpy * rqx * rpx * p1y + s * rpx * rpy = rpx * q1y + t * rpx * rqy * Subtracting these gives: * rpy * p1x - rpx * p1y = rpy * q1x - rpx * q1y + t * ( rpy * rqx - rpx * rqy ) * So t can be isolated: * t = (rpy * ( p1x - q1x ) + rpx * ( - p1y + q1y )) / ( rpy * rqx - rpx * rqy ) * and s can be found similarly * s = (rqy * (q1x - p1x) + rqx * (p1y - q1y))/( rqy * rpx - rqx * rpy) */ if (Vequ2 (q1, p1) || Vequ2 (q1, p2)) { S1[0] = q1[0]; S1[1] = q1[1]; } else if (Vequ2 (q2, p1) || Vequ2 (q2, p2)) { S1[0] = q2[0]; S1[1] = q2[1]; } else { s = (rqy * (p1[0] - q1[0]) + rqx * (q1[1] - p1[1])) / deel; if (s < 0 || s > 1.) return 0; t = (rpy * (p1[0] - q1[0]) + rpx * (q1[1] - p1[1])) / deel; if (t < 0 || t > 1.) return 0; S1[0] = q1[0] + ROUND (t * rqx); S1[1] = q1[1] + ROUND (t * rqy); } return 1; } } /* vect_inters2 */ pcb-4.3.0/src/macro.h0000664000175000017500000004215213773431044011260 00000000000000/*! * \file src/macro.h * * \brief Some commonly used macros not related to a special C-file. * * The file is included by global.h after const.h * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * Thomas.Nau@rz.uni-ulm.de */ #ifndef PCB_MACRO_H #define PCB_MACRO_H /* --------------------------------------------------------------------------- * macros to transform coord systems * draw.c uses a different definition of TO_SCREEN */ #ifndef SWAP_IDENT #define SWAP_IDENT Settings.ShowBottomSide #endif #define SWAP_SIGN_X(x) (x) #define SWAP_SIGN_Y(y) (-(y)) #define SWAP_ANGLE(a) (-(a)) #define SWAP_DELTA(d) (-(d)) #define SWAP_X(x) (SWAP_SIGN_X(x)) #define SWAP_Y(y) (PCB->MaxHeight +SWAP_SIGN_Y(y)) /* --------------------------------------------------------------------------- * misc macros, some might already be defined by */ #ifndef MIN #define MIN(a,b) ((a) < (b) ? (a) : (b)) #define MAX(a,b) ((a) > (b) ? (a) : (b)) #endif #ifndef SGN #define SGN(a) ((a) >0 ? 1 : ((a) == 0 ? 0 : -1)) #endif #define SGNZ(a) ((a) >=0 ? 1 : -1) #define MAKEMIN(a,b) if ((b) < (a)) (a) = (b) #define MAKEMAX(a,b) if ((b) > (a)) (a) = (b) #define ARG(n) (argc > (n) ? argv[n] : 0) #define ENTRIES(x) (sizeof((x))/sizeof((x)[0])) #define UNKNOWN(a) ((a) && *(a) ? (a) : "(unknown)") #define UNKNOWN_NAME(a, n) ((a) && *(a) ? (a) : (n)) #define NSTRCMP(a, b) ((a) ? ((b) ? strcmp((a),(b)) : 1) : -1) #define EMPTY(a) ((a) ? (a) : "") #define EMPTY_STRING_P(a) ((a) ? (a)[0]==0 : 1) #define XOR(a,b) (((a) && !(b)) || (!(a) && (b))) #define SQUARE(x) ((float) (x) * (float) (x)) #define TO_RADIANS(degrees) (M180 * (degrees)) /* Proper rounding for double -> Coord. */ #define DOUBLE_TO_COORD(x) ((x) >= 0 ? (Coord)((x) + 0.5) : (Coord)((x) - 0.5)) /* --------------------------------------------------------------------------- * layer macros */ #define LAYER_ON_STACK(n) (&PCB->Data->Layer[LayerStack[(n)]]) #define LAYER_PTR(n) (&PCB->Data->Layer[(n)]) #define CURRENT (PCB->SilkActive ? &PCB->Data->Layer[ \ (Settings.ShowBottomSide ? bottom_silk_layer : top_silk_layer)] \ : LAYER_ON_STACK(0)) #define INDEXOFCURRENT (PCB->SilkActive ? \ (Settings.ShowBottomSide ? bottom_silk_layer : top_silk_layer) \ : LayerStack[0]) #define SILKLAYER Layer[ \ (Settings.ShowBottomSide ? bottom_silk_layer : top_silk_layer)] #define BACKSILKLAYER Layer[ \ (Settings.ShowBottomSide ? top_silk_layer : bottom_silk_layer)] #define TEST_SILK_LAYER(layer) (GetLayerNumber (PCB->Data, layer) >= max_copper_layer) /* --------------------------------------------------------------------------- * returns the object ID */ #define OBJECT_ID(p) (((AnyObjectType *) p)->ID) /* --------------------------------------------------------------------------- * access macro for current buffer */ #define PASTEBUFFER (&Buffers[Settings.BufferNumber]) /* flag macros moved to flag.h */ /* --------------------------------------------------------------------------- * access macros for elements name structure */ #define DESCRIPTION_INDEX 0 #define NAMEONPCB_INDEX 1 #define VALUE_INDEX 2 #define NAME_INDEX(p) (TEST_FLAG(NAMEONPCBFLAG,(p)) ? NAMEONPCB_INDEX :\ (TEST_FLAG(DESCRIPTIONFLAG, (p)) ? \ DESCRIPTION_INDEX : VALUE_INDEX)) #define ELEMENT_NAME(p,e) ((e)->Name[NAME_INDEX((p))].TextString) #define DESCRIPTION_NAME(e) ((e)->Name[DESCRIPTION_INDEX].TextString) #define NAMEONPCB_NAME(e) ((e)->Name[NAMEONPCB_INDEX].TextString) #define VALUE_NAME(e) ((e)->Name[VALUE_INDEX].TextString) #define ELEMENT_TEXT(p,e) ((e)->Name[NAME_INDEX((p))]) #define DESCRIPTION_TEXT(e) ((e)->Name[DESCRIPTION_INDEX]) #define NAMEONPCB_TEXT(e) ((e)->Name[NAMEONPCB_INDEX]) #define VALUE_TEXT(e) ((e)->Name[VALUE_INDEX]) /* --------------------------------------------------------------------------- * Determines if text is actually visible */ #define TEXT_IS_VISIBLE(b, l, t) \ ((l)->On) /* --------------------------------------------------------------------------- * Determines if object is on front or back */ #define FRONT(o) \ ((TEST_FLAG(ONSOLDERFLAG, (o)) != 0) == SWAP_IDENT) /* --------------------------------------------------------------------------- * Determines if an object is on the given side. side is either BOTTOM_GROUP * or TOP_GROUP. */ #define ON_SIDE(element, side) \ (TEST_FLAG (ONSOLDERFLAG, element) == (side == BOTTOM_SIDE)) /* --------------------------------------------------------------------------- * some loop shortcuts * * a pointer is created from index addressing because the base pointer * may change when new memory is allocated; * * all data is relativ to an objects name 'top' which can be either * PCB or PasteBuffer */ #define END_LOOP }} while (0) #define STYLE_LOOP(top) do { \ Cardinal n; \ RouteStyleType *style; \ for (n = 0; n < NUM_STYLES; n++) \ { \ style = &(top)->RouteStyle[n] #define VIA_LOOP(top) do { \ GList *__iter, *__next; \ Cardinal n = 0; \ for (__iter = (top)->Via, __next = g_list_next (__iter); \ __iter != NULL; \ __iter = __next, __next = g_list_next (__iter), n++) { \ PinType *via = __iter->data; #define DRILL_LOOP(top) do { \ Cardinal n; \ DrillType *drill; \ for (n = 0; (top)->DrillN > 0 && n < (top)->DrillN; n++) \ { \ drill = &(top)->Drill[n] #define NETLIST_LOOP(top) do { \ Cardinal n; \ NetListType *netlist; \ for (n = (top)->NetListN-1; n != -1; n--) \ { \ netlist = &(top)->NetList[n] #define NET_LOOP(top) do { \ Cardinal n; \ NetType *net; \ for (n = (top)->NetN-1; n != -1; n--) \ { \ net = &(top)->Net[n] #define CONNECTION_LOOP(net) do { \ Cardinal n; \ ConnectionType *connection; \ for (n = (net)->ConnectionN-1; n != -1; n--) \ { \ connection = & (net)->Connection[n] #define ELEMENT_LOOP(top) do { \ GList *__iter, *__next; \ Cardinal n = 0; \ for (__iter = (top)->Element, __next = g_list_next (__iter); \ __iter != NULL; \ __iter = __next, __next = g_list_next (__iter), n++) { \ ElementType *element = __iter->data; #define RAT_LOOP(top) do { \ GList *__iter, *__next; \ Cardinal n = 0; \ for (__iter = (top)->Rat, __next = g_list_next (__iter); \ __iter != NULL; \ __iter = __next, __next = g_list_next (__iter), n++) { \ RatType *line = __iter->data; #define ELEMENTTEXT_LOOP(element) do { \ Cardinal n; \ TextType *text; \ for (n = MAX_ELEMENTNAMES-1; n != -1; n--) \ { \ text = &(element)->Name[n] #define ELEMENTNAME_LOOP(element) do { \ Cardinal n; \ char *textstring; \ for (n = MAX_ELEMENTNAMES-1; n != -1; n--) \ { \ textstring = (element)->Name[n].TextString #define PIN_LOOP(element) do { \ GList *__iter, *__next; \ Cardinal n = 0; \ for (__iter = (element)->Pin, __next = g_list_next (__iter); \ __iter != NULL; \ __iter = __next, __next = g_list_next (__iter), n++) { \ PinType *pin = __iter->data; #define PAD_LOOP(element) do { \ GList *__iter, *__next; \ Cardinal n = 0; \ for (__iter = (element)->Pad, __next = g_list_next (__iter); \ __iter != NULL; \ __iter = __next, __next = g_list_next (__iter), n++) { \ PadType *pad = __iter->data; #define ARC_LOOP(element) do { \ GList *__iter, *__next; \ Cardinal n = 0; \ for (__iter = (element)->Arc, __next = g_list_next (__iter); \ __iter != NULL; \ __iter = __next, __next = g_list_next (__iter), n++) { \ ArcType *arc = __iter->data; #define ELEMENTLINE_LOOP(element) do { \ GList *__iter, *__next; \ Cardinal n = 0; \ for (__iter = (element)->Line, __next = g_list_next (__iter); \ __iter != NULL; \ __iter = __next, __next = g_list_next (__iter), n++) { \ LineType *line = __iter->data; #define ELEMENTARC_LOOP(element) do { \ GList *__iter, *__next; \ Cardinal n = 0; \ for (__iter = (element)->Arc, __next = g_list_next (__iter); \ __iter != NULL; \ __iter = __next, __next = g_list_next (__iter), n++) { \ ArcType *arc = __iter->data; #define LINE_LOOP(layer) do { \ GList *__iter, *__next; \ Cardinal n = 0; \ for (__iter = (layer)->Line, __next = g_list_next (__iter); \ __iter != NULL; \ __iter = __next, __next = g_list_next (__iter), n++) { \ LineType *line = __iter->data; #define TEXT_LOOP(layer) do { \ GList *__iter, *__next; \ Cardinal n = 0; \ for (__iter = (layer)->Text, __next = g_list_next (__iter); \ __iter != NULL; \ __iter = __next, __next = g_list_next (__iter), n++) { \ TextType *text = __iter->data; #define POLYGON_LOOP(layer) do { \ GList *__iter, *__next; \ Cardinal n = 0; \ for (__iter = (layer)->Polygon, __next = g_list_next (__iter); \ __iter != NULL; \ __iter = __next, __next = g_list_next (__iter), n++) { \ PolygonType *polygon = __iter->data; #define POLYGONPOINT_LOOP(polygon) do { \ Cardinal n; \ PointType *point; \ for (n = (polygon)->PointN-1; n != -1; n--) \ { \ point = &(polygon)->Points[n] #define ENDALL_LOOP }} while (0); }} while(0) #define ALLPIN_LOOP(top) \ ELEMENT_LOOP(top); \ PIN_LOOP(element)\ #define ALLPAD_LOOP(top) \ ELEMENT_LOOP(top); \ PAD_LOOP(element) #define ALLLINE_LOOP(top) do { \ Cardinal l; \ LayerType *layer = (top)->Layer; \ for (l = 0; l < max_copper_layer + SILK_LAYER; l++, layer++) \ { \ LINE_LOOP(layer) #define ALLARC_LOOP(top) do { \ Cardinal l; \ LayerType *layer = (top)->Layer; \ for (l =0; l < max_copper_layer + SILK_LAYER; l++, layer++) \ { \ ARC_LOOP(layer) #define ALLPOLYGON_LOOP(top) do { \ Cardinal l; \ LayerType *layer = (top)->Layer; \ for (l = 0; l < max_copper_layer + SILK_LAYER; l++, layer++) \ { \ POLYGON_LOOP(layer) #define COPPERLINE_LOOP(top) do { \ Cardinal l; \ LayerType *layer = (top)->Layer; \ for (l = 0; l < max_copper_layer; l++, layer++) \ { \ LINE_LOOP(layer) #define COPPERARC_LOOP(top) do { \ Cardinal l; \ LayerType *layer = (top)->Layer; \ for (l =0; l < max_copper_layer; l++, layer++) \ { \ ARC_LOOP(layer) #define COPPERPOLYGON_LOOP(top) do { \ Cardinal l; \ LayerType *layer = (top)->Layer; \ for (l = 0; l < max_copper_layer; l++, layer++) \ { \ POLYGON_LOOP(layer) #define SILKLINE_LOOP(top) do { \ Cardinal l; \ LayerType *layer = (top)->Layer; \ layer += max_copper_layer + BOTTOM_SILK_LAYER; \ for (l = 0; l < 2; l++, layer++) \ { \ LINE_LOOP(layer) #define SILKARC_LOOP(top) do { \ Cardinal l; \ LayerType *layer = (top)->Layer; \ layer += max_copper_layer + BOTTOM_SILK_LAYER; \ for (l = 0; l < 2; l++, layer++) \ { \ ARC_LOOP(layer) #define SILKPOLYGON_LOOP(top) do { \ Cardinal l; \ LayerType *layer = (top)->Layer; \ layer += max_copper_layer + BOTTOM_SILK_LAYER; \ for (l = 0; l < 2; l++, layer++) \ { \ POLYGON_LOOP(layer) #define ALLTEXT_LOOP(top) do { \ Cardinal l; \ LayerType *layer = (top)->Layer; \ for (l = 0; l < max_copper_layer + SILK_LAYER; l++, layer++) \ { \ TEXT_LOOP(layer) #define VISIBLELINE_LOOP(top) do { \ Cardinal l; \ LayerType *layer = (top)->Layer; \ for (l = 0; l < max_copper_layer + SILK_LAYER; l++, layer++) \ { \ if (layer->On) \ LINE_LOOP(layer) #define VISIBLEARC_LOOP(top) do { \ Cardinal l; \ LayerType *layer = (top)->Layer; \ for (l = 0; l < max_copper_layer + SILK_LAYER; l++, layer++) \ { \ if (layer->On) \ ARC_LOOP(layer) #define VISIBLETEXT_LOOP(board) do { \ Cardinal l; \ LayerType *layer = (board)->Data->Layer; \ for (l = 0; l < max_copper_layer + SILK_LAYER; l++, layer++) \ { \ TEXT_LOOP(layer); \ if (TEXT_IS_VISIBLE((board), layer, text)) #define VISIBLEPOLYGON_LOOP(top) do { \ Cardinal l; \ LayerType *layer = (top)->Layer; \ for (l = 0; l < max_copper_layer + SILK_LAYER; l++, layer++) \ { \ if (layer->On) \ POLYGON_LOOP(layer) #define POINTER_LOOP(top) do { \ Cardinal n; \ void **ptr; \ for (n = (top)->PtrN-1; n != -1; n--) \ { \ ptr = &(top)->Ptr[n] #define MENU_LOOP(top) do { \ Cardinal l; \ LibraryMenuType *menu; \ for (l = (top)->MenuN-1; l != -1; l--) \ { \ menu = &(top)->Menu[l] #define ENTRY_LOOP(top) do { \ Cardinal n; \ LibraryEntryType *entry; \ for (n = (top)->EntryN-1; n != -1; n--) \ { \ entry = &(top)->Entry[n] #define GROUP_LOOP(data, group) do { \ Cardinal entry; \ for (entry = 0; entry < ((PCBType *)(data->pcb))->LayerGroups.Number[(group)]; entry++) \ { \ LayerType *layer; \ Cardinal number; \ number = ((PCBType *)(data->pcb))->LayerGroups.Entries[(group)][entry]; \ if (number >= max_copper_layer) \ continue; \ layer = &data->Layer[number]; #define LAYER_LOOP(data, ml) do { \ Cardinal n; \ for (n = 0; n < ml; n++) \ { \ LayerType *layer = (&data->Layer[(n)]); #define LAYER_TYPE_LOOP(data, ml, type) do { \ Cardinal n; \ for (n = 0; n < ml; n++) { \ LayerType *layer = (&data->Layer[(n)]); \ if (layer->Type != (type)) \ continue; #endif #define VIA_IS_BURIED(via) (via->BuriedFrom != 0 || via->BuriedTo != 0) #define VIA_ON_LAYER(via, layer) (layer >= via->BuriedFrom && layer <= via->BuriedTo ) pcb-4.3.0/src/edif.c0000664000175000017500000103005313773432516011064 00000000000000/* A Bison parser, made by GNU Bison 3.5.1. */ /* Bison implementation for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Undocumented macros, especially those whose name start with YY_, are private implementation details. Do not rely on them. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "3.5.1" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 0 /* Push parsers. */ #define YYPUSH 0 /* Pull parsers. */ #define YYPULL 1 /* Substitute the variable and function names. */ #define yyparse edifparse #define yylex ediflex #define yyerror ediferror #define yydebug edifdebug #define yynerrs edifnerrs #define yylval ediflval #define yychar edifchar /* First part of user prologue. */ #line 1 "edif.y" /* * PCB Edif parser based heavily on: * * Header: edif.y,v 1.18 87/12/07 19:59:49 roger Locked */ /************************************************************************ * * * edif.y * * * * EDIF 2.0.0 parser, Level 0 * * * * You are free to copy, distribute, use it, abuse it, make it * * write bad tracks all over the disk ... or anything else. * * * * Your friendly neighborhood Rogue Monster - roger@mips.com * * * ************************************************************************/ #include /* for malloc, free, atoi */ #include /* for strcpy */ #include #include #include "global.h" #include "data.h" /* from mymem.h, not include because of the malloc junk */ LibraryMenuType * GetLibraryMenuMemory (LibraryType *); LibraryEntryType * GetLibraryEntryMemory (LibraryMenuType *); /* * Local definitions. */ #define IDENT_LENGTH 255 #define Malloc(s) malloc(s) #define Free(p) free(p) #define Getc(s) getc(s) #define Ungetc(c) ungetc(c,Input) typedef struct _str_pair { char* str1; char* str2; struct _str_pair* next; } str_pair; typedef struct _pair_list { char* name; str_pair* list; } pair_list; str_pair* new_str_pair(char* s1, char* s2) { str_pair* ps = (str_pair *)malloc(sizeof(str_pair)); ps->str1 = s1; ps->str2 = s2; ps->next = NULL; return ps; } pair_list* new_pair_list(str_pair* ps) { pair_list* pl = (pair_list *)malloc(sizeof(pair_list)); pl->list = ps; pl->name = NULL; return pl; } void str_pair_free(str_pair* ps) { str_pair* node; while ( ps ) { free(ps->str1); free(ps->str2); node = ps; ps = ps->next; free(node); } } void pair_list_free(pair_list* pl) { str_pair_free(pl->list); free(pl->name); free(pl); } void define_pcb_net(str_pair* name, pair_list* nodes) { int tl; str_pair* done_node; str_pair* node; char* buf; char* p; LibraryEntryType *entry; LibraryMenuType *menu = GetLibraryMenuMemory (&PCB->NetlistLib); if ( !name->str1 ) { /* no net name given, stop now */ /* if renamed str2 also exists and must be freed */ if ( name->str2 ) free(name->str2); free(name); pair_list_free(nodes); return; } menu->Name = strdup (name->str1); free(name->str1); /* if renamed str2 also exists and must be freed */ if ( name->str2 ) free(name->str2); free(name); buf = (char *)malloc(256); if ( !buf ) { /* no memory */ pair_list_free(nodes); return; } node = nodes->list; free(nodes->name); free(nodes); while ( node ) { /* check for node with no instance */ if ( !node->str1 ) { /* toss it and move on */ free(node->str2); done_node = node; node = node->next; free(done_node); continue; } tl = strlen(node->str1) + strlen(node->str2); if ( tl + 3 > 256 ) { free(buf); buf = (char *)malloc(tl+3); if ( !buf ) { /* no memory */ str_pair_free(node); return; } } strcpy(buf,node->str1); /* make all upper case, because of PCB funky behaviour */ p=buf; while ( *p ) { *p = toupper( (int) *p); p++; } /* add dash separating designator from node */ *(buf+strlen(node->str1)) = '-'; /* check for the edif number prefix */ if ( node->str2[0] == '&' ) { /* skip number prefix */ strcpy(buf+strlen(node->str1)+1,node->str2 +1); } else { strcpy(buf+strlen(node->str1)+1,node->str2); } /* free the strings */ free(node->str1); free(node->str2); entry = GetLibraryEntryMemory (menu); entry->ListEntry = strdup(buf); done_node = node; node = node->next; free(done_node); } } /* forward function declarations */ static int yylex(void); static void yyerror(const char *); static void PopC(void); #line 267 "edif.c" # ifndef YY_CAST # ifdef __cplusplus # define YY_CAST(Type, Val) static_cast (Val) # define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) # else # define YY_CAST(Type, Val) ((Type) (Val)) # define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) # endif # endif # ifndef YY_NULLPTR # if defined __cplusplus # if 201103L <= __cplusplus # define YY_NULLPTR nullptr # else # define YY_NULLPTR 0 # endif # else # define YY_NULLPTR ((void*)0) # endif # endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif /* Use api.header.include to #include this header instead of duplicating it here. */ #ifndef YY_EDIF_Y_TAB_H_INCLUDED # define YY_EDIF_Y_TAB_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif #if YYDEBUG extern int edifdebug; #endif /* Token type. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE enum yytokentype { EDIF_TOK_IDENT = 258, EDIF_TOK_INT = 259, EDIF_TOK_KEYWORD = 260, EDIF_TOK_STR = 261, EDIF_TOK_ANGLE = 262, EDIF_TOK_BEHAVIOR = 263, EDIF_TOK_CALCULATED = 264, EDIF_TOK_CAPACITANCE = 265, EDIF_TOK_CENTERCENTER = 266, EDIF_TOK_CENTERLEFT = 267, EDIF_TOK_CENTERRIGHT = 268, EDIF_TOK_CHARGE = 269, EDIF_TOK_CONDUCTANCE = 270, EDIF_TOK_CURRENT = 271, EDIF_TOK_DISTANCE = 272, EDIF_TOK_DOCUMENT = 273, EDIF_TOK_ENERGY = 274, EDIF_TOK_EXTEND = 275, EDIF_TOK_FLUX = 276, EDIF_TOK_FREQUENCY = 277, EDIF_TOK_GENERIC = 278, EDIF_TOK_GRAPHIC = 279, EDIF_TOK_INDUCTANCE = 280, EDIF_TOK_INOUT = 281, EDIF_TOK_INPUT = 282, EDIF_TOK_LOGICMODEL = 283, EDIF_TOK_LOWERCENTER = 284, EDIF_TOK_LOWERLEFT = 285, EDIF_TOK_LOWERRIGHT = 286, EDIF_TOK_MASKLAYOUT = 287, EDIF_TOK_MASS = 288, EDIF_TOK_MEASURED = 289, EDIF_TOK_MX = 290, EDIF_TOK_MXR90 = 291, EDIF_TOK_MY = 292, EDIF_TOK_MYR90 = 293, EDIF_TOK_NETLIST = 294, EDIF_TOK_OUTPUT = 295, EDIF_TOK_PCBLAYOUT = 296, EDIF_TOK_POWER = 297, EDIF_TOK_R0 = 298, EDIF_TOK_R180 = 299, EDIF_TOK_R270 = 300, EDIF_TOK_R90 = 301, EDIF_TOK_REQUIRED = 302, EDIF_TOK_RESISTANCE = 303, EDIF_TOK_RIPPER = 304, EDIF_TOK_ROUND = 305, EDIF_TOK_SCHEMATIC = 306, EDIF_TOK_STRANGER = 307, EDIF_TOK_SYMBOLIC = 308, EDIF_TOK_TEMPERATURE = 309, EDIF_TOK_TIE = 310, EDIF_TOK_TIME = 311, EDIF_TOK_TRUNCATE = 312, EDIF_TOK_UPPERCENTER = 313, EDIF_TOK_UPPERLEFT = 314, EDIF_TOK_UPPERRIGHT = 315, EDIF_TOK_VOLTAGE = 316, EDIF_TOK_ACLOAD = 317, EDIF_TOK_AFTER = 318, EDIF_TOK_ANNOTATE = 319, EDIF_TOK_APPLY = 320, EDIF_TOK_ARC = 321, EDIF_TOK_ARRAY = 322, EDIF_TOK_ARRAYMACRO = 323, EDIF_TOK_ARRAYRELATEDINFO = 324, EDIF_TOK_ARRAYSITE = 325, EDIF_TOK_ATLEAST = 326, EDIF_TOK_ATMOST = 327, EDIF_TOK_AUTHOR = 328, EDIF_TOK_BASEARRAY = 329, EDIF_TOK_BECOMES = 330, EDIF_TOK_BETWEEN = 331, EDIF_TOK_BOOLEAN = 332, EDIF_TOK_BOOLEANDISPLAY = 333, EDIF_TOK_BOOLEANMAP = 334, EDIF_TOK_BORDERPATTERN = 335, EDIF_TOK_BORDERWIDTH = 336, EDIF_TOK_BOUNDINGBOX = 337, EDIF_TOK_CELL = 338, EDIF_TOK_CELLREF = 339, EDIF_TOK_CELLTYPE = 340, EDIF_TOK_CHANGE = 341, EDIF_TOK_CIRCLE = 342, EDIF_TOK_COLOR = 343, EDIF_TOK_COMMENT = 344, EDIF_TOK_COMMENTGRAPHICS = 345, EDIF_TOK_COMPOUND = 346, EDIF_TOK_CONNECTLOCATION = 347, EDIF_TOK_CONTENTS = 348, EDIF_TOK_CORNERTYPE = 349, EDIF_TOK_CRITICALITY = 350, EDIF_TOK_CURRENTMAP = 351, EDIF_TOK_CURVE = 352, EDIF_TOK_CYCLE = 353, EDIF_TOK_DATAORIGIN = 354, EDIF_TOK_DCFANINLOAD = 355, EDIF_TOK_DCFANOUTLOAD = 356, EDIF_TOK_DCMAXFANIN = 357, EDIF_TOK_DCMAXFANOUT = 358, EDIF_TOK_DELAY = 359, EDIF_TOK_DELTA = 360, EDIF_TOK_DERIVATION = 361, EDIF_TOK_DESIGN = 362, EDIF_TOK_DESIGNATOR = 363, EDIF_TOK_DIFFERENCE = 364, EDIF_TOK_DIRECTION = 365, EDIF_TOK_DISPLAY = 366, EDIF_TOK_DOMINATES = 367, EDIF_TOK_DOT = 368, EDIF_TOK_DURATION = 369, EDIF_TOK_E = 370, EDIF_TOK_EDIF = 371, EDIF_TOK_EDIFLEVEL = 372, EDIF_TOK_EDIFVERSION = 373, EDIF_TOK_ENCLOSUREDISTANCE = 374, EDIF_TOK_ENDTYPE = 375, EDIF_TOK_ENTRY = 376, EDIF_TOK_EVENT = 377, EDIF_TOK_EXACTLY = 378, EDIF_TOK_EXTERNAL = 379, EDIF_TOK_FABRICATE = 380, EDIF_TOK_FALSE = 381, EDIF_TOK_FIGURE = 382, EDIF_TOK_FIGUREAREA = 383, EDIF_TOK_FIGUREGROUP = 384, EDIF_TOK_FIGUREGROUPOBJECT = 385, EDIF_TOK_FIGUREGROUPOVERRIDE = 386, EDIF_TOK_FIGUREGROUPREF = 387, EDIF_TOK_FIGUREPERIMETER = 388, EDIF_TOK_FIGUREWIDTH = 389, EDIF_TOK_FILLPATTERN = 390, EDIF_TOK_FOLLOW = 391, EDIF_TOK_FORBIDDENEVENT = 392, EDIF_TOK_GLOBALPORTREF = 393, EDIF_TOK_GREATERTHAN = 394, EDIF_TOK_GRIDMAP = 395, EDIF_TOK_IGNORE = 396, EDIF_TOK_INCLUDEFIGUREGROUP = 397, EDIF_TOK_INITIAL = 398, EDIF_TOK_INSTANCE = 399, EDIF_TOK_INSTANCEBACKANNOTATE = 400, EDIF_TOK_INSTANCEGROUP = 401, EDIF_TOK_INSTANCEMAP = 402, EDIF_TOK_INSTANCEREF = 403, EDIF_TOK_INTEGER = 404, EDIF_TOK_INTEGERDISPLAY = 405, EDIF_TOK_INTERFACE = 406, EDIF_TOK_INTERFIGUREGROUPSPACING = 407, EDIF_TOK_INTERSECTION = 408, EDIF_TOK_INTRAFIGUREGROUPSPACING = 409, EDIF_TOK_INVERSE = 410, EDIF_TOK_ISOLATED = 411, EDIF_TOK_JOINED = 412, EDIF_TOK_JUSTIFY = 413, EDIF_TOK_KEYWORDDISPLAY = 414, EDIF_TOK_KEYWORDLEVEL = 415, EDIF_TOK_KEYWORDMAP = 416, EDIF_TOK_LESSTHAN = 417, EDIF_TOK_LIBRARY = 418, EDIF_TOK_LIBRARYREF = 419, EDIF_TOK_LISTOFNETS = 420, EDIF_TOK_LISTOFPORTS = 421, EDIF_TOK_LOADDELAY = 422, EDIF_TOK_LOGICASSIGN = 423, EDIF_TOK_LOGICINPUT = 424, EDIF_TOK_LOGICLIST = 425, EDIF_TOK_LOGICMAPINPUT = 426, EDIF_TOK_LOGICMAPOUTPUT = 427, EDIF_TOK_LOGICONEOF = 428, EDIF_TOK_LOGICOUTPUT = 429, EDIF_TOK_LOGICPORT = 430, EDIF_TOK_LOGICREF = 431, EDIF_TOK_LOGICVALUE = 432, EDIF_TOK_LOGICWAVEFORM = 433, EDIF_TOK_MAINTAIN = 434, EDIF_TOK_MATCH = 435, EDIF_TOK_MEMBER = 436, EDIF_TOK_MINOMAX = 437, EDIF_TOK_MINOMAXDISPLAY = 438, EDIF_TOK_MNM = 439, EDIF_TOK_MULTIPLEVALUESET = 440, EDIF_TOK_MUSTJOIN = 441, EDIF_TOK_NAME = 442, EDIF_TOK_NET = 443, EDIF_TOK_NETBACKANNOTATE = 444, EDIF_TOK_NETBUNDLE = 445, EDIF_TOK_NETDELAY = 446, EDIF_TOK_NETGROUP = 447, EDIF_TOK_NETMAP = 448, EDIF_TOK_NETREF = 449, EDIF_TOK_NOCHANGE = 450, EDIF_TOK_NONPERMUTABLE = 451, EDIF_TOK_NOTALLOWED = 452, EDIF_TOK_NOTCHSPACING = 453, EDIF_TOK_NUMBER = 454, EDIF_TOK_NUMBERDEFINITION = 455, EDIF_TOK_NUMBERDISPLAY = 456, EDIF_TOK_OFFPAGECONNECTOR = 457, EDIF_TOK_OFFSETEVENT = 458, EDIF_TOK_OPENSHAPE = 459, EDIF_TOK_ORIENTATION = 460, EDIF_TOK_ORIGIN = 461, EDIF_TOK_OVERHANGDISTANCE = 462, EDIF_TOK_OVERLAPDISTANCE = 463, EDIF_TOK_OVERSIZE = 464, EDIF_TOK_OWNER = 465, EDIF_TOK_PAGE = 466, EDIF_TOK_PAGESIZE = 467, EDIF_TOK_PARAMETER = 468, EDIF_TOK_PARAMETERASSIGN = 469, EDIF_TOK_PARAMETERDISPLAY = 470, EDIF_TOK_PATH = 471, EDIF_TOK_PATHDELAY = 472, EDIF_TOK_PATHWIDTH = 473, EDIF_TOK_PERMUTABLE = 474, EDIF_TOK_PHYSICALDESIGNRULE = 475, EDIF_TOK_PLUG = 476, EDIF_TOK_POINT = 477, EDIF_TOK_POINTDISPLAY = 478, EDIF_TOK_POINTLIST = 479, EDIF_TOK_POLYGON = 480, EDIF_TOK_PORT = 481, EDIF_TOK_PORTBACKANNOTATE = 482, EDIF_TOK_PORTBUNDLE = 483, EDIF_TOK_PORTDELAY = 484, EDIF_TOK_PORTGROUP = 485, EDIF_TOK_PORTIMPLEMENTATION = 486, EDIF_TOK_PORTINSTANCE = 487, EDIF_TOK_PORTLIST = 488, EDIF_TOK_PORTLISTALIAS = 489, EDIF_TOK_PORTMAP = 490, EDIF_TOK_PORTREF = 491, EDIF_TOK_PROGRAM = 492, EDIF_TOK_PROPERTY = 493, EDIF_TOK_PROPERTYDISPLAY = 494, EDIF_TOK_PROTECTIONFRAME = 495, EDIF_TOK_PT = 496, EDIF_TOK_RANGEVECTOR = 497, EDIF_TOK_RECTANGLE = 498, EDIF_TOK_RECTANGLESIZE = 499, EDIF_TOK_RENAME = 500, EDIF_TOK_RESOLVES = 501, EDIF_TOK_SCALE = 502, EDIF_TOK_SCALEX = 503, EDIF_TOK_SCALEY = 504, EDIF_TOK_SECTION = 505, EDIF_TOK_SHAPE = 506, EDIF_TOK_SIMULATE = 507, EDIF_TOK_SIMULATIONINFO = 508, EDIF_TOK_SINGLEVALUESET = 509, EDIF_TOK_SITE = 510, EDIF_TOK_SOCKET = 511, EDIF_TOK_SOCKETSET = 512, EDIF_TOK_STATUS = 513, EDIF_TOK_STEADY = 514, EDIF_TOK_STRING = 515, EDIF_TOK_STRINGDISPLAY = 516, EDIF_TOK_STRONG = 517, EDIF_TOK_SYMBOL = 518, EDIF_TOK_SYMMETRY = 519, EDIF_TOK_TABLE = 520, EDIF_TOK_TABLEDEFAULT = 521, EDIF_TOK_TECHNOLOGY = 522, EDIF_TOK_TEXTHEIGHT = 523, EDIF_TOK_TIMEINTERVAL = 524, EDIF_TOK_TIMESTAMP = 525, EDIF_TOK_TIMING = 526, EDIF_TOK_TRANSFORM = 527, EDIF_TOK_TRANSITION = 528, EDIF_TOK_TRIGGER = 529, EDIF_TOK_TRUE = 530, EDIF_TOK_UNCONSTRAINED = 531, EDIF_TOK_UNDEFINED = 532, EDIF_TOK_UNION = 533, EDIF_TOK_UNIT = 534, EDIF_TOK_UNUSED = 535, EDIF_TOK_USERDATA = 536, EDIF_TOK_VERSION = 537, EDIF_TOK_VIEW = 538, EDIF_TOK_VIEWLIST = 539, EDIF_TOK_VIEWMAP = 540, EDIF_TOK_VIEWREF = 541, EDIF_TOK_VIEWTYPE = 542, EDIF_TOK_VISIBLE = 543, EDIF_TOK_VOLTAGEMAP = 544, EDIF_TOK_WAVEVALUE = 545, EDIF_TOK_WEAK = 546, EDIF_TOK_WEAKJOINED = 547, EDIF_TOK_WHEN = 548, EDIF_TOK_WRITTEN = 549 }; #endif /* Tokens. */ #define EDIF_TOK_IDENT 258 #define EDIF_TOK_INT 259 #define EDIF_TOK_KEYWORD 260 #define EDIF_TOK_STR 261 #define EDIF_TOK_ANGLE 262 #define EDIF_TOK_BEHAVIOR 263 #define EDIF_TOK_CALCULATED 264 #define EDIF_TOK_CAPACITANCE 265 #define EDIF_TOK_CENTERCENTER 266 #define EDIF_TOK_CENTERLEFT 267 #define EDIF_TOK_CENTERRIGHT 268 #define EDIF_TOK_CHARGE 269 #define EDIF_TOK_CONDUCTANCE 270 #define EDIF_TOK_CURRENT 271 #define EDIF_TOK_DISTANCE 272 #define EDIF_TOK_DOCUMENT 273 #define EDIF_TOK_ENERGY 274 #define EDIF_TOK_EXTEND 275 #define EDIF_TOK_FLUX 276 #define EDIF_TOK_FREQUENCY 277 #define EDIF_TOK_GENERIC 278 #define EDIF_TOK_GRAPHIC 279 #define EDIF_TOK_INDUCTANCE 280 #define EDIF_TOK_INOUT 281 #define EDIF_TOK_INPUT 282 #define EDIF_TOK_LOGICMODEL 283 #define EDIF_TOK_LOWERCENTER 284 #define EDIF_TOK_LOWERLEFT 285 #define EDIF_TOK_LOWERRIGHT 286 #define EDIF_TOK_MASKLAYOUT 287 #define EDIF_TOK_MASS 288 #define EDIF_TOK_MEASURED 289 #define EDIF_TOK_MX 290 #define EDIF_TOK_MXR90 291 #define EDIF_TOK_MY 292 #define EDIF_TOK_MYR90 293 #define EDIF_TOK_NETLIST 294 #define EDIF_TOK_OUTPUT 295 #define EDIF_TOK_PCBLAYOUT 296 #define EDIF_TOK_POWER 297 #define EDIF_TOK_R0 298 #define EDIF_TOK_R180 299 #define EDIF_TOK_R270 300 #define EDIF_TOK_R90 301 #define EDIF_TOK_REQUIRED 302 #define EDIF_TOK_RESISTANCE 303 #define EDIF_TOK_RIPPER 304 #define EDIF_TOK_ROUND 305 #define EDIF_TOK_SCHEMATIC 306 #define EDIF_TOK_STRANGER 307 #define EDIF_TOK_SYMBOLIC 308 #define EDIF_TOK_TEMPERATURE 309 #define EDIF_TOK_TIE 310 #define EDIF_TOK_TIME 311 #define EDIF_TOK_TRUNCATE 312 #define EDIF_TOK_UPPERCENTER 313 #define EDIF_TOK_UPPERLEFT 314 #define EDIF_TOK_UPPERRIGHT 315 #define EDIF_TOK_VOLTAGE 316 #define EDIF_TOK_ACLOAD 317 #define EDIF_TOK_AFTER 318 #define EDIF_TOK_ANNOTATE 319 #define EDIF_TOK_APPLY 320 #define EDIF_TOK_ARC 321 #define EDIF_TOK_ARRAY 322 #define EDIF_TOK_ARRAYMACRO 323 #define EDIF_TOK_ARRAYRELATEDINFO 324 #define EDIF_TOK_ARRAYSITE 325 #define EDIF_TOK_ATLEAST 326 #define EDIF_TOK_ATMOST 327 #define EDIF_TOK_AUTHOR 328 #define EDIF_TOK_BASEARRAY 329 #define EDIF_TOK_BECOMES 330 #define EDIF_TOK_BETWEEN 331 #define EDIF_TOK_BOOLEAN 332 #define EDIF_TOK_BOOLEANDISPLAY 333 #define EDIF_TOK_BOOLEANMAP 334 #define EDIF_TOK_BORDERPATTERN 335 #define EDIF_TOK_BORDERWIDTH 336 #define EDIF_TOK_BOUNDINGBOX 337 #define EDIF_TOK_CELL 338 #define EDIF_TOK_CELLREF 339 #define EDIF_TOK_CELLTYPE 340 #define EDIF_TOK_CHANGE 341 #define EDIF_TOK_CIRCLE 342 #define EDIF_TOK_COLOR 343 #define EDIF_TOK_COMMENT 344 #define EDIF_TOK_COMMENTGRAPHICS 345 #define EDIF_TOK_COMPOUND 346 #define EDIF_TOK_CONNECTLOCATION 347 #define EDIF_TOK_CONTENTS 348 #define EDIF_TOK_CORNERTYPE 349 #define EDIF_TOK_CRITICALITY 350 #define EDIF_TOK_CURRENTMAP 351 #define EDIF_TOK_CURVE 352 #define EDIF_TOK_CYCLE 353 #define EDIF_TOK_DATAORIGIN 354 #define EDIF_TOK_DCFANINLOAD 355 #define EDIF_TOK_DCFANOUTLOAD 356 #define EDIF_TOK_DCMAXFANIN 357 #define EDIF_TOK_DCMAXFANOUT 358 #define EDIF_TOK_DELAY 359 #define EDIF_TOK_DELTA 360 #define EDIF_TOK_DERIVATION 361 #define EDIF_TOK_DESIGN 362 #define EDIF_TOK_DESIGNATOR 363 #define EDIF_TOK_DIFFERENCE 364 #define EDIF_TOK_DIRECTION 365 #define EDIF_TOK_DISPLAY 366 #define EDIF_TOK_DOMINATES 367 #define EDIF_TOK_DOT 368 #define EDIF_TOK_DURATION 369 #define EDIF_TOK_E 370 #define EDIF_TOK_EDIF 371 #define EDIF_TOK_EDIFLEVEL 372 #define EDIF_TOK_EDIFVERSION 373 #define EDIF_TOK_ENCLOSUREDISTANCE 374 #define EDIF_TOK_ENDTYPE 375 #define EDIF_TOK_ENTRY 376 #define EDIF_TOK_EVENT 377 #define EDIF_TOK_EXACTLY 378 #define EDIF_TOK_EXTERNAL 379 #define EDIF_TOK_FABRICATE 380 #define EDIF_TOK_FALSE 381 #define EDIF_TOK_FIGURE 382 #define EDIF_TOK_FIGUREAREA 383 #define EDIF_TOK_FIGUREGROUP 384 #define EDIF_TOK_FIGUREGROUPOBJECT 385 #define EDIF_TOK_FIGUREGROUPOVERRIDE 386 #define EDIF_TOK_FIGUREGROUPREF 387 #define EDIF_TOK_FIGUREPERIMETER 388 #define EDIF_TOK_FIGUREWIDTH 389 #define EDIF_TOK_FILLPATTERN 390 #define EDIF_TOK_FOLLOW 391 #define EDIF_TOK_FORBIDDENEVENT 392 #define EDIF_TOK_GLOBALPORTREF 393 #define EDIF_TOK_GREATERTHAN 394 #define EDIF_TOK_GRIDMAP 395 #define EDIF_TOK_IGNORE 396 #define EDIF_TOK_INCLUDEFIGUREGROUP 397 #define EDIF_TOK_INITIAL 398 #define EDIF_TOK_INSTANCE 399 #define EDIF_TOK_INSTANCEBACKANNOTATE 400 #define EDIF_TOK_INSTANCEGROUP 401 #define EDIF_TOK_INSTANCEMAP 402 #define EDIF_TOK_INSTANCEREF 403 #define EDIF_TOK_INTEGER 404 #define EDIF_TOK_INTEGERDISPLAY 405 #define EDIF_TOK_INTERFACE 406 #define EDIF_TOK_INTERFIGUREGROUPSPACING 407 #define EDIF_TOK_INTERSECTION 408 #define EDIF_TOK_INTRAFIGUREGROUPSPACING 409 #define EDIF_TOK_INVERSE 410 #define EDIF_TOK_ISOLATED 411 #define EDIF_TOK_JOINED 412 #define EDIF_TOK_JUSTIFY 413 #define EDIF_TOK_KEYWORDDISPLAY 414 #define EDIF_TOK_KEYWORDLEVEL 415 #define EDIF_TOK_KEYWORDMAP 416 #define EDIF_TOK_LESSTHAN 417 #define EDIF_TOK_LIBRARY 418 #define EDIF_TOK_LIBRARYREF 419 #define EDIF_TOK_LISTOFNETS 420 #define EDIF_TOK_LISTOFPORTS 421 #define EDIF_TOK_LOADDELAY 422 #define EDIF_TOK_LOGICASSIGN 423 #define EDIF_TOK_LOGICINPUT 424 #define EDIF_TOK_LOGICLIST 425 #define EDIF_TOK_LOGICMAPINPUT 426 #define EDIF_TOK_LOGICMAPOUTPUT 427 #define EDIF_TOK_LOGICONEOF 428 #define EDIF_TOK_LOGICOUTPUT 429 #define EDIF_TOK_LOGICPORT 430 #define EDIF_TOK_LOGICREF 431 #define EDIF_TOK_LOGICVALUE 432 #define EDIF_TOK_LOGICWAVEFORM 433 #define EDIF_TOK_MAINTAIN 434 #define EDIF_TOK_MATCH 435 #define EDIF_TOK_MEMBER 436 #define EDIF_TOK_MINOMAX 437 #define EDIF_TOK_MINOMAXDISPLAY 438 #define EDIF_TOK_MNM 439 #define EDIF_TOK_MULTIPLEVALUESET 440 #define EDIF_TOK_MUSTJOIN 441 #define EDIF_TOK_NAME 442 #define EDIF_TOK_NET 443 #define EDIF_TOK_NETBACKANNOTATE 444 #define EDIF_TOK_NETBUNDLE 445 #define EDIF_TOK_NETDELAY 446 #define EDIF_TOK_NETGROUP 447 #define EDIF_TOK_NETMAP 448 #define EDIF_TOK_NETREF 449 #define EDIF_TOK_NOCHANGE 450 #define EDIF_TOK_NONPERMUTABLE 451 #define EDIF_TOK_NOTALLOWED 452 #define EDIF_TOK_NOTCHSPACING 453 #define EDIF_TOK_NUMBER 454 #define EDIF_TOK_NUMBERDEFINITION 455 #define EDIF_TOK_NUMBERDISPLAY 456 #define EDIF_TOK_OFFPAGECONNECTOR 457 #define EDIF_TOK_OFFSETEVENT 458 #define EDIF_TOK_OPENSHAPE 459 #define EDIF_TOK_ORIENTATION 460 #define EDIF_TOK_ORIGIN 461 #define EDIF_TOK_OVERHANGDISTANCE 462 #define EDIF_TOK_OVERLAPDISTANCE 463 #define EDIF_TOK_OVERSIZE 464 #define EDIF_TOK_OWNER 465 #define EDIF_TOK_PAGE 466 #define EDIF_TOK_PAGESIZE 467 #define EDIF_TOK_PARAMETER 468 #define EDIF_TOK_PARAMETERASSIGN 469 #define EDIF_TOK_PARAMETERDISPLAY 470 #define EDIF_TOK_PATH 471 #define EDIF_TOK_PATHDELAY 472 #define EDIF_TOK_PATHWIDTH 473 #define EDIF_TOK_PERMUTABLE 474 #define EDIF_TOK_PHYSICALDESIGNRULE 475 #define EDIF_TOK_PLUG 476 #define EDIF_TOK_POINT 477 #define EDIF_TOK_POINTDISPLAY 478 #define EDIF_TOK_POINTLIST 479 #define EDIF_TOK_POLYGON 480 #define EDIF_TOK_PORT 481 #define EDIF_TOK_PORTBACKANNOTATE 482 #define EDIF_TOK_PORTBUNDLE 483 #define EDIF_TOK_PORTDELAY 484 #define EDIF_TOK_PORTGROUP 485 #define EDIF_TOK_PORTIMPLEMENTATION 486 #define EDIF_TOK_PORTINSTANCE 487 #define EDIF_TOK_PORTLIST 488 #define EDIF_TOK_PORTLISTALIAS 489 #define EDIF_TOK_PORTMAP 490 #define EDIF_TOK_PORTREF 491 #define EDIF_TOK_PROGRAM 492 #define EDIF_TOK_PROPERTY 493 #define EDIF_TOK_PROPERTYDISPLAY 494 #define EDIF_TOK_PROTECTIONFRAME 495 #define EDIF_TOK_PT 496 #define EDIF_TOK_RANGEVECTOR 497 #define EDIF_TOK_RECTANGLE 498 #define EDIF_TOK_RECTANGLESIZE 499 #define EDIF_TOK_RENAME 500 #define EDIF_TOK_RESOLVES 501 #define EDIF_TOK_SCALE 502 #define EDIF_TOK_SCALEX 503 #define EDIF_TOK_SCALEY 504 #define EDIF_TOK_SECTION 505 #define EDIF_TOK_SHAPE 506 #define EDIF_TOK_SIMULATE 507 #define EDIF_TOK_SIMULATIONINFO 508 #define EDIF_TOK_SINGLEVALUESET 509 #define EDIF_TOK_SITE 510 #define EDIF_TOK_SOCKET 511 #define EDIF_TOK_SOCKETSET 512 #define EDIF_TOK_STATUS 513 #define EDIF_TOK_STEADY 514 #define EDIF_TOK_STRING 515 #define EDIF_TOK_STRINGDISPLAY 516 #define EDIF_TOK_STRONG 517 #define EDIF_TOK_SYMBOL 518 #define EDIF_TOK_SYMMETRY 519 #define EDIF_TOK_TABLE 520 #define EDIF_TOK_TABLEDEFAULT 521 #define EDIF_TOK_TECHNOLOGY 522 #define EDIF_TOK_TEXTHEIGHT 523 #define EDIF_TOK_TIMEINTERVAL 524 #define EDIF_TOK_TIMESTAMP 525 #define EDIF_TOK_TIMING 526 #define EDIF_TOK_TRANSFORM 527 #define EDIF_TOK_TRANSITION 528 #define EDIF_TOK_TRIGGER 529 #define EDIF_TOK_TRUE 530 #define EDIF_TOK_UNCONSTRAINED 531 #define EDIF_TOK_UNDEFINED 532 #define EDIF_TOK_UNION 533 #define EDIF_TOK_UNIT 534 #define EDIF_TOK_UNUSED 535 #define EDIF_TOK_USERDATA 536 #define EDIF_TOK_VERSION 537 #define EDIF_TOK_VIEW 538 #define EDIF_TOK_VIEWLIST 539 #define EDIF_TOK_VIEWMAP 540 #define EDIF_TOK_VIEWREF 541 #define EDIF_TOK_VIEWTYPE 542 #define EDIF_TOK_VISIBLE 543 #define EDIF_TOK_VOLTAGEMAP 544 #define EDIF_TOK_WAVEVALUE 545 #define EDIF_TOK_WEAK 546 #define EDIF_TOK_WEAKJOINED 547 #define EDIF_TOK_WHEN 548 #define EDIF_TOK_WRITTEN 549 /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { #line 193 "edif.y" char* s; pair_list* pl; str_pair* ps; #line 913 "edif.c" }; typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif extern YYSTYPE ediflval; int edifparse (void); #endif /* !YY_EDIF_Y_TAB_H_INCLUDED */ #ifdef short # undef short #endif /* On compilers that do not define __PTRDIFF_MAX__ etc., make sure and (if available) are included so that the code can choose integer types of a good width. */ #ifndef __PTRDIFF_MAX__ # include /* INFRINGES ON USER NAME SPACE */ # if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ # include /* INFRINGES ON USER NAME SPACE */ # define YY_STDINT_H # endif #endif /* Narrow types that promote to a signed type and that can represent a signed or unsigned integer of at least N bits. In tables they can save space and decrease cache pressure. Promoting to a signed type helps avoid bugs in integer arithmetic. */ #ifdef __INT_LEAST8_MAX__ typedef __INT_LEAST8_TYPE__ yytype_int8; #elif defined YY_STDINT_H typedef int_least8_t yytype_int8; #else typedef signed char yytype_int8; #endif #ifdef __INT_LEAST16_MAX__ typedef __INT_LEAST16_TYPE__ yytype_int16; #elif defined YY_STDINT_H typedef int_least16_t yytype_int16; #else typedef short yytype_int16; #endif #if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ typedef __UINT_LEAST8_TYPE__ yytype_uint8; #elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ && UINT_LEAST8_MAX <= INT_MAX) typedef uint_least8_t yytype_uint8; #elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX typedef unsigned char yytype_uint8; #else typedef short yytype_uint8; #endif #if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ typedef __UINT_LEAST16_TYPE__ yytype_uint16; #elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ && UINT_LEAST16_MAX <= INT_MAX) typedef uint_least16_t yytype_uint16; #elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX typedef unsigned short yytype_uint16; #else typedef int yytype_uint16; #endif #ifndef YYPTRDIFF_T # if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ # define YYPTRDIFF_T __PTRDIFF_TYPE__ # define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ # elif defined PTRDIFF_MAX # ifndef ptrdiff_t # include /* INFRINGES ON USER NAME SPACE */ # endif # define YYPTRDIFF_T ptrdiff_t # define YYPTRDIFF_MAXIMUM PTRDIFF_MAX # else # define YYPTRDIFF_T long # define YYPTRDIFF_MAXIMUM LONG_MAX # endif #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned # endif #endif #define YYSIZE_MAXIMUM \ YY_CAST (YYPTRDIFF_T, \ (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ ? YYPTRDIFF_MAXIMUM \ : YY_CAST (YYSIZE_T, -1))) #define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) /* Stored state numbers (used for stacks). */ typedef yytype_int16 yy_state_t; /* State numbers in computations. */ typedef int yy_state_fast_t; #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ # define YY_(Msgid) dgettext ("bison-runtime", Msgid) # endif # endif # ifndef YY_ # define YY_(Msgid) Msgid # endif #endif #ifndef YY_ATTRIBUTE_PURE # if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) # define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) # else # define YY_ATTRIBUTE_PURE # endif #endif #ifndef YY_ATTRIBUTE_UNUSED # if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) # define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) # else # define YY_ATTRIBUTE_UNUSED # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(E) ((void) (E)) #else # define YYUSE(E) /* empty */ #endif #if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ /* Suppress an incorrect diagnostic about yylval being uninitialized. */ # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") # define YY_IGNORE_MAYBE_UNINITIALIZED_END \ _Pragma ("GCC diagnostic pop") #else # define YY_INITIAL_VALUE(Value) Value #endif #ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_END #endif #ifndef YY_INITIAL_VALUE # define YY_INITIAL_VALUE(Value) /* Nothing. */ #endif #if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ # define YY_IGNORE_USELESS_CAST_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") # define YY_IGNORE_USELESS_CAST_END \ _Pragma ("GCC diagnostic pop") #endif #ifndef YY_IGNORE_USELESS_CAST_BEGIN # define YY_IGNORE_USELESS_CAST_BEGIN # define YY_IGNORE_USELESS_CAST_END #endif #define YY_ASSERT(E) ((void) (0 && (E))) #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS # include /* INFRINGES ON USER NAME SPACE */ /* Use EXIT_SUCCESS as a witness for stdlib.h. */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's 'empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined EXIT_SUCCESS \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined EXIT_SUCCESS void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined EXIT_SUCCESS void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yy_state_t yyss_alloc; YYSTYPE yyvs_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) # define YYCOPY_NEEDED 1 /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ YYPTRDIFF_T yynewbytes; \ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ Stack = &yyptr->Stack_alloc; \ yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / YYSIZEOF (*yyptr); \ } \ while (0) #endif #if defined YYCOPY_NEEDED && YYCOPY_NEEDED /* Copy COUNT objects from SRC to DST. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(Dst, Src, Count) \ __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) # else # define YYCOPY(Dst, Src, Count) \ do \ { \ YYPTRDIFF_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (Dst)[yyi] = (Src)[yyi]; \ } \ while (0) # endif # endif #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ #define YYFINAL 11 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 2619 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 296 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 472 /* YYNRULES -- Number of rules. */ #define YYNRULES 1129 /* YYNSTATES -- Number of states. */ #define YYNSTATES 1626 #define YYUNDEFTOK 2 #define YYMAXUTOK 549 /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM as returned by yylex, with out-of-bounds checking. */ #define YYTRANSLATE(YYX) \ (0 <= (YYX) && (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM as returned by yylex. */ static const yytype_int16 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 295, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int16 yyrline[] = { 0, 505, 505, 508, 511, 512, 513, 514, 515, 516, 517, 520, 523, 526, 530, 533, 534, 537, 540, 541, 542, 543, 544, 545, 548, 551, 552, 555, 558, 559, 560, 561, 562, 565, 568, 571, 572, 575, 578, 581, 582, 583, 584, 585, 588, 591, 594, 597, 600, 603, 606, 607, 608, 611, 614, 615, 618, 619, 622, 625, 626, 627, 628, 631, 634, 635, 638, 641, 642, 645, 648, 651, 654, 657, 658, 659, 660, 661, 662, 663, 666, 669, 672, 673, 676, 679, 682, 683, 684, 687, 690, 691, 692, 695, 696, 697, 700, 703, 704, 707, 710, 713, 714, 717, 720, 721, 722, 723, 724, 725, 726, 727, 730, 733, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 756, 759, 760, 763, 766, 767, 768, 771, 774, 775, 778, 781, 784, 785, 786, 789, 792, 793, 796, 799, 800, 803, 806, 807, 810, 813, 814, 817, 820, 821, 824, 827, 828, 831, 834, 835, 838, 841, 842, 845, 848, 849, 850, 853, 856, 857, 858, 859, 860, 863, 866, 867, 870, 873, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 893, 896, 897, 898, 899, 902, 905, 906, 907, 910, 913, 914, 917, 918, 921, 922, 925, 926, 929, 932, 933, 936, 939, 940, 943, 946, 950, 951, 952, 953, 956, 959, 960, 961, 964, 968, 969, 970, 973, 974, 975, 976, 979, 980, 981, 984, 987, 988, 989, 990, 991, 992, 993, 996, 999, 1002, 1003, 1004, 1005, 1006, 1009, 1012, 1015, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1034, 1037, 1040, 1043, 1044, 1045, 1048, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1066, 1069, 1070, 1073, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1089, 1092, 1093, 1094, 1095, 1098, 1099, 1100, 1101, 1102, 1105, 1108, 1109, 1110, 1111, 1114, 1117, 1118, 1119, 1120, 1123, 1126, 1129, 1130, 1133, 1134, 1135, 1136, 1139, 1142, 1143, 1146, 1149, 1150, 1151, 1152, 1153, 1156, 1159, 1162, 1165, 1168, 1171, 1172, 1175, 1178, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1193, 1196, 1197, 1198, 1201, 1204, 1205, 1206, 1207, 1208, 1211, 1214, 1215, 1218, 1221, 1222, 1223, 1224, 1225, 1228, 1229, 1232, 1233, 1236, 1239, 1240, 1243, 1246, 1247, 1248, 1249, 1252, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1265, 1266, 1267, 1268, 1269, 1270, 1271, 1274, 1278, 1279, 1280, 1281, 1284, 1287, 1288, 1289, 1290, 1293, 1296, 1297, 1298, 1299, 1302, 1305, 1306, 1309, 1312, 1315, 1316, 1317, 1318, 1321, 1324, 1325, 1326, 1327, 1328, 1329, 1330, 1331, 1332, 1335, 1338, 1339, 1342, 1345, 1348, 1349, 1352, 1355, 1358, 1361, 1364, 1367, 1370, 1371, 1372, 1373, 1374, 1377, 1380, 1383, 1384, 1387, 1390, 1391, 1392, 1395, 1398, 1399, 1402, 1405, 1406, 1409, 1410, 1411, 1414, 1415, 1416, 1419, 1422, 1423, 1424, 1425, 1428, 1431, 1432, 1433, 1434, 1437, 1440, 1441, 1444, 1447, 1448, 1451, 1454, 1457, 1460, 1461, 1462, 1465, 1468, 1469, 1470, 1471, 1474, 1477, 1478, 1479, 1480, 1483, 1486, 1487, 1490, 1493, 1494, 1495, 1496, 1497, 1498, 1499, 1500, 1501, 1502, 1503, 1504, 1505, 1506, 1507, 1510, 1513, 1514, 1515, 1516, 1517, 1520, 1523, 1524, 1527, 1528, 1529, 1532, 1535, 1536, 1537, 1540, 1541, 1542, 1545, 1548, 1549, 1552, 1555, 1556, 1557, 1558, 1561, 1564, 1565, 1568, 1569, 1572, 1575, 1576, 1577, 1580, 1583, 1584, 1587, 1590, 1591, 1592, 1593, 1594, 1597, 1600, 1601, 1604, 1605, 1606, 1609, 1610, 1613, 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623, 1624, 1625, 1628, 1631, 1632, 1633, 1634, 1635, 1638, 1641, 1642, 1643, 1644, 1645, 1646, 1649, 1652, 1653, 1654, 1657, 1660, 1661, 1662, 1665, 1668, 1669, 1670, 1671, 1672, 1675, 1676, 1680, 1681, 1684, 1687, 1688, 1689, 1690, 1693, 1696, 1699, 1700, 1701, 1704, 1707, 1708, 1709, 1712, 1715, 1716, 1717, 1718, 1721, 1724, 1725, 1726, 1727, 1730, 1733, 1734, 1737, 1740, 1741, 1742, 1743, 1746, 1749, 1750, 1751, 1752, 1753, 1756, 1759, 1762, 1763, 1766, 1769, 1770, 1771, 1772, 1773, 1774, 1775, 1776, 1779, 1782, 1786, 1787, 1788, 1789, 1792, 1796, 1797, 1798, 1799, 1802, 1805, 1806, 1809, 1812, 1815, 1816, 1817, 1818, 1819, 1820, 1821, 1822, 1823, 1824, 1827, 1830, 1833, 1834, 1837, 1840, 1841, 1844, 1847, 1850, 1851, 1854, 1857, 1858, 1861, 1864, 1867, 1868, 1869, 1870, 1873, 1876, 1877, 1880, 1883, 1884, 1885, 1886, 1889, 1892, 1893, 1896, 1899, 1900, 1903, 1906, 1909, 1910, 1913, 1916, 1917, 1918, 1919, 1920, 1921, 1922, 1923, 1924, 1925, 1926, 1927, 1928, 1931, 1934, 1935, 1936, 1937, 1938, 1939, 1940, 1941, 1942, 1943, 1946, 1949, 1950, 1951, 1952, 1955, 1958, 1959, 1960, 1961, 1964, 1967, 1968, 1969, 1972, 1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2006, 2009, 2010, 2011, 2014, 2017, 2020, 2021, 2022, 2023, 2024, 2027, 2028, 2031, 2032, 2035, 2050, 2051, 2052, 2053, 2056, 2059, 2060, 2063, 2066, 2067, 2070, 2073, 2074, 2075, 2076, 2077, 2080, 2083, 2086, 2089, 2090, 2091, 2092, 2093, 2094, 2095, 2096, 2097, 2098, 2099, 2100, 2103, 2104, 2105, 2106, 2107, 2108, 2111, 2114, 2115, 2116, 2119, 2122, 2123, 2126, 2129, 2130, 2131, 2132, 2135, 2139, 2140, 2143, 2144, 2147, 2150, 2151, 2154, 2157, 2160, 2161, 2164, 2167, 2170, 2173, 2174, 2175, 2176, 2179, 2182, 2183, 2186, 2189, 2192, 2193, 2194, 2195, 2196, 2197, 2200, 2203, 2204, 2205, 2206, 2209, 2212, 2213, 2216, 2219, 2220, 2223, 2226, 2227, 2230, 2233, 2234, 2237, 2240, 2241, 2242, 2243, 2246, 2249, 2250, 2251, 2254, 2255, 2256, 2259, 2262, 2265, 2266, 2267, 2268, 2271, 2272, 2275, 2278, 2281, 2282, 2283, 2284, 2285, 2286, 2287, 2288, 2289, 2290, 2291, 2292, 2293, 2294, 2297, 2300, 2301, 2304, 2307, 2308, 2309, 2312, 2315, 2316, 2317, 2318, 2321, 2322, 2323, 2326, 2329, 2330, 2331, 2332, 2333, 2334, 2335, 2338, 2341, 2344, 2345, 2348, 2349, 2350, 2353, 2357, 2360, 2361, 2362, 2363, 2364, 2367, 2371, 2372, 2375, 2376, 2379, 2380, 2383, 2384, 2387, 2388, 2391, 2394, 2395, 2396, 2399, 2402, 2403, 2404, 2405, 2408, 2411, 2412, 2413, 2414, 2415, 2416, 2419, 2422, 2425, 2428, 2429, 2430, 2431, 2434, 2437, 2438, 2439, 2440, 2441, 2442, 2443, 2444, 2445, 2446, 2447, 2448, 2449, 2450, 2451, 2452, 2455, 2458, 2461, 2462, 2463, 2464, 2465, 2468, 2469, 2472, 2473, 2476, 2479, 2482, 2483, 2484, 2485, 2486, 2487, 2490, 2493, 2494, 2495, 2498, 2501, 2502, 2503, 2504, 2505, 2506, 2507, 2508, 2509, 2512, 2515, 2518, 2521, 2522, 2525, 2528, 2529, 2530, 2531, 2532, 2533, 2534, 2535, 2536, 2537, 2540, 2543, 2546, 2549, 2552, 2555, 2556, 2557, 2558, 2561, 2564, 2565, 2566, 2567, 2568, 2569, 2570, 2573, 2576, 2577, 2578, 2579, 2580, 2581, 2582, 2585, 2588, 2591, 2594 }; #endif #if YYDEBUG || YYERROR_VERBOSE || 0 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "EDIF_TOK_IDENT", "EDIF_TOK_INT", "EDIF_TOK_KEYWORD", "EDIF_TOK_STR", "EDIF_TOK_ANGLE", "EDIF_TOK_BEHAVIOR", "EDIF_TOK_CALCULATED", "EDIF_TOK_CAPACITANCE", "EDIF_TOK_CENTERCENTER", "EDIF_TOK_CENTERLEFT", "EDIF_TOK_CENTERRIGHT", "EDIF_TOK_CHARGE", "EDIF_TOK_CONDUCTANCE", "EDIF_TOK_CURRENT", "EDIF_TOK_DISTANCE", "EDIF_TOK_DOCUMENT", "EDIF_TOK_ENERGY", "EDIF_TOK_EXTEND", "EDIF_TOK_FLUX", "EDIF_TOK_FREQUENCY", "EDIF_TOK_GENERIC", "EDIF_TOK_GRAPHIC", "EDIF_TOK_INDUCTANCE", "EDIF_TOK_INOUT", "EDIF_TOK_INPUT", "EDIF_TOK_LOGICMODEL", "EDIF_TOK_LOWERCENTER", "EDIF_TOK_LOWERLEFT", "EDIF_TOK_LOWERRIGHT", "EDIF_TOK_MASKLAYOUT", "EDIF_TOK_MASS", "EDIF_TOK_MEASURED", "EDIF_TOK_MX", "EDIF_TOK_MXR90", "EDIF_TOK_MY", "EDIF_TOK_MYR90", "EDIF_TOK_NETLIST", "EDIF_TOK_OUTPUT", "EDIF_TOK_PCBLAYOUT", "EDIF_TOK_POWER", "EDIF_TOK_R0", "EDIF_TOK_R180", "EDIF_TOK_R270", "EDIF_TOK_R90", "EDIF_TOK_REQUIRED", "EDIF_TOK_RESISTANCE", "EDIF_TOK_RIPPER", "EDIF_TOK_ROUND", "EDIF_TOK_SCHEMATIC", "EDIF_TOK_STRANGER", "EDIF_TOK_SYMBOLIC", "EDIF_TOK_TEMPERATURE", "EDIF_TOK_TIE", "EDIF_TOK_TIME", "EDIF_TOK_TRUNCATE", "EDIF_TOK_UPPERCENTER", "EDIF_TOK_UPPERLEFT", "EDIF_TOK_UPPERRIGHT", "EDIF_TOK_VOLTAGE", "EDIF_TOK_ACLOAD", "EDIF_TOK_AFTER", "EDIF_TOK_ANNOTATE", "EDIF_TOK_APPLY", "EDIF_TOK_ARC", "EDIF_TOK_ARRAY", "EDIF_TOK_ARRAYMACRO", "EDIF_TOK_ARRAYRELATEDINFO", "EDIF_TOK_ARRAYSITE", "EDIF_TOK_ATLEAST", "EDIF_TOK_ATMOST", "EDIF_TOK_AUTHOR", "EDIF_TOK_BASEARRAY", "EDIF_TOK_BECOMES", "EDIF_TOK_BETWEEN", "EDIF_TOK_BOOLEAN", "EDIF_TOK_BOOLEANDISPLAY", "EDIF_TOK_BOOLEANMAP", "EDIF_TOK_BORDERPATTERN", "EDIF_TOK_BORDERWIDTH", "EDIF_TOK_BOUNDINGBOX", "EDIF_TOK_CELL", "EDIF_TOK_CELLREF", "EDIF_TOK_CELLTYPE", "EDIF_TOK_CHANGE", "EDIF_TOK_CIRCLE", "EDIF_TOK_COLOR", "EDIF_TOK_COMMENT", "EDIF_TOK_COMMENTGRAPHICS", "EDIF_TOK_COMPOUND", "EDIF_TOK_CONNECTLOCATION", "EDIF_TOK_CONTENTS", "EDIF_TOK_CORNERTYPE", "EDIF_TOK_CRITICALITY", "EDIF_TOK_CURRENTMAP", "EDIF_TOK_CURVE", "EDIF_TOK_CYCLE", "EDIF_TOK_DATAORIGIN", "EDIF_TOK_DCFANINLOAD", "EDIF_TOK_DCFANOUTLOAD", "EDIF_TOK_DCMAXFANIN", "EDIF_TOK_DCMAXFANOUT", "EDIF_TOK_DELAY", "EDIF_TOK_DELTA", "EDIF_TOK_DERIVATION", "EDIF_TOK_DESIGN", "EDIF_TOK_DESIGNATOR", "EDIF_TOK_DIFFERENCE", "EDIF_TOK_DIRECTION", "EDIF_TOK_DISPLAY", "EDIF_TOK_DOMINATES", "EDIF_TOK_DOT", "EDIF_TOK_DURATION", "EDIF_TOK_E", "EDIF_TOK_EDIF", "EDIF_TOK_EDIFLEVEL", "EDIF_TOK_EDIFVERSION", "EDIF_TOK_ENCLOSUREDISTANCE", "EDIF_TOK_ENDTYPE", "EDIF_TOK_ENTRY", "EDIF_TOK_EVENT", "EDIF_TOK_EXACTLY", "EDIF_TOK_EXTERNAL", "EDIF_TOK_FABRICATE", "EDIF_TOK_FALSE", "EDIF_TOK_FIGURE", "EDIF_TOK_FIGUREAREA", "EDIF_TOK_FIGUREGROUP", "EDIF_TOK_FIGUREGROUPOBJECT", "EDIF_TOK_FIGUREGROUPOVERRIDE", "EDIF_TOK_FIGUREGROUPREF", "EDIF_TOK_FIGUREPERIMETER", "EDIF_TOK_FIGUREWIDTH", "EDIF_TOK_FILLPATTERN", "EDIF_TOK_FOLLOW", "EDIF_TOK_FORBIDDENEVENT", "EDIF_TOK_GLOBALPORTREF", "EDIF_TOK_GREATERTHAN", "EDIF_TOK_GRIDMAP", "EDIF_TOK_IGNORE", "EDIF_TOK_INCLUDEFIGUREGROUP", "EDIF_TOK_INITIAL", "EDIF_TOK_INSTANCE", "EDIF_TOK_INSTANCEBACKANNOTATE", "EDIF_TOK_INSTANCEGROUP", "EDIF_TOK_INSTANCEMAP", "EDIF_TOK_INSTANCEREF", "EDIF_TOK_INTEGER", "EDIF_TOK_INTEGERDISPLAY", "EDIF_TOK_INTERFACE", "EDIF_TOK_INTERFIGUREGROUPSPACING", "EDIF_TOK_INTERSECTION", "EDIF_TOK_INTRAFIGUREGROUPSPACING", "EDIF_TOK_INVERSE", "EDIF_TOK_ISOLATED", "EDIF_TOK_JOINED", "EDIF_TOK_JUSTIFY", "EDIF_TOK_KEYWORDDISPLAY", "EDIF_TOK_KEYWORDLEVEL", "EDIF_TOK_KEYWORDMAP", "EDIF_TOK_LESSTHAN", "EDIF_TOK_LIBRARY", "EDIF_TOK_LIBRARYREF", "EDIF_TOK_LISTOFNETS", "EDIF_TOK_LISTOFPORTS", "EDIF_TOK_LOADDELAY", "EDIF_TOK_LOGICASSIGN", "EDIF_TOK_LOGICINPUT", "EDIF_TOK_LOGICLIST", "EDIF_TOK_LOGICMAPINPUT", "EDIF_TOK_LOGICMAPOUTPUT", "EDIF_TOK_LOGICONEOF", "EDIF_TOK_LOGICOUTPUT", "EDIF_TOK_LOGICPORT", "EDIF_TOK_LOGICREF", "EDIF_TOK_LOGICVALUE", "EDIF_TOK_LOGICWAVEFORM", "EDIF_TOK_MAINTAIN", "EDIF_TOK_MATCH", "EDIF_TOK_MEMBER", "EDIF_TOK_MINOMAX", "EDIF_TOK_MINOMAXDISPLAY", "EDIF_TOK_MNM", "EDIF_TOK_MULTIPLEVALUESET", "EDIF_TOK_MUSTJOIN", "EDIF_TOK_NAME", "EDIF_TOK_NET", "EDIF_TOK_NETBACKANNOTATE", "EDIF_TOK_NETBUNDLE", "EDIF_TOK_NETDELAY", "EDIF_TOK_NETGROUP", "EDIF_TOK_NETMAP", "EDIF_TOK_NETREF", "EDIF_TOK_NOCHANGE", "EDIF_TOK_NONPERMUTABLE", "EDIF_TOK_NOTALLOWED", "EDIF_TOK_NOTCHSPACING", "EDIF_TOK_NUMBER", "EDIF_TOK_NUMBERDEFINITION", "EDIF_TOK_NUMBERDISPLAY", "EDIF_TOK_OFFPAGECONNECTOR", "EDIF_TOK_OFFSETEVENT", "EDIF_TOK_OPENSHAPE", "EDIF_TOK_ORIENTATION", "EDIF_TOK_ORIGIN", "EDIF_TOK_OVERHANGDISTANCE", "EDIF_TOK_OVERLAPDISTANCE", "EDIF_TOK_OVERSIZE", "EDIF_TOK_OWNER", "EDIF_TOK_PAGE", "EDIF_TOK_PAGESIZE", "EDIF_TOK_PARAMETER", "EDIF_TOK_PARAMETERASSIGN", "EDIF_TOK_PARAMETERDISPLAY", "EDIF_TOK_PATH", "EDIF_TOK_PATHDELAY", "EDIF_TOK_PATHWIDTH", "EDIF_TOK_PERMUTABLE", "EDIF_TOK_PHYSICALDESIGNRULE", "EDIF_TOK_PLUG", "EDIF_TOK_POINT", "EDIF_TOK_POINTDISPLAY", "EDIF_TOK_POINTLIST", "EDIF_TOK_POLYGON", "EDIF_TOK_PORT", "EDIF_TOK_PORTBACKANNOTATE", "EDIF_TOK_PORTBUNDLE", "EDIF_TOK_PORTDELAY", "EDIF_TOK_PORTGROUP", "EDIF_TOK_PORTIMPLEMENTATION", "EDIF_TOK_PORTINSTANCE", "EDIF_TOK_PORTLIST", "EDIF_TOK_PORTLISTALIAS", "EDIF_TOK_PORTMAP", "EDIF_TOK_PORTREF", "EDIF_TOK_PROGRAM", "EDIF_TOK_PROPERTY", "EDIF_TOK_PROPERTYDISPLAY", "EDIF_TOK_PROTECTIONFRAME", "EDIF_TOK_PT", "EDIF_TOK_RANGEVECTOR", "EDIF_TOK_RECTANGLE", "EDIF_TOK_RECTANGLESIZE", "EDIF_TOK_RENAME", "EDIF_TOK_RESOLVES", "EDIF_TOK_SCALE", "EDIF_TOK_SCALEX", "EDIF_TOK_SCALEY", "EDIF_TOK_SECTION", "EDIF_TOK_SHAPE", "EDIF_TOK_SIMULATE", "EDIF_TOK_SIMULATIONINFO", "EDIF_TOK_SINGLEVALUESET", "EDIF_TOK_SITE", "EDIF_TOK_SOCKET", "EDIF_TOK_SOCKETSET", "EDIF_TOK_STATUS", "EDIF_TOK_STEADY", "EDIF_TOK_STRING", "EDIF_TOK_STRINGDISPLAY", "EDIF_TOK_STRONG", "EDIF_TOK_SYMBOL", "EDIF_TOK_SYMMETRY", "EDIF_TOK_TABLE", "EDIF_TOK_TABLEDEFAULT", "EDIF_TOK_TECHNOLOGY", "EDIF_TOK_TEXTHEIGHT", "EDIF_TOK_TIMEINTERVAL", "EDIF_TOK_TIMESTAMP", "EDIF_TOK_TIMING", "EDIF_TOK_TRANSFORM", "EDIF_TOK_TRANSITION", "EDIF_TOK_TRIGGER", "EDIF_TOK_TRUE", "EDIF_TOK_UNCONSTRAINED", "EDIF_TOK_UNDEFINED", "EDIF_TOK_UNION", "EDIF_TOK_UNIT", "EDIF_TOK_UNUSED", "EDIF_TOK_USERDATA", "EDIF_TOK_VERSION", "EDIF_TOK_VIEW", "EDIF_TOK_VIEWLIST", "EDIF_TOK_VIEWMAP", "EDIF_TOK_VIEWREF", "EDIF_TOK_VIEWTYPE", "EDIF_TOK_VISIBLE", "EDIF_TOK_VOLTAGEMAP", "EDIF_TOK_WAVEVALUE", "EDIF_TOK_WEAK", "EDIF_TOK_WEAKJOINED", "EDIF_TOK_WHEN", "EDIF_TOK_WRITTEN", "')'", "$accept", "PopC", "Edif", "_Edif", "EdifFileName", "EdifLevel", "EdifVersion", "AcLoad", "_AcLoad", "After", "_After", "Annotate", "_Annotate", "Apply", "_Apply", "Arc", "Array", "_Array", "ArrayMacro", "ArrayRelInfo", "_ArrayRelInfo", "ArraySite", "AtLeast", "AtMost", "Author", "BaseArray", "Becomes", "_Becomes", "Between", "__Between", "_Between", "Boolean", "_Boolean", "BooleanDisp", "_BooleanDisp", "BooleanMap", "BooleanValue", "BorderPat", "BorderWidth", "BoundBox", "Cell", "_Cell", "CellNameDef", "CellRef", "_CellRef", "CellNameRef", "CellType", "_CellType", "Change", "__Change", "_Change", "Circle", "_Circle", "Color", "Comment", "_Comment", "CommGraph", "_CommGraph", "Compound", "Contents", "_Contents", "ConnectLoc", "_ConnectLoc", "CornerType", "_CornerType", "Criticality", "_Criticality", "CurrentMap", "Curve", "_Curve", "Cycle", "_Cycle", "DataOrigin", "_DataOrigin", "DcFanInLoad", "_DcFanInLoad", "DcFanOutLoad", "_DcFanOutLoad", "DcMaxFanIn", "_DcMaxFanIn", "DcMaxFanOut", "_DcMaxFanOut", "Delay", "_Delay", "Delta", "_Delta", "Derivation", "_Derivation", "Design", "_Design", "Designator", "_Designator", "DesignNameDef", "DesignRule", "_DesignRule", "Difference", "_Difference", "Direction", "_Direction", "Display", "_Display", "_DisplayJust", "_DisplayOrien", "_DisplayOrg", "Dominates", "_Dominates", "Dot", "_Dot", "Duration", "EncloseDist", "_EncloseDist", "EndType", "_EndType", "Entry", "___Entry", "__Entry", "_Entry", "Event", "_Event", "Exactly", "External", "_External", "Fabricate", "False", "FigGrp", "_FigGrp", "FigGrpNameDef", "FigGrpNameRef", "FigGrpObj", "_FigGrpObj", "FigGrpOver", "_FigGrpOver", "FigGrpRef", "_FigGrpRef", "Figure", "_Figure", "FigureArea", "_FigureArea", "FigureOp", "FigurePerim", "_FigurePerim", "FigureWidth", "_FigureWidth", "FillPattern", "Follow", "__Follow", "_Follow", "Forbidden", "_Forbidden", "Form", "_Form", "GlobPortRef", "GreaterThan", "GridMap", "Ignore", "IncFigGrp", "_IncFigGrp", "Initial", "Instance", "_Instance", "InstanceRef", "_InstanceRef", "InstBackAn", "_InstBackAn", "InstGroup", "_InstGroup", "InstMap", "_InstMap", "InstNameDef", "InstNameRef", "IntDisplay", "_IntDisplay", "Integer", "_Integer", "Interface", "_Interface", "InterFigGrp", "_InterFigGrp", "Intersection", "_Intersection", "IntraFigGrp", "_IntraFigGrp", "Inverse", "_Inverse", "Isolated", "Joined", "_Joined", "Justify", "_Justify", "KeywordDisp", "_KeywordDisp", "KeywordLevel", "KeywordMap", "_KeywordMap", "KeywordName", "LayerNameDef", "LessThan", "LibNameDef", "LibNameRef", "Library", "_Library", "LibraryRef", "ListOfNets", "_ListOfNets", "ListOfPorts", "_ListOfPorts", "LoadDelay", "_LoadDelay", "LogicAssn", "___LogicAssn", "__LogicAssn", "_LogicAssn", "LogicIn", "_LogicIn", "LogicList", "_LogicList", "LogicMapIn", "_LogicMapIn", "LogicMapOut", "_LogicMapOut", "LogicNameDef", "LogicNameRef", "LogicOneOf", "_LogicOneOf", "LogicOut", "_LogicOut", "LogicPort", "_LogicPort", "LogicRef", "_LogicRef", "LogicValue", "_LogicValue", "LogicWave", "_LogicWave", "Maintain", "__Maintain", "_Maintain", "Match", "__Match", "_Match", "Member", "_Member", "MiNoMa", "_MiNoMa", "MiNoMaDisp", "_MiNoMaDisp", "MiNoMaValue", "Mnm", "_Mnm", "MultValSet", "_MultValSet", "MustJoin", "_MustJoin", "Name", "_Name", "NameDef", "NameRef", "Net", "_Net", "NetBackAn", "_NetBackAn", "NetBundle", "_NetBundle", "NetDelay", "_NetDelay", "NetGroup", "_NetGroup", "NetMap", "_NetMap", "NetNameDef", "NetNameRef", "NetRef", "_NetRef", "NoChange", "NonPermut", "_NonPermut", "NotAllowed", "_NotAllowed", "NotchSpace", "_NotchSpace", "Number", "_Number", "NumbDisplay", "_NumbDisplay", "NumberDefn", "_NumberDefn", "OffPageConn", "_OffPageConn", "OffsetEvent", "OpenShape", "_OpenShape", "Orientation", "_Orientation", "Origin", "OverhngDist", "_OverhngDist", "OverlapDist", "_OverlapDist", "Oversize", "_Oversize", "Owner", "Page", "_Page", "PageSize", "ParamDisp", "_ParamDisp", "Parameter", "_Parameter", "ParamAssign", "Path", "_Path", "PathDelay", "_PathDelay", "PathWidth", "Permutable", "_Permutable", "Plug", "_Plug", "Point", "_Point", "PointDisp", "_PointDisp", "PointList", "_PointList", "PointValue", "Polygon", "_Polygon", "Port", "_Port", "PortBackAn", "_PortBackAn", "PortBundle", "_PortBundle", "PortDelay", "_PortDelay", "PortGroup", "_PortGroup", "PortImpl", "_PortImpl", "PortInst", "_PortInst", "PortList", "_PortList", "PortListAls", "PortMap", "_PortMap", "PortNameDef", "PortNameRef", "PortRef", "_PortRef", "Program", "_Program", "PropDisplay", "_PropDisplay", "Property", "_Property", "PropNameDef", "PropNameRef", "ProtectFrame", "_ProtectFrame", "Range", "RangeVector", "_RangeVector", "Rectangle", "_Rectangle", "RectSize", "_RectSize", "Rename", "__Rename", "_Rename", "Resolves", "_Resolves", "RuleNameDef", "Scale", "ScaledInt", "ScaleX", "ScaleY", "Section", "_Section", "Shape", "_Shape", "SimNameDef", "Simulate", "_Simulate", "SimulInfo", "_SimulInfo", "SingleValSet", "_SingleValSet", "Site", "_Site", "Socket", "_Socket", "SocketSet", "_SocketSet", "Status", "_Status", "Steady", "__Steady", "_Steady", "StrDisplay", "String", "_String", "_StrDisplay", "Strong", "Symbol", "_Symbol", "Symmetry", "_Symmetry", "Table", "_Table", "TableDeflt", "__TableDeflt", "_TableDeflt", "Technology", "_Technology", "TextHeight", "TimeIntval", "__TimeIntval", "_TimeIntval", "TimeStamp", "Timing", "_Timing", "Transform", "_TransX", "_TransY", "_TransDelta", "_TransOrien", "_TransOrg", "Transition", "_Transition", "Trigger", "_Trigger", "True", "TypedValue", "Unconstrained", "Undefined", "Union", "_Union", "Unit", "_Unit", "Unused", "UserData", "_UserData", "ValueNameDef", "ValueNameRef", "Version", "View", "_View", "ViewList", "_ViewList", "ViewMap", "_ViewMap", "ViewNameDef", "ViewNameRef", "ViewRef", "_ViewRef", "ViewType", "_ViewType", "Visible", "VoltageMap", "WaveValue", "Weak", "WeakJoined", "_WeakJoined", "When", "_When", "Written", "_Written", "Ident", "Str", "Int", "Keyword", YY_NULLPTR }; #endif # ifdef YYPRINT /* YYTOKNUM[NUM] -- (External) token number corresponding to the (internal) symbol number NUM (which must be that of a token). */ static const yytype_int16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 41 }; # endif #define YYPACT_NINF (-1333) #define yypact_value_is_default(Yyn) \ ((Yyn) == YYPACT_NINF) #define YYTABLE_NINF (-1) #define yytable_value_is_error(Yyn) \ 0 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ static const yytype_int16 yypact[] = { 41, 152, 149, -1333, 176, 81, 305, -1333, -1333, -1333, -1333, -1333, 33, -1333, -1333, 59, -1333, 148, 317, 101, -1333, -1333, -1333, -1333, 437, 150, -1333, -1333, -1333, 148, 148, 304, 81, 312, -1333, -1333, -1333, -1333, -1333, 33, -1333, -1333, 148, 150, 316, -1333, -1333, 1508, 1780, 272, -1333, -1333, -1333, 150, -1333, 148, -1333, 122, 715, 148, 148, 111, -1333, 997, 1020, 148, 148, 152, 148, 176, 300, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 150, 1588, 280, -1333, -1333, 150, -1333, -1333, 152, 152, 152, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 148, 150, 148, 111, -1333, 36, -1333, -1333, -1333, 150, -1333, -1333, -1333, 150, 148, 150, -1333, 1023, 150, 66, -1333, 150, 150, 150, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 150, 260, 150, -1333, -1333, 424, -1333, 317, -1333, 317, 273, 439, -1333, 148, 111, -1333, -1333, -1333, -1333, 439, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 310, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 148, 150, -1333, 81, -1333, 441, 254, 254, 266, -1333, -1333, -1333, -1333, 150, 150, 150, 150, 416, 49, 115, 91, 801, 77, 437, 2006, -1333, -1333, -1333, -1333, -1333, 71, 148, -1333, 376, -1333, -1333, -1333, -1333, -1333, -1333, 343, 445, -1333, 445, -1333, 148, -1333, 158, -1333, -1333, -1333, -1333, 300, -1333, -1333, -1333, -1333, 148, -1333, -1333, -1333, -1333, 276, 144, -1333, -1333, -1333, -1333, -1333, -1333, 111, -1333, -1333, -1333, -1333, 260, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 150, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 150, -1333, -1333, -1333, -1333, -1333, 150, 81, 150, -1333, -1333, -1333, 546, 152, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 148, 437, 437, 437, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 33, -1333, 33, -1333, 33, -1333, 150, 150, 144, -1333, -1333, -1333, 33, -1333, 33, -1333, -1333, -1333, -1333, 150, -1333, -1333, 132, 152, 152, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 468, -1333, 148, 150, 306, 306, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 144, -1333, -1333, -1333, -1333, -1333, 111, 111, -1333, -1333, -1333, -1333, 81, -1333, 1442, -1333, -1333, 1794, 519, 832, 940, -1333, 148, -1333, 437, 150, -1333, 150, -1333, 150, 111, 111, 150, 1196, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 152, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 150, 152, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 148, 150, -1333, -1333, -1333, 150, 321, -1333, 1196, 81, 1196, 1196, 148, 1196, -1333, -1333, -1333, 150, -1333, -1333, -1333, -1333, -1333, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, -1333, 1198, -1333, -1333, -1333, 322, 867, 148, -1333, -1333, 150, 1263, -1333, -1333, 376, -1333, -1333, 1263, -1333, -1333, 150, 1196, -1333, -1333, 1263, -1333, 342, 461, 1545, 1545, 1545, 461, 1545, -1333, 130, 1545, 461, 461, -29, 300, 81, 276, -1333, 150, -1333, -1333, -1333, 81, 276, 81, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 1879, 444, 466, -1333, 425, -1333, 382, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 150, -1333, -1333, -1333, -1333, 150, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 540, -1333, -1333, -1333, -1333, 150, -1333, -1333, 1545, 111, 111, 42, 111, 111, 111, 1276, -1333, -1333, -1333, -1333, 130, -1333, -1333, -1333, -1333, 130, -1333, -1333, 130, -1333, -1333, 1545, 130, -1333, -1333, -1333, -1333, -1333, 130, -1333, -1333, 1545, 1545, -1333, -1333, -1333, -1333, 130, 150, 150, -1333, 150, 63, -1333, 63, 63, 63, 150, 150, 150, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 150, -1333, -1333, 186, 529, -1333, 653, 833, 529, 605, -1333, 171, 529, 581, -1333, 783, -1333, -1333, 150, -1333, 130, -1333, -1333, 150, 150, -1333, 53, -1333, 150, 150, 150, -1333, 150, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 130, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 130, -1333, -1333, 130, -1333, -1333, -75, 361, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 990, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 81, -34, -1333, -1333, 59, 548, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 442, 460, 548, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 539, 523, 93, 93, 93, 93, 548, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 150, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 543, -1333, -1333, 108, -1333, 108, 108, -1333, 152, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 1584, 148, 81, -1333, 150, -1333, 150, -1333, -1333, 894, -1333, 708, 252, -1333, -1333, 150, -1333, 150, -1333, -1333, 561, 46, -1333, -1333, 150, -1333, 150, -1333, -1333, 150, -1333, -1333, 150, -1333, -1333, 150, -1333, -1333, 150, -1333, -1333, 26, 86, -1333, 431, 421, 150, -1333, 130, -1333, -1333, 531, 281, 152, -1333, -1333, 1023, -73, -1333, -1333, 631, -1333, 512, 762, -1333, -1333, 481, 365, 588, 454, -1333, 76, 104, 108, 108, 108, 108, 108, 108, 104, 437, 418, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 51, -1333, -1333, 424, -1333, -1333, -1333, -1333, -1333, 150, 436, 561, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 523, -1333, -31, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 523, -1333, -1333, -31, -1333, -1333, -1333, -1333, 150, 453, 150, -1333, -1333, -1333, -1333, 529, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 148, 321, -1333, -1333, -1333, -1333, -1333, 711, 150, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 726, 176, 529, 81, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 620, 108, 152, -1333, -1333, -1333, -1333, -1333, -1333, 59, 454, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 260, 150, 691, -1333, -1333, 751, -85, -1333, -1333, -1333, -115, -1333, 726, -1333, -1333, -1333, 568, 562, 635, -1333, -1333, 449, 1253, -1333, -1333, 97, -1333, -1333, -1333, 448, -1333, -1333, -1333, 150, -1333, 384, -24, -1333, -1333, -24, 150, -1333, -1333, 950, 950, -1333, -1333, -1333, 523, -1333, -1333, -1333, -1333, -1333, -122, -1333, -1333, 150, -1333, -1333, 150, 86, 148, 150, -1333, -77, -1333, -1333, -1333, 150, -1333, -90, -1333, -1333, -1333, -1333, 33, -1333, -1333, -1333, -1333, 33, -1333, -1333, 33, -1333, 148, 409, -1333, 530, 111, 150, -1333, -1333, 150, 260, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 260, 260, 675, 553, 553, 675, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 99, -1333, -1333, -1333, 812, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 679, -1333, -1333, 946, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 651, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 34, 276, 104, 104, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 1014, 671, -1333, -1333, 634, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 150, -1333, -1333, -1333, -1333, -1333, -1333, 950, 150, 453, -1333, -1333, -119, -1333, -1333, -1333, -1333, -1333, 150, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 684, 255, 255, -1333, -1333, -1333, -1333, -1333, 150, 624, -1333, -1333, -1333, -117, 260, -117, -1333, -1333, -1333, -117, -1333, -117, -1333, -1333, -117, -1333, -117, 269, -1333, -1333, -1333, 428, 529, 104, 560, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -98, -1333, -1333, -1333, -1333, -1333, -1333, 150, -1333, 255, 150, 255, -1333, -1333, -1333, -1333, 739, -1333, -64, -1333, -1333, 26, -1333, -1333, -31, -1333, -1333, -1333, -1333, -1333, 111, 111, -1333, -1333, -1333, 150, 114, 64, -1333, 150, -1333, -127, -1333, -1333, -1333, -1333, 150, -1333, -52, -1333, -1333, -1333, -52, -1333, -1333, -1333, -1333, -1333, 150, -1333, -1333, -1333, -1333, -1333, 28, -1333, -1333, -46, -1333, -1333, -1333, -1333, -1333, -1333, 383, 890, -1333, -1333, -1333, -1333, -1333, -1333, 1023, 657, -1333, -1333, 148, -1333, 564, -1333, -1333, -1333, 11, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 684, -1333, -1333, -1333, -1333, -1333, -1333, 81, 26, -1333, -1333, -1333, -1333, -1333, 150, -1333, -1333, -1333, 150, 150, -1333, 150, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 534, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 113, -1333, -117, 260, -1333, -1333, -1333, -1333, -1333, 255, -1333, 890, -1333, -1333, 150, -1333, -1333, -1333, -1333, 26, 150, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 148, 148, -1333, 725, -1333, 150, -1333, -1333, -31, 376, -1333, -1333, 150, -1333, -1333, -1333, -1333, 577, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 260, 950, -1333, -1333, -1333, 26, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 150, -1333, 150, 148, -1333, -1333, 272, -1333, -1333, -1333, -1333, -1333, 150, -1333, 150, -1333, 260, -1333, -1333, -1333, 150, -1333, 150, -1333, -1333, -1333, 150, -46, -1333, 280, -1333, -1333, 150, -1333, -1333, -1333, -1333, -1333, -1333, 150, -1333, -1333 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. Performed when YYTABLE does not specify something else to do. Zero means the default is an error. */ static const yytype_int16 yydefact[] = { 0, 0, 0, 1126, 0, 0, 0, 590, 11, 591, 589, 1, 0, 587, 883, 0, 882, 0, 0, 0, 2, 586, 588, 1127, 0, 0, 885, 884, 1128, 0, 0, 0, 0, 213, 211, 212, 593, 279, 592, 0, 946, 881, 0, 0, 0, 4, 285, 0, 0, 215, 214, 940, 947, 0, 12, 0, 457, 0, 0, 0, 0, 0, 101, 0, 0, 0, 0, 0, 0, 0, 0, 284, 292, 289, 290, 295, 286, 287, 291, 288, 296, 293, 297, 294, 443, 444, 445, 446, 447, 448, 449, 450, 451, 0, 0, 217, 216, 13, 0, 456, 458, 0, 0, 0, 929, 3, 9, 8, 6, 7, 5, 10, 0, 0, 0, 0, 891, 0, 136, 137, 138, 0, 232, 233, 234, 0, 0, 0, 848, 0, 0, 0, 1054, 0, 0, 0, 68, 67, 442, 683, 686, 684, 685, 679, 681, 682, 680, 0, 0, 0, 218, 455, 0, 184, 0, 462, 0, 0, 0, 70, 0, 0, 100, 102, 135, 231, 0, 727, 59, 396, 564, 656, 737, 942, 1022, 1023, 1024, 1025, 1026, 0, 1027, 843, 987, 1129, 1053, 1058, 1057, 1056, 1055, 345, 262, 1021, 1101, 678, 0, 0, 210, 0, 176, 0, 0, 0, 0, 928, 931, 932, 930, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 842, 847, 844, 846, 845, 0, 0, 687, 82, 84, 175, 178, 179, 177, 180, 0, 0, 256, 0, 465, 0, 1119, 0, 69, 892, 99, 333, 0, 58, 62, 61, 60, 0, 395, 398, 399, 397, 0, 0, 563, 567, 566, 565, 571, 572, 0, 655, 659, 658, 657, 0, 736, 740, 739, 738, 941, 944, 945, 943, 0, 1051, 1037, 1048, 1049, 1038, 1036, 1046, 1050, 1044, 1045, 1043, 1047, 1039, 1040, 1041, 1042, 0, 344, 349, 348, 347, 346, 0, 0, 0, 83, 664, 980, 0, 0, 255, 258, 259, 257, 260, 464, 467, 468, 466, 469, 0, 0, 0, 0, 1118, 1120, 1124, 1122, 1121, 1123, 1125, 0, 64, 0, 393, 0, 569, 0, 0, 0, 574, 576, 575, 0, 661, 0, 742, 701, 1035, 747, 0, 463, 81, 0, 0, 0, 186, 912, 979, 985, 984, 982, 981, 983, 986, 0, 80, 0, 0, 151, 837, 63, 65, 392, 394, 568, 570, 1028, 1029, 0, 660, 662, 741, 743, 470, 0, 0, 663, 667, 666, 665, 0, 460, 0, 264, 278, 0, 0, 0, 0, 73, 0, 47, 0, 0, 152, 0, 838, 0, 0, 0, 0, 0, 263, 271, 268, 269, 274, 265, 266, 270, 277, 267, 275, 272, 276, 273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 185, 199, 193, 198, 188, 190, 187, 194, 195, 197, 196, 192, 191, 189, 200, 0, 911, 914, 913, 915, 88, 87, 86, 0, 0, 1076, 72, 77, 79, 74, 78, 76, 75, 0, 0, 150, 836, 573, 0, 0, 261, 0, 0, 0, 0, 0, 0, 320, 355, 356, 0, 318, 321, 322, 319, 889, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 526, 0, 506, 85, 1085, 0, 0, 0, 1063, 352, 0, 0, 202, 203, 299, 424, 425, 0, 434, 435, 0, 0, 1031, 1032, 0, 354, 0, 0, 0, 0, 0, 0, 0, 647, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 501, 504, 887, 0, 0, 0, 525, 529, 539, 530, 528, 533, 536, 535, 534, 538, 537, 532, 540, 527, 531, 0, 0, 0, 383, 0, 627, 0, 822, 1075, 1083, 1080, 1079, 1082, 1081, 1078, 1077, 1084, 0, 890, 201, 204, 205, 0, 300, 423, 426, 427, 433, 699, 700, 0, 1030, 1033, 1034, 281, 0, 282, 283, 0, 0, 0, 0, 0, 0, 0, 917, 866, 865, 868, 867, 0, 864, 863, 314, 315, 0, 324, 325, 0, 329, 330, 0, 0, 429, 430, 646, 648, 649, 0, 651, 652, 0, 0, 578, 870, 878, 877, 0, 0, 0, 507, 0, 0, 436, 0, 0, 0, 0, 0, 0, 1096, 1098, 1099, 1097, 1091, 1093, 1092, 1094, 1100, 1095, 0, 401, 1065, 0, 0, 374, 0, 0, 0, 0, 606, 0, 0, 0, 766, 0, 994, 298, 0, 280, 0, 227, 228, 0, 0, 54, 0, 55, 0, 0, 0, 918, 0, 313, 316, 317, 323, 326, 327, 328, 331, 332, 0, 419, 420, 428, 431, 432, 650, 653, 654, 0, 689, 690, 0, 694, 695, 0, 0, 876, 879, 880, 66, 112, 142, 219, 221, 500, 502, 503, 505, 886, 888, 948, 1102, 1104, 1090, 0, 114, 1064, 1068, 1067, 1069, 1066, 1070, 0, 370, 391, 390, 0, 0, 373, 378, 375, 377, 376, 380, 382, 386, 384, 385, 387, 635, 634, 637, 0, 0, 605, 610, 608, 607, 609, 623, 626, 630, 629, 628, 631, 830, 829, 832, 0, 0, 0, 0, 0, 0, 765, 773, 775, 769, 770, 771, 772, 767, 768, 774, 787, 821, 825, 824, 823, 826, 698, 226, 229, 230, 45, 46, 56, 0, 57, 254, 351, 461, 916, 418, 421, 422, 688, 691, 692, 693, 696, 697, 577, 579, 869, 871, 872, 0, 438, 581, 0, 729, 0, 0, 851, 0, 950, 1106, 400, 406, 416, 414, 408, 409, 407, 411, 402, 403, 415, 405, 413, 404, 412, 417, 410, 0, 0, 0, 371, 0, 372, 0, 183, 182, 0, 996, 0, 0, 639, 638, 0, 640, 0, 141, 140, 0, 0, 834, 833, 0, 835, 0, 16, 15, 0, 155, 154, 0, 158, 157, 0, 161, 160, 0, 164, 163, 0, 0, 53, 0, 0, 0, 41, 0, 40, 39, 0, 0, 0, 1060, 1059, 0, 0, 828, 827, 0, 752, 0, 0, 903, 905, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 129, 130, 122, 117, 127, 115, 128, 119, 120, 116, 121, 123, 118, 125, 124, 131, 126, 0, 561, 1086, 1088, 369, 181, 172, 173, 174, 0, 0, 0, 995, 999, 998, 997, 1000, 379, 381, 636, 139, 0, 619, 0, 622, 624, 625, 831, 14, 153, 156, 159, 162, 0, 782, 783, 0, 786, 788, 789, 734, 0, 923, 0, 48, 38, 42, 43, 0, 817, 437, 441, 440, 439, 580, 585, 583, 582, 584, 0, 718, 643, 728, 732, 731, 730, 0, 0, 751, 761, 763, 757, 758, 759, 760, 756, 753, 755, 762, 754, 764, 475, 777, 0, 0, 0, 0, 850, 856, 861, 855, 853, 854, 858, 859, 852, 857, 860, 862, 0, 0, 0, 904, 908, 909, 906, 910, 907, 0, 0, 949, 955, 957, 962, 954, 952, 953, 959, 956, 960, 951, 958, 961, 963, 1105, 1109, 1108, 1107, 0, 0, 0, 302, 303, 0, 0, 335, 336, 389, 0, 388, 0, 518, 633, 632, 0, 0, 0, 669, 703, 0, 0, 792, 791, 0, 896, 1017, 1111, 0, 560, 562, 1089, 0, 171, 0, 0, 342, 725, 0, 0, 167, 166, 0, 0, 618, 621, 620, 0, 480, 479, 781, 785, 784, 0, 37, 965, 0, 924, 44, 0, 0, 35, 0, 719, 0, 207, 208, 209, 0, 1052, 0, 776, 779, 778, 780, 0, 453, 459, 1062, 1061, 0, 715, 849, 0, 840, 0, 0, 28, 0, 0, 0, 26, 25, 0, 0, 71, 103, 105, 108, 110, 106, 107, 109, 111, 0, 0, 0, 0, 0, 0, 301, 304, 311, 305, 306, 307, 308, 309, 310, 312, 968, 0, 337, 338, 1072, 0, 360, 359, 517, 520, 519, 521, 595, 0, 472, 612, 0, 668, 672, 671, 670, 673, 702, 710, 711, 707, 704, 705, 706, 709, 708, 712, 133, 790, 801, 796, 793, 794, 795, 798, 797, 799, 800, 895, 899, 897, 898, 0, 0, 0, 0, 1110, 1112, 1116, 1113, 1115, 1114, 1117, 1087, 0, 0, 989, 990, 0, 341, 343, 724, 726, 165, 496, 509, 0, 51, 50, 52, 1014, 1013, 1015, 0, 0, 0, 733, 735, 0, 922, 350, 816, 819, 818, 0, 36, 717, 642, 645, 644, 206, 474, 476, 477, 452, 454, 714, 716, 839, 841, 148, 0, 0, 27, 31, 29, 30, 32, 0, 0, 24, 713, 874, 0, 0, 0, 223, 144, 676, 0, 745, 0, 722, 749, 0, 901, 0, 0, 334, 339, 340, 0, 0, 0, 1002, 358, 367, 365, 362, 363, 366, 364, 361, 368, 594, 603, 601, 596, 598, 600, 599, 597, 602, 604, 0, 611, 616, 614, 613, 615, 617, 0, 134, 0, 0, 0, 1016, 1018, 1020, 1019, 0, 18, 0, 482, 483, 550, 548, 549, 0, 251, 250, 249, 248, 247, 0, 0, 993, 991, 992, 0, 0, 0, 49, 0, 478, 0, 926, 964, 966, 34, 0, 149, 0, 491, 493, 492, 0, 513, 515, 514, 820, 542, 0, 873, 875, 97, 222, 224, 0, 675, 677, 0, 721, 723, 748, 750, 900, 902, 0, 0, 967, 969, 970, 1071, 1074, 1073, 0, 0, 804, 803, 0, 1003, 1004, 471, 473, 132, 93, 92, 90, 91, 357, 936, 934, 935, 0, 17, 22, 19, 21, 20, 23, 0, 487, 485, 484, 486, 551, 552, 0, 246, 253, 252, 0, 0, 988, 0, 495, 499, 497, 498, 508, 511, 510, 1012, 0, 925, 927, 147, 490, 494, 512, 516, 0, 1103, 0, 0, 143, 145, 146, 744, 746, 0, 237, 0, 236, 238, 0, 972, 974, 973, 975, 976, 0, 802, 812, 814, 808, 809, 810, 811, 807, 806, 813, 805, 815, 0, 0, 1005, 1006, 94, 0, 95, 937, 0, 523, 488, 489, 0, 547, 674, 225, 353, 920, 541, 546, 544, 543, 545, 96, 98, 0, 0, 556, 554, 555, 243, 239, 241, 240, 242, 641, 977, 978, 0, 720, 0, 0, 169, 1007, 1008, 89, 933, 939, 938, 524, 0, 481, 0, 921, 0, 558, 557, 559, 0, 244, 0, 245, 971, 893, 0, 0, 1009, 1010, 522, 919, 0, 553, 235, 894, 168, 170, 1011, 0, 33, 1001 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { -1333, -25, -1333, -1333, -1333, 8, -1333, -906, -1333, -1333, -1333, -265, -1333, -1333, -1333, -1333, 173, -1333, -1333, -1333, -1333, -1333, 223, 139, -1333, -1333, -996, -1333, -1333, -1333, -1333, 645, -1333, -1333, -1333, -1333, -168, 470, 473, -285, 599, -1333, -1333, -91, -1333, -1333, -1333, -1333, -557, -1333, -1333, -1333, -1333, 504, 1011, -1333, -878, -1333, -1333, -1333, -1333, -1333, -1333, -310, -1333, -316, -1333, -1333, -291, -1333, -1333, -1333, -1333, -1333, -902, -1333, -901, -1333, -896, -1333, -893, -1333, -891, -1333, -1333, -1333, -630, -1333, -1333, -1333, -666, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -26, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -890, -1333, -1333, 527, -1333, -1333, -1333, -1333, -1333, -284, -1333, -1333, -1333, -1333, -1333, -1333, 528, -1333, -11, 3, 1663, -1333, -7, -1333, 1085, -1333, -880, -1333, -1333, -1333, 1301, -1333, -1333, -1333, -1333, 544, -1043, -1333, -1333, -1333, -1333, 716, -1333, -1333, 329, -1333, -570, -1333, -1333, -1333, -872, -1333, 308, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 4, -1333, 180, -1333, 745, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -834, -1333, -1333, -1333, -871, -1333, -1333, -1333, -1333, -1333, -1333, 263, 858, -1333, -1333, -1333, -517, -1333, -1333, -1333, -1333, -1202, -181, -428, -1333, -1333, -1333, -1333, -1333, -1109, -1333, -1333, -1333, -1333, -1333, -99, -514, -1097, -1333, -1333, -1333, -1333, -1333, -1332, -1333, -1333, -1333, -1227, -1333, -420, -1333, -1333, -1333, -1333, -1333, -665, -1333, 769, -1333, -193, -1333, -209, -1333, 90, -1333, -1333, -1333, -1333, 355, -1333, 903, 128, -1025, -1333, -1333, -1333, -141, -1333, -242, -1333, -287, -1333, -1333, -1333, 55, 123, -674, -1333, -502, -1333, -1333, -1333, -1333, -1333, -1333, 813, -1333, 472, -1333, -1333, -1333, -1333, -1333, -251, -1333, -1333, -560, -1333, -582, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -83, 105, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 656, -864, -1333, -1333, -1333, 830, -1333, -1333, -1333, -155, -1333, -210, -1333, -1333, -113, -1333, -1333, -1333, -105, -1333, -889, -1333, -213, -1333, -803, -1333, -1333, -1333, -874, -1333, -1333, -1333, -1333, -679, -882, 502, -1333, -1333, -1333, -699, -1333, 767, -1333, -1333, -1333, -1333, -1333, 845, 339, -1333, -942, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 902, -1333, 141, -1333, -1333, -44, -1333, -1333, -1333, -1333, 213, -1333, -1333, -1333, 411, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -189, -1333, -363, -1333, -1333, -214, 873, -1333, -1333, -1333, -1333, -1333, -195, -1333, -1300, -1333, -1333, -1333, -1333, 904, -1333, 712, -1333, -1333, -1333, -1333, -706, -1333, -1248, -1333, -1333, -1333, -1333, -1333, -980, -186, -1333, -1333, -1333, -912, -1333, -1333, -1333, -1333, -467, -1333, -1089, 1032, -1333, -1333, -241, 742, -1333, -1333, -235, -1333, -1333, -1333, -1333, -1333, -770, -1333, -1333, -1333, 727, -1333, -1333, -1333, 203, -1333, -1333, -1333, -1333, -1333, 1551, 12, 347, -1333 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { -1, 21, 2, 58, 6, 31, 18, 797, 893, 1268, 1391, 1078, 1186, 1070, 1182, 1518, 925, 1305, 914, 851, 915, 916, 615, 616, 324, 917, 1141, 1287, 617, 695, 819, 174, 211, 249, 330, 555, 135, 72, 73, 950, 310, 398, 364, 198, 303, 227, 399, 460, 1388, 1467, 1551, 1207, 1515, 74, 75, 117, 952, 1097, 557, 750, 867, 1252, 1382, 76, 121, 778, 884, 558, 1339, 1439, 1183, 1421, 326, 403, 799, 896, 800, 899, 801, 902, 802, 905, 989, 1135, 1589, 1611, 877, 976, 107, 199, 762, 873, 152, 359, 395, 484, 515, 1043, 1164, 22, 33, 49, 95, 149, 559, 651, 1209, 1336, 1407, 439, 689, 77, 125, 1452, 1524, 1576, 1606, 1277, 1399, 618, 108, 235, 360, 136, 361, 392, 393, 34, 531, 604, 35, 47, 485, 591, 953, 1100, 441, 619, 486, 442, 624, 443, 627, 78, 954, 1101, 1217, 981, 1131, 185, 224, 1018, 620, 388, 1498, 420, 487, 1389, 955, 1221, 674, 871, 579, 675, 769, 879, 580, 676, 1105, 755, 253, 332, 175, 212, 671, 746, 444, 711, 488, 521, 445, 631, 489, 524, 560, 854, 918, 50, 93, 1060, 1171, 56, 45, 57, 1172, 390, 621, 154, 349, 109, 237, 304, 1231, 1375, 1049, 1166, 1002, 1143, 1271, 1393, 1483, 1558, 1326, 1423, 1291, 1411, 561, 653, 562, 654, 504, 1292, 1293, 1412, 1327, 1427, 956, 1107, 1484, 1596, 455, 505, 1433, 1513, 1272, 1396, 1489, 1525, 1572, 1604, 787, 967, 176, 213, 1144, 334, 1145, 262, 338, 644, 726, 855, 919, 36, 12, 492, 649, 957, 1229, 581, 678, 958, 1232, 779, 990, 784, 888, 582, 680, 1111, 773, 679, 882, 1529, 1030, 1160, 446, 538, 447, 637, 177, 214, 267, 342, 306, 352, 959, 1113, 1278, 1210, 1340, 96, 147, 150, 448, 720, 449, 723, 490, 599, 221, 960, 1116, 1085, 1061, 1176, 856, 1158, 1359, 1211, 1342, 982, 1134, 79, 857, 924, 1008, 1149, 178, 215, 272, 344, 1343, 1442, 195, 1212, 1345, 858, 927, 583, 682, 859, 1050, 804, 1003, 809, 909, 961, 1117, 1360, 1458, 1019, 1156, 1072, 584, 684, 928, 789, 683, 891, 327, 405, 1063, 1179, 80, 179, 129, 1180, 861, 930, 622, 645, 727, 1096, 1334, 450, 646, 9, 15, 25, 564, 655, 493, 389, 263, 1462, 1548, 962, 1120, 1214, 1347, 932, 862, 933, 362, 396, 623, 701, 1507, 1598, 1010, 1152, 1298, 1416, 110, 157, 1390, 1475, 1554, 26, 180, 216, 39, 565, 863, 934, 1153, 1299, 1219, 1348, 1453, 1532, 1584, 236, 307, 81, 1132, 1279, 1410, 240, 764, 878, 1363, 1463, 1549, 1590, 1613, 1623, 1142, 1294, 1123, 1263, 137, 181, 340, 341, 491, 528, 223, 295, 1046, 82, 131, 923, 1177, 404, 468, 672, 1222, 1352, 469, 510, 509, 970, 872, 1128, 570, 669, 83, 567, 1074, 568, 866, 935, 966, 1124, 206, 241, 38, 27, 116, 189 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule whose number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { 41, 592, 275, 883, 261, 273, 785, 1147, 756, 514, 232, 1027, 771, 52, 51, 1351, 803, 1001, 54, 892, 260, 1036, 71, 1148, 1236, 1038, 1039, 1005, 97, 1288, 648, 1040, 99, 105, 1041, 46, 40, 656, 1044, 658, 864, 1290, 23, 250, 1138, 1023, 312, 335, 317, 3, 1058, 1419, 1057, 28, 1082, 28, 1081, 1102, 1059, 345, 1031, 1093, 1083, 1084, 1118, 23, 3, 3, 138, 3, 28, 183, 23, 151, 3, 28, 183, 23, 331, 3, 853, 1270, 417, 23, 3, 1022, 1138, 1133, 159, 3, 942, 1243, 162, 1486, 1516, 28, 164, 28, 1275, 881, 165, 1092, 167, 23, 3, 182, 184, 3, 190, 191, 192, 3, 1482, 608, 673, 28, 3, 3, 1528, 28, 1384, 67, 193, 1028, 196, 609, 1432, 1062, 1505, 163, 988, 1087, 203, 1155, 1189, 1296, 844, 735, 845, 737, 739, 741, 843, 187, 19, 887, 843, 37, 28, 11, 1531, 681, 28, 1355, 219, 3, 642, 1, 1213, 681, 37, 964, 200, 681, 201, 908, 929, 643, 20, 1220, 226, 869, 681, 20, 229, 920, 20, 1385, 20, 3, 1216, 612, 242, 243, 244, 245, 247, 252, 258, 265, 270, 274, 1577, 1000, 1488, 194, 1510, 20, 169, 251, 1512, 1216, 115, 988, 1371, 20, 114, 32, 114, 466, 309, 62, 314, 643, 993, 613, 323, 1196, 20, 62, 20, 62, 20, 771, 1580, 1197, 114, 754, 277, 278, 114, 320, 32, 4, 1285, 1088, 299, 1253, 1241, 1251, 677, 940, 1139, 20, 1242, 1254, 1255, 62, 1260, 20, 4, 4, 869, 346, 1496, 1496, 161, 321, 3, 114, 62, 1042, 1108, 4, 20, 1114, 1000, 754, 4, 194, 347, 20, 384, 4, 1303, 62, 348, 1228, 351, 747, 28, 1557, 357, 1285, 1139, 754, 1286, 1286, 4, 687, 171, 4, 264, 1386, 264, 4, 1309, 170, 256, 257, 4, 4, 209, 1502, 371, 370, 373, 372, 375, 374, 1329, 376, 377, 1246, 1500, 1599, 380, 379, 382, 381, 24, 5, 681, 20, 383, 228, 1350, 386, 20, 20, 1583, 20, 367, 368, 369, 1223, 650, 173, 24, 4, 681, 20, 401, 657, 20, 3, 20, 947, 1478, 1369, 1465, 1367, 1379, 5, 1378, 268, 7, 1370, 20, 20, 14, 20, 62, 781, 29, 677, 296, 412, 1383, 1544, 437, 453, 20, 463, 1607, 647, 42, 43, 472, 385, 473, 20, 474, 1394, 1397, 477, 20, 1174, 1184, 53, 1449, 114, 20, 410, 20, 322, 67, 5, 339, 62, 673, 1403, 98, 1491, 1566, 343, 112, 113, 20, 20, 20, 69, 126, 127, 471, 130, 1568, 20, 1256, 1492, 336, 337, 7, 17, 67, 20, 133, 20, 378, 1075, 350, 1422, 608, 609, 30, 507, 754, 610, 840, 69, 1425, 1429, 4, 23, 104, 20, 512, 936, 1424, 1428, 513, 478, 69, 20, 62, 937, 7, 7, 7, 158, 257, 160, 529, 1601, 28, 44, 20, 69, 407, 1384, 48, 1550, 1459, 166, 479, 1603, 55, 94, 188, 339, 554, 20, 518, 752, 611, 577, 148, 1552, 1016, 587, 588, 681, 938, 168, 246, 480, 593, 481, 62, 596, 612, 194, 1469, 600, 1473, 1487, 1275, 208, 197, 940, 1468, 1264, 1472, 634, 1016, 1362, 168, 681, 37, 339, 217, 234, 652, 613, 1051, 408, 409, 28, 308, 4, 62, 936, 3, 603, 62, 1450, 239, 62, 62, 937, 302, 225, 133, 305, 874, 1533, 1066, 20, 67, 475, 476, 482, 1535, 397, 69, 1358, 1537, 1538, 1593, 255, 1159, 685, 1539, 1522, 20, 1540, 686, 202, 20, 1542, 62, 300, 301, 849, 1594, 134, 20, 1076, 1322, 688, 1052, 895, 1456, 1323, 939, 1553, 319, 1276, 402, 218, 673, 530, 1556, 940, 702, 670, 946, 894, 333, 705, 218, 1401, 708, 67, 1053, 20, 714, 37, 62, 569, 251, 911, 717, 912, 673, 614, 1265, 913, 681, 677, 483, 728, 731, 732, 1289, 733, 734, 1266, 736, 738, 740, 742, 743, 744, 63, 62, 677, 942, 114, 943, 1574, 1582, 1386, 790, 745, 1055, 69, 748, 1573, 1079, 760, 766, 1007, 776, 876, 782, 20, 796, 37, 807, 20, 1076, 812, 7, 813, 988, 366, 816, 817, 1015, 62, 353, 821, 822, 823, 354, 824, 1009, 1048, 67, 946, 791, 792, 793, 794, 1605, 825, 673, 1174, 758, 69, 134, 1122, 790, 62, 828, 452, 1095, 831, 104, 774, 834, 836, 104, 20, 1130, 256, 257, 7, 7, 754, 20, 1220, 400, 869, 1067, 4, 1151, 1181, 790, 62, 850, 69, 20, 62, 840, 69, 1230, 869, 69, 69, 791, 792, 793, 794, 1563, 20, 1161, 1162, 758, 20, 1033, 62, 20, 20, 840, 62, 470, 1406, 692, 693, 1163, 697, 698, 699, 1075, 1275, 791, 792, 793, 794, 758, 69, 1016, 1016, 758, 355, 681, 62, 937, 875, 1068, 1338, 936, 774, 681, 20, 1341, 938, 1137, 62, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1541, 1275, 910, 1136, 775, 62, 1406, 356, 69, 757, 1432, 207, 62, 772, 938, 7, 1461, 788, 795, 210, 1194, 1547, 20, 62, 7, 511, 938, 67, 869, 1016, 101, 940, 681, 869, 20, 69, 62, 525, 1588, 1239, 1193, 694, 818, 940, 315, 1276, 1200, 102, 62, 20, 949, 67, 936, 977, 971, 1281, 972, 1355, 1283, 62, 937, 979, 984, 457, 248, 986, 586, 987, 795, 1187, 413, 991, 1201, 414, 994, 942, 995, 67, 775, 996, 62, 67, 997, 939, 20, 998, 103, 1127, 999, 458, 868, 20, 1004, 1190, 795, 459, 1011, 938, 1012, 67, 1523, 1017, 1021, 67, 415, 1499, 1503, 1029, 20, 62, 1035, 973, 8, 1054, 940, 1265, 1069, 1077, 1091, 1034, 69, 1368, 1346, 1034, 69, 67, 1266, 418, 758, 1051, 62, 440, 759, 978, 20, 1098, 974, 67, 20, 1099, 898, 901, 904, 907, 419, 1034, 69, 696, 297, 975, 1125, 1565, 626, 629, 222, 633, 20, 1115, 639, 1129, 20, 3, 885, 1202, 62, 254, 820, 1121, 69, 156, 1295, 1479, 67, 1140, 231, 1203, 1555, 1185, 128, 1480, 69, 104, 20, 1244, 1204, 1052, 1146, 765, 1333, 673, 259, 1150, 768, 1154, 20, 1372, 1400, 69, 1335, 1337, 1405, 946, 1095, 1408, 69, 969, 1112, 1567, 67, 1053, 1205, 20, 153, 155, 155, 69, 328, 1165, 20, 992, 571, 806, 572, 921, 772, 118, 691, 681, 69, 20, 1578, 172, 269, 1167, 1353, 266, 1409, 62, 1612, 1622, 69, 1245, 20, 62, 937, 788, 1595, 1086, 122, 713, 194, 69, 1354, 271, 20, 119, 421, 1344, 67, 722, 725, 1313, 120, 1392, 573, 20, 1602, 839, 574, 1314, 1402, 870, 69, 835, 1482, 788, 100, 106, 123, 1191, 1192, 938, 788, 1206, 1261, 124, 20, 62, 963, 880, 1224, 759, 1355, 1527, 1526, 1188, 1233, 276, 111, 1238, 1249, 69, 575, 1259, 20, 889, 758, 1267, 168, 1417, 576, 1274, 423, 238, 1280, 20, 1414, 1282, 1284, 406, 1457, 1104, 69, 1109, 1109, 1455, 1104, 425, 1285, 886, 1025, 1286, 1297, 1436, 681, 1300, 20, 0, 1301, 1302, 1262, 1307, 0, 1308, 0, 4, 838, 1311, 0, 1312, 0, 788, 0, 1316, 1315, 840, 69, 0, 1318, 1317, 0, 1320, 1319, 1216, 0, 1324, 0, 422, 0, 1331, 20, 0, 1332, 465, 0, 0, 204, 0, 0, 0, 169, 0, 0, 0, 841, 0, 67, 0, 1175, 1178, 0, 0, 67, 0, 810, 985, 0, 205, 220, 0, 1349, 0, 0, 0, 1356, 7, 104, 7, 7, 0, 7, 842, 1365, 170, 781, 1376, 677, 843, 230, 365, 0, 0, 0, 968, 844, 0, 845, 0, 0, 69, 171, 461, 0, 462, 0, 69, 67, 1519, 846, 233, 1521, 0, 0, 20, 0, 0, 1387, 0, 0, 20, 847, 0, 806, 172, 311, 1016, 316, 0, 681, 0, 325, 848, 0, 0, 391, 394, 0, 0, 0, 759, 1413, 897, 900, 903, 906, 313, 0, 318, 1415, 69, 563, 329, 1418, 7, 0, 543, 0, 0, 1420, 0, 849, 173, 788, 20, 0, 62, 0, 544, 0, 890, 0, 7, 545, 7, 7, 7, 7, 7, 7, 0, 0, 0, 1431, 478, 1571, 0, 0, 1434, 546, 1437, 0, 0, 1126, 1440, 0, 1443, 358, 0, 1445, 0, 1447, 1451, 0, 0, 1330, 1454, 479, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 363, 0, 0, 62, 937, 0, 1248, 0, 608, 609, 480, 1464, 481, 610, 0, 547, 506, 0, 1466, 0, 0, 1471, 1600, 0, 387, 508, 0, 1476, 0, 0, 548, 549, 0, 478, 1157, 1490, 0, 0, 0, 625, 628, 938, 632, 0, 0, 638, 1495, 1497, 1501, 0, 1504, 1616, 1506, 0, 788, 788, 479, 1508, 940, 1509, 611, 0, 1621, 1511, 416, 0, 482, 438, 454, 1514, 464, 0, 1006, 1051, 0, 1517, 612, 480, 1520, 481, 0, 1020, 1024, 7, 7, 424, 0, 1032, 451, 456, 0, 467, 0, 0, 1534, 0, 0, 67, 1094, 613, 751, 0, 1103, 763, 0, 550, 780, 0, 0, 1119, 805, 788, 788, 690, 0, 0, 0, 0, 0, 0, 700, 551, 0, 0, 0, 1559, 0, 0, 0, 1560, 1561, 0, 1562, 482, 0, 483, 712, 0, 0, 0, 69, 0, 1175, 788, 0, 0, 721, 724, 552, 1564, 553, 1569, 67, 1053, 20, 0, 0, 0, 0, 0, 0, 0, 0, 1581, 0, 1306, 0, 0, 0, 1585, 0, 0, 0, 788, 860, 788, 0, 556, 0, 0, 0, 0, 578, 59, 60, 0, 0, 1591, 0, 1321, 1592, 61, 62, 0, 1597, 69, 0, 63, 566, 0, 0, 0, 483, 585, 0, 0, 0, 1493, 1494, 20, 635, 0, 0, 10, 0, 0, 13, 16, 0, 20, 1608, 0, 1609, 64, 516, 0, 519, 522, 0, 526, 0, 636, 1614, 837, 1615, 0, 0, 0, 65, 0, 1617, 0, 1618, 0, 0, 411, 1619, 1620, 0, 59, 60, 0, 1624, 0, 0, 0, 0, 61, 62, 1625, 0, 589, 0, 63, 1218, 0, 0, 594, 0, 0, 0, 597, 0, 0, 601, 0, 605, 608, 609, 10, 0, 132, 610, 0, 139, 140, 141, 142, 0, 64, 0, 703, 143, 144, 145, 146, 706, 0, 0, 709, 0, 0, 0, 715, 65, 0, 0, 0, 0, 718, 0, 788, 704, 10, 10, 10, 0, 707, 729, 1304, 710, 66, 0, 1310, 716, 0, 0, 936, 0, 611, 719, 0, 0, 0, 62, 937, 0, 0, 0, 730, 0, 67, 0, 186, 749, 612, 0, 761, 767, 0, 777, 0, 783, 0, 798, 1045, 808, 0, 1064, 0, 0, 814, 1089, 0, 0, 753, 0, 0, 613, 770, 0, 68, 938, 786, 0, 0, 0, 811, 0, 0, 0, 939, 815, 826, 69, 0, 0, 66, 0, 940, 0, 70, 829, 0, 0, 832, 0, 0, 20, 0, 0, 0, 0, 0, 827, 0, 922, 67, 926, 926, 0, 931, 0, 830, 0, 0, 833, 0, 852, 0, 941, 0, 0, 0, 0, 0, 0, 0, 1395, 1398, 0, 0, 0, 942, 0, 943, 298, 68, 1404, 865, 517, 0, 520, 523, 0, 527, 0, 944, 0, 0, 69, 0, 84, 85, 86, 0, 945, 70, 0, 0, 614, 0, 0, 0, 20, 0, 0, 0, 0, 1546, 87, 88, 89, 0, 0, 0, 946, 590, 1169, 0, 0, 0, 0, 595, 1026, 1426, 1430, 598, 0, 0, 602, 0, 606, 0, 0, 947, 0, 847, 0, 90, 91, 92, 394, 0, 1106, 926, 1110, 1110, 926, 1106, 0, 0, 0, 0, 0, 0, 759, 1460, 0, 0, 10, 0, 0, 0, 0, 1198, 69, 0, 0, 0, 0, 0, 0, 0, 0, 1226, 0, 0, 948, 951, 20, 1235, 0, 0, 62, 1257, 0, 1470, 659, 1474, 980, 0, 0, 0, 1586, 1587, 1485, 0, 660, 0, 965, 0, 0, 0, 661, 10, 10, 0, 662, 0, 0, 983, 663, 0, 426, 0, 0, 0, 0, 664, 0, 665, 0, 427, 354, 0, 0, 1013, 428, 429, 0, 666, 667, 668, 0, 1610, 0, 0, 0, 1037, 0, 0, 1056, 0, 0, 1071, 1080, 430, 1014, 431, 0, 0, 0, 1530, 0, 0, 0, 0, 0, 0, 1047, 0, 0, 1065, 0, 0, 1073, 1090, 0, 0, 0, 926, 506, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 1361, 0, 0, 432, 433, 0, 0, 0, 1373, 0, 0, 1380, 0, 434, 435, 10, 0, 0, 0, 0, 0, 0, 0, 0, 10, 279, 0, 0, 280, 0, 0, 0, 281, 282, 283, 284, 1575, 285, 1579, 286, 287, 0, 0, 288, 0, 0, 0, 0, 0, 0, 436, 289, 0, 0, 0, 0, 0, 0, 0, 0, 290, 0, 0, 0, 0, 0, 291, 0, 0, 0, 0, 0, 292, 1168, 293, 0, 0, 0, 0, 294, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, 1170, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1435, 0, 1438, 0, 0, 0, 1441, 1195, 1444, 0, 1208, 1446, 0, 1448, 0, 0, 0, 1225, 0, 0, 0, 0, 0, 1234, 0, 0, 1240, 1250, 1199, 0, 0, 1215, 0, 0, 1269, 0, 0, 0, 1227, 0, 0, 0, 0, 0, 1237, 0, 0, 1247, 1258, 0, 0, 0, 0, 0, 0, 1273, 532, 533, 534, 535, 536, 537, 539, 540, 541, 542, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1325, 607, 0, 0, 0, 630, 0, 0, 0, 0, 640, 641, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1543, 0, 0, 0, 0, 0, 0, 1357, 0, 0, 0, 0, 0, 0, 0, 1366, 0, 0, 1377, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1364, 0, 0, 0, 0, 0, 0, 0, 1374, 0, 0, 1381, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1570, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 10, 10, 0, 10, 0, 0, 0, 1477, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1481, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1536, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 1545, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10 }; static const yytype_int16 yycheck[] = { 25, 518, 216, 773, 213, 215, 680, 1003, 673, 476, 199, 923, 677, 39, 39, 1217, 682, 908, 43, 789, 213, 927, 47, 1003, 1113, 927, 927, 909, 53, 1138, 544, 927, 57, 58, 927, 32, 24, 551, 927, 553, 746, 1138, 6, 211, 75, 919, 235, 256, 237, 3, 930, 1299, 930, 4, 934, 4, 934, 939, 930, 269, 924, 935, 934, 934, 946, 6, 3, 3, 93, 3, 4, 5, 6, 98, 3, 4, 5, 6, 246, 3, 746, 1124, 392, 6, 3, 919, 75, 978, 113, 3, 188, 1116, 117, 1393, 66, 4, 121, 4, 122, 773, 125, 935, 127, 6, 3, 130, 131, 3, 133, 134, 135, 3, 176, 71, 148, 4, 3, 3, 1450, 4, 86, 238, 147, 196, 149, 72, 178, 930, 255, 117, 104, 934, 157, 1015, 1076, 257, 226, 651, 228, 653, 654, 655, 219, 131, 111, 775, 219, 19, 4, 0, 1450, 236, 4, 272, 179, 3, 185, 116, 1100, 236, 32, 867, 154, 236, 156, 795, 845, 242, 295, 284, 195, 286, 236, 295, 199, 67, 295, 143, 295, 3, 265, 139, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 1524, 167, 1396, 241, 1423, 295, 149, 150, 1427, 265, 61, 104, 1229, 295, 115, 131, 115, 398, 235, 89, 237, 242, 888, 162, 241, 1097, 295, 89, 295, 89, 295, 888, 1524, 1097, 115, 181, 216, 217, 115, 73, 131, 187, 170, 934, 224, 1117, 1116, 1117, 194, 144, 273, 295, 1116, 1117, 1117, 89, 1120, 295, 187, 187, 286, 278, 141, 141, 115, 99, 3, 115, 89, 927, 941, 187, 295, 944, 167, 181, 187, 241, 295, 295, 140, 187, 1156, 89, 301, 1111, 303, 93, 4, 1483, 307, 170, 273, 181, 173, 173, 187, 599, 199, 187, 201, 259, 201, 187, 1160, 182, 183, 184, 187, 187, 161, 1412, 330, 330, 332, 332, 334, 334, 1184, 336, 337, 1116, 1411, 1563, 342, 342, 344, 344, 261, 245, 236, 295, 349, 197, 1217, 352, 295, 295, 1532, 295, 320, 321, 322, 1105, 545, 260, 261, 187, 236, 295, 367, 552, 295, 3, 295, 250, 1391, 1229, 1375, 1229, 1232, 245, 1232, 214, 1, 1229, 295, 295, 5, 295, 89, 192, 17, 194, 295, 392, 1248, 1458, 395, 396, 295, 398, 1576, 543, 29, 30, 403, 247, 405, 295, 407, 1265, 1266, 410, 295, 1052, 1067, 42, 121, 115, 295, 390, 295, 237, 238, 245, 257, 89, 148, 1275, 55, 1399, 1513, 264, 59, 60, 295, 295, 295, 281, 65, 66, 402, 68, 1513, 295, 1117, 1399, 276, 277, 67, 118, 238, 295, 126, 295, 338, 64, 302, 1321, 71, 72, 117, 460, 181, 76, 157, 281, 1322, 1323, 187, 6, 258, 295, 471, 82, 1322, 1323, 475, 109, 281, 295, 89, 90, 101, 102, 103, 112, 184, 114, 487, 1572, 4, 161, 295, 281, 378, 86, 158, 1467, 1354, 126, 132, 1572, 160, 205, 131, 338, 505, 295, 479, 672, 123, 510, 206, 1467, 233, 514, 515, 236, 127, 77, 78, 153, 521, 155, 89, 524, 139, 241, 1384, 528, 1386, 1396, 122, 160, 84, 144, 1384, 63, 1386, 538, 233, 1221, 77, 236, 390, 378, 210, 267, 547, 162, 159, 384, 385, 4, 83, 187, 89, 82, 3, 530, 89, 266, 270, 89, 89, 90, 164, 194, 126, 200, 758, 1457, 65, 295, 238, 408, 409, 209, 1458, 85, 281, 1221, 1458, 1458, 1554, 212, 1027, 586, 1458, 180, 295, 1458, 591, 294, 295, 1458, 89, 224, 225, 292, 1554, 275, 295, 212, 169, 604, 215, 790, 1352, 174, 136, 1475, 239, 203, 282, 279, 148, 130, 1483, 144, 619, 151, 231, 790, 251, 624, 279, 1275, 627, 238, 239, 295, 631, 479, 89, 287, 150, 68, 637, 70, 148, 254, 168, 74, 236, 194, 278, 646, 647, 648, 1138, 650, 651, 179, 653, 654, 655, 656, 657, 658, 94, 89, 194, 188, 115, 190, 1522, 1532, 259, 62, 669, 930, 281, 672, 1522, 934, 675, 676, 221, 678, 106, 680, 295, 682, 530, 684, 295, 212, 687, 308, 689, 104, 319, 692, 693, 138, 89, 125, 697, 698, 699, 129, 701, 256, 166, 238, 231, 100, 101, 102, 103, 1576, 711, 148, 1353, 108, 281, 275, 274, 62, 89, 720, 177, 243, 723, 258, 95, 726, 727, 258, 295, 269, 183, 184, 353, 354, 181, 295, 284, 366, 286, 234, 187, 264, 98, 62, 89, 746, 281, 295, 89, 157, 281, 165, 286, 281, 281, 100, 101, 102, 103, 1505, 295, 26, 27, 108, 295, 110, 89, 295, 295, 157, 89, 400, 114, 608, 609, 40, 611, 612, 613, 64, 122, 100, 101, 102, 103, 108, 281, 233, 233, 108, 220, 236, 89, 90, 758, 290, 97, 82, 95, 236, 295, 224, 127, 988, 89, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 1458, 122, 819, 988, 191, 89, 114, 253, 281, 673, 178, 158, 89, 677, 127, 452, 248, 681, 229, 166, 1097, 249, 295, 89, 461, 470, 127, 238, 286, 233, 107, 144, 236, 286, 295, 281, 89, 482, 105, 1116, 1097, 610, 695, 144, 237, 203, 87, 124, 89, 295, 867, 238, 82, 137, 871, 1131, 873, 272, 1134, 89, 90, 878, 879, 23, 211, 882, 511, 884, 229, 1075, 392, 888, 113, 392, 891, 188, 893, 238, 191, 896, 89, 238, 899, 136, 295, 902, 163, 970, 905, 49, 754, 295, 909, 1095, 229, 55, 913, 127, 915, 238, 1449, 918, 919, 238, 392, 1411, 1412, 924, 295, 89, 927, 9, 1, 930, 144, 168, 933, 934, 935, 280, 281, 1229, 1205, 280, 281, 238, 179, 392, 108, 159, 89, 395, 271, 217, 295, 938, 34, 238, 295, 938, 791, 792, 793, 794, 392, 280, 281, 610, 224, 47, 967, 1513, 533, 534, 179, 536, 295, 945, 539, 976, 295, 3, 774, 204, 89, 212, 695, 947, 281, 103, 1143, 1391, 238, 990, 199, 216, 1482, 1068, 67, 1391, 281, 258, 295, 1116, 225, 215, 1003, 146, 1190, 148, 213, 1008, 676, 1010, 295, 1229, 1275, 281, 1200, 1201, 1276, 231, 243, 1279, 281, 869, 943, 1513, 238, 239, 251, 295, 101, 102, 103, 281, 241, 1034, 295, 888, 145, 230, 147, 842, 888, 20, 607, 236, 281, 295, 1524, 222, 223, 1050, 214, 214, 1279, 89, 1590, 1613, 281, 1116, 295, 89, 90, 909, 1555, 934, 20, 630, 241, 281, 232, 215, 295, 50, 392, 1204, 238, 640, 641, 1166, 57, 1264, 189, 295, 1572, 69, 193, 1166, 1275, 755, 281, 726, 176, 939, 57, 58, 50, 1096, 1097, 127, 946, 1100, 1120, 57, 295, 89, 867, 773, 1107, 271, 272, 195, 1449, 1075, 1113, 216, 58, 1116, 1117, 281, 227, 1120, 295, 789, 108, 1124, 77, 1296, 235, 1128, 392, 201, 1131, 295, 1294, 1134, 1135, 369, 1353, 940, 281, 942, 943, 1352, 945, 392, 170, 774, 919, 173, 1149, 1335, 236, 1152, 295, -1, 1155, 1156, 1120, 1158, -1, 1160, -1, 187, 727, 1164, -1, 1166, -1, 1015, -1, 1171, 1171, 157, 281, -1, 1176, 1176, -1, 1179, 1179, 265, -1, 1182, -1, 392, -1, 1186, 295, -1, 1189, 398, -1, -1, 157, -1, -1, -1, 149, -1, -1, -1, 186, -1, 238, -1, 1052, 1053, -1, -1, 238, -1, 684, 879, -1, 157, 179, -1, 1217, -1, -1, -1, 1221, 842, 258, 844, 845, -1, 847, 213, 1229, 182, 192, 1232, 194, 219, 199, 308, -1, -1, -1, 868, 226, -1, 228, -1, -1, 281, 199, 283, -1, 285, -1, 281, 238, 1439, 240, 199, 1442, -1, -1, 295, -1, -1, 1263, -1, -1, 295, 252, -1, 230, 222, 235, 233, 237, -1, 236, -1, 241, 263, -1, -1, 353, 354, -1, -1, -1, 271, 1287, 791, 792, 793, 794, 235, -1, 237, 1295, 281, 505, 241, 1299, 920, -1, 79, -1, -1, 1305, -1, 292, 260, 1156, 295, -1, 89, -1, 91, -1, 789, -1, 938, 96, 940, 941, 942, 943, 944, 945, -1, -1, -1, 1329, 109, 1516, -1, -1, 1334, 112, 1336, -1, -1, 967, 1340, -1, 1342, 307, -1, 1345, -1, 1347, 1348, -1, -1, 1185, 1352, 132, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 307, -1, -1, 89, 90, -1, 92, -1, 71, 72, 153, 1375, 155, 76, -1, 156, 452, -1, 1382, -1, -1, 1385, 1571, -1, 352, 461, -1, 1391, -1, -1, 171, 172, -1, 109, 1026, 1399, -1, -1, -1, 533, 534, 127, 536, -1, -1, 539, 1410, 1411, 1412, -1, 1414, 1600, 1416, -1, 1265, 1266, 132, 1421, 144, 1423, 123, -1, 1611, 1427, 392, -1, 209, 395, 396, 1433, 398, -1, 909, 159, -1, 1439, 139, 153, 1442, 155, -1, 918, 919, 1067, 1068, 392, -1, 924, 395, 396, -1, 398, -1, -1, 1458, -1, -1, 238, 935, 162, 672, -1, 939, 675, -1, 246, 678, -1, -1, 946, 682, 1322, 1323, 607, -1, -1, -1, -1, -1, -1, 614, 262, -1, -1, -1, 1489, -1, -1, -1, 1493, 1494, -1, 1496, 209, -1, 278, 630, -1, -1, -1, 281, -1, 1353, 1354, -1, -1, 640, 641, 289, 1513, 291, 1515, 238, 239, 295, -1, -1, -1, -1, -1, -1, -1, -1, 1527, -1, 1157, -1, -1, -1, 1533, -1, -1, -1, 1384, 746, 1386, -1, 505, -1, -1, -1, -1, 510, 80, 81, -1, -1, 1551, -1, 1181, 1554, 88, 89, -1, 1558, 281, -1, 94, 505, -1, -1, -1, 278, 510, -1, -1, -1, 1405, 1406, 295, 538, -1, -1, 1, -1, -1, 4, 5, -1, 295, 1584, -1, 1586, 120, 478, -1, 480, 481, -1, 483, -1, 538, 1596, 727, 1598, -1, -1, -1, 135, -1, 1604, -1, 1606, -1, -1, 142, 1610, 1611, -1, 80, 81, -1, 1616, -1, -1, -1, -1, 88, 89, 1623, -1, 515, -1, 94, 1101, -1, -1, 521, -1, -1, -1, 525, -1, -1, 528, -1, 530, 71, 72, 67, -1, 69, 76, -1, 35, 36, 37, 38, -1, 120, -1, 619, 43, 44, 45, 46, 624, -1, -1, 627, -1, -1, -1, 631, 135, -1, -1, -1, -1, 637, -1, 1522, 619, 101, 102, 103, -1, 624, 646, 1156, 627, 218, -1, 1160, 631, -1, -1, 82, -1, 123, 637, -1, -1, -1, 89, 90, -1, -1, -1, 646, -1, 238, -1, 131, 672, 139, -1, 675, 676, -1, 678, -1, 680, -1, 682, 927, 684, -1, 930, -1, -1, 689, 934, -1, -1, 672, -1, -1, 162, 676, -1, 268, 127, 680, -1, -1, -1, 684, -1, -1, -1, 136, 689, 711, 281, -1, -1, 218, -1, 144, -1, 288, 720, -1, -1, 723, -1, -1, 295, -1, -1, -1, -1, -1, 711, -1, 842, 238, 844, 845, -1, 847, -1, 720, -1, -1, 723, -1, 746, -1, 175, -1, -1, -1, -1, -1, -1, -1, 1265, 1266, -1, -1, -1, 188, -1, 190, 224, 268, 1275, 746, 478, -1, 480, 481, -1, 483, -1, 202, -1, -1, 281, -1, 11, 12, 13, -1, 211, 288, -1, -1, 254, -1, -1, -1, 295, -1, -1, -1, -1, 1461, 29, 30, 31, -1, -1, -1, 231, 515, 1050, -1, -1, -1, -1, 521, 920, 1322, 1323, 525, -1, -1, 528, -1, 530, -1, -1, 250, -1, 252, -1, 58, 59, 60, 938, -1, 940, 941, 942, 943, 944, 945, -1, -1, -1, -1, -1, -1, 271, 1354, -1, -1, 308, -1, -1, -1, -1, 1097, 281, -1, -1, -1, -1, -1, -1, -1, -1, 1107, -1, -1, 293, 867, 295, 1113, -1, -1, 89, 1117, -1, 1384, 8, 1386, 878, -1, -1, -1, 1546, 1547, 1393, -1, 18, -1, 867, -1, -1, -1, 24, 353, 354, -1, 28, -1, -1, 878, 32, -1, 119, -1, -1, -1, -1, 39, -1, 41, -1, 128, 129, -1, -1, 915, 133, 134, -1, 51, 52, 53, -1, 1587, -1, -1, -1, 927, -1, -1, 930, -1, -1, 933, 934, 152, 915, 154, -1, -1, -1, 1450, -1, -1, -1, -1, -1, -1, 927, -1, -1, 930, -1, -1, 933, 934, -1, -1, -1, 1067, 1068, -1, -1, -1, -1, -1, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 1221, -1, -1, 197, 198, -1, -1, -1, 1229, -1, -1, 1232, -1, 207, 208, 452, -1, -1, -1, -1, -1, -1, -1, -1, 461, 7, -1, -1, 10, -1, -1, -1, 14, 15, 16, 17, 1522, 19, 1524, 21, 22, -1, -1, 25, -1, -1, -1, -1, -1, -1, 244, 33, -1, -1, -1, -1, -1, -1, -1, -1, 42, -1, -1, -1, -1, -1, 48, -1, -1, -1, -1, -1, 54, 1050, 56, -1, -1, -1, -1, 61, -1, -1, -1, -1, -1, -1, -1, 281, -1, -1, -1, -1, -1, -1, 1050, -1, -1, -1, -1, -1, -1, 295, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1334, -1, 1336, -1, -1, -1, 1340, 1097, 1342, -1, 1100, 1345, -1, 1347, -1, -1, -1, 1107, -1, -1, -1, -1, -1, 1113, -1, -1, 1116, 1117, 1097, -1, -1, 1100, -1, -1, 1124, -1, -1, -1, 1107, -1, -1, -1, -1, -1, 1113, -1, -1, 1116, 1117, -1, -1, -1, -1, -1, -1, 1124, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1182, 531, -1, -1, -1, 535, -1, -1, -1, -1, 540, 541, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1182, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1458, -1, -1, -1, -1, -1, -1, 1221, -1, -1, -1, -1, -1, -1, -1, 1229, -1, -1, 1232, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1221, -1, -1, -1, -1, -1, -1, -1, 1229, -1, -1, 1232, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1515, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 842, -1, 844, 845, -1, 847, -1, -1, -1, 1391, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1391, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1458, -1, 920, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 938, 1458, 940, 941, 942, 943, 944, 945, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1051, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1067, 1068 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_int16 yystos[] = { 0, 116, 298, 3, 187, 245, 300, 549, 551, 663, 764, 0, 550, 764, 549, 664, 764, 118, 302, 111, 295, 297, 395, 6, 261, 665, 695, 765, 4, 766, 117, 301, 131, 396, 423, 426, 549, 552, 764, 698, 765, 297, 766, 766, 161, 488, 423, 427, 158, 397, 483, 297, 395, 766, 297, 160, 487, 489, 299, 80, 81, 88, 89, 94, 120, 135, 218, 238, 268, 281, 288, 297, 333, 334, 349, 350, 359, 407, 439, 609, 650, 711, 737, 754, 11, 12, 13, 29, 30, 31, 58, 59, 60, 484, 205, 398, 587, 297, 766, 297, 350, 107, 124, 163, 258, 297, 350, 384, 416, 495, 690, 737, 766, 766, 115, 670, 766, 351, 20, 50, 57, 360, 20, 50, 57, 408, 766, 766, 551, 652, 766, 738, 764, 126, 275, 332, 419, 728, 297, 35, 36, 37, 38, 43, 44, 45, 46, 588, 206, 399, 589, 297, 388, 551, 493, 551, 493, 691, 766, 297, 766, 670, 297, 765, 297, 297, 766, 297, 77, 149, 182, 199, 222, 260, 327, 468, 538, 576, 614, 651, 696, 729, 297, 5, 297, 445, 764, 765, 766, 767, 297, 297, 297, 297, 241, 620, 297, 84, 339, 385, 301, 301, 294, 297, 350, 737, 762, 327, 766, 670, 327, 328, 469, 539, 577, 615, 697, 210, 279, 297, 350, 596, 650, 734, 446, 766, 297, 341, 552, 297, 350, 650, 690, 737, 267, 417, 709, 496, 709, 270, 715, 763, 297, 297, 297, 297, 78, 297, 327, 329, 332, 150, 297, 466, 468, 766, 183, 184, 297, 538, 540, 542, 543, 670, 201, 297, 576, 578, 670, 223, 297, 614, 616, 620, 297, 695, 696, 765, 765, 7, 10, 14, 15, 16, 17, 19, 21, 22, 25, 33, 42, 48, 54, 56, 61, 735, 295, 445, 764, 765, 766, 766, 164, 340, 497, 200, 580, 710, 83, 297, 336, 350, 690, 737, 297, 336, 350, 690, 737, 766, 73, 99, 237, 297, 320, 350, 368, 646, 650, 737, 330, 332, 467, 766, 541, 542, 276, 277, 544, 670, 730, 731, 579, 670, 617, 620, 297, 297, 297, 494, 552, 297, 581, 125, 129, 220, 253, 297, 350, 389, 418, 420, 680, 737, 338, 551, 766, 765, 765, 765, 297, 395, 297, 395, 297, 395, 297, 297, 544, 297, 395, 297, 395, 297, 140, 247, 297, 350, 449, 669, 491, 551, 421, 422, 551, 390, 681, 85, 337, 342, 766, 297, 282, 369, 741, 647, 741, 544, 670, 670, 423, 142, 297, 333, 334, 349, 350, 359, 407, 439, 451, 609, 650, 711, 737, 754, 119, 128, 133, 134, 152, 154, 197, 198, 207, 208, 244, 297, 350, 405, 420, 432, 435, 437, 472, 476, 572, 574, 590, 592, 661, 737, 177, 297, 350, 526, 737, 23, 49, 55, 343, 283, 285, 297, 350, 650, 690, 737, 742, 746, 766, 765, 297, 297, 297, 670, 670, 297, 109, 132, 153, 155, 209, 278, 391, 428, 434, 452, 474, 478, 594, 732, 551, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 516, 527, 551, 297, 551, 748, 747, 766, 297, 297, 734, 392, 428, 434, 423, 428, 434, 475, 428, 434, 479, 766, 428, 434, 733, 297, 130, 424, 424, 424, 424, 424, 424, 424, 573, 424, 424, 424, 424, 79, 91, 96, 112, 156, 171, 172, 246, 262, 289, 291, 297, 331, 350, 354, 363, 400, 480, 512, 514, 650, 666, 699, 737, 755, 757, 287, 752, 145, 147, 189, 193, 227, 235, 297, 350, 458, 462, 555, 563, 625, 640, 737, 766, 297, 297, 428, 434, 429, 497, 297, 428, 434, 297, 428, 434, 595, 297, 428, 434, 423, 425, 428, 434, 424, 71, 72, 76, 123, 139, 162, 254, 318, 319, 324, 415, 433, 448, 492, 656, 682, 436, 656, 682, 438, 656, 682, 424, 477, 656, 682, 297, 350, 737, 575, 656, 682, 424, 424, 185, 242, 545, 657, 662, 332, 517, 552, 542, 401, 297, 513, 515, 667, 517, 542, 517, 8, 18, 24, 28, 32, 39, 41, 51, 52, 53, 753, 151, 470, 743, 148, 456, 459, 463, 194, 556, 567, 564, 236, 626, 644, 641, 297, 297, 359, 297, 406, 656, 682, 670, 670, 318, 325, 448, 670, 670, 670, 656, 683, 297, 350, 737, 297, 350, 737, 297, 350, 737, 473, 656, 682, 297, 350, 737, 297, 350, 737, 591, 656, 682, 593, 656, 682, 546, 658, 297, 350, 737, 297, 297, 297, 297, 517, 297, 517, 297, 517, 297, 517, 297, 297, 297, 297, 471, 93, 297, 350, 355, 650, 690, 737, 181, 465, 536, 552, 108, 271, 297, 350, 386, 650, 716, 146, 297, 350, 456, 460, 737, 536, 552, 566, 95, 191, 297, 350, 361, 559, 650, 192, 297, 350, 561, 567, 737, 536, 552, 643, 62, 100, 101, 102, 103, 229, 297, 303, 350, 370, 372, 374, 376, 386, 629, 650, 230, 297, 350, 631, 644, 737, 297, 297, 350, 737, 297, 297, 319, 326, 492, 297, 297, 297, 297, 297, 350, 737, 297, 350, 737, 297, 350, 737, 297, 657, 297, 656, 682, 69, 157, 186, 213, 219, 226, 228, 240, 252, 263, 292, 297, 315, 350, 386, 481, 547, 602, 610, 623, 627, 650, 654, 678, 700, 716, 737, 758, 356, 552, 286, 456, 457, 750, 387, 695, 765, 106, 382, 717, 461, 456, 567, 568, 750, 362, 466, 766, 382, 562, 456, 644, 645, 750, 304, 540, 542, 371, 578, 670, 373, 578, 670, 375, 578, 670, 377, 578, 670, 382, 632, 297, 68, 70, 74, 314, 316, 317, 321, 482, 548, 67, 312, 551, 739, 611, 312, 551, 624, 642, 642, 655, 551, 677, 679, 701, 759, 82, 90, 127, 136, 144, 175, 188, 190, 202, 211, 231, 250, 293, 297, 335, 350, 352, 430, 440, 454, 522, 553, 557, 582, 597, 633, 673, 678, 716, 737, 760, 537, 766, 552, 749, 297, 297, 9, 34, 47, 383, 137, 217, 297, 350, 443, 607, 737, 297, 456, 297, 297, 104, 378, 560, 297, 566, 567, 297, 297, 297, 297, 297, 297, 167, 378, 502, 630, 297, 643, 644, 221, 612, 256, 686, 297, 297, 350, 737, 138, 233, 297, 447, 637, 644, 297, 481, 637, 644, 758, 551, 729, 196, 297, 570, 610, 644, 110, 280, 297, 303, 350, 370, 372, 374, 376, 386, 393, 629, 650, 736, 737, 166, 500, 628, 159, 215, 239, 297, 335, 350, 352, 430, 454, 485, 600, 633, 648, 650, 737, 65, 234, 290, 297, 309, 350, 639, 737, 756, 64, 212, 297, 307, 335, 350, 352, 430, 454, 485, 599, 600, 633, 648, 650, 737, 297, 481, 637, 644, 243, 659, 353, 422, 426, 431, 441, 643, 644, 312, 464, 551, 523, 642, 312, 551, 565, 565, 583, 642, 464, 598, 634, 643, 644, 674, 765, 274, 726, 761, 297, 766, 339, 751, 297, 269, 444, 712, 378, 608, 379, 540, 542, 75, 273, 297, 322, 724, 503, 540, 542, 297, 322, 724, 613, 297, 264, 687, 702, 297, 643, 638, 766, 603, 734, 571, 26, 27, 40, 394, 297, 501, 297, 350, 650, 737, 486, 490, 764, 536, 552, 601, 740, 552, 649, 653, 98, 310, 366, 642, 516, 308, 695, 765, 659, 620, 297, 297, 307, 335, 350, 430, 454, 650, 737, 87, 113, 204, 216, 225, 251, 297, 347, 350, 402, 585, 605, 621, 659, 675, 737, 265, 442, 644, 704, 284, 455, 744, 750, 297, 350, 650, 737, 481, 554, 165, 498, 558, 297, 350, 650, 736, 737, 297, 335, 350, 352, 454, 553, 557, 599, 633, 737, 92, 297, 350, 352, 357, 430, 454, 485, 648, 650, 737, 297, 454, 673, 765, 727, 63, 168, 179, 297, 305, 350, 440, 504, 530, 737, 297, 122, 203, 413, 584, 713, 297, 413, 297, 413, 297, 170, 173, 323, 510, 517, 518, 510, 517, 518, 725, 503, 257, 297, 688, 703, 297, 297, 297, 643, 644, 313, 766, 297, 297, 610, 644, 297, 297, 623, 627, 297, 395, 297, 395, 297, 395, 766, 169, 174, 297, 350, 508, 520, 737, 637, 670, 297, 297, 620, 660, 620, 403, 620, 97, 364, 586, 224, 606, 618, 618, 622, 364, 676, 705, 297, 378, 502, 745, 214, 232, 272, 297, 350, 386, 604, 635, 650, 716, 718, 737, 297, 350, 352, 361, 430, 454, 553, 559, 650, 737, 499, 297, 350, 352, 430, 650, 737, 358, 430, 86, 143, 259, 297, 344, 453, 692, 306, 542, 505, 643, 644, 531, 643, 644, 414, 561, 567, 631, 637, 644, 413, 114, 404, 413, 584, 714, 511, 519, 297, 725, 297, 689, 702, 297, 718, 297, 367, 404, 509, 637, 643, 644, 521, 637, 643, 644, 297, 178, 528, 297, 650, 620, 297, 650, 365, 297, 650, 619, 297, 650, 297, 650, 297, 650, 121, 266, 297, 409, 706, 297, 744, 750, 740, 636, 643, 644, 248, 671, 719, 297, 553, 297, 345, 637, 643, 644, 297, 637, 643, 644, 693, 297, 350, 440, 504, 530, 737, 176, 506, 524, 644, 704, 378, 502, 532, 297, 322, 724, 670, 670, 297, 141, 297, 450, 517, 518, 297, 510, 517, 297, 255, 297, 684, 297, 297, 528, 297, 528, 529, 297, 348, 66, 297, 311, 620, 297, 620, 180, 344, 410, 533, 692, 195, 524, 569, 644, 704, 707, 729, 297, 303, 350, 370, 372, 374, 376, 386, 629, 650, 736, 737, 766, 249, 672, 720, 322, 346, 724, 404, 694, 517, 378, 502, 507, 297, 297, 297, 297, 750, 297, 450, 510, 517, 518, 297, 650, 620, 534, 637, 643, 644, 411, 524, 569, 644, 704, 297, 378, 502, 708, 297, 766, 766, 105, 380, 721, 297, 297, 322, 724, 497, 525, 297, 685, 718, 620, 510, 517, 518, 535, 378, 412, 502, 297, 297, 766, 381, 587, 722, 297, 297, 620, 297, 297, 297, 297, 620, 589, 723, 297, 297 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_int16 yyr1[] = { 0, 296, 297, 298, 299, 299, 299, 299, 299, 299, 299, 300, 301, 302, 303, 304, 304, 305, 306, 306, 306, 306, 306, 306, 307, 308, 308, 309, 310, 310, 310, 310, 310, 311, 312, 313, 313, 314, 315, 316, 316, 316, 316, 316, 317, 318, 319, 320, 321, 322, 323, 323, 323, 324, 325, 325, 326, 326, 327, 328, 328, 328, 328, 329, 330, 330, 331, 332, 332, 333, 334, 335, 336, 337, 337, 337, 337, 337, 337, 337, 338, 339, 340, 340, 341, 342, 343, 343, 343, 344, 345, 345, 345, 346, 346, 346, 347, 348, 348, 349, 350, 351, 351, 352, 353, 353, 353, 353, 353, 353, 353, 353, 354, 355, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 357, 358, 358, 359, 360, 360, 360, 361, 362, 362, 363, 364, 365, 365, 365, 366, 367, 367, 368, 369, 369, 370, 371, 371, 372, 373, 373, 374, 375, 375, 376, 377, 377, 378, 379, 379, 380, 381, 381, 382, 383, 383, 383, 384, 385, 385, 385, 385, 385, 386, 387, 387, 388, 389, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 391, 392, 392, 392, 392, 393, 394, 394, 394, 395, 396, 396, 397, 397, 398, 398, 399, 399, 400, 401, 401, 402, 403, 403, 404, 405, 406, 406, 406, 406, 407, 408, 408, 408, 409, 410, 410, 410, 411, 411, 411, 411, 412, 412, 412, 413, 414, 414, 414, 414, 414, 414, 414, 415, 416, 417, 417, 417, 417, 417, 418, 419, 420, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 422, 423, 424, 425, 425, 425, 426, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 428, 429, 429, 430, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, 432, 433, 433, 433, 433, 434, 434, 434, 434, 434, 435, 436, 436, 436, 436, 437, 438, 438, 438, 438, 439, 440, 441, 441, 442, 442, 442, 442, 443, 444, 444, 445, 446, 446, 446, 446, 446, 447, 448, 449, 450, 451, 452, 452, 453, 454, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 456, 457, 457, 457, 458, 459, 459, 459, 459, 459, 460, 461, 461, 462, 463, 463, 463, 463, 463, 464, 464, 465, 465, 466, 467, 467, 468, 469, 469, 469, 469, 470, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, 472, 473, 473, 473, 473, 474, 475, 475, 475, 475, 476, 477, 477, 477, 477, 478, 479, 479, 480, 481, 482, 482, 482, 482, 483, 484, 484, 484, 484, 484, 484, 484, 484, 484, 485, 486, 486, 487, 488, 489, 489, 490, 491, 492, 493, 494, 495, 496, 496, 496, 496, 496, 497, 498, 499, 499, 500, 501, 501, 501, 502, 503, 503, 504, 505, 505, 506, 506, 506, 507, 507, 507, 508, 509, 509, 509, 509, 510, 511, 511, 511, 511, 512, 513, 513, 514, 515, 515, 516, 517, 518, 519, 519, 519, 520, 521, 521, 521, 521, 522, 523, 523, 523, 523, 524, 525, 525, 526, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 528, 529, 529, 529, 529, 529, 530, 531, 531, 532, 532, 532, 533, 534, 534, 534, 535, 535, 535, 536, 537, 537, 538, 539, 539, 539, 539, 540, 541, 541, 542, 542, 543, 544, 544, 544, 545, 546, 546, 547, 548, 548, 548, 548, 548, 549, 550, 550, 551, 551, 551, 552, 552, 553, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 555, 556, 556, 556, 556, 556, 557, 558, 558, 558, 558, 558, 558, 559, 560, 560, 560, 561, 562, 562, 562, 563, 564, 564, 564, 564, 564, 565, 565, 566, 566, 567, 568, 568, 568, 568, 569, 570, 571, 571, 571, 572, 573, 573, 573, 574, 575, 575, 575, 575, 576, 577, 577, 577, 577, 578, 579, 579, 580, 581, 581, 581, 581, 582, 583, 583, 583, 583, 583, 584, 585, 586, 586, 587, 588, 588, 588, 588, 588, 588, 588, 588, 589, 590, 591, 591, 591, 591, 592, 593, 593, 593, 593, 594, 595, 595, 596, 597, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 599, 600, 601, 601, 602, 603, 603, 604, 605, 606, 606, 607, 608, 608, 609, 610, 611, 611, 611, 611, 612, 613, 613, 614, 615, 615, 615, 615, 616, 617, 617, 618, 619, 619, 620, 621, 622, 622, 623, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 625, 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 627, 628, 628, 628, 628, 629, 630, 630, 630, 630, 631, 632, 632, 632, 633, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 635, 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 637, 638, 638, 638, 639, 640, 641, 641, 641, 641, 641, 642, 642, 643, 643, 644, 645, 645, 645, 645, 646, 647, 647, 648, 649, 649, 650, 651, 651, 651, 651, 651, 652, 653, 654, 655, 655, 655, 655, 655, 655, 655, 655, 655, 655, 655, 655, 656, 656, 656, 656, 656, 656, 657, 658, 658, 658, 659, 660, 660, 661, 662, 662, 662, 662, 663, 664, 664, 665, 665, 666, 667, 667, 668, 669, 670, 670, 671, 672, 673, 674, 674, 674, 674, 675, 676, 676, 677, 678, 679, 679, 679, 679, 679, 679, 680, 681, 681, 681, 681, 682, 683, 683, 684, 685, 685, 686, 687, 687, 688, 689, 689, 690, 691, 691, 691, 691, 692, 693, 693, 693, 694, 694, 694, 695, 696, 697, 697, 697, 697, 698, 698, 699, 700, 701, 701, 701, 701, 701, 701, 701, 701, 701, 701, 701, 701, 701, 701, 702, 703, 703, 704, 705, 705, 705, 706, 707, 707, 707, 707, 708, 708, 708, 709, 710, 710, 710, 710, 710, 710, 710, 711, 712, 713, 713, 714, 714, 714, 715, 716, 717, 717, 717, 717, 717, 718, 719, 719, 720, 720, 721, 721, 722, 722, 723, 723, 724, 725, 725, 725, 726, 727, 727, 727, 727, 728, 729, 729, 729, 729, 729, 729, 730, 731, 732, 733, 733, 733, 733, 734, 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, 736, 737, 738, 738, 738, 738, 738, 739, 739, 740, 740, 741, 742, 743, 743, 743, 743, 743, 743, 744, 745, 745, 745, 746, 747, 747, 747, 747, 747, 747, 747, 747, 747, 748, 749, 750, 751, 751, 752, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 754, 755, 756, 757, 758, 759, 759, 759, 759, 760, 761, 761, 761, 761, 761, 761, 761, 762, 763, 763, 763, 763, 763, 763, 763, 764, 765, 766, 767 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ static const yytype_int8 yyr2[] = { 0, 2, 1, 7, 0, 2, 2, 2, 2, 2, 2, 1, 3, 5, 3, 1, 1, 3, 1, 2, 2, 2, 2, 2, 3, 1, 1, 3, 1, 2, 2, 2, 2, 5, 5, 0, 1, 3, 3, 1, 1, 1, 2, 2, 3, 3, 3, 3, 2, 3, 1, 1, 1, 4, 1, 1, 1, 1, 3, 0, 2, 2, 2, 3, 1, 2, 3, 1, 1, 5, 3, 3, 4, 1, 2, 2, 2, 2, 2, 2, 1, 4, 0, 1, 1, 3, 1, 1, 1, 4, 1, 1, 1, 0, 1, 1, 5, 0, 2, 5, 3, 0, 2, 3, 0, 2, 2, 2, 2, 2, 2, 2, 3, 3, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 0, 1, 3, 1, 1, 1, 3, 1, 1, 3, 3, 0, 2, 2, 4, 0, 1, 4, 0, 1, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 0, 2, 3, 1, 1, 1, 4, 1, 2, 2, 2, 2, 3, 1, 1, 1, 3, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 1, 1, 2, 2, 3, 1, 1, 1, 6, 1, 1, 0, 1, 0, 1, 0, 1, 3, 0, 2, 3, 1, 2, 3, 6, 1, 1, 2, 2, 3, 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 3, 1, 1, 1, 1, 1, 2, 2, 3, 5, 1, 2, 2, 2, 2, 4, 2, 3, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 3, 1, 1, 1, 3, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 0, 1, 3, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 1, 1, 2, 2, 1, 1, 1, 1, 1, 5, 1, 1, 2, 2, 5, 1, 1, 2, 2, 5, 4, 1, 1, 1, 1, 2, 2, 3, 1, 2, 3, 0, 2, 2, 2, 2, 3, 3, 4, 2, 3, 1, 1, 2, 4, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 4, 0, 1, 1, 3, 1, 2, 2, 2, 2, 3, 0, 2, 3, 0, 2, 2, 2, 2, 1, 1, 1, 1, 3, 1, 2, 3, 0, 2, 2, 2, 3, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 1, 1, 2, 2, 3, 1, 1, 2, 2, 5, 1, 1, 2, 2, 3, 1, 1, 2, 3, 0, 2, 2, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 2, 3, 3, 1, 2, 1, 1, 3, 1, 1, 5, 1, 2, 2, 2, 2, 3, 3, 0, 2, 3, 0, 2, 2, 4, 1, 1, 5, 1, 1, 1, 1, 1, 0, 1, 1, 3, 1, 1, 1, 2, 3, 0, 2, 2, 2, 3, 0, 2, 3, 0, 2, 1, 1, 3, 0, 2, 2, 3, 1, 1, 1, 2, 3, 1, 2, 2, 2, 4, 0, 1, 3, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 0, 2, 2, 2, 2, 4, 1, 1, 0, 1, 1, 4, 1, 1, 1, 1, 1, 1, 4, 1, 2, 3, 0, 2, 2, 2, 3, 1, 2, 1, 1, 5, 1, 1, 1, 3, 0, 2, 3, 0, 2, 2, 2, 2, 3, 1, 2, 1, 1, 1, 1, 1, 4, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 1, 2, 2, 2, 2, 4, 1, 2, 2, 2, 2, 2, 4, 1, 2, 2, 3, 0, 2, 2, 3, 0, 2, 2, 2, 2, 1, 1, 1, 1, 4, 0, 1, 1, 1, 2, 3, 0, 2, 2, 4, 1, 2, 2, 5, 1, 1, 2, 2, 3, 0, 2, 2, 2, 3, 1, 2, 3, 0, 2, 2, 2, 3, 1, 2, 2, 2, 2, 4, 3, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 3, 6, 1, 1, 2, 2, 6, 1, 1, 2, 2, 5, 1, 1, 3, 3, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 1, 2, 5, 0, 1, 4, 3, 1, 2, 3, 1, 2, 3, 3, 0, 2, 2, 2, 3, 0, 2, 3, 0, 2, 2, 2, 3, 1, 2, 3, 0, 2, 4, 3, 1, 2, 3, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 1, 2, 2, 2, 4, 1, 1, 2, 2, 3, 0, 2, 2, 3, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 0, 2, 2, 4, 3, 0, 2, 2, 2, 2, 1, 1, 1, 1, 4, 0, 1, 1, 1, 4, 0, 1, 3, 1, 2, 4, 1, 2, 2, 2, 2, 1, 1, 3, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 3, 0, 2, 2, 4, 1, 2, 5, 1, 1, 2, 2, 4, 1, 1, 1, 1, 3, 0, 2, 1, 5, 1, 4, 4, 4, 3, 1, 2, 2, 2, 3, 1, 2, 1, 3, 1, 2, 2, 2, 2, 2, 3, 0, 2, 2, 2, 3, 0, 1, 4, 0, 1, 3, 0, 1, 3, 1, 2, 3, 0, 2, 2, 2, 4, 1, 1, 1, 1, 2, 2, 3, 3, 0, 2, 2, 2, 1, 2, 3, 3, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 0, 2, 3, 0, 2, 2, 4, 1, 1, 1, 1, 0, 1, 1, 3, 1, 2, 2, 2, 2, 2, 2, 3, 4, 1, 1, 1, 1, 1, 8, 3, 1, 2, 2, 2, 2, 7, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 4, 1, 1, 1, 3, 0, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 3, 1, 1, 2, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 2, 2, 2, 2, 1, 1, 1, 1, 3, 5, 1, 2, 2, 2, 2, 2, 3, 0, 2, 2, 3, 0, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 4, 0, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 5, 3, 3, 0, 2, 2, 2, 3, 1, 2, 2, 2, 2, 2, 2, 3, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY) \ { \ yychar = (Token); \ yylval = (Value); \ YYPOPSTACK (yylen); \ yystate = *yyssp; \ goto yybackup; \ } \ else \ { \ yyerror (YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (0) /* Error token number */ #define YYTERROR 1 #define YYERRCODE 256 /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (0) /* This macro is provided for backward compatibility. */ #ifndef YY_LOCATION_PRINT # define YY_LOCATION_PRINT(File, Loc) ((void) 0) #endif # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value); \ YYFPRINTF (stderr, "\n"); \ } \ } while (0) /*-----------------------------------. | Print this symbol's value on YYO. | `-----------------------------------*/ static void yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep) { FILE *yyoutput = yyo; YYUSE (yyoutput); if (!yyvaluep) return; # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyo, yytoknum[yytype], *yyvaluep); # endif YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN YYUSE (yytype); YY_IGNORE_MAYBE_UNINITIALIZED_END } /*---------------------------. | Print this symbol on YYO. | `---------------------------*/ static void yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep) { YYFPRINTF (yyo, "%s %s (", yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); yy_symbol_value_print (yyo, yytype, yyvaluep); YYFPRINTF (yyo, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ static void yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) { YYFPRINTF (stderr, "Stack now"); for (; yybottom <= yytop; yybottom++) { int yybot = *yybottom; YYFPRINTF (stderr, " %d", yybot); } YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (0) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ static void yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, int yyrule) { int yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yystos[+yyssp[yyi + 1 - yynrhs]], &yyvsp[(yyi + 1) - (yynrhs)] ); YYFPRINTF (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyssp, yyvsp, Rule); \ } while (0) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S))) # else /* Return the length of YYSTR. */ static YYPTRDIFF_T yystrlen (const char *yystr) { YYPTRDIFF_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ static char * yystpcpy (char *yydest, const char *yysrc) { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYPTRDIFF_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYPTRDIFF_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; else goto append; append: default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (yyres) return yystpcpy (yyres, yystr) - yyres; else return yystrlen (yystr); } # endif /* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message about the unexpected token YYTOKEN for the state stack whose top is YYSSP. Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is not large enough to hold the message. In that case, also set *YYMSG_ALLOC to the required number of bytes. Return 2 if the required number of bytes is too large to store. */ static int yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, yy_state_t *yyssp, int yytoken) { enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; /* Internationalized format string. */ const char *yyformat = YY_NULLPTR; /* Arguments of yyformat: reported tokens (one for the "unexpected", one per "expected"). */ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; /* Actual size of YYARG. */ int yycount = 0; /* Cumulated lengths of YYARG. */ YYPTRDIFF_T yysize = 0; /* There are many possibilities here to consider: - If this state is a consistent state with a default action, then the only way this function was invoked is if the default action is an error action. In that case, don't check for expected tokens because there are none. - The only way there can be no lookahead present (in yychar) is if this state is a consistent state with a default action. Thus, detecting the absence of a lookahead is sufficient to determine that there is no unexpected or expected token to report. In that case, just report a simple "syntax error". - Don't assume there isn't a lookahead just because this state is a consistent state with a default action. There might have been a previous inconsistent state, consistent state with a non-default action, or user semantic action that manipulated yychar. - Of course, the expected token list depends on states to have correct lookahead information, and it depends on the parser not to perform extra reductions after fetching a lookahead from the scanner and before detecting a syntax error. Thus, state merging (from LALR or IELR) and default reductions corrupt the expected token list. However, the list is correct for canonical LR with one exception: it will still contain any token that will not be accepted due to an error action in a later state. */ if (yytoken != YYEMPTY) { int yyn = yypact[+*yyssp]; YYPTRDIFF_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); yysize = yysize0; yyarg[yycount++] = yytname[yytoken]; if (!yypact_value_is_default (yyn)) { /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. In other words, skip the first -YYN actions for this state because they are default actions. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yyx; for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR && !yytable_value_is_error (yytable[yyx + yyn])) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; break; } yyarg[yycount++] = yytname[yyx]; { YYPTRDIFF_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) yysize = yysize1; else return 2; } } } } switch (yycount) { # define YYCASE_(N, S) \ case N: \ yyformat = S; \ break default: /* Avoid compiler warnings. */ YYCASE_(0, YY_("syntax error")); YYCASE_(1, YY_("syntax error, unexpected %s")); YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); # undef YYCASE_ } { /* Don't count the "%s"s in the final size, but reserve room for the terminator. */ YYPTRDIFF_T yysize1 = yysize + (yystrlen (yyformat) - 2 * yycount) + 1; if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) yysize = yysize1; else return 2; } if (*yymsg_alloc < yysize) { *yymsg_alloc = 2 * yysize; if (! (yysize <= *yymsg_alloc && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; return 1; } /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ { char *yyp = *yymsg; int yyi = 0; while ((*yyp = *yyformat) != '\0') if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyformat += 2; } else { ++yyp; ++yyformat; } } return 0; } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) { YYUSE (yyvaluep); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN YYUSE (yytype); YY_IGNORE_MAYBE_UNINITIALIZED_END } /* The lookahead symbol. */ int yychar; /* The semantic value of the lookahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; /*----------. | yyparse. | `----------*/ int yyparse (void) { yy_state_fast_t yystate; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* The stacks and their tools: 'yyss': related to states. 'yyvs': related to semantic values. Refer to the stacks through separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yy_state_t yyssa[YYINITDEPTH]; yy_state_t *yyss; yy_state_t *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs; YYSTYPE *yyvsp; YYPTRDIFF_T yystacksize; int yyn; int yyresult; /* Lookahead token as an internal (translated) token number. */ int yytoken = 0; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYPTRDIFF_T yymsg_alloc = sizeof yymsgbuf; #endif #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; yyssp = yyss = yyssa; yyvsp = yyvs = yyvsa; yystacksize = YYINITDEPTH; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ goto yysetstate; /*------------------------------------------------------------. | yynewstate -- push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; /*--------------------------------------------------------------------. | yysetstate -- set current state (the top of the stack) to yystate. | `--------------------------------------------------------------------*/ yysetstate: YYDPRINTF ((stderr, "Entering state %d\n", yystate)); YY_ASSERT (0 <= yystate && yystate < YYNSTATES); YY_IGNORE_USELESS_CAST_BEGIN *yyssp = YY_CAST (yy_state_t, yystate); YY_IGNORE_USELESS_CAST_END if (yyss + yystacksize - 1 <= yyssp) #if !defined yyoverflow && !defined YYSTACK_RELOCATE goto yyexhaustedlab; #else { /* Get the current used size of the three stacks, in elements. */ YYPTRDIFF_T yysize = yyssp - yyss + 1; # if defined yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ yy_state_t *yyss1 = yyss; YYSTYPE *yyvs1 = yyvs; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * YYSIZEOF (*yyssp), &yyvs1, yysize * YYSIZEOF (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } # else /* defined YYSTACK_RELOCATE */ /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yy_state_t *yyss1 = yyss; union yyalloc *yyptr = YY_CAST (union yyalloc *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YY_IGNORE_USELESS_CAST_BEGIN YYDPRINTF ((stderr, "Stack size increased to %ld\n", YY_CAST (long, yystacksize))); YY_IGNORE_USELESS_CAST_END if (yyss + yystacksize - 1 <= yyssp) YYABORT; } #endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ if (yystate == YYFINAL) YYACCEPT; goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yypact_value_is_default (yyn)) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = yylex (); } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yytable_value_is_error (yyn)) goto yyerrlab; yyn = -yyn; goto yyreduce; } /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); yystate = yyn; YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END /* Discard the shifted token. */ yychar = YYEMPTY; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: '$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 2: #line 505 "edif.y" { PopC(); } #line 3758 "edif.c" break; case 11: #line 520 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 3764 "edif.c" break; case 12: #line 523 "edif.y" { free((yyvsp[-1].s)); } #line 3770 "edif.c" break; case 13: #line 527 "edif.y" { free((yyvsp[-3].s)); free((yyvsp[-2].s)); free((yyvsp[-1].s)); } #line 3776 "edif.c" break; case 25: #line 551 "edif.y" { free((yyvsp[0].s)); } #line 3782 "edif.c" break; case 34: #line 568 "edif.y" { str_pair_free((yyvsp[-3].ps)); free((yyvsp[-2].s)); } #line 3788 "edif.c" break; case 36: #line 572 "edif.y" { free((yyvsp[0].s)); } #line 3794 "edif.c" break; case 47: #line 597 "edif.y" { free((yyvsp[-1].s)); } #line 3800 "edif.c" break; case 69: #line 645 "edif.y" { free((yyvsp[-3].s)); free((yyvsp[-2].s)); } #line 3806 "edif.c" break; case 70: #line 648 "edif.y" { free((yyvsp[-1].s)); } #line 3812 "edif.c" break; case 80: #line 666 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 3818 "edif.c" break; case 84: #line 676 "edif.y" { free((yyvsp[0].s)); } #line 3824 "edif.c" break; case 91: #line 691 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 3830 "edif.c" break; case 102: #line 714 "edif.y" { free((yyvsp[0].s)); } #line 3836 "edif.c" break; case 140: #line 774 "edif.y" { free((yyvsp[0].s)); } #line 3842 "edif.c" break; case 147: #line 789 "edif.y" { free((yyvsp[-2].s)); } #line 3848 "edif.c" break; case 150: #line 796 "edif.y" { free((yyvsp[-2].s)); } #line 3854 "edif.c" break; case 182: #line 866 "edif.y" { free((yyvsp[0].s)); } #line 3860 "edif.c" break; case 184: #line 870 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 3866 "edif.c" break; case 240: #line 974 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 3872 "edif.c" break; case 247: #line 987 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 3878 "edif.c" break; case 278: #line 1034 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 3884 "edif.c" break; case 279: #line 1037 "edif.y" { free((yyvsp[0].s)); } #line 3890 "edif.c" break; case 333: #line 1123 "edif.y" { free((yyvsp[-3].s)); free((yyvsp[-2].s)); } #line 3896 "edif.c" break; case 336: #line 1130 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 3902 "edif.c" break; case 337: #line 1133 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 3908 "edif.c" break; case 344: #line 1146 "edif.y" { free((yyvsp[-2].s)); } #line 3914 "edif.c" break; case 346: #line 1150 "edif.y" { free((yyvsp[0].s)); } #line 3920 "edif.c" break; case 347: #line 1151 "edif.y" { free((yyvsp[0].s)); } #line 3926 "edif.c" break; case 348: #line 1152 "edif.y" { free((yyvsp[0].s)); } #line 3932 "edif.c" break; case 369: #line 1193 "edif.y" { (yyval.s)=(yyvsp[-2].s); } #line 3938 "edif.c" break; case 371: #line 1197 "edif.y" { free((yyvsp[0].s)); } #line 3944 "edif.c" break; case 374: #line 1204 "edif.y" { free((yyvsp[0].s)); } #line 3950 "edif.c" break; case 381: #line 1215 "edif.y" { free((yyvsp[0].s)); } #line 3956 "edif.c" break; case 384: #line 1222 "edif.y" { free((yyvsp[0].s)); } #line 3962 "edif.c" break; case 388: #line 1228 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 3968 "edif.c" break; case 390: #line 1232 "edif.y" { (yyval.s)=(yyvsp[0].s); } #line 3974 "edif.c" break; case 393: #line 1239 "edif.y" { free((yyvsp[0].s)); } #line 3980 "edif.c" break; case 397: #line 1247 "edif.y" { free((yyvsp[0].s)); } #line 3986 "edif.c" break; case 408: #line 1262 "edif.y" { pair_list_free((yyvsp[0].pl)); } #line 3992 "edif.c" break; case 437: #line 1312 "edif.y" { (yyval.pl) = new_pair_list((yyvsp[-1].ps)); } #line 3998 "edif.c" break; case 438: #line 1315 "edif.y" { (yyval.ps)=NULL; } #line 4004 "edif.c" break; case 439: #line 1316 "edif.y" { (yyvsp[0].ps)->next = (yyvsp[-1].ps); (yyval.ps) = (yyvsp[0].ps); } #line 4010 "edif.c" break; case 455: #line 1342 "edif.y" { free((yyvsp[-1].s)); } #line 4016 "edif.c" break; case 459: #line 1352 "edif.y" { free((yyvsp[0].s)); } #line 4022 "edif.c" break; case 460: #line 1355 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 4028 "edif.c" break; case 462: #line 1361 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 4034 "edif.c" break; case 463: #line 1364 "edif.y" { free((yyvsp[0].s)); } #line 4040 "edif.c" break; case 483: #line 1406 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 4046 "edif.c" break; case 484: #line 1409 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 4052 "edif.c" break; case 492: #line 1423 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 4058 "edif.c" break; case 506: #line 1451 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 4064 "edif.c" break; case 507: #line 1454 "edif.y" { free((yyvsp[0].s)); } #line 4070 "edif.c" break; case 514: #line 1469 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 4076 "edif.c" break; case 549: #line 1524 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 4082 "edif.c" break; case 555: #line 1536 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 4088 "edif.c" break; case 560: #line 1545 "edif.y" { free((yyvsp[-2].s)); } #line 4094 "edif.c" break; case 561: #line 1548 "edif.y" { free((yyvsp[0].s)); } #line 4100 "edif.c" break; case 562: #line 1549 "edif.y" { free((yyvsp[0].s)); } #line 4106 "edif.c" break; case 582: #line 1591 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 4112 "edif.c" break; case 585: #line 1594 "edif.y" { pair_list_free((yyvsp[0].pl)); } #line 4118 "edif.c" break; case 586: #line 1597 "edif.y" { (yyval.s)=(yyvsp[-1].s); } #line 4124 "edif.c" break; case 587: #line 1600 "edif.y" { (yyval.s)=(yyvsp[0].s); } #line 4130 "edif.c" break; case 589: #line 1604 "edif.y" { (yyval.ps) = new_str_pair((yyvsp[0].s),NULL); } #line 4136 "edif.c" break; case 590: #line 1605 "edif.y" { (yyval.ps) = new_str_pair((yyvsp[0].s),NULL); } #line 4142 "edif.c" break; case 591: #line 1606 "edif.y" { (yyval.ps)=(yyvsp[0].ps); } #line 4148 "edif.c" break; case 592: #line 1609 "edif.y" { (yyval.s)=(yyvsp[0].s); } #line 4154 "edif.c" break; case 593: #line 1610 "edif.y" { (yyval.s)=(yyvsp[0].s); } #line 4160 "edif.c" break; case 594: #line 1613 "edif.y" { define_pcb_net((yyvsp[-2].ps), (yyvsp[-1].pl)); } #line 4166 "edif.c" break; case 595: #line 1616 "edif.y" { (yyval.pl)=(yyvsp[0].pl); } #line 4172 "edif.c" break; case 611: #line 1638 "edif.y" { str_pair_free((yyvsp[-2].ps)); } #line 4178 "edif.c" break; case 632: #line 1675 "edif.y" { (yyval.ps)=(yyvsp[0].ps); } #line 4184 "edif.c" break; case 633: #line 1676 "edif.y" { (yyval.ps)=NULL; } #line 4190 "edif.c" break; case 634: #line 1680 "edif.y" { free((yyvsp[0].s)); } #line 4196 "edif.c" break; case 639: #line 1689 "edif.y" { free((yyvsp[0].s)); } #line 4202 "edif.c" break; case 644: #line 1700 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 4208 "edif.c" break; case 698: #line 1802 "edif.y" { free((yyvsp[-3].s)); } #line 4214 "edif.c" break; case 701: #line 1809 "edif.y" { free((yyvsp[-1].s)); } #line 4220 "edif.c" break; case 727: #line 1861 "edif.y" { free((yyvsp[-1].s)); } #line 4226 "edif.c" break; case 730: #line 1868 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 4232 "edif.c" break; case 747: #line 1903 "edif.y" { free((yyvsp[-2].s)); free((yyvsp[-1].s)); } #line 4238 "edif.c" break; case 766: #line 1934 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 4244 "edif.c" break; case 789: #line 1969 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 4250 "edif.c" break; case 791: #line 1975 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 4256 "edif.c" break; case 803: #line 1991 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 4262 "edif.c" break; case 818: #line 2010 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 4268 "edif.c" break; case 823: #line 2021 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 4274 "edif.c" break; case 827: #line 2027 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 4280 "edif.c" break; case 829: #line 2031 "edif.y" { (yyval.s)=(yyvsp[0].s); } #line 4286 "edif.c" break; case 831: #line 2036 "edif.y" { if ((yyvsp[-1].ps)) { (yyval.ps) = new_str_pair((yyvsp[-1].ps)->str1,(yyvsp[-2].s)); free((yyvsp[-1].ps)); } else { /* handle port with no instance by passing up the chain */ (yyval.ps) = new_str_pair(NULL,(yyvsp[-2].s)); } } #line 4303 "edif.c" break; case 832: #line 2050 "edif.y" { (yyval.ps)=NULL; } #line 4309 "edif.c" break; case 833: #line 2051 "edif.y" { (yyval.ps)=(yyvsp[0].ps); } #line 4315 "edif.c" break; case 834: #line 2052 "edif.y" { (yyval.ps) = new_str_pair((yyvsp[0].s),NULL); } #line 4321 "edif.c" break; case 835: #line 2053 "edif.y" { (yyval.ps)=NULL; } #line 4327 "edif.c" break; case 848: #line 2080 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 4333 "edif.c" break; case 849: #line 2083 "edif.y" { free((yyvsp[0].s)); } #line 4339 "edif.c" break; case 881: #line 2136 "edif.y" { (yyval.ps) = new_str_pair((yyvsp[-2].s),(yyvsp[-1].s)); } #line 4345 "edif.c" break; case 882: #line 2139 "edif.y" { (yyval.s)=(yyvsp[0].s); } #line 4351 "edif.c" break; case 883: #line 2140 "edif.y" { (yyval.s)=(yyvsp[0].s); } #line 4357 "edif.c" break; case 884: #line 2143 "edif.y" { (yyval.s)=(yyvsp[0].s); } #line 4363 "edif.c" break; case 885: #line 2144 "edif.y" { (yyval.s)=NULL; } #line 4369 "edif.c" break; case 889: #line 2154 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 4375 "edif.c" break; case 891: #line 2160 "edif.y" { free((yyvsp[0].s)); } #line 4381 "edif.c" break; case 892: #line 2161 "edif.y" { free((yyvsp[-2].s)); free((yyvsp[-1].s)); } #line 4387 "edif.c" break; case 893: #line 2164 "edif.y" { free((yyvsp[-2].s)); free((yyvsp[-1].s)); } #line 4393 "edif.c" break; case 894: #line 2167 "edif.y" { free((yyvsp[-2].s)); free((yyvsp[-1].s)); } #line 4399 "edif.c" break; case 896: #line 2173 "edif.y" { free((yyvsp[0].s)); } #line 4405 "edif.c" break; case 898: #line 2175 "edif.y" { free((yyvsp[0].s)); } #line 4411 "edif.c" break; case 903: #line 2186 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 4417 "edif.c" break; case 935: #line 2250 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 4423 "edif.c" break; case 943: #line 2266 "edif.y" { free((yyvsp[0].s)); } #line 4429 "edif.c" break; case 946: #line 2271 "edif.y" { free((yyvsp[0].s)); } #line 4435 "edif.c" break; case 973: #line 2316 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 4441 "edif.c" break; case 987: #line 2338 "edif.y" { free((yyvsp[-1].s)); } #line 4447 "edif.c" break; case 994: #line 2354 "edif.y" { free((yyvsp[-6].s)); free((yyvsp[-5].s)); free((yyvsp[-4].s)); free((yyvsp[-3].s)); free((yyvsp[-2].s)); free((yyvsp[-1].s)); } #line 4453 "edif.c" break; case 1054: #line 2461 "edif.y" { free((yyvsp[0].s)); } #line 4459 "edif.c" break; case 1055: #line 2462 "edif.y" { free((yyvsp[0].s)); } #line 4465 "edif.c" break; case 1056: #line 2463 "edif.y" { free((yyvsp[0].s)); } #line 4471 "edif.c" break; case 1057: #line 2464 "edif.y" { free((yyvsp[0].s)); } #line 4477 "edif.c" break; case 1059: #line 2468 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 4483 "edif.c" break; case 1061: #line 2472 "edif.y" { free((yyvsp[0].s)); } #line 4489 "edif.c" break; case 1063: #line 2476 "edif.y" { free((yyvsp[-1].s)); } #line 4495 "edif.c" break; case 1085: #line 2512 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 4501 "edif.c" break; case 1086: #line 2515 "edif.y" { free((yyvsp[0].s)); } #line 4507 "edif.c" break; case 1107: #line 2556 "edif.y" { str_pair_free((yyvsp[0].ps)); } #line 4513 "edif.c" break; case 1109: #line 2558 "edif.y" { pair_list_free((yyvsp[0].pl)); } #line 4519 "edif.c" break; case 1126: #line 2585 "edif.y" { (yyval.s)=(yyvsp[0].s); } #line 4525 "edif.c" break; case 1127: #line 2588 "edif.y" { (yyval.s)=(yyvsp[0].s); } #line 4531 "edif.c" break; case 1128: #line 2591 "edif.y" { (yyval.s)=(yyvsp[0].s); } #line 4537 "edif.c" break; case 1129: #line 2594 "edif.y" { (yyval.s)=(yyvsp[0].s); } #line 4543 "edif.c" break; #line 4547 "edif.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires that yytoken be updated with the new translation. We take the approach of translating immediately before every use of yytoken. One alternative is translating here after every semantic action, but that translation would be missed if the semantic action invokes YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an incorrect destructor might then be invoked immediately. In the case of YYERROR or YYBACKUP, subsequent parser actions might lead to an incorrect destructor call or verbose syntax error message before the lookahead is translated. */ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ { const int yylhs = yyr1[yyn] - YYNTOKENS; const int yyi = yypgoto[yylhs] + *yyssp; yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp ? yytable[yyi] : yydefgoto[yylhs]); } goto yynewstate; /*--------------------------------------. | yyerrlab -- here on detecting error. | `--------------------------------------*/ yyerrlab: /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (YY_("syntax error")); #else # define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ yyssp, yytoken) { char const *yymsgp = YY_("syntax error"); int yysyntax_error_status; yysyntax_error_status = YYSYNTAX_ERROR; if (yysyntax_error_status == 0) yymsgp = yymsg; else if (yysyntax_error_status == 1) { if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = YY_CAST (char *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, yymsg_alloc))); if (!yymsg) { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; yysyntax_error_status = 2; } else { yysyntax_error_status = YYSYNTAX_ERROR; yymsgp = yymsg; } } yyerror (yymsgp); if (yysyntax_error_status == 2) goto yyexhaustedlab; } # undef YYSYNTAX_ERROR #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval); yychar = YYEMPTY; } } /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (0) YYERROR; /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (!yypact_value_is_default (yyn)) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", yystos[yystate], yyvsp); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #if !defined yyoverflow || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif /*-----------------------------------------------------. | yyreturn -- parsing is finished, return the result. | `-----------------------------------------------------*/ yyreturn: if (yychar != YYEMPTY) { /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = YYTRANSLATE (yychar); yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval); } /* Do not reclaim the symbols of the rule whose action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[+*yyssp], yyvsp); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif return yyresult; } #line 2597 "edif.y" /* * xmalloc: * * Garbage function for 'alloca()'. */ char *xmalloc(int siz) { return ((char *)Malloc(siz)); } /* * Token & context carriers: * * These are the linkage pointers for threading this context garbage * for converting identifiers into parser tokens. */ typedef struct TokenCar { struct TokenCar *Next; /* pointer to next carrier */ struct Token *Token; /* associated token */ } TokenCar; typedef struct UsedCar { struct UsedCar *Next; /* pointer to next carrier */ short Code; /* used '%token' value */ } UsedCar; typedef struct ContextCar { struct ContextCar *Next; /* pointer to next carrier */ struct Context *Context; /* associated context */ union { int Single; /* single usage flag (context tree) */ struct UsedCar *Used; /* single used list (context stack) */ } u; } ContextCar; /* * Token definitions: * * This associates the '%token' codings with strings which are to * be free standing tokens. Doesn't have to be in sorted order but the * strings must be in lower case. */ typedef struct Token { char *Name; /* token name */ int Code; /* '%token' value */ struct Token *Next; /* hash table linkage */ } Token; static Token TokenDef[] = { {"angle", EDIF_TOK_ANGLE}, {"behavior", EDIF_TOK_BEHAVIOR}, {"calculated", EDIF_TOK_CALCULATED}, {"capacitance", EDIF_TOK_CAPACITANCE}, {"centercenter", EDIF_TOK_CENTERCENTER}, {"centerleft", EDIF_TOK_CENTERLEFT}, {"centerright", EDIF_TOK_CENTERRIGHT}, {"charge", EDIF_TOK_CHARGE}, {"conductance", EDIF_TOK_CONDUCTANCE}, {"current", EDIF_TOK_CURRENT}, {"distance", EDIF_TOK_DISTANCE}, {"document", EDIF_TOK_DOCUMENT}, {"energy", EDIF_TOK_ENERGY}, {"extend", EDIF_TOK_EXTEND}, {"flux", EDIF_TOK_FLUX}, {"frequency", EDIF_TOK_FREQUENCY}, {"generic", EDIF_TOK_GENERIC}, {"graphic", EDIF_TOK_GRAPHIC}, {"inductance", EDIF_TOK_INDUCTANCE}, {"inout", EDIF_TOK_INOUT}, {"input", EDIF_TOK_INPUT}, {"logicmodel", EDIF_TOK_LOGICMODEL}, {"lowercenter", EDIF_TOK_LOWERCENTER}, {"lowerleft", EDIF_TOK_LOWERLEFT}, {"lowerright", EDIF_TOK_LOWERRIGHT}, {"masklayout", EDIF_TOK_MASKLAYOUT}, {"mass", EDIF_TOK_MASS}, {"measured", EDIF_TOK_MEASURED}, {"mx", EDIF_TOK_MX}, {"mxr90", EDIF_TOK_MXR90}, {"my", EDIF_TOK_MY}, {"myr90", EDIF_TOK_MYR90}, {"netlist", EDIF_TOK_NETLIST}, {"output", EDIF_TOK_OUTPUT}, {"pcblayout", EDIF_TOK_PCBLAYOUT}, {"power", EDIF_TOK_POWER}, {"r0", EDIF_TOK_R0}, {"r180", EDIF_TOK_R180}, {"r270", EDIF_TOK_R270}, {"r90", EDIF_TOK_R90}, {"required", EDIF_TOK_REQUIRED}, {"resistance", EDIF_TOK_RESISTANCE}, {"ripper", EDIF_TOK_RIPPER}, {"round", EDIF_TOK_ROUND}, {"schematic", EDIF_TOK_SCHEMATIC}, {"stranger", EDIF_TOK_STRANGER}, {"symbolic", EDIF_TOK_SYMBOLIC}, {"temperature", EDIF_TOK_TEMPERATURE}, {"tie", EDIF_TOK_TIE}, {"time", EDIF_TOK_TIME}, {"truncate", EDIF_TOK_TRUNCATE}, {"uppercenter", EDIF_TOK_UPPERCENTER}, {"upperleft", EDIF_TOK_UPPERLEFT}, {"upperright", EDIF_TOK_UPPERRIGHT}, {"voltage", EDIF_TOK_VOLTAGE} }; static int TokenDefSize = sizeof(TokenDef) / sizeof(Token); /* * Token enable definitions: * * There is one array for each set of tokens enabled by a * particular context (barf). Another array is used to bind * these arrays to a context. */ static short e_CellType[] = {EDIF_TOK_TIE, EDIF_TOK_RIPPER, EDIF_TOK_GENERIC}; static short e_CornerType[] = {EDIF_TOK_EXTEND, EDIF_TOK_TRUNCATE, EDIF_TOK_ROUND}; static short e_Derivation[] = {EDIF_TOK_CALCULATED, EDIF_TOK_MEASURED, EDIF_TOK_REQUIRED}; static short e_Direction[] = {EDIF_TOK_INPUT, EDIF_TOK_OUTPUT, EDIF_TOK_INOUT}; static short e_EndType[] = {EDIF_TOK_EXTEND, EDIF_TOK_TRUNCATE, EDIF_TOK_ROUND}; static short e_Justify[] = {EDIF_TOK_CENTERCENTER, EDIF_TOK_CENTERLEFT, EDIF_TOK_CENTERRIGHT, EDIF_TOK_LOWERCENTER, EDIF_TOK_LOWERLEFT, EDIF_TOK_LOWERRIGHT, EDIF_TOK_UPPERCENTER, EDIF_TOK_UPPERLEFT, EDIF_TOK_UPPERRIGHT}; static short e_Orientation[] = {EDIF_TOK_R0, EDIF_TOK_R90, EDIF_TOK_R180, EDIF_TOK_R270, EDIF_TOK_MX, EDIF_TOK_MY, EDIF_TOK_MXR90, EDIF_TOK_MYR90}; static short e_Unit[] = {EDIF_TOK_DISTANCE, EDIF_TOK_CAPACITANCE, EDIF_TOK_CURRENT, EDIF_TOK_RESISTANCE, EDIF_TOK_TEMPERATURE, EDIF_TOK_TIME, EDIF_TOK_VOLTAGE, EDIF_TOK_MASS, EDIF_TOK_FREQUENCY, EDIF_TOK_INDUCTANCE, EDIF_TOK_ENERGY, EDIF_TOK_POWER, EDIF_TOK_CHARGE, EDIF_TOK_CONDUCTANCE, EDIF_TOK_FLUX, EDIF_TOK_ANGLE}; static short e_ViewType[] = {EDIF_TOK_MASKLAYOUT, EDIF_TOK_PCBLAYOUT, EDIF_TOK_NETLIST, EDIF_TOK_SCHEMATIC, EDIF_TOK_SYMBOLIC, EDIF_TOK_BEHAVIOR, EDIF_TOK_LOGICMODEL, EDIF_TOK_DOCUMENT, EDIF_TOK_GRAPHIC, EDIF_TOK_STRANGER}; /* * Token tying table: * * This binds enabled tokens to a context. */ typedef struct Tie { short *Enable; /* pointer to enable array */ short Origin; /* '%token' value of context */ short EnableSize; /* size of enabled array */ } Tie; #define TE(e,o) {e,o,sizeof(e)/sizeof(short)} static Tie TieDef[] = { TE(e_CellType, EDIF_TOK_CELLTYPE), TE(e_CornerType, EDIF_TOK_CORNERTYPE), TE(e_Derivation, EDIF_TOK_DERIVATION), TE(e_Direction, EDIF_TOK_DIRECTION), TE(e_EndType, EDIF_TOK_ENDTYPE), TE(e_Justify, EDIF_TOK_JUSTIFY), TE(e_Orientation, EDIF_TOK_ORIENTATION), TE(e_Unit, EDIF_TOK_UNIT), TE(e_ViewType, EDIF_TOK_VIEWTYPE) }; static int TieDefSize = sizeof(TieDef) / sizeof(Tie); /* * Context definitions: * * This associates keyword strings with '%token' values. It * also creates a pretty much empty header for later building of * the context tree. Again they needn't be sorted, but strings * must be lower case. */ typedef struct Context { char *Name; /* keyword name */ short Code; /* '%token' value */ short Flags; /* special operation flags */ struct ContextCar *Context; /* contexts which can be moved to */ struct TokenCar *Token; /* active tokens */ struct Context *Next; /* hash table linkage */ } Context; static Context ContextDef[] = { {"", 0}, /* start context */ {"acload", EDIF_TOK_ACLOAD}, {"after", EDIF_TOK_AFTER}, {"annotate", EDIF_TOK_ANNOTATE}, {"apply", EDIF_TOK_APPLY}, {"arc", EDIF_TOK_ARC}, {"array", EDIF_TOK_ARRAY}, {"arraymacro", EDIF_TOK_ARRAYMACRO}, {"arrayrelatedinfo", EDIF_TOK_ARRAYRELATEDINFO}, {"arraysite", EDIF_TOK_ARRAYSITE}, {"atleast", EDIF_TOK_ATLEAST}, {"atmost", EDIF_TOK_ATMOST}, {"author", EDIF_TOK_AUTHOR}, {"basearray", EDIF_TOK_BASEARRAY}, {"becomes", EDIF_TOK_BECOMES}, {"between", EDIF_TOK_BETWEEN}, {"boolean", EDIF_TOK_BOOLEAN}, {"booleandisplay", EDIF_TOK_BOOLEANDISPLAY}, {"booleanmap", EDIF_TOK_BOOLEANMAP}, {"borderpattern", EDIF_TOK_BORDERPATTERN}, {"borderwidth", EDIF_TOK_BORDERWIDTH}, {"boundingbox", EDIF_TOK_BOUNDINGBOX}, {"cell", EDIF_TOK_CELL}, {"cellref", EDIF_TOK_CELLREF}, {"celltype", EDIF_TOK_CELLTYPE}, {"change", EDIF_TOK_CHANGE}, {"circle", EDIF_TOK_CIRCLE}, {"color", EDIF_TOK_COLOR}, {"comment", EDIF_TOK_COMMENT}, {"commentgraphics", EDIF_TOK_COMMENTGRAPHICS}, {"compound", EDIF_TOK_COMPOUND}, {"connectlocation", EDIF_TOK_CONNECTLOCATION}, {"contents", EDIF_TOK_CONTENTS}, {"cornertype", EDIF_TOK_CORNERTYPE}, {"criticality", EDIF_TOK_CRITICALITY}, {"currentmap", EDIF_TOK_CURRENTMAP}, {"curve", EDIF_TOK_CURVE}, {"cycle", EDIF_TOK_CYCLE}, {"dataorigin", EDIF_TOK_DATAORIGIN}, {"dcfaninload", EDIF_TOK_DCFANINLOAD}, {"dcfanoutload", EDIF_TOK_DCFANOUTLOAD}, {"dcmaxfanin", EDIF_TOK_DCMAXFANIN}, {"dcmaxfanout", EDIF_TOK_DCMAXFANOUT}, {"delay", EDIF_TOK_DELAY}, {"delta", EDIF_TOK_DELTA}, {"derivation", EDIF_TOK_DERIVATION}, {"design", EDIF_TOK_DESIGN}, {"designator", EDIF_TOK_DESIGNATOR}, {"difference", EDIF_TOK_DIFFERENCE}, {"direction", EDIF_TOK_DIRECTION}, {"display", EDIF_TOK_DISPLAY}, {"dominates", EDIF_TOK_DOMINATES}, {"dot", EDIF_TOK_DOT}, {"duration", EDIF_TOK_DURATION}, {"e", EDIF_TOK_E}, {"edif", EDIF_TOK_EDIF}, {"ediflevel", EDIF_TOK_EDIFLEVEL}, {"edifversion", EDIF_TOK_EDIFVERSION}, {"enclosuredistance", EDIF_TOK_ENCLOSUREDISTANCE}, {"endtype", EDIF_TOK_ENDTYPE}, {"entry", EDIF_TOK_ENTRY}, {"exactly", EDIF_TOK_EXACTLY}, {"external", EDIF_TOK_EXTERNAL}, {"fabricate", EDIF_TOK_FABRICATE}, {"false", EDIF_TOK_FALSE}, {"figure", EDIF_TOK_FIGURE}, {"figurearea", EDIF_TOK_FIGUREAREA}, {"figuregroup", EDIF_TOK_FIGUREGROUP}, {"figuregroupobject", EDIF_TOK_FIGUREGROUPOBJECT}, {"figuregroupoverride", EDIF_TOK_FIGUREGROUPOVERRIDE}, {"figuregroupref", EDIF_TOK_FIGUREGROUPREF}, {"figureperimeter", EDIF_TOK_FIGUREPERIMETER}, {"figurewidth", EDIF_TOK_FIGUREWIDTH}, {"fillpattern", EDIF_TOK_FILLPATTERN}, {"follow", EDIF_TOK_FOLLOW}, {"forbiddenevent", EDIF_TOK_FORBIDDENEVENT}, {"globalportref", EDIF_TOK_GLOBALPORTREF}, {"greaterthan", EDIF_TOK_GREATERTHAN}, {"gridmap", EDIF_TOK_GRIDMAP}, {"ignore", EDIF_TOK_IGNORE}, {"includefiguregroup", EDIF_TOK_INCLUDEFIGUREGROUP}, {"initial", EDIF_TOK_INITIAL}, {"instance", EDIF_TOK_INSTANCE}, {"instancebackannotate", EDIF_TOK_INSTANCEBACKANNOTATE}, {"instancegroup", EDIF_TOK_INSTANCEGROUP}, {"instancemap", EDIF_TOK_INSTANCEMAP}, {"instanceref", EDIF_TOK_INSTANCEREF}, {"integer", EDIF_TOK_INTEGER}, {"integerdisplay", EDIF_TOK_INTEGERDISPLAY}, {"interface", EDIF_TOK_INTERFACE}, {"interfiguregroupspacing", EDIF_TOK_INTERFIGUREGROUPSPACING}, {"intersection", EDIF_TOK_INTERSECTION}, {"intrafiguregroupspacing", EDIF_TOK_INTRAFIGUREGROUPSPACING}, {"inverse", EDIF_TOK_INVERSE}, {"isolated", EDIF_TOK_ISOLATED}, {"joined", EDIF_TOK_JOINED}, {"justify", EDIF_TOK_JUSTIFY}, {"keyworddisplay", EDIF_TOK_KEYWORDDISPLAY}, {"keywordlevel", EDIF_TOK_KEYWORDLEVEL}, {"keywordmap", EDIF_TOK_KEYWORDMAP}, {"lessthan", EDIF_TOK_LESSTHAN}, {"library", EDIF_TOK_LIBRARY}, {"libraryref", EDIF_TOK_LIBRARYREF}, {"listofnets", EDIF_TOK_LISTOFNETS}, {"listofports", EDIF_TOK_LISTOFPORTS}, {"loaddelay", EDIF_TOK_LOADDELAY}, {"logicassign", EDIF_TOK_LOGICASSIGN}, {"logicinput", EDIF_TOK_LOGICINPUT}, {"logiclist", EDIF_TOK_LOGICLIST}, {"logicmapinput", EDIF_TOK_LOGICMAPINPUT}, {"logicmapoutput", EDIF_TOK_LOGICMAPOUTPUT}, {"logiconeof", EDIF_TOK_LOGICONEOF}, {"logicoutput", EDIF_TOK_LOGICOUTPUT}, {"logicport", EDIF_TOK_LOGICPORT}, {"logicref", EDIF_TOK_LOGICREF}, {"logicvalue", EDIF_TOK_LOGICVALUE}, {"logicwaveform", EDIF_TOK_LOGICWAVEFORM}, {"maintain", EDIF_TOK_MAINTAIN}, {"match", EDIF_TOK_MATCH}, {"member", EDIF_TOK_MEMBER}, {"minomax", EDIF_TOK_MINOMAX}, {"minomaxdisplay", EDIF_TOK_MINOMAXDISPLAY}, {"mnm", EDIF_TOK_MNM}, {"multiplevalueset", EDIF_TOK_MULTIPLEVALUESET}, {"mustjoin", EDIF_TOK_MUSTJOIN}, {"name", EDIF_TOK_NAME}, {"net", EDIF_TOK_NET}, {"netbackannotate", EDIF_TOK_NETBACKANNOTATE}, {"netbundle", EDIF_TOK_NETBUNDLE}, {"netdelay", EDIF_TOK_NETDELAY}, {"netgroup", EDIF_TOK_NETGROUP}, {"netmap", EDIF_TOK_NETMAP}, {"netref", EDIF_TOK_NETREF}, {"nochange", EDIF_TOK_NOCHANGE}, {"nonpermutable", EDIF_TOK_NONPERMUTABLE}, {"notallowed", EDIF_TOK_NOTALLOWED}, {"notchspacing", EDIF_TOK_NOTCHSPACING}, {"number", EDIF_TOK_NUMBER}, {"numberdefinition", EDIF_TOK_NUMBERDEFINITION}, {"numberdisplay", EDIF_TOK_NUMBERDISPLAY}, {"offpageconnector", EDIF_TOK_OFFPAGECONNECTOR}, {"offsetevent", EDIF_TOK_OFFSETEVENT}, {"openshape", EDIF_TOK_OPENSHAPE}, {"orientation", EDIF_TOK_ORIENTATION}, {"origin", EDIF_TOK_ORIGIN}, {"overhangdistance", EDIF_TOK_OVERHANGDISTANCE}, {"overlapdistance", EDIF_TOK_OVERLAPDISTANCE}, {"oversize", EDIF_TOK_OVERSIZE}, {"owner", EDIF_TOK_OWNER}, {"page", EDIF_TOK_PAGE}, {"pagesize", EDIF_TOK_PAGESIZE}, {"parameter", EDIF_TOK_PARAMETER}, {"parameterassign", EDIF_TOK_PARAMETERASSIGN}, {"parameterdisplay", EDIF_TOK_PARAMETERDISPLAY}, {"path", EDIF_TOK_PATH}, {"pathdelay", EDIF_TOK_PATHDELAY}, {"pathwidth", EDIF_TOK_PATHWIDTH}, {"permutable", EDIF_TOK_PERMUTABLE}, {"physicaldesignrule", EDIF_TOK_PHYSICALDESIGNRULE}, {"plug", EDIF_TOK_PLUG}, {"point", EDIF_TOK_POINT}, {"pointdisplay", EDIF_TOK_POINTDISPLAY}, {"pointlist", EDIF_TOK_POINTLIST}, {"polygon", EDIF_TOK_POLYGON}, {"port", EDIF_TOK_PORT}, {"portbackannotate", EDIF_TOK_PORTBACKANNOTATE}, {"portbundle", EDIF_TOK_PORTBUNDLE}, {"portdelay", EDIF_TOK_PORTDELAY}, {"portgroup", EDIF_TOK_PORTGROUP}, {"portimplementation", EDIF_TOK_PORTIMPLEMENTATION}, {"portinstance", EDIF_TOK_PORTINSTANCE}, {"portlist", EDIF_TOK_PORTLIST}, {"portlistalias", EDIF_TOK_PORTLISTALIAS}, {"portmap", EDIF_TOK_PORTMAP}, {"portref", EDIF_TOK_PORTREF}, {"program", EDIF_TOK_PROGRAM}, {"property", EDIF_TOK_PROPERTY}, {"propertydisplay", EDIF_TOK_PROPERTYDISPLAY}, {"protectionframe", EDIF_TOK_PROTECTIONFRAME}, {"pt", EDIF_TOK_PT}, {"rangevector", EDIF_TOK_RANGEVECTOR}, {"rectangle", EDIF_TOK_RECTANGLE}, {"rectanglesize", EDIF_TOK_RECTANGLESIZE}, {"rename", EDIF_TOK_RENAME}, {"resolves", EDIF_TOK_RESOLVES}, {"scale", EDIF_TOK_SCALE}, {"scalex", EDIF_TOK_SCALEX}, {"scaley", EDIF_TOK_SCALEY}, {"section", EDIF_TOK_SECTION}, {"shape", EDIF_TOK_SHAPE}, {"simulate", EDIF_TOK_SIMULATE}, {"simulationinfo", EDIF_TOK_SIMULATIONINFO}, {"singlevalueset", EDIF_TOK_SINGLEVALUESET}, {"site", EDIF_TOK_SITE}, {"socket", EDIF_TOK_SOCKET}, {"socketset", EDIF_TOK_SOCKETSET}, {"status", EDIF_TOK_STATUS}, {"steady", EDIF_TOK_STEADY}, {"string", EDIF_TOK_STRING}, {"stringdisplay", EDIF_TOK_STRINGDISPLAY}, {"strong", EDIF_TOK_STRONG}, {"symbol", EDIF_TOK_SYMBOL}, {"symmetry", EDIF_TOK_SYMMETRY}, {"table", EDIF_TOK_TABLE}, {"tabledefault", EDIF_TOK_TABLEDEFAULT}, {"technology", EDIF_TOK_TECHNOLOGY}, {"textheight", EDIF_TOK_TEXTHEIGHT}, {"timeinterval", EDIF_TOK_TIMEINTERVAL}, {"timestamp", EDIF_TOK_TIMESTAMP}, {"timing", EDIF_TOK_TIMING}, {"transform", EDIF_TOK_TRANSFORM}, {"transition", EDIF_TOK_TRANSITION}, {"trigger", EDIF_TOK_TRIGGER}, {"true", EDIF_TOK_TRUE}, {"unconstrained", EDIF_TOK_UNCONSTRAINED}, {"undefined", EDIF_TOK_UNDEFINED}, {"union", EDIF_TOK_UNION}, {"unit", EDIF_TOK_UNIT}, {"unused", EDIF_TOK_UNUSED}, {"userdata", EDIF_TOK_USERDATA}, {"version", EDIF_TOK_VERSION}, {"view", EDIF_TOK_VIEW}, {"viewlist", EDIF_TOK_VIEWLIST}, {"viewmap", EDIF_TOK_VIEWMAP}, {"viewref", EDIF_TOK_VIEWREF}, {"viewtype", EDIF_TOK_VIEWTYPE}, {"visible", EDIF_TOK_VISIBLE}, {"voltagemap", EDIF_TOK_VOLTAGEMAP}, {"wavevalue", EDIF_TOK_WAVEVALUE}, {"weak", EDIF_TOK_WEAK}, {"weakjoined", EDIF_TOK_WEAKJOINED}, {"when", EDIF_TOK_WHEN}, {"written", EDIF_TOK_WRITTEN} }; static int ContextDefSize = sizeof(ContextDef) / sizeof(Context); /* * Context follower tables: * * This is pretty ugly, an array is defined for each context * which has following context levels. Yet another table is used * to bind these arrays to the originating contexts. * Arrays are declared as: * * static short f_[] = { ... }; * * The array entries are the '%token' values for all keywords which * can be reached from the context. Like I said, ugly, * but it works. * A negative entry means that the follow can only occur once within * the specified context. */ static short f_NULL[] = {EDIF_TOK_EDIF}; static short f_Edif[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_EDIFVERSION, EDIF_TOK_EDIFLEVEL, EDIF_TOK_KEYWORDMAP, -EDIF_TOK_STATUS, EDIF_TOK_EXTERNAL, EDIF_TOK_LIBRARY, EDIF_TOK_DESIGN, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_AcLoad[] = {EDIF_TOK_MNM, EDIF_TOK_E, EDIF_TOK_MINOMAXDISPLAY}; static short f_After[] = {EDIF_TOK_MNM, EDIF_TOK_E, EDIF_TOK_FOLLOW, EDIF_TOK_MAINTAIN, EDIF_TOK_LOGICASSIGN, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Annotate[] = {EDIF_TOK_STRINGDISPLAY}; static short f_Apply[] = {EDIF_TOK_CYCLE, EDIF_TOK_LOGICINPUT, EDIF_TOK_LOGICOUTPUT, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Arc[] = {EDIF_TOK_PT}; static short f_Array[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME}; static short f_ArrayMacro[] = {EDIF_TOK_PLUG}; static short f_ArrayRelatedInfo[] = {EDIF_TOK_BASEARRAY, EDIF_TOK_ARRAYSITE, EDIF_TOK_ARRAYMACRO, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_ArraySite[] = {EDIF_TOK_SOCKET}; static short f_AtLeast[] = {EDIF_TOK_E}; static short f_AtMost[] = {EDIF_TOK_E}; static short f_Becomes[] = {EDIF_TOK_NAME, EDIF_TOK_LOGICLIST, EDIF_TOK_LOGICONEOF}; /* static short f_Between[] = {EDIF_TOK_ATLEAST, EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, EDIF_TOK_LESSTHAN}; */ static short f_Boolean[] = {EDIF_TOK_FALSE, EDIF_TOK_TRUE, EDIF_TOK_BOOLEANDISPLAY, EDIF_TOK_BOOLEAN}; static short f_BooleanDisplay[] = {EDIF_TOK_FALSE, EDIF_TOK_TRUE, EDIF_TOK_DISPLAY}; static short f_BooleanMap[] = {EDIF_TOK_FALSE, EDIF_TOK_TRUE}; static short f_BorderPattern[] = {EDIF_TOK_BOOLEAN}; static short f_BoundingBox[] = {EDIF_TOK_RECTANGLE}; static short f_Cell[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_CELLTYPE, -EDIF_TOK_STATUS, -EDIF_TOK_VIEWMAP, EDIF_TOK_VIEW, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA, EDIF_TOK_PROPERTY}; static short f_CellRef[] = {EDIF_TOK_NAME, EDIF_TOK_LIBRARYREF}; static short f_Change[] = {EDIF_TOK_NAME, EDIF_TOK_PORTREF, EDIF_TOK_PORTLIST, EDIF_TOK_BECOMES, EDIF_TOK_TRANSITION}; static short f_Circle[] = {EDIF_TOK_PT, EDIF_TOK_PROPERTY}; static short f_Color[] = {EDIF_TOK_E}; static short f_CommentGraphics[] = {EDIF_TOK_ANNOTATE, EDIF_TOK_FIGURE, EDIF_TOK_INSTANCE, -EDIF_TOK_BOUNDINGBOX, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Compound[] = {EDIF_TOK_NAME}; static short f_ConnectLocation[] = {EDIF_TOK_FIGURE}; static short f_Contents[] = {EDIF_TOK_INSTANCE, EDIF_TOK_OFFPAGECONNECTOR, EDIF_TOK_FIGURE, EDIF_TOK_SECTION, EDIF_TOK_NET, EDIF_TOK_NETBUNDLE, EDIF_TOK_PAGE, EDIF_TOK_COMMENTGRAPHICS, EDIF_TOK_PORTIMPLEMENTATION, EDIF_TOK_TIMING, EDIF_TOK_SIMULATE, EDIF_TOK_WHEN, EDIF_TOK_FOLLOW, EDIF_TOK_LOGICPORT, -EDIF_TOK_BOUNDINGBOX, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Criticality[] = {EDIF_TOK_INTEGERDISPLAY}; static short f_CurrentMap[] = {EDIF_TOK_MNM, EDIF_TOK_E}; static short f_Curve[] = {EDIF_TOK_ARC, EDIF_TOK_PT}; static short f_Cycle[] = {EDIF_TOK_DURATION}; static short f_DataOrigin[] = {EDIF_TOK_VERSION}; static short f_DcFanInLoad[] = {EDIF_TOK_E, EDIF_TOK_NUMBERDISPLAY}; static short f_DcFanOutLoad[] = {EDIF_TOK_E, EDIF_TOK_NUMBERDISPLAY}; static short f_DcMaxFanIn[] = {EDIF_TOK_E, EDIF_TOK_NUMBERDISPLAY}; static short f_DcMaxFanOut[] = {EDIF_TOK_E, EDIF_TOK_NUMBERDISPLAY}; static short f_Delay[] = {EDIF_TOK_MNM, EDIF_TOK_E}; static short f_Delta[] = {EDIF_TOK_PT}; static short f_Design[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_CELLREF, EDIF_TOK_STATUS, EDIF_TOK_COMMENT, EDIF_TOK_PROPERTY, EDIF_TOK_USERDATA}; static short f_Designator[] = {EDIF_TOK_STRINGDISPLAY}; static short f_Difference[] = {EDIF_TOK_FIGUREGROUPREF, EDIF_TOK_INTERSECTION, EDIF_TOK_UNION, EDIF_TOK_DIFFERENCE, EDIF_TOK_INVERSE, EDIF_TOK_OVERSIZE}; static short f_Display[] = {EDIF_TOK_NAME, EDIF_TOK_FIGUREGROUPOVERRIDE, EDIF_TOK_JUSTIFY, EDIF_TOK_ORIENTATION, EDIF_TOK_ORIGIN}; static short f_Dominates[] = {EDIF_TOK_NAME}; static short f_Dot[] = {EDIF_TOK_PT, EDIF_TOK_PROPERTY}; static short f_Duration[] = {EDIF_TOK_E}; static short f_EnclosureDistance[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_LESSTHAN, EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN, EDIF_TOK_SINGLEVALUESET, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Entry[] = {EDIF_TOK_MATCH, EDIF_TOK_CHANGE, EDIF_TOK_STEADY, EDIF_TOK_LOGICREF, EDIF_TOK_PORTREF, EDIF_TOK_NOCHANGE, EDIF_TOK_TABLE, EDIF_TOK_DELAY, EDIF_TOK_LOADDELAY}; static short f_Exactly[] = {EDIF_TOK_E}; static short f_External[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_EDIFLEVEL, EDIF_TOK_TECHNOLOGY, -EDIF_TOK_STATUS, EDIF_TOK_CELL, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Fabricate[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME}; static short f_Figure[] = {EDIF_TOK_NAME, EDIF_TOK_FIGUREGROUPOVERRIDE, EDIF_TOK_CIRCLE, EDIF_TOK_DOT, EDIF_TOK_OPENSHAPE, EDIF_TOK_PATH, EDIF_TOK_POLYGON, EDIF_TOK_RECTANGLE, EDIF_TOK_SHAPE, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_FigureArea[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_LESSTHAN, EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN, EDIF_TOK_SINGLEVALUESET, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_FigureGroup[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, -EDIF_TOK_CORNERTYPE, -EDIF_TOK_ENDTYPE, -EDIF_TOK_PATHWIDTH, -EDIF_TOK_BORDERWIDTH, -EDIF_TOK_COLOR, -EDIF_TOK_FILLPATTERN, -EDIF_TOK_BORDERPATTERN, -EDIF_TOK_TEXTHEIGHT, -EDIF_TOK_VISIBLE, EDIF_TOK_INCLUDEFIGUREGROUP, EDIF_TOK_COMMENT, EDIF_TOK_PROPERTY, EDIF_TOK_USERDATA}; static short f_FigureGroupObject[] = {EDIF_TOK_NAME, EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_INTERSECTION, EDIF_TOK_UNION, EDIF_TOK_DIFFERENCE, EDIF_TOK_INVERSE, EDIF_TOK_OVERSIZE}; static short f_FigureGroupOverride[] = {EDIF_TOK_NAME, -EDIF_TOK_CORNERTYPE, -EDIF_TOK_ENDTYPE, -EDIF_TOK_PATHWIDTH, -EDIF_TOK_BORDERWIDTH, -EDIF_TOK_COLOR, -EDIF_TOK_FILLPATTERN, -EDIF_TOK_TEXTHEIGHT, -EDIF_TOK_BORDERPATTERN, EDIF_TOK_VISIBLE, EDIF_TOK_COMMENT, EDIF_TOK_PROPERTY, EDIF_TOK_USERDATA}; static short f_FigureGroupRef[] = {EDIF_TOK_NAME, EDIF_TOK_LIBRARYREF}; static short f_FigurePerimeter[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_LESSTHAN, EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN, EDIF_TOK_SINGLEVALUESET, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_FigureWidth[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_LESSTHAN, EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN, EDIF_TOK_SINGLEVALUESET, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_FillPattern[] = {EDIF_TOK_BOOLEAN}; static short f_Follow[] = {EDIF_TOK_NAME, EDIF_TOK_PORTREF, EDIF_TOK_TABLE, EDIF_TOK_DELAY, EDIF_TOK_LOADDELAY}; static short f_ForbiddenEvent[] = {EDIF_TOK_TIMEINTERVAL, EDIF_TOK_EVENT}; static short f_GlobalPortRef[] = {EDIF_TOK_NAME}; static short f_GreaterThan[] = {EDIF_TOK_E}; static short f_GridMap[] = {EDIF_TOK_E}; static short f_IncludeFigureGroup[] = {EDIF_TOK_FIGUREGROUPREF, EDIF_TOK_INTERSECTION, EDIF_TOK_UNION, EDIF_TOK_DIFFERENCE, EDIF_TOK_INVERSE, EDIF_TOK_OVERSIZE}; static short f_Instance[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_ARRAY, EDIF_TOK_VIEWREF, EDIF_TOK_VIEWLIST, -EDIF_TOK_TRANSFORM, EDIF_TOK_PARAMETERASSIGN, EDIF_TOK_PORTINSTANCE, EDIF_TOK_TIMING, -EDIF_TOK_DESIGNATOR, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_InstanceBackAnnotate[] = {EDIF_TOK_INSTANCEREF, -EDIF_TOK_DESIGNATOR, EDIF_TOK_TIMING, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT}; static short f_InstanceGroup[] = {EDIF_TOK_INSTANCEREF}; static short f_InstanceMap[] = {EDIF_TOK_INSTANCEREF, EDIF_TOK_INSTANCEGROUP, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_InstanceRef[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, EDIF_TOK_INSTANCEREF, EDIF_TOK_VIEWREF}; static short f_Integer[] = {EDIF_TOK_INTEGERDISPLAY, EDIF_TOK_INTEGER}; static short f_IntegerDisplay[] = {EDIF_TOK_DISPLAY}; static short f_Interface[] = {EDIF_TOK_PORT, EDIF_TOK_PORTBUNDLE, -EDIF_TOK_SYMBOL, -EDIF_TOK_PROTECTIONFRAME, -EDIF_TOK_ARRAYRELATEDINFO, EDIF_TOK_PARAMETER, EDIF_TOK_JOINED, EDIF_TOK_MUSTJOIN, EDIF_TOK_WEAKJOINED, EDIF_TOK_PERMUTABLE, EDIF_TOK_TIMING, EDIF_TOK_SIMULATE, -EDIF_TOK_DESIGNATOR, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_InterFigureGroupSpacing[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_LESSTHAN, EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN, EDIF_TOK_SINGLEVALUESET, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Intersection[] = {EDIF_TOK_FIGUREGROUPREF, EDIF_TOK_INTERSECTION, EDIF_TOK_UNION, EDIF_TOK_DIFFERENCE, EDIF_TOK_INVERSE, EDIF_TOK_OVERSIZE}; static short f_IntraFigureGroupSpacing[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_LESSTHAN, EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN, EDIF_TOK_SINGLEVALUESET, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Inverse[] = {EDIF_TOK_FIGUREGROUPREF, EDIF_TOK_INTERSECTION, EDIF_TOK_UNION, EDIF_TOK_DIFFERENCE, EDIF_TOK_INVERSE, EDIF_TOK_OVERSIZE}; static short f_Joined[] = {EDIF_TOK_PORTREF, EDIF_TOK_PORTLIST, EDIF_TOK_GLOBALPORTREF}; static short f_KeywordDisplay[] = {EDIF_TOK_DISPLAY}; static short f_KeywordMap[] = {EDIF_TOK_KEYWORDLEVEL, EDIF_TOK_COMMENT}; static short f_LessThan[] = {EDIF_TOK_E}; static short f_Library[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_EDIFLEVEL, EDIF_TOK_TECHNOLOGY, -EDIF_TOK_STATUS, EDIF_TOK_CELL, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_LibraryRef[] = {EDIF_TOK_NAME}; static short f_ListOfNets[] = {EDIF_TOK_NET}; static short f_ListOfPorts[] = {EDIF_TOK_PORT, EDIF_TOK_PORTBUNDLE}; static short f_LoadDelay[] = {EDIF_TOK_MNM, EDIF_TOK_E, EDIF_TOK_MINOMAXDISPLAY}; static short f_LogicAssign[] = {EDIF_TOK_NAME, EDIF_TOK_PORTREF, EDIF_TOK_LOGICREF, EDIF_TOK_TABLE, EDIF_TOK_DELAY, EDIF_TOK_LOADDELAY}; static short f_LogicInput[] = {EDIF_TOK_PORTLIST, EDIF_TOK_PORTREF, EDIF_TOK_NAME, EDIF_TOK_LOGICWAVEFORM}; static short f_LogicList[] = {EDIF_TOK_NAME, EDIF_TOK_LOGICONEOF, EDIF_TOK_IGNORE}; static short f_LogicMapInput[] = {EDIF_TOK_LOGICREF}; static short f_LogicMapOutput[] = {EDIF_TOK_LOGICREF}; static short f_LogicOneOf[] = {EDIF_TOK_NAME, EDIF_TOK_LOGICLIST}; static short f_LogicOutput[] = {EDIF_TOK_PORTLIST, EDIF_TOK_PORTREF, EDIF_TOK_NAME, EDIF_TOK_LOGICWAVEFORM}; static short f_LogicPort[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_LogicRef[] = {EDIF_TOK_NAME, EDIF_TOK_LIBRARYREF}; static short f_LogicValue[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, -EDIF_TOK_VOLTAGEMAP, -EDIF_TOK_CURRENTMAP, -EDIF_TOK_BOOLEANMAP, -EDIF_TOK_COMPOUND, -EDIF_TOK_WEAK ,-EDIF_TOK_STRONG, -EDIF_TOK_DOMINATES, -EDIF_TOK_LOGICMAPOUTPUT, -EDIF_TOK_LOGICMAPINPUT, -EDIF_TOK_ISOLATED, EDIF_TOK_RESOLVES, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_LogicWaveform[] = {EDIF_TOK_NAME, EDIF_TOK_LOGICLIST, EDIF_TOK_LOGICONEOF, EDIF_TOK_IGNORE}; static short f_Maintain[] = {EDIF_TOK_NAME, EDIF_TOK_PORTREF, EDIF_TOK_DELAY, EDIF_TOK_LOADDELAY}; static short f_Match[] = {EDIF_TOK_NAME, EDIF_TOK_PORTREF, EDIF_TOK_PORTLIST, EDIF_TOK_LOGICLIST, EDIF_TOK_LOGICONEOF}; static short f_Member[] = {EDIF_TOK_NAME}; static short f_MiNoMax[] = {EDIF_TOK_MNM, EDIF_TOK_E, EDIF_TOK_MINOMAXDISPLAY, EDIF_TOK_MINOMAX}; static short f_MiNoMaxDisplay[] = {EDIF_TOK_MNM, EDIF_TOK_E, EDIF_TOK_DISPLAY}; static short f_Mnm[] = {EDIF_TOK_E, EDIF_TOK_UNDEFINED, EDIF_TOK_UNCONSTRAINED}; static short f_MultipleValueSet[] = {EDIF_TOK_RANGEVECTOR}; static short f_MustJoin[] = {EDIF_TOK_PORTREF, EDIF_TOK_PORTLIST, EDIF_TOK_WEAKJOINED, EDIF_TOK_JOINED}; static short f_Name[] = {EDIF_TOK_DISPLAY}; static short f_Net[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, -EDIF_TOK_CRITICALITY, EDIF_TOK_NETDELAY, EDIF_TOK_FIGURE, EDIF_TOK_NET, EDIF_TOK_INSTANCE, EDIF_TOK_COMMENTGRAPHICS, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA, EDIF_TOK_JOINED, EDIF_TOK_ARRAY}; static short f_NetBackAnnotate[] = {EDIF_TOK_NETREF, EDIF_TOK_NETDELAY, -EDIF_TOK_CRITICALITY, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT}; static short f_NetBundle[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_ARRAY, EDIF_TOK_LISTOFNETS, EDIF_TOK_FIGURE, EDIF_TOK_COMMENTGRAPHICS, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_NetDelay[] = {EDIF_TOK_DERIVATION, EDIF_TOK_DELAY, EDIF_TOK_TRANSITION, EDIF_TOK_BECOMES}; static short f_NetGroup[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, EDIF_TOK_NETREF}; static short f_NetMap[] = {EDIF_TOK_NETREF, EDIF_TOK_NETGROUP, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_NetRef[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, EDIF_TOK_NETREF, EDIF_TOK_INSTANCEREF, EDIF_TOK_VIEWREF}; static short f_NonPermutable[] = {EDIF_TOK_PORTREF, EDIF_TOK_PERMUTABLE}; static short f_NotAllowed[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_NotchSpacing[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_LESSTHAN, EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN, EDIF_TOK_SINGLEVALUESET, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Number[] = {EDIF_TOK_E, EDIF_TOK_NUMBERDISPLAY, EDIF_TOK_NUMBER}; static short f_NumberDefinition[] = {EDIF_TOK_SCALE, -EDIF_TOK_GRIDMAP, EDIF_TOK_COMMENT}; static short f_NumberDisplay[] = {EDIF_TOK_E, EDIF_TOK_DISPLAY}; static short f_OffPageConnector[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, -EDIF_TOK_UNUSED, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_OffsetEvent[] = {EDIF_TOK_EVENT, EDIF_TOK_E}; static short f_OpenShape[] = {EDIF_TOK_CURVE, EDIF_TOK_PROPERTY}; static short f_Origin[] = {EDIF_TOK_PT}; static short f_OverhangDistance[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_LESSTHAN, EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN, EDIF_TOK_SINGLEVALUESET, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_OverlapDistance[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_LESSTHAN, EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN, EDIF_TOK_SINGLEVALUESET, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Oversize[] = {EDIF_TOK_FIGUREGROUPREF, EDIF_TOK_INTERSECTION, EDIF_TOK_UNION, EDIF_TOK_DIFFERENCE, EDIF_TOK_INVERSE, EDIF_TOK_OVERSIZE, EDIF_TOK_CORNERTYPE}; static short f_Page[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_ARRAY, EDIF_TOK_INSTANCE, EDIF_TOK_NET, EDIF_TOK_NETBUNDLE, EDIF_TOK_COMMENTGRAPHICS, EDIF_TOK_PORTIMPLEMENTATION, -EDIF_TOK_PAGESIZE, -EDIF_TOK_BOUNDINGBOX, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_PageSize[] = {EDIF_TOK_RECTANGLE}; static short f_Parameter[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_ARRAY, EDIF_TOK_BOOLEAN, EDIF_TOK_INTEGER, EDIF_TOK_MINOMAX, EDIF_TOK_NUMBER, EDIF_TOK_POINT, EDIF_TOK_STRING}; static short f_ParameterAssign[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, EDIF_TOK_BOOLEAN, EDIF_TOK_INTEGER, EDIF_TOK_MINOMAX, EDIF_TOK_NUMBER, EDIF_TOK_POINT, EDIF_TOK_STRING}; static short f_ParameterDisplay[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, EDIF_TOK_DISPLAY}; static short f_Path[] = {EDIF_TOK_POINTLIST, EDIF_TOK_PROPERTY}; static short f_PathDelay[] = {EDIF_TOK_DELAY, EDIF_TOK_EVENT}; static short f_Permutable[] = {EDIF_TOK_PORTREF, EDIF_TOK_PERMUTABLE, EDIF_TOK_NONPERMUTABLE}; static short f_PhysicalDesignRule[] = {EDIF_TOK_FIGUREWIDTH, EDIF_TOK_FIGUREAREA, EDIF_TOK_RECTANGLESIZE, EDIF_TOK_FIGUREPERIMETER, EDIF_TOK_OVERLAPDISTANCE, EDIF_TOK_OVERHANGDISTANCE, EDIF_TOK_ENCLOSUREDISTANCE, EDIF_TOK_INTERFIGUREGROUPSPACING, EDIF_TOK_NOTCHSPACING, EDIF_TOK_INTRAFIGUREGROUPSPACING, EDIF_TOK_NOTALLOWED, EDIF_TOK_FIGUREGROUP, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Plug[] = {EDIF_TOK_SOCKETSET}; static short f_Point[] = {EDIF_TOK_PT, EDIF_TOK_POINTDISPLAY, EDIF_TOK_POINT}; static short f_PointDisplay[] = {EDIF_TOK_PT, EDIF_TOK_DISPLAY}; static short f_PointList[] = {EDIF_TOK_PT}; static short f_Polygon[] = {EDIF_TOK_POINTLIST, EDIF_TOK_PROPERTY}; static short f_Port[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_ARRAY, -EDIF_TOK_DIRECTION, -EDIF_TOK_UNUSED, EDIF_TOK_PORTDELAY, -EDIF_TOK_DESIGNATOR, -EDIF_TOK_DCFANINLOAD, -EDIF_TOK_DCFANOUTLOAD, -EDIF_TOK_DCMAXFANIN, -EDIF_TOK_DCMAXFANOUT, -EDIF_TOK_ACLOAD, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_PortBackAnnotate[] = {EDIF_TOK_PORTREF, -EDIF_TOK_DESIGNATOR, EDIF_TOK_PORTDELAY, -EDIF_TOK_DCFANINLOAD, -EDIF_TOK_DCFANOUTLOAD, -EDIF_TOK_DCMAXFANIN, -EDIF_TOK_DCMAXFANOUT, -EDIF_TOK_ACLOAD, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT}; static short f_PortBundle[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_ARRAY, EDIF_TOK_LISTOFPORTS, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_PortDelay[] = {EDIF_TOK_DERIVATION, EDIF_TOK_DELAY, EDIF_TOK_LOADDELAY, EDIF_TOK_TRANSITION, EDIF_TOK_BECOMES}; static short f_PortGroup[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, EDIF_TOK_PORTREF}; static short f_PortImplementation[] = {EDIF_TOK_PORTREF, EDIF_TOK_NAME, EDIF_TOK_MEMBER, -EDIF_TOK_CONNECTLOCATION, EDIF_TOK_FIGURE, EDIF_TOK_INSTANCE, EDIF_TOK_COMMENTGRAPHICS, EDIF_TOK_PROPERTYDISPLAY, EDIF_TOK_KEYWORDDISPLAY, EDIF_TOK_PROPERTY, EDIF_TOK_USERDATA, EDIF_TOK_COMMENT}; static short f_PortInstance[] = {EDIF_TOK_PORTREF, EDIF_TOK_NAME, EDIF_TOK_MEMBER, -EDIF_TOK_UNUSED, EDIF_TOK_PORTDELAY, -EDIF_TOK_DESIGNATOR, -EDIF_TOK_DCFANINLOAD, -EDIF_TOK_DCFANOUTLOAD, -EDIF_TOK_DCMAXFANIN, -EDIF_TOK_DCMAXFANOUT, -EDIF_TOK_ACLOAD, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_PortList[] = {EDIF_TOK_PORTREF, EDIF_TOK_NAME, EDIF_TOK_MEMBER}; static short f_PortListAlias[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_ARRAY, EDIF_TOK_PORTLIST}; static short f_PortMap[] = {EDIF_TOK_PORTREF, EDIF_TOK_PORTGROUP, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_PortRef[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, EDIF_TOK_PORTREF, EDIF_TOK_INSTANCEREF, EDIF_TOK_VIEWREF}; static short f_Program[] = {EDIF_TOK_VERSION}; static short f_Property[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_BOOLEAN, EDIF_TOK_INTEGER, EDIF_TOK_MINOMAX, EDIF_TOK_NUMBER, EDIF_TOK_POINT, EDIF_TOK_STRING, -EDIF_TOK_OWNER, -EDIF_TOK_UNIT, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT}; static short f_PropertyDisplay[] = {EDIF_TOK_NAME, EDIF_TOK_DISPLAY}; static short f_ProtectionFrame[] = {EDIF_TOK_PORTIMPLEMENTATION, EDIF_TOK_FIGURE, EDIF_TOK_INSTANCE, EDIF_TOK_COMMENTGRAPHICS, -EDIF_TOK_BOUNDINGBOX, EDIF_TOK_PROPERTYDISPLAY, EDIF_TOK_KEYWORDDISPLAY, EDIF_TOK_PARAMETERDISPLAY, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_RangeVector[] = {EDIF_TOK_LESSTHAN, EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN, EDIF_TOK_SINGLEVALUESET}; static short f_Rectangle[] = {EDIF_TOK_PT, EDIF_TOK_PROPERTY}; static short f_RectangleSize[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_RANGEVECTOR, EDIF_TOK_MULTIPLEVALUESET,EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Rename[] = {EDIF_TOK_NAME, EDIF_TOK_STRINGDISPLAY}; static short f_Resolves[] = {EDIF_TOK_NAME}; static short f_Scale[] = {EDIF_TOK_E, EDIF_TOK_UNIT}; static short f_Section[] = {EDIF_TOK_SECTION, EDIF_TOK_INSTANCE}; static short f_Shape[] = {EDIF_TOK_CURVE, EDIF_TOK_PROPERTY}; static short f_Simulate[] = {EDIF_TOK_NAME, EDIF_TOK_PORTLISTALIAS, EDIF_TOK_WAVEVALUE, EDIF_TOK_APPLY, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_SimulationInfo[] = {EDIF_TOK_LOGICVALUE, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_SingleValueSet[] = {EDIF_TOK_LESSTHAN, EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN}; static short f_Site[] = {EDIF_TOK_VIEWREF, EDIF_TOK_TRANSFORM}; static short f_Socket[] = {EDIF_TOK_SYMMETRY}; static short f_SocketSet[] = {EDIF_TOK_SYMMETRY, EDIF_TOK_SITE}; static short f_Status[] = {EDIF_TOK_WRITTEN, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Steady[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, EDIF_TOK_PORTREF, EDIF_TOK_PORTLIST, EDIF_TOK_DURATION, EDIF_TOK_TRANSITION, EDIF_TOK_BECOMES}; static short f_String[] = {EDIF_TOK_STRINGDISPLAY, EDIF_TOK_STRING}; static short f_StringDisplay[] = {EDIF_TOK_DISPLAY}; static short f_Strong[] = {EDIF_TOK_NAME}; static short f_Symbol[] = {EDIF_TOK_PORTIMPLEMENTATION, EDIF_TOK_FIGURE, EDIF_TOK_INSTANCE, EDIF_TOK_COMMENTGRAPHICS, EDIF_TOK_ANNOTATE, -EDIF_TOK_PAGESIZE, -EDIF_TOK_BOUNDINGBOX, EDIF_TOK_PROPERTYDISPLAY, EDIF_TOK_KEYWORDDISPLAY, EDIF_TOK_PARAMETERDISPLAY, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Symmetry[] = {EDIF_TOK_TRANSFORM}; static short f_Table[] = {EDIF_TOK_ENTRY, EDIF_TOK_TABLEDEFAULT}; static short f_TableDefault[] = {EDIF_TOK_LOGICREF, EDIF_TOK_PORTREF, EDIF_TOK_NOCHANGE, EDIF_TOK_TABLE, EDIF_TOK_DELAY, EDIF_TOK_LOADDELAY}; static short f_Technology[] = {EDIF_TOK_NUMBERDEFINITION, EDIF_TOK_FIGUREGROUP, EDIF_TOK_FABRICATE, -EDIF_TOK_SIMULATIONINFO, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA, -EDIF_TOK_PHYSICALDESIGNRULE}; static short f_TimeInterval[] = {EDIF_TOK_EVENT, EDIF_TOK_OFFSETEVENT, EDIF_TOK_DURATION}; static short f_Timing[] = {EDIF_TOK_DERIVATION, EDIF_TOK_PATHDELAY, EDIF_TOK_FORBIDDENEVENT, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Transform[] = {EDIF_TOK_SCALEX, EDIF_TOK_SCALEY, EDIF_TOK_DELTA, EDIF_TOK_ORIENTATION, EDIF_TOK_ORIGIN}; static short f_Transition[] = {EDIF_TOK_NAME, EDIF_TOK_LOGICLIST, EDIF_TOK_LOGICONEOF}; static short f_Trigger[] = {EDIF_TOK_CHANGE, EDIF_TOK_STEADY, EDIF_TOK_INITIAL}; static short f_Union[] = {EDIF_TOK_FIGUREGROUPREF, EDIF_TOK_INTERSECTION, EDIF_TOK_UNION, EDIF_TOK_DIFFERENCE, EDIF_TOK_INVERSE, EDIF_TOK_OVERSIZE}; static short f_View[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_VIEWTYPE, EDIF_TOK_INTERFACE, -EDIF_TOK_STATUS, -EDIF_TOK_CONTENTS, EDIF_TOK_COMMENT, EDIF_TOK_PROPERTY, EDIF_TOK_USERDATA}; static short f_ViewList[] = {EDIF_TOK_VIEWREF, EDIF_TOK_VIEWLIST}; static short f_ViewMap[] = {EDIF_TOK_PORTMAP, EDIF_TOK_PORTBACKANNOTATE, EDIF_TOK_INSTANCEMAP, EDIF_TOK_INSTANCEBACKANNOTATE, EDIF_TOK_NETMAP, EDIF_TOK_NETBACKANNOTATE, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_ViewRef[] = {EDIF_TOK_NAME, EDIF_TOK_CELLREF}; static short f_Visible[] = {EDIF_TOK_FALSE, EDIF_TOK_TRUE}; static short f_VoltageMap[] = {EDIF_TOK_MNM, EDIF_TOK_E}; static short f_WaveValue[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_E, EDIF_TOK_LOGICWAVEFORM}; static short f_Weak[] = {EDIF_TOK_NAME}; static short f_WeakJoined[] = {EDIF_TOK_PORTREF, EDIF_TOK_PORTLIST, EDIF_TOK_JOINED}; static short f_When[] = {EDIF_TOK_TRIGGER, EDIF_TOK_AFTER, EDIF_TOK_FOLLOW, EDIF_TOK_MAINTAIN, EDIF_TOK_LOGICASSIGN, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Written[] = {EDIF_TOK_TIMESTAMP, EDIF_TOK_AUTHOR, EDIF_TOK_PROGRAM, EDIF_TOK_DATAORIGIN, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; /* * Context binding table: * * This binds context follower arrays to their originating context. */ typedef struct Binder { short *Follower; /* pointer to follower array */ short Origin; /* '%token' value of origin */ short FollowerSize; /* size of follower array */ } Binder; #define BE(f,o) {f,o,sizeof(f)/sizeof(short)} static Binder BinderDef[] = { BE(f_NULL, 0), BE(f_Edif, EDIF_TOK_EDIF), BE(f_AcLoad, EDIF_TOK_ACLOAD), BE(f_After, EDIF_TOK_AFTER), BE(f_Annotate, EDIF_TOK_ANNOTATE), BE(f_Apply, EDIF_TOK_APPLY), BE(f_Arc, EDIF_TOK_ARC), BE(f_Array, EDIF_TOK_ARRAY), BE(f_ArrayMacro, EDIF_TOK_ARRAYMACRO), BE(f_ArrayRelatedInfo, EDIF_TOK_ARRAYRELATEDINFO), BE(f_ArraySite, EDIF_TOK_ARRAYSITE), BE(f_AtLeast, EDIF_TOK_ATLEAST), BE(f_AtMost, EDIF_TOK_ATMOST), BE(f_Becomes, EDIF_TOK_BECOMES), BE(f_Boolean, EDIF_TOK_BOOLEAN), BE(f_BooleanDisplay, EDIF_TOK_BOOLEANDISPLAY), BE(f_BooleanMap, EDIF_TOK_BOOLEANMAP), BE(f_BorderPattern, EDIF_TOK_BORDERPATTERN), BE(f_BoundingBox, EDIF_TOK_BOUNDINGBOX), BE(f_Cell, EDIF_TOK_CELL), BE(f_CellRef, EDIF_TOK_CELLREF), BE(f_Change, EDIF_TOK_CHANGE), BE(f_Circle, EDIF_TOK_CIRCLE), BE(f_Color, EDIF_TOK_COLOR), BE(f_CommentGraphics, EDIF_TOK_COMMENTGRAPHICS), BE(f_Compound, EDIF_TOK_COMPOUND), BE(f_ConnectLocation, EDIF_TOK_CONNECTLOCATION), BE(f_Contents, EDIF_TOK_CONTENTS), BE(f_Criticality, EDIF_TOK_CRITICALITY), BE(f_CurrentMap, EDIF_TOK_CURRENTMAP), BE(f_Curve, EDIF_TOK_CURVE), BE(f_Cycle, EDIF_TOK_CYCLE), BE(f_DataOrigin, EDIF_TOK_DATAORIGIN), BE(f_DcFanInLoad, EDIF_TOK_DCFANINLOAD), BE(f_DcFanOutLoad, EDIF_TOK_DCFANOUTLOAD), BE(f_DcMaxFanIn, EDIF_TOK_DCMAXFANIN), BE(f_DcMaxFanOut, EDIF_TOK_DCMAXFANOUT), BE(f_Delay, EDIF_TOK_DELAY), BE(f_Delta, EDIF_TOK_DELTA), BE(f_Design, EDIF_TOK_DESIGN), BE(f_Designator, EDIF_TOK_DESIGNATOR), BE(f_Difference, EDIF_TOK_DIFFERENCE), BE(f_Display, EDIF_TOK_DISPLAY), BE(f_Dominates, EDIF_TOK_DOMINATES), BE(f_Dot, EDIF_TOK_DOT), BE(f_Duration, EDIF_TOK_DURATION), BE(f_EnclosureDistance, EDIF_TOK_ENCLOSUREDISTANCE), BE(f_Entry, EDIF_TOK_ENTRY), BE(f_Exactly, EDIF_TOK_EXACTLY), BE(f_External, EDIF_TOK_EXTERNAL), BE(f_Fabricate, EDIF_TOK_FABRICATE), BE(f_Figure, EDIF_TOK_FIGURE), BE(f_FigureArea, EDIF_TOK_FIGUREAREA), BE(f_FigureGroup, EDIF_TOK_FIGUREGROUP), BE(f_FigureGroupObject, EDIF_TOK_FIGUREGROUPOBJECT), BE(f_FigureGroupOverride, EDIF_TOK_FIGUREGROUPOVERRIDE), BE(f_FigureGroupRef, EDIF_TOK_FIGUREGROUPREF), BE(f_FigurePerimeter, EDIF_TOK_FIGUREPERIMETER), BE(f_FigureWidth, EDIF_TOK_FIGUREWIDTH), BE(f_FillPattern, EDIF_TOK_FILLPATTERN), BE(f_Follow, EDIF_TOK_FOLLOW), BE(f_ForbiddenEvent, EDIF_TOK_FORBIDDENEVENT), BE(f_GlobalPortRef, EDIF_TOK_GLOBALPORTREF), BE(f_GreaterThan, EDIF_TOK_GREATERTHAN), BE(f_GridMap, EDIF_TOK_GRIDMAP), BE(f_IncludeFigureGroup, EDIF_TOK_INCLUDEFIGUREGROUP), BE(f_Instance, EDIF_TOK_INSTANCE), BE(f_InstanceBackAnnotate, EDIF_TOK_INSTANCEBACKANNOTATE), BE(f_InstanceGroup, EDIF_TOK_INSTANCEGROUP), BE(f_InstanceMap, EDIF_TOK_INSTANCEMAP), BE(f_InstanceRef, EDIF_TOK_INSTANCEREF), BE(f_Integer, EDIF_TOK_INTEGER), BE(f_IntegerDisplay, EDIF_TOK_INTEGERDISPLAY), BE(f_InterFigureGroupSpacing, EDIF_TOK_INTERFIGUREGROUPSPACING), BE(f_Interface, EDIF_TOK_INTERFACE), BE(f_Intersection, EDIF_TOK_INTERSECTION), BE(f_IntraFigureGroupSpacing, EDIF_TOK_INTRAFIGUREGROUPSPACING), BE(f_Inverse, EDIF_TOK_INVERSE), BE(f_Joined, EDIF_TOK_JOINED), BE(f_KeywordDisplay, EDIF_TOK_KEYWORDDISPLAY), BE(f_KeywordMap, EDIF_TOK_KEYWORDMAP), BE(f_LessThan, EDIF_TOK_LESSTHAN), BE(f_Library, EDIF_TOK_LIBRARY), BE(f_LibraryRef, EDIF_TOK_LIBRARYREF), BE(f_ListOfNets, EDIF_TOK_LISTOFNETS), BE(f_ListOfPorts, EDIF_TOK_LISTOFPORTS), BE(f_LoadDelay, EDIF_TOK_LOADDELAY), BE(f_LogicAssign, EDIF_TOK_LOGICASSIGN), BE(f_LogicInput, EDIF_TOK_LOGICINPUT), BE(f_LogicList, EDIF_TOK_LOGICLIST), BE(f_LogicMapInput, EDIF_TOK_LOGICMAPINPUT), BE(f_LogicMapOutput, EDIF_TOK_LOGICMAPOUTPUT), BE(f_LogicOneOf, EDIF_TOK_LOGICONEOF), BE(f_LogicOutput, EDIF_TOK_LOGICOUTPUT), BE(f_LogicPort, EDIF_TOK_LOGICPORT), BE(f_LogicRef, EDIF_TOK_LOGICREF), BE(f_LogicValue, EDIF_TOK_LOGICVALUE), BE(f_LogicWaveform, EDIF_TOK_LOGICWAVEFORM), BE(f_Maintain, EDIF_TOK_MAINTAIN), BE(f_Match, EDIF_TOK_MATCH), BE(f_Member, EDIF_TOK_MEMBER), BE(f_MiNoMax, EDIF_TOK_MINOMAX), BE(f_MiNoMaxDisplay, EDIF_TOK_MINOMAXDISPLAY), BE(f_Mnm, EDIF_TOK_MNM), BE(f_MultipleValueSet, EDIF_TOK_MULTIPLEVALUESET), BE(f_MustJoin, EDIF_TOK_MUSTJOIN), BE(f_Name, EDIF_TOK_NAME), BE(f_Net, EDIF_TOK_NET), BE(f_NetBackAnnotate, EDIF_TOK_NETBACKANNOTATE), BE(f_NetBundle, EDIF_TOK_NETBUNDLE), BE(f_NetDelay, EDIF_TOK_NETDELAY), BE(f_NetGroup, EDIF_TOK_NETGROUP), BE(f_NetMap, EDIF_TOK_NETMAP), BE(f_NetRef, EDIF_TOK_NETREF), BE(f_NonPermutable, EDIF_TOK_NONPERMUTABLE), BE(f_NotAllowed, EDIF_TOK_NOTALLOWED), BE(f_NotchSpacing, EDIF_TOK_NOTCHSPACING), BE(f_Number, EDIF_TOK_NUMBER), BE(f_NumberDefinition, EDIF_TOK_NUMBERDEFINITION), BE(f_NumberDisplay, EDIF_TOK_NUMBERDISPLAY), BE(f_OffPageConnector, EDIF_TOK_OFFPAGECONNECTOR), BE(f_OffsetEvent, EDIF_TOK_OFFSETEVENT), BE(f_OpenShape, EDIF_TOK_OPENSHAPE), BE(f_Origin, EDIF_TOK_ORIGIN), BE(f_OverhangDistance, EDIF_TOK_OVERHANGDISTANCE), BE(f_OverlapDistance, EDIF_TOK_OVERLAPDISTANCE), BE(f_Oversize, EDIF_TOK_OVERSIZE), BE(f_Page, EDIF_TOK_PAGE), BE(f_PageSize, EDIF_TOK_PAGESIZE), BE(f_Parameter, EDIF_TOK_PARAMETER), BE(f_ParameterAssign, EDIF_TOK_PARAMETERASSIGN), BE(f_ParameterDisplay, EDIF_TOK_PARAMETERDISPLAY), BE(f_Path, EDIF_TOK_PATH), BE(f_PathDelay, EDIF_TOK_PATHDELAY), BE(f_Permutable, EDIF_TOK_PERMUTABLE), BE(f_PhysicalDesignRule, EDIF_TOK_PHYSICALDESIGNRULE), BE(f_Plug, EDIF_TOK_PLUG), BE(f_Point, EDIF_TOK_POINT), BE(f_PointDisplay, EDIF_TOK_POINTDISPLAY), BE(f_PointList, EDIF_TOK_POINTLIST), BE(f_Polygon, EDIF_TOK_POLYGON), BE(f_Port, EDIF_TOK_PORT), BE(f_PortBackAnnotate, EDIF_TOK_PORTBACKANNOTATE), BE(f_PortBundle, EDIF_TOK_PORTBUNDLE), BE(f_PortDelay, EDIF_TOK_PORTDELAY), BE(f_PortGroup, EDIF_TOK_PORTGROUP), BE(f_PortImplementation, EDIF_TOK_PORTIMPLEMENTATION), BE(f_PortInstance, EDIF_TOK_PORTINSTANCE), BE(f_PortList, EDIF_TOK_PORTLIST), BE(f_PortListAlias, EDIF_TOK_PORTLISTALIAS), BE(f_PortMap, EDIF_TOK_PORTMAP), BE(f_PortRef, EDIF_TOK_PORTREF), BE(f_Program, EDIF_TOK_PROGRAM), BE(f_Property, EDIF_TOK_PROPERTY), BE(f_PropertyDisplay, EDIF_TOK_PROPERTYDISPLAY), BE(f_ProtectionFrame, EDIF_TOK_PROTECTIONFRAME), BE(f_RangeVector, EDIF_TOK_RANGEVECTOR), BE(f_Rectangle, EDIF_TOK_RECTANGLE), BE(f_RectangleSize, EDIF_TOK_RECTANGLESIZE), BE(f_Rename, EDIF_TOK_RENAME), BE(f_Resolves, EDIF_TOK_RESOLVES), BE(f_Scale, EDIF_TOK_SCALE), BE(f_Section, EDIF_TOK_SECTION), BE(f_Shape, EDIF_TOK_SHAPE), BE(f_Simulate, EDIF_TOK_SIMULATE), BE(f_SimulationInfo, EDIF_TOK_SIMULATIONINFO), BE(f_SingleValueSet, EDIF_TOK_SINGLEVALUESET), BE(f_Site, EDIF_TOK_SITE), BE(f_Socket, EDIF_TOK_SOCKET), BE(f_SocketSet, EDIF_TOK_SOCKETSET), BE(f_Status, EDIF_TOK_STATUS), BE(f_Steady, EDIF_TOK_STEADY), BE(f_String, EDIF_TOK_STRING), BE(f_StringDisplay, EDIF_TOK_STRINGDISPLAY), BE(f_Strong, EDIF_TOK_STRONG), BE(f_Symbol, EDIF_TOK_SYMBOL), BE(f_Symmetry, EDIF_TOK_SYMMETRY), BE(f_Table, EDIF_TOK_TABLE), BE(f_TableDefault, EDIF_TOK_TABLEDEFAULT), BE(f_Technology, EDIF_TOK_TECHNOLOGY), BE(f_TimeInterval, EDIF_TOK_TIMEINTERVAL), BE(f_Timing, EDIF_TOK_TIMING), BE(f_Transform, EDIF_TOK_TRANSFORM), BE(f_Transition, EDIF_TOK_TRANSITION), BE(f_Trigger, EDIF_TOK_TRIGGER), BE(f_Union, EDIF_TOK_UNION), BE(f_View, EDIF_TOK_VIEW), BE(f_ViewList, EDIF_TOK_VIEWLIST), BE(f_ViewMap, EDIF_TOK_VIEWMAP), BE(f_ViewRef, EDIF_TOK_VIEWREF), BE(f_Visible, EDIF_TOK_VISIBLE), BE(f_VoltageMap, EDIF_TOK_VOLTAGEMAP), BE(f_WaveValue, EDIF_TOK_WAVEVALUE), BE(f_Weak, EDIF_TOK_WEAK), BE(f_WeakJoined, EDIF_TOK_WEAKJOINED), BE(f_When, EDIF_TOK_WHEN), BE(f_Written, EDIF_TOK_WRITTEN) }; static int BinderDefSize = sizeof(BinderDef) / sizeof(Binder); /* * Keyword table: * * This hash table holds all strings which may have to be matched * to. WARNING: it is assumed that there is no overlap of the 'token' * and 'context' strings. */ typedef struct Keyword { struct Keyword *Next; /* pointer to next entry */ char *String; /* pointer to associated string */ } Keyword; #define KEYWORD_HASH 127 /* hash table size */ static Keyword *KeywordTable[KEYWORD_HASH]; /* * Enter keyword: * * The passed string is entered into the keyword hash table. */ static void EnterKeyword(char * str) { /* * Locals. */ register Keyword *key; register unsigned int hsh; register char *cp; /* * Create the hash code, and add an entry to the table. */ for (hsh = 0, cp = str; *cp; hsh += hsh + *cp++); hsh %= KEYWORD_HASH; key = (Keyword *) Malloc(sizeof(Keyword)); key->Next = KeywordTable[hsh]; (KeywordTable[hsh] = key)->String = str; } /* * Find keyword: * * The passed string is located within the keyword table. If an * entry exists, then the value of the keyword string is returned. This * is real useful for doing string comparisons by pointer value later. * If there is no match, a NULL is returned. */ static char *FindKeyword(char * str) { /* * Locals. */ register Keyword *wlk,*owk; register unsigned int hsh; register char *cp; char lower[IDENT_LENGTH + 1]; /* * Create a lower case copy of the string. */ for (cp = lower; *str;) if (isupper( (int) *str)) *cp++ = tolower( (int) *str++); else *cp++ = *str++; *cp = '\0'; /* * Search the hash table for a match. */ for (hsh = 0, cp = lower; *cp; hsh += hsh + *cp++); hsh %= KEYWORD_HASH; for (owk = NULL, wlk = KeywordTable[hsh]; wlk; wlk = (owk = wlk)->Next) if (!strcmp(wlk->String,lower)){ /* * Readjust the LRU. */ if (owk){ owk->Next = wlk->Next; wlk->Next = KeywordTable[hsh]; KeywordTable[hsh] = wlk; } return (wlk->String); } return (NULL); } /* * Token hash table. */ #define TOKEN_HASH 51 static Token *TokenHash[TOKEN_HASH]; /* * Find token: * * A pointer to the token of the passed code is returned. If * no such beastie is present a NULL is returned instead. */ static Token *FindToken(register int cod) { /* * Locals. */ register Token *wlk,*owk; register unsigned int hsh; /* * Search the hash table for a matching token. */ hsh = cod % TOKEN_HASH; for (owk = NULL, wlk = TokenHash[hsh]; wlk; wlk = (owk = wlk)->Next) if (cod == wlk->Code){ if (owk){ owk->Next = wlk->Next; wlk->Next = TokenHash[hsh]; TokenHash[hsh] = wlk; } break; } return (wlk); } /* * Context hash table. */ #define CONTEXT_HASH 127 static Context *ContextHash[CONTEXT_HASH]; /* * Find context: * * A pointer to the context of the passed code is returned. If * no such beastie is present a NULL is returned instead. */ static Context *FindContext(register int cod) { /* * Locals. */ register Context *wlk,*owk; register unsigned int hsh; /* * Search the hash table for a matching context. */ hsh = cod % CONTEXT_HASH; for (owk = NULL, wlk = ContextHash[hsh]; wlk; wlk = (owk = wlk)->Next) if (cod == wlk->Code){ if (owk){ owk->Next = wlk->Next; wlk->Next = ContextHash[hsh]; ContextHash[hsh] = wlk; } break; } return (wlk); } /* * Parser state variables. */ static FILE *Input = NULL; /* input stream */ static FILE *Error = NULL; /* error stream */ static char *InFile; /* file name on the input stream */ static long LineNumber; /* current input line number */ static ContextCar *CSP = NULL; /* top of context stack */ static char yytext[IDENT_LENGTH + 1]; /* token buffer */ static char CharBuf[IDENT_LENGTH + 1]; /* garbage buffer */ /* * Token stacking variables. */ #ifdef DEBUG #define TS_DEPTH 8 #define TS_MASK (TS_DEPTH - 1) static unsigned int TSP = 0; /* token stack pointer */ static char *TokenStack[TS_DEPTH]; /* token name strings */ static short TokenType[TS_DEPTH]; /* token types */ /* * Stack: * * Add a token to the debug stack. The passed string and type are * what is to be pushed. */ static int Stack(char * str, int typ) { /* * Free any previous string, then push. */ if (TokenStack[TSP & TS_MASK]) Free(TokenStack[TSP & TS_MASK]); TokenStack[TSP & TS_MASK] = strcpy((char *)Malloc(strlen(str) + 1),str); TokenType[TSP & TS_MASK] = typ; TSP += 1; return 0; } /* * Dump stack: * * This displays the last set of accumulated tokens. */ static int DumpStack() { /* * Locals. */ register int i; register Context *cxt; register Token *tok; register char *nam; /* * Run through the list displaying the oldest first. */ fprintf(Error,"\n\n"); for (i = 0; i < TS_DEPTH; i += 1) if (TokenStack[(TSP + i) & TS_MASK]){ /* * Get the type name string. */ if ((cxt = FindContext(TokenType[(TSP + i) & TS_MASK]))) nam = cxt->Name; else if ((tok = FindToken(TokenType[(TSP + i) & TS_MASK]))) nam = tok->Name; else switch (TokenType[(TSP + i) & TS_MASK]){ case EDIF_TOK_IDENT: nam = "IDENT"; break; case EDIF_TOK_INT: nam = "INT"; break; case EDIF_TOK_KEYWORD: nam = "KEYWORD"; break; case EDIF_TOK_STR: nam = "STR"; break; default: nam = "?"; break; } /* * Now print the token state. */ fprintf(Error,"%2d %-16.16s '%s'\n",TS_DEPTH - i,nam, TokenStack[(TSP + i) & TS_MASK]); } fprintf(Error,"\n"); return 0; } #else #define Stack(s,t) #endif /* DEBUG */ /* * yyerror: * * Standard error reporter, it prints out the passed string * preceeded by the current filename and line number. */ static void yyerror(const char *ers) { #ifdef DEBUG DumpStack(); #endif /* DEBUG */ fprintf(Error,"%s, line %ld: %s\n",InFile,LineNumber,ers); } /* * String bucket definitions. */ #define BUCKET_SIZE 64 typedef struct Bucket { struct Bucket *Next; /* pointer to next bucket */ int Index; /* pointer to next free slot */ char Data[BUCKET_SIZE]; /* string data */ } Bucket; static Bucket *CurrentBucket = NULL; /* string bucket list */ static int StringSize = 0; /* current string length */ /* * Push string: * * This adds the passed charater to the current string bucket. */ static void PushString(char chr) { /* * Locals. */ register Bucket *bck; /* * Make sure there is room for the push. */ if ((bck = CurrentBucket)->Index >= BUCKET_SIZE){ bck = (Bucket *) Malloc(sizeof(Bucket)); bck->Next = CurrentBucket; (CurrentBucket = bck)->Index = 0; } /* * Push the character. */ bck->Data[bck->Index++] = chr; StringSize += 1; } /* * Form string: * * This converts the current string bucket into a real live string, * whose pointer is returned. */ static char *FormString() { /* * Locals. */ register Bucket *bck; register char *cp; /* * Allocate space for the string, set the pointer at the end. */ cp = (char *) Malloc(StringSize + 1); cp += StringSize; *cp-- = '\0'; /* * Yank characters out of the bucket. */ for (bck = CurrentBucket; bck->Index || bck->Next;){ if (!bck->Index){ CurrentBucket = bck->Next; Free(bck); bck = CurrentBucket; } *cp-- = bck->Data[--bck->Index]; } /* reset buffer size to zero */ StringSize =0; return (cp + 1); } /* * Parse EDIF: * * This builds the context tree and then calls the real parser. * It is passed two file streams, the first is where the input comes * from; the second is where error messages get printed. */ void ParseEDIF(char* filename,FILE* err) { /* * Locals. */ register int i; static int ContextDefined = 1; /* * Set up the file state to something useful. */ InFile = filename; Input = fopen(filename,"r"); Error = err; LineNumber = 1; /* * Define both the enabled token and context strings. */ if (ContextDefined){ for (i = TokenDefSize; i--; EnterKeyword(TokenDef[i].Name)){ register unsigned int hsh; hsh = TokenDef[i].Code % TOKEN_HASH; TokenDef[i].Next = TokenHash[hsh]; TokenHash[hsh] = &TokenDef[i]; } for (i = ContextDefSize; i--; EnterKeyword(ContextDef[i].Name)){ register unsigned int hsh; hsh = ContextDef[i].Code % CONTEXT_HASH; ContextDef[i].Next = ContextHash[hsh]; ContextHash[hsh] = &ContextDef[i]; } /* * Build the context tree. */ for (i = BinderDefSize; i--;){ register Context *cxt; register int j; /* * Define the current context to have carriers bound to it. */ cxt = FindContext(BinderDef[i].Origin); for (j = BinderDef[i].FollowerSize; j--;){ register ContextCar *cc; /* * Add carriers to the current context. */ cc = (ContextCar *) Malloc(sizeof(ContextCar)); cc->Next = cxt->Context; (cxt->Context = cc)->Context = FindContext(ABS(BinderDef[i].Follower[j])); cc->u.Single = BinderDef[i].Follower[j] < 0; } } /* * Build the token tree. */ for (i = TieDefSize; i--;){ register Context *cxt; register int j; /* * Define the current context to have carriers bound to it. */ cxt = FindContext(TieDef[i].Origin); for (j = TieDef[i].EnableSize; j--;){ register TokenCar *tc; /* * Add carriers to the current context. */ tc = (TokenCar *) Malloc(sizeof(TokenCar)); tc->Next = cxt->Token; (cxt->Token = tc)->Token = FindToken(TieDef[i].Enable[j]); } } /* * Put a bogus context on the stack which has 'EDIF' as its * follower. */ CSP = (ContextCar *) Malloc(sizeof(ContextCar)); CSP->Next = NULL; CSP->Context = FindContext(0); CSP->u.Used = NULL; ContextDefined = 0; } /* * Create an initial, empty string bucket. */ CurrentBucket = (Bucket *) Malloc(sizeof(Bucket)); CurrentBucket->Next = 0; CurrentBucket->Index = 0; /* * Fill the token stack with NULLs if debugging is enabled. */ #ifdef DEBUG for (i = TS_DEPTH; i--; TokenStack[i] = NULL) if (TokenStack[i]) Free(TokenStack[i]); TSP = 0; #endif /* DEBUG */ /* * Go parse things! */ edifparse(); } /* * Match token: * * The passed string is looked up in the current context's token * list to see if it is enabled. If so the token value is returned, * if not then zero. */ static int MatchToken(register char * str) { /* * Locals. */ register TokenCar *wlk,*owk; /* * Convert the string to the proper form, then search the token * carrier list for a match. */ str = FindKeyword(str); for (owk = NULL, wlk = CSP->Context->Token; wlk; wlk = (owk = wlk)->Next) if (str == wlk->Token->Name){ if (owk){ owk->Next = wlk->Next; wlk->Next = CSP->Context->Token; CSP->Context->Token = wlk; } return (wlk->Token->Code); } return (0); } /* * Match context: * * If the passed keyword string is within the current context, the * new context is pushed and token value is returned. A zero otherwise. */ static int MatchContext(register char * str) { /* * Locals. */ register ContextCar *wlk,*owk; /* * See if the context is present. */ str = FindKeyword(str); for (owk = NULL, wlk = CSP->Context->Context; wlk; wlk = (owk = wlk)->Next) if (str == wlk->Context->Name){ if (owk){ owk->Next = wlk->Next; wlk->Next = CSP->Context->Context; CSP->Context->Context = wlk; } /* * If a single context, make sure it isn't already used. */ if (wlk->u.Single){ register UsedCar *usc; for (usc = CSP->u.Used; usc; usc = usc->Next) if (usc->Code == wlk->Context->Code) break; if (usc){ sprintf(CharBuf,"'%s' is used more than once within '%s'", str,CSP->Context->Name); yyerror(CharBuf); } else { usc = (UsedCar *) Malloc(sizeof(UsedCar)); usc->Next = CSP->u.Used; (CSP->u.Used = usc)->Code = wlk->Context->Code; } } /* * Push the new context. */ owk = (ContextCar *) Malloc(sizeof(ContextCar)); owk->Next = CSP; (CSP = owk)->Context = wlk->Context; owk->u.Used = NULL; return (wlk->Context->Code); } return (0); } /* * PopC: * * This pops the current context. */ static void PopC() { /* * Locals. */ register UsedCar *usc; register ContextCar *csp; /* * Release single markers and pop context. */ while ( (usc = CSP->u.Used) ){ CSP->u.Used = usc->Next; Free(usc); } csp = CSP->Next; Free(CSP); CSP = csp; } /* * Lexical analyzer states. */ #define L_START 0 #define L_INT 1 #define L_IDENT 2 #define L_KEYWORD 3 #define L_STRING 4 #define L_KEYWORD2 5 #define L_ASCIICHAR 6 #define L_ASCIICHAR2 7 /* * yylex: * * This is the lexical analyzer called by the YACC/BISON parser. * It returns a pretty restricted set of token types and does the * context movement when acceptable keywords are found. The token * value returned is a NULL terminated string to allocated storage * (ie - it should get released some time) with some restrictions. * The token value for integers is strips a leading '+' if present. * String token values have the leading and trailing '"'-s stripped. * '%' conversion characters in string values are passed converted. * The '(' and ')' characters do not have a token value. */ static int yylex() { /* * Locals. */ register int c,s,l; /* * Keep on sucking up characters until we find something which * explicitly forces us out of this function. */ for (s = L_START, l = 0; 1;){ yytext[l++] = c = Getc(Input); switch (s){ /* * Starting state, look for something resembling a token. */ case L_START: if (isdigit(c) || c == '-') s = L_INT; else if (isalpha(c) || c == '&') s = L_IDENT; else if (isspace(c)){ if (c == '\n') LineNumber += 1; l = 0; } else if (c == '('){ l = 0; s = L_KEYWORD; } else if (c == '"') s = L_STRING; else if (c == '+'){ l = 0; /* strip '+' */ s = L_INT; } else if (c == EOF) return ('\0'); else { yytext[1] = '\0'; Stack(yytext,c); return (c); } break; /* * Suck up the integer digits. */ case L_INT: if (isdigit(c)) break; Ungetc(c); yytext[--l] = '\0'; yylval.s = strcpy((char *)Malloc(l + 1),yytext); Stack(yytext,EDIF_TOK_INT); return (EDIF_TOK_INT); /* * Grab an identifier, see if the current context enables * it with a specific token value. */ case L_IDENT: if (isalpha(c) || isdigit(c) || c == '_') break; Ungetc(c); yytext[--l] = '\0'; if (CSP->Context->Token && (c = MatchToken(yytext))){ Stack(yytext,c); return (c); } yylval.s = strcpy((char *)Malloc(l + 1),yytext); Stack(yytext, EDIF_TOK_IDENT); return (EDIF_TOK_IDENT); /* * Scan until you find the start of an identifier, discard * any whitespace found. On no identifier, return a '('. */ case L_KEYWORD: if (isalpha(c) || c == '&'){ s = L_KEYWORD2; break; } else if (isspace(c)){ l = 0; break; } Ungetc(c); Stack("(",'('); return ('('); /* * Suck up the keyword identifier, if it matches the set of * allowable contexts then return its token value and push * the context, otherwise just return the identifier string. */ case L_KEYWORD2: if (isalpha(c) || isdigit(c) || c == '_') break; Ungetc(c); yytext[--l] = '\0'; if ( (c = MatchContext(yytext)) ){ Stack(yytext,c); return (c); } yylval.s = strcpy((char *)Malloc(l + 1),yytext); Stack(yytext, EDIF_TOK_KEYWORD); return (EDIF_TOK_KEYWORD); /* * Suck up string characters but once resolved they should * be deposited in the string bucket because they can be * arbitrarily long. */ case L_STRING: if (c == '\n') LineNumber += 1; else if (c == '\r') ; else if (c == '"' || c == EOF){ yylval.s = FormString(); Stack(yylval.s, EDIF_TOK_STR); return (EDIF_TOK_STR); } else if (c == '%') s = L_ASCIICHAR; else PushString(c); l = 0; break; /* * Skip white space and look for integers to be pushed * as characters. */ case L_ASCIICHAR: if (isdigit(c)){ s = L_ASCIICHAR2; break; } else if (c == '%' || c == EOF) s = L_STRING; else if (c == '\n') LineNumber += 1; l = 0; break; /* * Convert the accumulated integer into a char and push. */ case L_ASCIICHAR2: if (isdigit(c)) break; Ungetc(c); yytext[--l] = '\0'; PushString(atoi(yytext)); s = L_ASCIICHAR; l = 0; break; } } } pcb-4.3.0/src/pcb-menu.res.h0000664000175000017500000006217514017001275012453 00000000000000# 32 "pcb-menu.res" char *s = N_("About..."); # 33 "pcb-menu.res" char *s = N_("Save layout"); # 33 "pcb-menu.res" char *s = N_("Ctrl-S"); # 33 "pcb-menu.res" char *s = N_("Ctrls"); # 34 "pcb-menu.res" char *s = N_("Save layout as..."); # 34 "pcb-menu.res" char *s = N_("Shift Ctrl-S"); # 34 "pcb-menu.res" char *s = N_("Shift Ctrls"); # 35 "pcb-menu.res" char *s = N_("Revert"); # 37 "pcb-menu.res" char *s = N_("Import Schematics"); # 38 "pcb-menu.res" char *s = N_("gschem"); # 39 "pcb-menu.res" char *s = N_("TinyCAD"); # 41 "pcb-menu.res" char *s = N_("Load layout"); # 42 "pcb-menu.res" char *s = N_("Load element data to paste-buffer"); # 43 "pcb-menu.res" char *s = N_("Load layout data to paste-buffer"); # 44 "pcb-menu.res" char *s = N_("Load netlist file"); # 45 "pcb-menu.res" char *s = N_("Load vendor resource file"); # 46 "pcb-menu.res" char *s = N_("Print layout..."); # 47 "pcb-menu.res" char *s = N_("Export layout..."); # 48 "pcb-menu.res" char *s = N_("Calibrate Printer..."); # 50 "pcb-menu.res" char *s = N_("Save connection data of..."); # 51 "pcb-menu.res" char *s = N_(" a single element"); # 52 "pcb-menu.res" char *s = N_(" all elements"); # 53 "pcb-menu.res" char *s = N_(" unused pins"); # 55 "pcb-menu.res" char *s = N_("Start new layout"); # 55 "pcb-menu.res" char *s = N_("Ctrl-N"); # 55 "pcb-menu.res" char *s = N_("Ctrln"); # 57 "pcb-menu.res" char *s = N_("Quit Program"); # 57 "pcb-menu.res" char *s = N_("Ctrl-Q"); # 57 "pcb-menu.res" char *s = N_("Ctrlq"); # 60 "pcb-menu.res" char *s = N_("Flip up/down"); # 60 "pcb-menu.res" char *s = N_("Tab"); # 60 "pcb-menu.res" char *s = N_("Tab"); # 61 "pcb-menu.res" char *s = N_("Flip left/right"); # 61 "pcb-menu.res" char *s = N_("Shift-Tab"); # 61 "pcb-menu.res" char *s = N_("ShiftTab"); # 62 "pcb-menu.res" char *s = N_("Spin 180°"); # 62 "pcb-menu.res" char *s = N_("Ctrl-Tab"); # 62 "pcb-menu.res" char *s = N_("CtrlTab"); # 63 "pcb-menu.res" char *s = N_("Swap Sides"); # 63 "pcb-menu.res" char *s = N_("Ctrl-Shift-Tab"); # 63 "pcb-menu.res" char *s = N_("Ctrl ShiftTab"); # 64 "pcb-menu.res" char *s = N_("Center cursor"); # 64 "pcb-menu.res" char *s = N_("C"); # 64 "pcb-menu.res" char *s = N_("c"); # 65 "pcb-menu.res" char *s = N_("Show soldermask"); # 67 "pcb-menu.res" char *s = N_("Displayed element-name..."); # 68 "pcb-menu.res" char *s = N_("Description"); # 69 "pcb-menu.res" char *s = N_("Reference Designator"); # 70 "pcb-menu.res" char *s = N_("Value"); # 71 "pcb-menu.res" char *s = N_("Lock Names"); # 72 "pcb-menu.res" char *s = N_("Only Names"); # 73 "pcb-menu.res" char *s = N_("Hide Names"); # 218 "pcb-menu.res" char *s = N_("Pinout shows number"); # 76 "pcb-menu.res" char *s = N_("Open pinout menu"); # 451 "pcb-menu.res" char *s = N_("Shift-D"); # 451 "pcb-menu.res" char *s = N_("Shiftd"); # 79 "pcb-menu.res" char *s = N_("Zoom In 2X"); # 82 "pcb-menu.res" /* xgettext:no-c-format */ char *s = N_("Zoom In 20%"); # 83 "pcb-menu.res" char *s = N_("Z"); # 83 "pcb-menu.res" char *s = N_("z"); # 83 "pcb-menu.res" /* xgettext:no-c-format */ char *s = N_("Zoom Out 20%"); # 84 "pcb-menu.res" char *s = N_("Shift-Z"); # 84 "pcb-menu.res" char *s = N_("Shiftz"); # 85 "pcb-menu.res" char *s = N_("Zoom Out 2X"); # 86 "pcb-menu.res" char *s = N_("Zoom Max"); # 86 "pcb-menu.res" char *s = N_("V"); # 86 "pcb-menu.res" char *s = N_("v"); # 87 "pcb-menu.res" char *s = N_("Zoom Toggle"); # 87 "pcb-menu.res" char *s = N_("`"); # 87 "pcb-menu.res" char *s = N_("`"); # 89 "pcb-menu.res" char *s = N_("Zoom to 0.1mil/px"); # 90 "pcb-menu.res" char *s = N_("Zoom to 0.01mm/px"); # 91 "pcb-menu.res" char *s = N_("Zoom to 1mil/px"); # 92 "pcb-menu.res" char *s = N_("Zoom to 0.05mm/px"); # 93 "pcb-menu.res" char *s = N_("Zoom to 2.5mil/px"); # 94 "pcb-menu.res" char *s = N_("Zoom to 0.1mm/px"); # 95 "pcb-menu.res" char *s = N_("Zoom to 10mil/px"); # 98 "pcb-menu.res" char *s = N_("mil"); # 99 "pcb-menu.res" char *s = N_("mm"); # 100 "pcb-menu.res" char *s = N_("Display grid"); # 101 "pcb-menu.res" char *s = N_("Realign grid"); # 102 "pcb-menu.res" char *s = N_("No Grid"); # 104 "pcb-menu.res" char *s = N_("0.1 mil"); # 105 "pcb-menu.res" char *s = N_("1 mil"); # 106 "pcb-menu.res" char *s = N_("5 mil"); # 107 "pcb-menu.res" char *s = N_("10 mil"); # 108 "pcb-menu.res" char *s = N_("25 mil"); # 109 "pcb-menu.res" char *s = N_("50 mil"); # 110 "pcb-menu.res" char *s = N_("100 mil"); # 112 "pcb-menu.res" char *s = N_("0.01 mm"); # 113 "pcb-menu.res" char *s = N_("0.05 mm"); # 114 "pcb-menu.res" char *s = N_("0.1 mm"); # 115 "pcb-menu.res" char *s = N_("0.25 mm"); # 116 "pcb-menu.res" char *s = N_("0.5 mm"); # 117 "pcb-menu.res" char *s = N_("1 mm"); # 119 "pcb-menu.res" char *s = N_("Grid -"); # 119 "pcb-menu.res" char *s = N_("Shift-G"); # 119 "pcb-menu.res" char *s = N_("Shiftg"); # 120 "pcb-menu.res" char *s = N_("Grid +"); # 120 "pcb-menu.res" char *s = N_("G"); # 120 "pcb-menu.res" char *s = N_("g"); # 123 "pcb-menu.res" char *s = N_("Shown Layers"); # 126 "pcb-menu.res" char *s = N_("Edit Layer Groups"); # 128 "pcb-menu.res" char *s = N_("Current Layer"); # 131 "pcb-menu.res" char *s = N_("Delete current layer"); # 132 "pcb-menu.res" char *s = N_("Add new layer"); # 133 "pcb-menu.res" char *s = N_("Move current layer up"); # 134 "pcb-menu.res" char *s = N_("Move current layer down"); # 138 "pcb-menu.res" char *s = N_("Undo last operation"); # 138 "pcb-menu.res" char *s = N_("U"); # 138 "pcb-menu.res" char *s = N_("u"); # 139 "pcb-menu.res" char *s = N_("Redo last undone operation"); # 139 "pcb-menu.res" char *s = N_("Shift-R"); # 139 "pcb-menu.res" char *s = N_("Shiftr"); # 140 "pcb-menu.res" char *s = N_("Clear undo-buffer"); # 140 "pcb-menu.res" char *s = N_("Shift-Ctrl-U"); # 140 "pcb-menu.res" char *s = N_("Shift Ctrlu"); # 285 "pcb-menu.res" char *s = N_("Cut selection to buffer"); # 144 "pcb-menu.res" char *s = N_("Ctrl-X"); # 144 "pcb-menu.res" char *s = N_("Ctrlx"); # 283 "pcb-menu.res" char *s = N_("Copy selection to buffer"); # 147 "pcb-menu.res" char *s = N_("Ctrl-C"); # 147 "pcb-menu.res" char *s = N_("Ctrlc"); # 287 "pcb-menu.res" char *s = N_("Paste buffer to layout"); # 148 "pcb-menu.res" char *s = N_("Ctrl-V"); # 148 "pcb-menu.res" char *s = N_("Ctrlv"); # 150 "pcb-menu.res" char *s = N_("Unselect all"); # 150 "pcb-menu.res" char *s = N_("Shift-Alt-A"); # 150 "pcb-menu.res" char *s = N_("Shift Alta"); # 151 "pcb-menu.res" char *s = N_("Select all visible"); # 151 "pcb-menu.res" char *s = N_("Alt-A"); # 151 "pcb-menu.res" char *s = N_("Alta"); # 153 "pcb-menu.res" char *s = N_("Edit Names..."); # 154 "pcb-menu.res" char *s = N_(" Change text on layout"); # 154 "pcb-menu.res" char *s = N_("N"); # 154 "pcb-menu.res" char *s = N_("n"); # 155 "pcb-menu.res" char *s = N_(" Edit name of layout"); # 156 "pcb-menu.res" char *s = N_(" Edit name of active layer"); # 157 "pcb-menu.res" char *s = N_("Edit Attributes..."); # 158 "pcb-menu.res" char *s = N_(" Layout"); # 159 "pcb-menu.res" char *s = N_(" CurrentLayer"); # 160 "pcb-menu.res" char *s = N_(" Element"); # 162 "pcb-menu.res" char *s = N_("Board Sizes"); # 163 "pcb-menu.res" char *s = N_("Route Styles"); # 166 "pcb-menu.res" char *s = N_("Edit..."); # 169 "pcb-menu.res" char *s = N_("Via type"); # 170 "pcb-menu.res" char *s = N_("Through-hole"); # 170 "pcb-menu.res" char *s = N_("Xtrl-Shift-P"); # 215 "pcb-menu.res" char *s = N_("Ctrl Shiftp"); # 171 "pcb-menu.res" char *s = N_("Buried from"); # 171 "pcb-menu.res" char *s = N_("Xtrl-Shift-F"); # 171 "pcb-menu.res" char *s = N_("Ctrl Shiftf"); # 172 "pcb-menu.res" char *s = N_("Buried to"); # 172 "pcb-menu.res" char *s = N_("Xtrl-Shift-T"); # 172 "pcb-menu.res" char *s = N_("Ctrl Shiftt"); # 176 "pcb-menu.res" char *s = N_("None"); # 177 "pcb-menu.res" char *s = N_("Via"); # 177 "pcb-menu.res" char *s = N_("F1"); # 177 "pcb-menu.res" char *s = N_("F1"); # 178 "pcb-menu.res" char *s = N_("Line"); # 178 "pcb-menu.res" char *s = N_("F2"); # 178 "pcb-menu.res" char *s = N_("F2"); # 179 "pcb-menu.res" char *s = N_("Arc"); # 179 "pcb-menu.res" char *s = N_("F3"); # 179 "pcb-menu.res" char *s = N_("F3"); # 180 "pcb-menu.res" char *s = N_("Text"); # 180 "pcb-menu.res" char *s = N_("F4"); # 180 "pcb-menu.res" char *s = N_("F4"); # 181 "pcb-menu.res" char *s = N_("Rectangle"); # 181 "pcb-menu.res" char *s = N_("F5"); # 181 "pcb-menu.res" char *s = N_("F5"); # 182 "pcb-menu.res" char *s = N_("Polygon"); # 182 "pcb-menu.res" char *s = N_("F6"); # 182 "pcb-menu.res" char *s = N_("F6"); # 183 "pcb-menu.res" char *s = N_("Polygon Hole"); # 184 "pcb-menu.res" char *s = N_("Buffer"); # 184 "pcb-menu.res" char *s = N_("F7"); # 184 "pcb-menu.res" char *s = N_("F7"); # 353 "pcb-menu.res" char *s = N_("Remove"); # 185 "pcb-menu.res" char *s = N_("F8"); # 185 "pcb-menu.res" char *s = N_("F8"); # 186 "pcb-menu.res" char *s = N_("Rotate"); # 186 "pcb-menu.res" char *s = N_("F9"); # 186 "pcb-menu.res" char *s = N_("F9"); # 187 "pcb-menu.res" char *s = N_("Thermal"); # 187 "pcb-menu.res" char *s = N_("F10"); # 187 "pcb-menu.res" char *s = N_("F10"); # 431 "pcb-menu.res" char *s = N_("Arrow"); # 188 "pcb-menu.res" char *s = N_("F11"); # 188 "pcb-menu.res" char *s = N_("F11"); # 189 "pcb-menu.res" char *s = N_("Insert Point"); # 189 "pcb-menu.res" char *s = N_("Insert"); # 189 "pcb-menu.res" char *s = N_("Insert"); # 190 "pcb-menu.res" char *s = N_("Move"); # 191 "pcb-menu.res" char *s = N_("Copy"); # 192 "pcb-menu.res" char *s = N_("Lock"); # 192 "pcb-menu.res" char *s = N_("F12"); # 192 "pcb-menu.res" char *s = N_("F12"); # 193 "pcb-menu.res" char *s = N_("Cancel"); # 193 "pcb-menu.res" char *s = N_("Esc"); # 193 "pcb-menu.res" char *s = N_("Escape"); # 195 "pcb-menu.res" char *s = N_("Command"); # 195 "pcb-menu.res" char *s = N_(":"); # 195 "pcb-menu.res" char *s = N_(":"); # 198 "pcb-menu.res" char *s = N_("Layer groups"); # 199 "pcb-menu.res" char *s = N_("Edit layer groupings"); # 201 "pcb-menu.res" char *s = N_("'All-direction' lines"); # 201 "pcb-menu.res" char *s = N_("."); # 201 "pcb-menu.res" char *s = N_("."); # 202 "pcb-menu.res" char *s = N_("Auto swap line start angle"); # 203 "pcb-menu.res" char *s = N_("Orthogonal moves"); # 204 "pcb-menu.res" char *s = N_("Crosshair snaps to pins and pads"); # 205 "pcb-menu.res" char *s = N_("Crosshair shows DRC clearance"); # 206 "pcb-menu.res" char *s = N_("Auto enforce DRC clearance"); # 208 "pcb-menu.res" char *s = N_("Rubber band mode"); # 209 "pcb-menu.res" char *s = N_("Require unique element names"); # 210 "pcb-menu.res" char *s = N_("Auto-zero delta measurements"); # 211 "pcb-menu.res" char *s = N_("New lines, arcs clear polygons"); # 212 "pcb-menu.res" char *s = N_("New polygons are full ones"); # 213 "pcb-menu.res" char *s = N_("Show autorouter trials"); # 214 "pcb-menu.res" char *s = N_("Thin draw"); # 214 "pcb-menu.res" char *s = N_("|"); # 214 "pcb-menu.res" char *s = N_("|"); # 215 "pcb-menu.res" char *s = N_("Thin draw poly"); # 215 "pcb-menu.res" char *s = N_("Ctrl-Shift-P"); # 216 "pcb-menu.res" char *s = N_("Check polygons"); # 219 "pcb-menu.res" char *s = N_("Pins/Via show Name/Number"); # 219 "pcb-menu.res" char *s = N_("D"); # 219 "pcb-menu.res" char *s = N_("d"); # 220 "pcb-menu.res" char *s = N_("Enable vendor drill mapping"); # 221 "pcb-menu.res" char *s = N_("Import Settings"); # 222 "pcb-menu.res" char *s = N_("New elements added at..."); # 223 "pcb-menu.res" char *s = N_(" Center"); # 224 "pcb-menu.res" char *s = N_(" Mark"); # 225 "pcb-menu.res" char *s = N_(" Crosshair"); # 227 "pcb-menu.res" char *s = N_("Set Dispersion"); # 232 "pcb-menu.res" char *s = N_("Select all visible objects"); # 233 "pcb-menu.res" char *s = N_("Select all found objects"); # 234 "pcb-menu.res" char *s = N_("Select all connected objects"); # 236 "pcb-menu.res" char *s = N_("Unselect all objects"); # 237 "pcb-menu.res" char *s = N_("unselect all found objects"); # 238 "pcb-menu.res" char *s = N_("unselect all connected objects"); # 240 "pcb-menu.res" char *s = N_("Select by name"); # 241 "pcb-menu.res" char *s = N_("All objects"); # 278 "pcb-menu.res" char *s = N_("Elements"); # 243 "pcb-menu.res" char *s = N_("Pads"); # 279 "pcb-menu.res" char *s = N_("Pins"); # 245 "pcb-menu.res" char *s = N_("Text Objects"); # 246 "pcb-menu.res" char *s = N_("Vias"); # 248 "pcb-menu.res" char *s = N_("Auto-place selected elements"); # 248 "pcb-menu.res" char *s = N_("Ctrl-P"); # 248 "pcb-menu.res" char *s = N_("Ctrlp"); # 249 "pcb-menu.res" char *s = N_("Disperse all elements"); # 250 "pcb-menu.res" char *s = N_("Move selected elements to other side"); # 250 "pcb-menu.res" char *s = N_("Shift-B"); # 250 "pcb-menu.res" char *s = N_("Shiftb"); # 251 "pcb-menu.res" char *s = N_("Move selected to current layer"); # 251 "pcb-menu.res" char *s = N_("Shift-M"); # 251 "pcb-menu.res" char *s = N_("Shiftm"); # 252 "pcb-menu.res" char *s = N_("Delete selected objects"); # 252 "pcb-menu.res" char *s = N_("Delete"); # 252 "pcb-menu.res" char *s = N_("Delete"); # 253 "pcb-menu.res" char *s = N_("Convert selection to element"); # 255 "pcb-menu.res" char *s = N_("Optimize selected rats"); # 321 "pcb-menu.res" char *s = N_("Auto-route selected rats"); # 256 "pcb-menu.res" char *s = N_("Alt-R"); # 256 "pcb-menu.res" char *s = N_("Altr"); # 257 "pcb-menu.res" char *s = N_("Rip up selected auto-routed tracks"); # 259 "pcb-menu.res" char *s = N_("Change size of selected objects"); # 260 "pcb-menu.res" char *s = N_("Lines -10 mil"); # 261 "pcb-menu.res" char *s = N_("Lines +10 mil"); # 262 "pcb-menu.res" char *s = N_("Pads -10 mil"); # 263 "pcb-menu.res" char *s = N_("Pads +10 mil"); # 274 "pcb-menu.res" char *s = N_("Pins -10 mil"); # 275 "pcb-menu.res" char *s = N_("Pins +10 mil"); # 266 "pcb-menu.res" char *s = N_("Texts -10 mil"); # 267 "pcb-menu.res" char *s = N_("Texts +10 mil"); # 272 "pcb-menu.res" char *s = N_("Vias -10 mil"); # 273 "pcb-menu.res" char *s = N_("Vias +10 mil"); # 271 "pcb-menu.res" char *s = N_("Change drilling hole of selected objects"); # 277 "pcb-menu.res" char *s = N_("Change square-flag of selected objects"); # 289 "pcb-menu.res" char *s = N_("Rotate buffer 90 deg CCW"); # 290 "pcb-menu.res" char *s = N_("Shift-F7"); # 290 "pcb-menu.res" char *s = N_("ShiftF7"); # 291 "pcb-menu.res" char *s = N_("Rotate buffer 90 deg CW"); # 292 "pcb-menu.res" char *s = N_("Arbitrarily Rotate Buffer"); # 293 "pcb-menu.res" char *s = N_("Mirror buffer (up/down)"); # 294 "pcb-menu.res" char *s = N_("Mirror buffer (left/right)"); # 297 "pcb-menu.res" char *s = N_("Clear buffer"); # 298 "pcb-menu.res" char *s = N_("Convert buffer to element"); # 299 "pcb-menu.res" char *s = N_("Break buffer elements to pieces"); # 300 "pcb-menu.res" char *s = N_("Save buffer elements to file"); # 302 "pcb-menu.res" char *s = N_("Select current buffer"); # 303 "pcb-menu.res" char *s = N_("#1"); # 303 "pcb-menu.res" char *s = N_("Shift-1"); # 303 "pcb-menu.res" char *s = N_("Shift1"); # 304 "pcb-menu.res" char *s = N_("#2"); # 304 "pcb-menu.res" char *s = N_("Shift-2"); # 304 "pcb-menu.res" char *s = N_("Shift2"); # 305 "pcb-menu.res" char *s = N_("#3"); # 305 "pcb-menu.res" char *s = N_("Shift-3"); # 305 "pcb-menu.res" char *s = N_("Shift3"); # 306 "pcb-menu.res" char *s = N_("#4"); # 306 "pcb-menu.res" char *s = N_("Shift-4"); # 306 "pcb-menu.res" char *s = N_("Shift4"); # 307 "pcb-menu.res" char *s = N_("#5"); # 307 "pcb-menu.res" char *s = N_("Shift-5"); # 307 "pcb-menu.res" char *s = N_("Shift5"); # 311 "pcb-menu.res" char *s = N_("Lookup connection to object"); # 311 "pcb-menu.res" char *s = N_("Ctrl-F"); # 311 "pcb-menu.res" char *s = N_("Ctrlf"); # 312 "pcb-menu.res" char *s = N_("Reset scanned pads/pins/vias"); # 313 "pcb-menu.res" char *s = N_("Reset scanned lines/polygons"); # 314 "pcb-menu.res" char *s = N_("Reset all connections"); # 314 "pcb-menu.res" char *s = N_("Shift-F"); # 314 "pcb-menu.res" char *s = N_("Shiftf"); # 316 "pcb-menu.res" char *s = N_("Optimize rats-nest"); # 317 "pcb-menu.res" char *s = N_("O"); # 317 "pcb-menu.res" char *s = N_("o"); # 318 "pcb-menu.res" char *s = N_("Erase rats-nest"); # 318 "pcb-menu.res" char *s = N_("E"); # 318 "pcb-menu.res" char *s = N_("e"); # 319 "pcb-menu.res" char *s = N_("Erase selected rats"); # 319 "pcb-menu.res" char *s = N_("Shift-E"); # 319 "pcb-menu.res" char *s = N_("Shifte"); # 322 "pcb-menu.res" char *s = N_("Auto-route all rats"); # 323 "pcb-menu.res" char *s = N_("Toporouter"); # 324 "pcb-menu.res" char *s = N_("Rip up all auto-routed tracks"); # 326 "pcb-menu.res" char *s = N_("Auto-Optimize"); # 326 "pcb-menu.res" char *s = N_("Shift-="); # 326 "pcb-menu.res" char *s = N_("Shift="); # 327 "pcb-menu.res" char *s = N_("Debumpify"); # 328 "pcb-menu.res" char *s = N_("Unjaggy"); # 329 "pcb-menu.res" char *s = N_("Vianudge"); # 330 "pcb-menu.res" char *s = N_("Viatrim"); # 331 "pcb-menu.res" char *s = N_("Orthopull"); # 332 "pcb-menu.res" char *s = N_("SimpleOpts"); # 332 "pcb-menu.res" char *s = N_("="); # 332 "pcb-menu.res" char *s = N_("="); # 333 "pcb-menu.res" char *s = N_("Miter"); # 334 "pcb-menu.res" char *s = N_("Puller"); # 334 "pcb-menu.res" char *s = N_("Y"); # 334 "pcb-menu.res" char *s = N_("y"); # 335 "pcb-menu.res" char *s = N_("Global Puller"); # 336 "pcb-menu.res" char *s = N_("Selected"); # 337 "pcb-menu.res" char *s = N_("Found"); # 338 "pcb-menu.res" char *s = N_("All"); # 340 "pcb-menu.res" char *s = N_("Only autorouted nets"); # 342 "pcb-menu.res" char *s = N_("Design Rule Checker"); # 344 "pcb-menu.res" char *s = N_("Apply vendor drill mapping"); # 348 "pcb-menu.res" char *s = N_("Generate object report"); # 348 "pcb-menu.res" char *s = N_("Ctrl-R"); # 348 "pcb-menu.res" char *s = N_("Ctrlr"); # 349 "pcb-menu.res" char *s = N_("Generate drill summary"); # 350 "pcb-menu.res" char *s = N_("Report found pins/pads"); # 351 "pcb-menu.res" char *s = N_("Report net length"); # 351 "pcb-menu.res" char *s = N_("R"); # 351 "pcb-menu.res" char *s = N_("r"); # 352 "pcb-menu.res" char *s = N_("Key Bindings"); # 353 "pcb-menu.res" char *s = N_("Backspace"); # 353 "pcb-menu.res" char *s = N_("BackSpace"); # 373 "pcb-menu.res" char *s = N_("Remove Connected"); # 356 "pcb-menu.res" char *s = N_("Shift-Backspace"); # 356 "pcb-menu.res" char *s = N_("ShiftBackSpace"); # 373 "pcb-menu.res" char *s = N_("Shift-Delete"); # 373 "pcb-menu.res" char *s = N_("ShiftDelete"); # 390 "pcb-menu.res" char *s = N_("Set Same"); # 390 "pcb-menu.res" char *s = N_("A"); # 390 "pcb-menu.res" char *s = N_("a"); # 391 "pcb-menu.res" char *s = N_("Flip Object"); # 391 "pcb-menu.res" char *s = N_("B"); # 391 "pcb-menu.res" char *s = N_("b"); # 392 "pcb-menu.res" char *s = N_("Find Connections"); # 392 "pcb-menu.res" char *s = N_("F"); # 392 "pcb-menu.res" char *s = N_("f"); # 393 "pcb-menu.res" char *s = N_("ToggleHideName Object"); # 393 "pcb-menu.res" char *s = N_("H"); # 393 "pcb-menu.res" char *s = N_("h"); # 394 "pcb-menu.res" char *s = N_("ToggleHideName SelectedElement"); # 394 "pcb-menu.res" char *s = N_("Shift-H"); # 394 "pcb-menu.res" char *s = N_("Shifth"); # 395 "pcb-menu.res" char *s = N_("ChangeHole Object"); # 395 "pcb-menu.res" char *s = N_("Ctrl-H"); # 395 "pcb-menu.res" char *s = N_("Ctrlh"); # 396 "pcb-menu.res" char *s = N_("ChangeJoin Object"); # 396 "pcb-menu.res" char *s = N_("J"); # 396 "pcb-menu.res" char *s = N_("j"); # 397 "pcb-menu.res" char *s = N_("ChangeJoin SelectedObject"); # 397 "pcb-menu.res" char *s = N_("Shift-J"); # 397 "pcb-menu.res" char *s = N_("Shiftj"); # 398 "pcb-menu.res" char *s = N_("Clear Object +"); # 398 "pcb-menu.res" char *s = N_("K"); # 398 "pcb-menu.res" char *s = N_("k"); # 399 "pcb-menu.res" char *s = N_("Clear Object -"); # 399 "pcb-menu.res" char *s = N_("Shift-K"); # 399 "pcb-menu.res" char *s = N_("Shiftk"); # 400 "pcb-menu.res" char *s = N_("Clear Selected +"); # 400 "pcb-menu.res" char *s = N_("Ctrl-K"); # 400 "pcb-menu.res" char *s = N_("Ctrlk"); # 401 "pcb-menu.res" char *s = N_("Clear Selected -"); # 401 "pcb-menu.res" char *s = N_("Shift-Ctrl-K"); # 401 "pcb-menu.res" char *s = N_("Shift Ctrlk"); # 402 "pcb-menu.res" char *s = N_("Line Tool size +"); # 402 "pcb-menu.res" char *s = N_("L"); # 402 "pcb-menu.res" char *s = N_("l"); # 403 "pcb-menu.res" char *s = N_("Line Tool size -"); # 403 "pcb-menu.res" char *s = N_("Shift-L"); # 403 "pcb-menu.res" char *s = N_("Shiftl"); # 404 "pcb-menu.res" char *s = N_("Move Object to current layer"); # 404 "pcb-menu.res" char *s = N_("M"); # 404 "pcb-menu.res" char *s = N_("m"); # 405 "pcb-menu.res" char *s = N_("MarkCrosshair"); # 405 "pcb-menu.res" char *s = N_("Ctrl-M"); # 405 "pcb-menu.res" char *s = N_("Ctrlm"); # 406 "pcb-menu.res" char *s = N_("Select shortest rat"); # 406 "pcb-menu.res" char *s = N_("Shift-N"); # 406 "pcb-menu.res" char *s = N_("Shiftn"); # 407 "pcb-menu.res" char *s = N_("AddRats to selected pins"); # 407 "pcb-menu.res" char *s = N_("Shift-O"); # 407 "pcb-menu.res" char *s = N_("Shifto"); # 413 "pcb-menu.res" char *s = N_("ChangeOctagon Object"); # 413 "pcb-menu.res" char *s = N_("Ctrl-O"); # 413 "pcb-menu.res" char *s = N_("Ctrlo"); # 414 "pcb-menu.res" char *s = N_("Polygon PreviousPoint"); # 414 "pcb-menu.res" char *s = N_("P"); # 414 "pcb-menu.res" char *s = N_("p"); # 415 "pcb-menu.res" char *s = N_("Polygon Close"); # 415 "pcb-menu.res" char *s = N_("Shift-P"); # 415 "pcb-menu.res" char *s = N_("Shiftp"); # 416 "pcb-menu.res" char *s = N_("ChangeSquare Object"); # 416 "pcb-menu.res" char *s = N_("Q"); # 416 "pcb-menu.res" char *s = N_("q"); # 417 "pcb-menu.res" char *s = N_("ChangeSize +"); # 417 "pcb-menu.res" char *s = N_("S"); # 417 "pcb-menu.res" char *s = N_("s"); # 418 "pcb-menu.res" char *s = N_("ChangeSize -"); # 418 "pcb-menu.res" char *s = N_("Shift-S"); # 418 "pcb-menu.res" char *s = N_("Shifts"); # 419 "pcb-menu.res" char *s = N_("ChangeDrill +5 mil"); # 419 "pcb-menu.res" char *s = N_("Alt-S"); # 419 "pcb-menu.res" char *s = N_("Alts"); # 420 "pcb-menu.res" char *s = N_("ChangeDrill -5 mil"); # 420 "pcb-menu.res" char *s = N_("Alt-Shift-S"); # 420 "pcb-menu.res" char *s = N_("Alt Shifts"); # 421 "pcb-menu.res" char *s = N_("Text Tool scale +10 mil"); # 421 "pcb-menu.res" char *s = N_("T"); # 421 "pcb-menu.res" char *s = N_("t"); # 422 "pcb-menu.res" char *s = N_("Text Tool scale -10 mil"); # 422 "pcb-menu.res" char *s = N_("Shift-T"); # 422 "pcb-menu.res" char *s = N_("Shiftt"); # 423 "pcb-menu.res" char *s = N_("Via Tool size +5 mil"); # 423 "pcb-menu.res" char *s = N_("Shift-V"); # 423 "pcb-menu.res" char *s = N_("Shiftv"); # 424 "pcb-menu.res" char *s = N_("Via Tool size -5 mil"); # 424 "pcb-menu.res" char *s = N_("Shift-Ctrl-V"); # 424 "pcb-menu.res" char *s = N_("Shift Ctrlv"); # 425 "pcb-menu.res" char *s = N_("Via Tool drill +5 mil"); # 425 "pcb-menu.res" char *s = N_("Alt-V"); # 425 "pcb-menu.res" char *s = N_("Altv"); # 426 "pcb-menu.res" char *s = N_("Via Tool drill -5 mil"); # 426 "pcb-menu.res" char *s = N_("Alt-Shift-V"); # 426 "pcb-menu.res" char *s = N_("Alt Shiftv"); # 427 "pcb-menu.res" char *s = N_("AddRats Selected"); # 427 "pcb-menu.res" char *s = N_("Shift-W"); # 427 "pcb-menu.res" char *s = N_("Shiftw"); # 428 "pcb-menu.res" char *s = N_("Add All Rats"); # 428 "pcb-menu.res" char *s = N_("W"); # 428 "pcb-menu.res" char *s = N_("w"); # 429 "pcb-menu.res" char *s = N_("Undo"); # 429 "pcb-menu.res" char *s = N_("Alt-Z"); # 429 "pcb-menu.res" char *s = N_("Altz"); # 430 "pcb-menu.res" char *s = N_("Cycle Clip"); # 430 "pcb-menu.res" char *s = N_("/"); # 430 "pcb-menu.res" char *s = N_("/"); # 431 "pcb-menu.res" char *s = N_("Space"); # 431 "pcb-menu.res" char *s = N_("space"); # 432 "pcb-menu.res" char *s = N_("Temp Arrow ON"); # 432 "pcb-menu.res" char *s = N_("["); # 432 "pcb-menu.res" char *s = N_("["); # 433 "pcb-menu.res" char *s = N_("Temp Arrow OFF"); # 433 "pcb-menu.res" char *s = N_("]"); # 433 "pcb-menu.res" char *s = N_("]"); # 435 "pcb-menu.res" char *s = N_("Step Up"); # 439 "pcb-menu.res" char *s = N_("Up"); # 435 "pcb-menu.res" char *s = N_("Up"); # 436 "pcb-menu.res" char *s = N_("Step Down"); # 440 "pcb-menu.res" char *s = N_("Down"); # 436 "pcb-menu.res" char *s = N_("Down"); # 437 "pcb-menu.res" char *s = N_("Step Left"); # 441 "pcb-menu.res" char *s = N_("Left"); # 437 "pcb-menu.res" char *s = N_("Left"); # 438 "pcb-menu.res" char *s = N_("Step Right"); # 442 "pcb-menu.res" char *s = N_("Right"); # 438 "pcb-menu.res" char *s = N_("Right"); # 439 "pcb-menu.res" char *s = N_("Step +Up"); # 439 "pcb-menu.res" char *s = N_("ShiftUp"); # 440 "pcb-menu.res" char *s = N_("Step +Down"); # 440 "pcb-menu.res" char *s = N_("ShiftDown"); # 441 "pcb-menu.res" char *s = N_("Step +Left"); # 441 "pcb-menu.res" char *s = N_("ShiftLeft"); # 442 "pcb-menu.res" char *s = N_("Step +Right"); # 442 "pcb-menu.res" char *s = N_("ShiftRight"); # 443 "pcb-menu.res" char *s = N_("Click"); # 443 "pcb-menu.res" char *s = N_("Enter"); # 443 "pcb-menu.res" char *s = N_("Enter"); # 447 "pcb-menu.res" char *s = N_("Board Layout"); # 448 "pcb-menu.res" char *s = N_("Library"); # 449 "pcb-menu.res" char *s = N_("Message Log"); # 450 "pcb-menu.res" char *s = N_("Netlist"); # 451 "pcb-menu.res" char *s = N_("Pinout"); pcb-4.3.0/src/dbus.xml0000664000175000017500000000147213773431044011465 00000000000000 pcb-4.3.0/src/buffer.c0000664000175000017500000012433713773431044011431 00000000000000/*! * \file src/buffer.c * * \brief Functions used by paste- and move/copy buffer. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996, 2005 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * Thomas.Nau@rz.uni-ulm.de * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "global.h" #include "buffer.h" #include "copy.h" #include "create.h" #include "crosshair.h" #include "data.h" #include "error.h" #include "flags.h" #include "mymem.h" #include "mirror.h" #include "misc.h" #include "parse_l.h" #include "polygon.h" #include "rats.h" #include "rotate.h" #include "remove.h" #include "rtree.h" #include "search.h" #include "select.h" #include "set.h" #ifdef HAVE_LIBDMALLOC #include #endif /* --------------------------------------------------------------------------- * some local prototypes */ static void *AddViaToBuffer (PinType *); static void *AddLineToBuffer (LayerType *, LineType *); static void *AddArcToBuffer (LayerType *, ArcType *); static void *AddRatToBuffer (RatType *); static void *AddTextToBuffer (LayerType *, TextType *); static void *AddPolygonToBuffer (LayerType *, PolygonType *); static void *AddElementToBuffer (ElementType *); static void *MoveViaToBuffer (PinType *); static void *MoveLineToBuffer (LayerType *, LineType *); static void *MoveArcToBuffer (LayerType *, ArcType *); static void *MoveRatToBuffer (RatType *); static void *MoveTextToBuffer (LayerType *, TextType *); static void *MovePolygonToBuffer (LayerType *, PolygonType *); static void *MoveElementToBuffer (ElementType *); static void SwapBuffer (BufferType *); /* --------------------------------------------------------------------------- * some local identifiers */ static DataType *Dest, *Source; static ObjectFunctionType AddBufferFunctions = { AddLineToBuffer, AddTextToBuffer, AddPolygonToBuffer, AddViaToBuffer, AddElementToBuffer, NULL, NULL, NULL, NULL, NULL, AddArcToBuffer, AddRatToBuffer }, MoveBufferFunctions = { MoveLineToBuffer, MoveTextToBuffer, MovePolygonToBuffer, MoveViaToBuffer, MoveElementToBuffer, NULL, NULL, NULL, NULL, NULL, MoveArcToBuffer, MoveRatToBuffer}; static int ExtraFlag = 0; /*! * \brief Copies a via to paste buffer. */ static void * AddViaToBuffer (PinType *Via) { return (CreateNewViaEx (Dest, Via->X, Via->Y, Via->Thickness, Via->Clearance, Via->Mask, Via->DrillingHole, Via->Name, MaskFlags (Via->Flags, NOCOPY_FLAGS | ExtraFlag), Via->BuriedFrom, Via->BuriedTo)); } /*! * \brief Copies a rat-line to paste buffer. */ static void * AddRatToBuffer (RatType *Rat) { return (CreateNewRat (Dest, Rat->Point1.X, Rat->Point1.Y, Rat->Point2.X, Rat->Point2.Y, Rat->group1, Rat->group2, Rat->Thickness, MaskFlags (Rat->Flags, NOCOPY_FLAGS | ExtraFlag))); } /*! * \brief Copies a line to buffer. */ static void * AddLineToBuffer (LayerType *Layer, LineType *Line) { LineType *line; LayerType *layer = &Dest->Layer[GetLayerNumber (Source, Layer)]; line = CreateNewLineOnLayer (layer, Line->Point1.X, Line->Point1.Y, Line->Point2.X, Line->Point2.Y, Line->Thickness, Line->Clearance, MaskFlags (Line->Flags, NOCOPY_FLAGS | ExtraFlag)); if (line && Line->Number) line->Number = strdup (Line->Number); return (line); } /*! * \brief Copies an arc to buffer. */ static void * AddArcToBuffer (LayerType *Layer, ArcType *Arc) { LayerType *layer = &Dest->Layer[GetLayerNumber (Source, Layer)]; return (CreateNewArcOnLayer (layer, Arc->X, Arc->Y, Arc->Width, Arc->Height, Arc->StartAngle, Arc->Delta, Arc->Thickness, Arc->Clearance, MaskFlags (Arc->Flags, NOCOPY_FLAGS | ExtraFlag))); } /*! * \brief Copies a text to buffer. */ static void * AddTextToBuffer (LayerType *Layer, TextType *Text) { LayerType *layer = &Dest->Layer[GetLayerNumber (Source, Layer)]; return (CreateNewText (layer, &PCB->Font, Text->X, Text->Y, Text->Direction, Text->Scale, Text->TextString, MaskFlags (Text->Flags, ExtraFlag))); } /*! * \brief Copies a polygon to buffer. */ static void * AddPolygonToBuffer (LayerType *Layer, PolygonType *Polygon) { LayerType *layer = &Dest->Layer[GetLayerNumber (Source, Layer)]; PolygonType *polygon; polygon = CreateNewPolygon (layer, Polygon->Flags); CopyPolygonLowLevel (polygon, Polygon); /* Update the polygon r-tree. Unlike similarly named functions for * other objects, CreateNewPolygon does not do this as it creates a * skeleton polygon object, which won't have correct bounds. */ if (!layer->polygon_tree) layer->polygon_tree = r_create_tree (NULL, 0, 0); r_insert_entry (layer->polygon_tree, (BoxType *)polygon, 0); CLEAR_FLAG (NOCOPY_FLAGS | ExtraFlag, polygon); return (polygon); } /*! * \brief Copies a element to buffer. */ static void * AddElementToBuffer (ElementType *Element) { return CopyElementLowLevel (Dest, Element, false, 0, 0, NOCOPY_FLAGS | ExtraFlag); } /*! * \brief Moves a via to paste buffer without allocating memory for the * name. */ static void * MoveViaToBuffer (PinType *via) { RestoreToPolygon (Source, VIA_TYPE, via, via); r_delete_entry (Source->via_tree, (BoxType *) via); Source->Via = g_list_remove (Source->Via, via); Source->ViaN --; Dest->Via = g_list_append (Dest->Via, via); Dest->ViaN ++; CLEAR_FLAG (WARNFLAG | NOCOPY_FLAGS, via); if (!Dest->via_tree) Dest->via_tree = r_create_tree (NULL, 0, 0); r_insert_entry (Dest->via_tree, (BoxType *)via, 0); ClearFromPolygon (Dest, VIA_TYPE, via, via); return via; } /*! * \brief Moves a rat-line to paste buffer. */ static void * MoveRatToBuffer (RatType *rat) { r_delete_entry (Source->rat_tree, (BoxType *)rat); Source->Rat = g_list_remove (Source->Rat, rat); Source->RatN --; Dest->Rat = g_list_append (Dest->Rat, rat); Dest->RatN ++; CLEAR_FLAG (NOCOPY_FLAGS, rat); if (!Dest->rat_tree) Dest->rat_tree = r_create_tree (NULL, 0, 0); r_insert_entry (Dest->rat_tree, (BoxType *)rat, 0); return rat; } /*! * \brief Moves a line to buffer. */ static void * MoveLineToBuffer (LayerType *layer, LineType *line) { LayerType *lay = &Dest->Layer[GetLayerNumber (Source, layer)]; RestoreToPolygon (Source, LINE_TYPE, layer, line); r_delete_entry (layer->line_tree, (BoxType *)line); layer->Line = g_list_remove (layer->Line, line); layer->LineN --; lay->Line = g_list_append (lay->Line, line); lay->LineN ++; CLEAR_FLAG (NOCOPY_FLAGS, line); if (!lay->line_tree) lay->line_tree = r_create_tree (NULL, 0, 0); r_insert_entry (lay->line_tree, (BoxType *)line, 0); ClearFromPolygon (Dest, LINE_TYPE, lay, line); return (line); } /*! * \brief Moves an arc to buffer. */ static void * MoveArcToBuffer (LayerType *layer, ArcType *arc) { LayerType *lay = &Dest->Layer[GetLayerNumber (Source, layer)]; RestoreToPolygon (Source, ARC_TYPE, layer, arc); r_delete_entry (layer->arc_tree, (BoxType *)arc); layer->Arc = g_list_remove (layer->Arc, arc); layer->ArcN --; lay->Arc = g_list_append (lay->Arc, arc); lay->ArcN ++; CLEAR_FLAG (NOCOPY_FLAGS, arc); if (!lay->arc_tree) lay->arc_tree = r_create_tree (NULL, 0, 0); r_insert_entry (lay->arc_tree, (BoxType *)arc, 0); ClearFromPolygon (Dest, ARC_TYPE, lay, arc); return (arc); } /*! * \brief Moves a text to buffer without allocating memory for the name. */ static void * MoveTextToBuffer (LayerType *layer, TextType *text) { LayerType *lay = &Dest->Layer[GetLayerNumber (Source, layer)]; r_delete_entry (layer->text_tree, (BoxType *)text); RestoreToPolygon (Source, TEXT_TYPE, layer, text); layer->Text = g_list_remove (layer->Text, text); layer->TextN --; lay->Text = g_list_append (lay->Text, text); lay->TextN ++; if (!lay->text_tree) lay->text_tree = r_create_tree (NULL, 0, 0); r_insert_entry (lay->text_tree, (BoxType *)text, 0); ClearFromPolygon (Dest, TEXT_TYPE, lay, text); return (text); } /*! * \brief Moves a polygon to buffer. * * Doesn't allocate memory for the points. */ static void * MovePolygonToBuffer (LayerType *layer, PolygonType *polygon) { LayerType *lay = &Dest->Layer[GetLayerNumber (Source, layer)]; r_delete_entry (layer->polygon_tree, (BoxType *)polygon); layer->Polygon = g_list_remove (layer->Polygon, polygon); layer->PolygonN --; lay->Polygon = g_list_append (lay->Polygon, polygon); lay->PolygonN ++; CLEAR_FLAG (NOCOPY_FLAGS, polygon); if (!lay->polygon_tree) lay->polygon_tree = r_create_tree (NULL, 0, 0); r_insert_entry (lay->polygon_tree, (BoxType *)polygon, 0); return (polygon); } /*! * \brief Moves a element to buffer without allocating memory for * pins/names. */ static void * MoveElementToBuffer (ElementType *element) { /* * Delete the element from the source (remove it from trees, * restore to polygons) */ r_delete_element (Source, element); Source->Element = g_list_remove (Source->Element, element); Source->ElementN --; Dest->Element = g_list_append (Dest->Element, element); Dest->ElementN ++; PIN_LOOP (element); { RestoreToPolygon(Source, PIN_TYPE, element, pin); CLEAR_FLAG (WARNFLAG | NOCOPY_FLAGS, pin); } END_LOOP; PAD_LOOP (element); { RestoreToPolygon(Source, PAD_TYPE, element, pad); CLEAR_FLAG (WARNFLAG | NOCOPY_FLAGS, pad); } END_LOOP; SetElementBoundingBox (Dest, element, &PCB->Font); /* * Now clear the from the polygons in the destination */ PIN_LOOP (element); { ClearFromPolygon (Dest, PIN_TYPE, element, pin); } END_LOOP; PAD_LOOP (element); { ClearFromPolygon (Dest, PAD_TYPE, element, pad); } END_LOOP; return element; } /*! * \brief Calculates the bounding box of the buffer. */ void SetBufferBoundingBox (BufferType *Buffer) { BoxType *box = GetDataBoundingBox (Buffer->Data); if (box) Buffer->BoundingBox = *box; } /*! * \brief Clears the contents of the paste buffer. */ void ClearBuffer (BufferType *Buffer) { if (Buffer && Buffer->Data) { FreeDataMemory (Buffer->Data); Buffer->Data->pcb = PCB; } } /*! * \brief Copies all selected and visible objects to the paste buffer. * * \return true if any objects have been removed. */ void AddSelectedToBuffer (BufferType *Buffer, Coord X, Coord Y, bool LeaveSelected) { /* switch crosshair off because adding objects to the pastebuffer * may change the 'valid' area for the cursor */ if (!LeaveSelected) ExtraFlag = SELECTEDFLAG; notify_crosshair_change (false); Source = PCB->Data; Dest = Buffer->Data; SelectedOperation (&AddBufferFunctions, false, ALL_TYPES); /* set origin to passed or current position */ if (X || Y) { Buffer->X = X; Buffer->Y = Y; } else { Buffer->X = Crosshair.X; Buffer->Y = Crosshair.Y; } notify_crosshair_change (true); ExtraFlag = 0; } /*! * \brief Loads element data from file/library into buffer. * * Parse the file with disabled 'PCB mode' (see parser). * * \return false on error, if successful, update some other stuff and * reposition the pastebuffer. */ bool LoadElementToBuffer (BufferType *Buffer, char *Name, bool FromFile) { ElementType *element; ClearBuffer (Buffer); if (FromFile) { if (!ParseElementFile (Buffer->Data, Name)) { if (Settings.ShowBottomSide) SwapBuffer (Buffer); SetBufferBoundingBox (Buffer); if (Buffer->Data->ElementN) { element = Buffer->Data->Element->data; Buffer->X = element->MarkX; Buffer->Y = element->MarkY; } else { Buffer->X = 0; Buffer->Y = 0; } return (true); } } else { if (!ParseLibraryEntry (Buffer->Data, Name) && Buffer->Data->ElementN != 0) { element = Buffer->Data->Element->data; /* always add elements using top-side coordinates */ if (Settings.ShowBottomSide) MirrorElementCoordinates (Buffer->Data, element, 0); SetElementBoundingBox (Buffer->Data, element, &PCB->Font); /* set buffer offset to 'mark' position */ Buffer->X = element->MarkX; Buffer->Y = element->MarkY; SetBufferBoundingBox (Buffer); return (true); } } /* release memory which might have been acquired */ ClearBuffer (Buffer); return (false); } typedef struct { char *footprint; int footprint_allocated; int menu_idx; int entry_idx; } FootprintHashEntry; static FootprintHashEntry *footprint_hash = 0; int footprint_hash_size = 0; void clear_footprint_hash () { int i; if (!footprint_hash) return; for (i=0; ifootprint, b->footprint); if (i == 0) i = a->menu_idx - b->menu_idx; if (i == 0) i = a->entry_idx - b->entry_idx; return i; } void make_footprint_hash () { int i, j; char *fp; int num_entries = 0; clear_footprint_hash (); for (i=0; i 1) { i = (min+max)/2; c = strcmp (footprint, footprint_hash[i].footprint); if (c < 0) max = i; else if (c > 0) min = i; else { /* We want to return the first match, not just any match. */ while (i > 0 && strcmp (footprint, footprint_hash[i-1].footprint) == 0) i--; return & footprint_hash[i]; } } return NULL; } /*! * \brief . * * \return zero on success, non-zero on error. */ int LoadFootprintByName (BufferType *Buffer, char *Footprint) { int i; FootprintHashEntry *fpe; LibraryMenuType *menu; LibraryEntryType *entry; char *with_fp = NULL; if (!footprint_hash) make_footprint_hash (); fpe = search_footprint_hash (Footprint); if (!fpe) { with_fp = Concat (Footprint, ".fp", NULL); fpe = search_footprint_hash (with_fp); if (fpe) Footprint = with_fp; } if (!fpe) { Message(_("Unable to load footprint %s\n"), Footprint); return 1; } menu = & Library.Menu[fpe->menu_idx]; entry = & menu->Entry[fpe->entry_idx]; if (entry->Template == (char *) -1) { i = LoadElementToBuffer (Buffer, entry->AllocatedMemory, true); if (with_fp) free (with_fp); return i ? 0 : 1; } else { char *args; args = Concat("'", EMPTY (entry->Template), "' '", EMPTY (entry->Value), "' '", EMPTY (entry->Package), "'", NULL); i = LoadElementToBuffer (Buffer, args, false); free (args); if (with_fp) free (with_fp); return i ? 0 : 1; } #ifdef DEBUG { int j; printf("Library path: %s\n", Settings.LibraryPath); printf("Library tree: %s\n", Settings.LibraryTree); printf("Library:\n"); for (i=0; iData->ElementN == 0) { Message(_("Footprint %s contains no elements"), name); return 1; } if (PASTEBUFFER->Data->ElementN > 1) { Message(_("Footprint %s contains multiple elements"), name); return 1; } e = PASTEBUFFER->Data->Element->data; if (e->Name[0].TextString) free (e->Name[0].TextString); e->Name[0].TextString = strdup (name); if (e->Name[1].TextString) free (e->Name[1].TextString); e->Name[1].TextString = refdes ? strdup (refdes) : 0; if (e->Name[2].TextString) free (e->Name[2].TextString); e->Name[2].TextString = value ? strdup (value) : 0; return 0; } /*! * \brief Break buffer element into pieces. */ bool SmashBufferElement (BufferType *Buffer) { ElementType *element; Cardinal group; LayerType *top_layer, *bottom_layer; if (Buffer->Data->ElementN != 1) { Message (_("Error! Buffer doesn't contain a single element\n")); return (false); } /* * At this point the buffer should contain just a single element. * Now we detach the single element from the buffer and then clear the * buffer, ready to receive the smashed elements. As a result of detaching * it the single element is orphaned from the buffer and thus will not be * free()'d by FreeDataMemory (called via ClearBuffer). This leaves it * around for us to smash bits off it. It then becomes our responsibility, * however, to free the single element when we're finished with it. */ element = Buffer->Data->Element->data; Buffer->Data->Element = NULL; Buffer->Data->ElementN = 0; ClearBuffer (Buffer); ELEMENTLINE_LOOP (element); { CreateNewLineOnLayer (&Buffer->Data->SILKLAYER, line->Point1.X, line->Point1.Y, line->Point2.X, line->Point2.Y, line->Thickness, 0, NoFlags ()); if (line) line->Number = STRDUP (NAMEONPCB_NAME (element)); } END_LOOP; ARC_LOOP (element); { CreateNewArcOnLayer (&Buffer->Data->SILKLAYER, arc->X, arc->Y, arc->Width, arc->Height, arc->StartAngle, arc->Delta, arc->Thickness, 0, NoFlags ()); } END_LOOP; PIN_LOOP (element); { FlagType f = NoFlags (); AddFlags (f, VIAFLAG); if (TEST_FLAG (HOLEFLAG, pin)) AddFlags (f, HOLEFLAG); CreateNewVia (Buffer->Data, pin->X, pin->Y, pin->Thickness, pin->Clearance, pin->Mask, pin->DrillingHole, pin->Number, f); } END_LOOP; group = GetLayerGroupNumberBySide (SWAP_IDENT ? BOTTOM_SIDE : TOP_SIDE); top_layer = &Buffer->Data->Layer[PCB->LayerGroups.Entries[group][0]]; group = GetLayerGroupNumberBySide (SWAP_IDENT ? TOP_SIDE : BOTTOM_SIDE); bottom_layer = &Buffer->Data->Layer[PCB->LayerGroups.Entries[group][0]]; PAD_LOOP (element); { LineType *line; line = CreateNewLineOnLayer (TEST_FLAG (ONSOLDERFLAG, pad) ? bottom_layer : top_layer, pad->Point1.X, pad->Point1.Y, pad->Point2.X, pad->Point2.Y, pad->Thickness, pad->Clearance, NoFlags ()); if (line) line->Number = STRDUP (pad->Number); } END_LOOP; FreeElementMemory (element); g_slice_free (ElementType, element); return (true); } /*! * \brief See if a polygon is a rectangle. * * If so, canonicalize it. */ static int polygon_is_rectangle (PolygonType *poly) { int i, best; PointType temp[4]; if (poly->PointN != 4 || poly->HoleIndexN != 0) return 0; best = 0; for (i=1; i<4; i++) if (poly->Points[i].X < poly->Points[best].X || poly->Points[i].Y < poly->Points[best].Y) best = i; for (i=0; i<4; i++) temp[i] = poly->Points[(i+best)%4]; if (temp[0].X == temp[1].X) memcpy (poly->Points, temp, sizeof(temp)); else { /* reverse them */ poly->Points[0] = temp[0]; poly->Points[1] = temp[3]; poly->Points[2] = temp[2]; poly->Points[3] = temp[1]; } if (poly->Points[0].X == poly->Points[1].X && poly->Points[1].Y == poly->Points[2].Y && poly->Points[2].X == poly->Points[3].X && poly->Points[3].Y == poly->Points[0].Y) return 1; return 0; } /*! * \brief Convert buffer contents into an element. */ bool ConvertBufferToElement (BufferType *Buffer) { ElementType *Element; Cardinal group; Cardinal pin_n = 1; bool hasParts = false, crooked = false; int onsolder; bool warned = false; if (Buffer->Data->pcb == 0) Buffer->Data->pcb = PCB; Element = CreateNewElement (PCB->Data, &PCB->Font, NoFlags (), NULL, NULL, NULL, PASTEBUFFER->X, PASTEBUFFER->Y, 0, 100, MakeFlags (SWAP_IDENT ? ONSOLDERFLAG : NOFLAG), false); if (!Element) return (false); VIA_LOOP (Buffer->Data); { char num[8]; if (via->Mask < via->Thickness) via->Mask = via->Thickness + 2 * MASKFRAME; if (via->Name) CreateNewPin (Element, via->X, via->Y, via->Thickness, via->Clearance, via->Mask, via->DrillingHole, NULL, via->Name, MaskFlags (via->Flags, VIAFLAG | NOCOPY_FLAGS | SELECTEDFLAG | WARNFLAG)); else { sprintf (num, "%d", pin_n++); CreateNewPin (Element, via->X, via->Y, via->Thickness, via->Clearance, via->Mask, via->DrillingHole, NULL, num, MaskFlags (via->Flags, VIAFLAG | NOCOPY_FLAGS | SELECTEDFLAG | WARNFLAG)); } hasParts = true; } END_LOOP; for (onsolder = 0; onsolder < 2; onsolder ++) { int side; int onsolderflag; if ((!onsolder) == (!SWAP_IDENT)) { side = TOP_SIDE; onsolderflag = NOFLAG; } else { side = BOTTOM_SIDE; onsolderflag = ONSOLDERFLAG; } #define MAYBE_WARN() \ if (onsolder && !hasParts && !warned) \ { \ warned = true; \ Message \ (_("Warning: All of the pads are on the opposite\n" \ "side from the component - that's probably not what\n" \ "you wanted\n")); \ } \ /* get the component-side SM pads */ group = GetLayerGroupNumberBySide (side); GROUP_LOOP (Buffer->Data, group); { char num[8]; LINE_LOOP (layer); { sprintf (num, "%d", pin_n++); CreateNewPad (Element, line->Point1.X, line->Point1.Y, line->Point2.X, line->Point2.Y, line->Thickness, line->Clearance, line->Thickness + line->Clearance, NULL, line->Number ? line->Number : num, MakeFlags (onsolderflag)); MAYBE_WARN(); hasParts = true; } END_LOOP; POLYGON_LOOP (layer); { Coord x1, y1, x2, y2, w, h, t; if (! polygon_is_rectangle (polygon)) { crooked = true; continue; } w = polygon->Points[2].X - polygon->Points[0].X; h = polygon->Points[1].Y - polygon->Points[0].Y; t = (w < h) ? w : h; x1 = polygon->Points[0].X + t/2; y1 = polygon->Points[0].Y + t/2; x2 = x1 + (w-t); y2 = y1 + (h-t); sprintf (num, "%d", pin_n++); CreateNewPad (Element, x1, y1, x2, y2, t, 2 * Settings.Keepaway, t + Settings.Keepaway, NULL, num, MakeFlags (SQUAREFLAG | onsolderflag)); MAYBE_WARN(); hasParts = true; } END_LOOP; } END_LOOP; } /* now add the silkscreen. NOTE: elements must have pads or pins too */ LINE_LOOP (&Buffer->Data->SILKLAYER); { if (line->Number && !NAMEONPCB_NAME (Element)) NAMEONPCB_NAME (Element) = strdup (line->Number); CreateNewLineInElement (Element, line->Point1.X, line->Point1.Y, line->Point2.X, line->Point2.Y, line->Thickness); hasParts = true; } END_LOOP; ARC_LOOP (&Buffer->Data->SILKLAYER); { CreateNewArcInElement (Element, arc->X, arc->Y, arc->Width, arc->Height, arc->StartAngle, arc->Delta, arc->Thickness); hasParts = true; } END_LOOP; if (!hasParts) { DestroyObject (PCB->Data, ELEMENT_TYPE, Element, Element, Element); Message (_("There was nothing to convert!\n" "Elements must have some silk, pads or pins.\n")); return (false); } if (crooked) Message (_("There were polygons that can't be made into pins!\n" "So they were not included in the element\n")); Element->MarkX = Buffer->X; Element->MarkY = Buffer->Y; if (SWAP_IDENT) SET_FLAG (ONSOLDERFLAG, Element); SetElementBoundingBox (PCB->Data, Element, &PCB->Font); ClearBuffer (Buffer); MoveObjectToBuffer (Buffer->Data, PCB->Data, ELEMENT_TYPE, Element, Element, Element); SetBufferBoundingBox (Buffer); return (true); } /*! * \brief Load PCB into buffer. * * Parse the file with enabled 'PCB mode' (see parser). * If successful, update some other stuff. */ bool LoadLayoutToBuffer (BufferType *Buffer, char *Filename) { PCBType *newPCB = CreateNewPCB (); /* new data isn't added to the undo list */ if (!ParsePCB (newPCB, Filename)) { /* clear data area and replace pointer */ ClearBuffer (Buffer); free (Buffer->Data); Buffer->Data = newPCB->Data; newPCB->Data = NULL; Buffer->X = newPCB->CursorX; Buffer->Y = newPCB->CursorY; RemovePCB (newPCB); Buffer->Data->pcb = PCB; return (true); } /* release unused memory */ RemovePCB (newPCB); Buffer->Data->pcb = PCB; return (false); } /*! * \brief Rotates the contents of the pastebuffer. */ void RotateBuffer (BufferType *Buffer, BYTE Number) { /* rotate vias */ VIA_LOOP (Buffer->Data); { r_delete_entry (Buffer->Data->via_tree, (BoxType *)via); ROTATE_VIA_LOWLEVEL (via, Buffer->X, Buffer->Y, Number); SetPinBoundingBox (via); r_insert_entry (Buffer->Data->via_tree, (BoxType *)via, 0); } END_LOOP; /* elements */ ELEMENT_LOOP (Buffer->Data); { RotateElementLowLevel (Buffer->Data, element, Buffer->X, Buffer->Y, Number); } END_LOOP; /* all layer related objects */ ALLLINE_LOOP (Buffer->Data); { r_delete_entry (layer->line_tree, (BoxType *)line); RotateLineLowLevel (line, Buffer->X, Buffer->Y, Number); r_insert_entry (layer->line_tree, (BoxType *)line, 0); } ENDALL_LOOP; ALLARC_LOOP (Buffer->Data); { r_delete_entry (layer->arc_tree, (BoxType *)arc); RotateArcLowLevel (arc, Buffer->X, Buffer->Y, Number); r_insert_entry (layer->arc_tree, (BoxType *)arc, 0); } ENDALL_LOOP; ALLTEXT_LOOP (Buffer->Data); { r_delete_entry (layer->text_tree, (BoxType *)text); RotateTextLowLevel (text, Buffer->X, Buffer->Y, Number); r_insert_entry (layer->text_tree, (BoxType *)text, 0); } ENDALL_LOOP; ALLPOLYGON_LOOP (Buffer->Data); { r_delete_entry (layer->polygon_tree, (BoxType *)polygon); RotatePolygonLowLevel (polygon, Buffer->X, Buffer->Y, Number); r_insert_entry (layer->polygon_tree, (BoxType *)polygon, 0); } ENDALL_LOOP; /* finally the origin and the bounding box */ ROTATE (Buffer->X, Buffer->Y, Buffer->X, Buffer->Y, Number); RotateBoxLowLevel (&Buffer->BoundingBox, Buffer->X, Buffer->Y, Number); crosshair_update_range(); } static void free_rotate (Coord *x, Coord *y, Coord cx, Coord cy, double cosa, double sina) { double nx, ny; Coord px = *x - cx; Coord py = *y - cy; nx = px * cosa + py * sina; ny = py * cosa - px * sina; *x = nx + cx; *y = ny + cy; } void FreeRotateElementLowLevel (DataType *Data, ElementType *Element, Coord X, Coord Y, double cosa, double sina, Angle angle) { /* solder side objects need a different orientation */ /* the text subroutine decides by itself if the direction * is to be corrected */ #if 0 ELEMENTTEXT_LOOP (Element); { if (Data && Data->name_tree[n]) r_delete_entry (Data->name_tree[n], (BoxType *)text); RotateTextLowLevel (text, X, Y, Number); } END_LOOP; #endif ELEMENTLINE_LOOP (Element); { free_rotate (&line->Point1.X, &line->Point1.Y, X, Y, cosa, sina); free_rotate (&line->Point2.X, &line->Point2.Y, X, Y, cosa, sina); SetLineBoundingBox (line); } END_LOOP; PIN_LOOP (Element); { /* pre-delete the pins from the pin-tree before their coordinates change */ if (Data) r_delete_entry (Data->pin_tree, (BoxType *)pin); RestoreToPolygon (Data, PIN_TYPE, Element, pin); free_rotate (&pin->X, &pin->Y, X, Y, cosa, sina); SetPinBoundingBox (pin); } END_LOOP; PAD_LOOP (Element); { /* pre-delete the pads before their coordinates change */ if (Data) r_delete_entry (Data->pad_tree, (BoxType *)pad); RestoreToPolygon (Data, PAD_TYPE, Element, pad); free_rotate (&pad->Point1.X, &pad->Point1.Y, X, Y, cosa, sina); free_rotate (&pad->Point2.X, &pad->Point2.Y, X, Y, cosa, sina); SetLineBoundingBox ((LineType *) pad); } END_LOOP; ARC_LOOP (Element); { free_rotate (&arc->X, &arc->Y, X, Y, cosa, sina); arc->StartAngle = NormalizeAngle (arc->StartAngle + angle); } END_LOOP; free_rotate (&Element->MarkX, &Element->MarkY, X, Y, cosa, sina); SetElementBoundingBox (Data, Element, &PCB->Font); ClearFromPolygon (Data, ELEMENT_TYPE, Element, Element); } void FreeRotateBuffer (BufferType *Buffer, Angle angle) { double cosa, sina; cosa = cos(angle * M_PI/180.0); sina = sin(angle * M_PI/180.0); /* rotate vias */ VIA_LOOP (Buffer->Data); { r_delete_entry (Buffer->Data->via_tree, (BoxType *)via); free_rotate (&via->X, &via->Y, Buffer->X, Buffer->Y, cosa, sina); SetPinBoundingBox (via); r_insert_entry (Buffer->Data->via_tree, (BoxType *)via, 0); } END_LOOP; /* elements */ ELEMENT_LOOP (Buffer->Data); { FreeRotateElementLowLevel (Buffer->Data, element, Buffer->X, Buffer->Y, cosa, sina, angle); } END_LOOP; /* all layer related objects */ ALLLINE_LOOP (Buffer->Data); { r_delete_entry (layer->line_tree, (BoxType *)line); free_rotate (&line->Point1.X, &line->Point1.Y, Buffer->X, Buffer->Y, cosa, sina); free_rotate (&line->Point2.X, &line->Point2.Y, Buffer->X, Buffer->Y, cosa, sina); SetLineBoundingBox (line); r_insert_entry (layer->line_tree, (BoxType *)line, 0); } ENDALL_LOOP; ALLARC_LOOP (Buffer->Data); { r_delete_entry (layer->arc_tree, (BoxType *)arc); free_rotate (&arc->X, &arc->Y, Buffer->X, Buffer->Y, cosa, sina); arc->StartAngle = NormalizeAngle (arc->StartAngle + angle); r_insert_entry (layer->arc_tree, (BoxType *)arc, 0); } ENDALL_LOOP; /* FIXME: rotate text */ ALLPOLYGON_LOOP (Buffer->Data); { r_delete_entry (layer->polygon_tree, (BoxType *)polygon); POLYGONPOINT_LOOP (polygon); { free_rotate (&point->X, &point->Y, Buffer->X, Buffer->Y, cosa, sina); } END_LOOP; SetPolygonBoundingBox (polygon); r_insert_entry (layer->polygon_tree, (BoxType *)polygon, 0); } ENDALL_LOOP; SetBufferBoundingBox (Buffer); crosshair_update_range(); } /* -------------------------------------------------------------------------- */ static const char freerotatebuffer_syntax[] = N_("FreeRotateBuffer([Angle])"); static const char freerotatebuffer_help[] = N_("Rotates the current paste buffer contents by the specified angle. The\n" "angle is given in degrees. If no angle is given, the user is prompted\n" "for one.\n"); /* %start-doc actions FreeRotateBuffer Rotates the contents of the pastebuffer by an arbitrary angle. If no angle is given, the user is prompted for one. %end-doc */ int ActionFreeRotateBuffer(int argc, char **argv, Coord x, Coord y) { char *angle_s; if (argc < 1) angle_s = gui->prompt_for (_("Enter Rotation (degrees, CCW):"), "0"); else angle_s = argv[0]; notify_crosshair_change (false); FreeRotateBuffer(PASTEBUFFER, strtod(angle_s, 0)); notify_crosshair_change (true); return 0; } /*! * \brief Initializes the buffers by allocating memory. */ void InitBuffers (void) { int i; for (i = 0; i < MAX_BUFFER; i++) Buffers[i].Data = CreateNewBuffer (); } void UninitBuffers (void) { int i; for (i = 0; i < MAX_BUFFER; i++) { ClearBuffer (Buffers+i); free (Buffers[i].Data); } } void SwapBuffers (void) { int i; for (i = 0; i < MAX_BUFFER; i++) SwapBuffer (&Buffers[i]); crosshair_update_range(); } void MirrorBuffer (BufferType *Buffer) { int i; if (Buffer->Data->ElementN) { Message (_("You can't mirror a buffer that has elements!\n")); return; } for (i = 0; i < max_copper_layer + SILK_LAYER; i++) { LayerType *layer = Buffer->Data->Layer + i; if (layer->TextN) { Message (_("You can't mirror a buffer that has text!\n")); return; } } /* set buffer offset to 'mark' position */ Buffer->X = SWAP_X (Buffer->X); Buffer->Y = SWAP_Y (Buffer->Y); VIA_LOOP (Buffer->Data); { via->X = SWAP_X (via->X); via->Y = SWAP_Y (via->Y); } END_LOOP; ALLLINE_LOOP (Buffer->Data); { line->Point1.X = SWAP_X (line->Point1.X); line->Point1.Y = SWAP_Y (line->Point1.Y); line->Point2.X = SWAP_X (line->Point2.X); line->Point2.Y = SWAP_Y (line->Point2.Y); } ENDALL_LOOP; ALLARC_LOOP (Buffer->Data); { r_delete_entry(layer->arc_tree, (BoxType*)arc); arc->X = SWAP_X (arc->X); arc->Y = SWAP_Y (arc->Y); arc->StartAngle = SWAP_ANGLE (arc->StartAngle); arc->Delta = SWAP_DELTA (arc->Delta); SetArcBoundingBox (arc); r_insert_entry(layer->arc_tree, (BoxType*)arc, 0); } ENDALL_LOOP; ALLPOLYGON_LOOP (Buffer->Data); { r_delete_entry(layer->polygon_tree, (BoxType*)polygon); POLYGONPOINT_LOOP (polygon); { point->X = SWAP_X (point->X); point->Y = SWAP_Y (point->Y); } END_LOOP; SetPolygonBoundingBox (polygon); r_insert_entry(layer->polygon_tree, (BoxType*)polygon, 0); } ENDALL_LOOP; SetBufferBoundingBox (Buffer); crosshair_update_range(); } /*! * \brief Flip components/tracks from one side to the other. */ static void SwapBuffer (BufferType *Buffer) { int j, k; Cardinal top_group, bottom_group; LayerType swap; ELEMENT_LOOP (Buffer->Data); { r_delete_element (Buffer->Data, element); MirrorElementCoordinates (Buffer->Data, element, 0); } END_LOOP; /* set buffer offset to 'mark' position */ Buffer->X = SWAP_X (Buffer->X); Buffer->Y = SWAP_Y (Buffer->Y); VIA_LOOP (Buffer->Data); { r_delete_entry (Buffer->Data->via_tree, (BoxType *)via); via->X = SWAP_X (via->X); via->Y = SWAP_Y (via->Y); SetPinBoundingBox (via); r_insert_entry (Buffer->Data->via_tree, (BoxType *)via, 0); } END_LOOP; ALLLINE_LOOP (Buffer->Data); { r_delete_entry (layer->line_tree, (BoxType *)line); line->Point1.X = SWAP_X (line->Point1.X); line->Point1.Y = SWAP_Y (line->Point1.Y); line->Point2.X = SWAP_X (line->Point2.X); line->Point2.Y = SWAP_Y (line->Point2.Y); SetLineBoundingBox (line); r_insert_entry (layer->line_tree, (BoxType *)line, 0); } ENDALL_LOOP; ALLARC_LOOP (Buffer->Data); { r_delete_entry (layer->arc_tree, (BoxType *)arc); arc->X = SWAP_X (arc->X); arc->Y = SWAP_Y (arc->Y); arc->StartAngle = SWAP_ANGLE (arc->StartAngle); arc->Delta = SWAP_DELTA (arc->Delta); SetArcBoundingBox (arc); r_insert_entry (layer->arc_tree, (BoxType *)arc, 0); } ENDALL_LOOP; ALLPOLYGON_LOOP (Buffer->Data); { r_delete_entry (layer->polygon_tree, (BoxType *)polygon); POLYGONPOINT_LOOP (polygon); { point->X = SWAP_X (point->X); point->Y = SWAP_Y (point->Y); } END_LOOP; SetPolygonBoundingBox (polygon); r_insert_entry (layer->polygon_tree, (BoxType *)polygon, 0); /* hmmm, how to handle clip */ } ENDALL_LOOP; ALLTEXT_LOOP (Buffer->Data); { r_delete_entry (layer->text_tree, (BoxType *)text); text->X = SWAP_X (text->X); text->Y = SWAP_Y (text->Y); TOGGLE_FLAG (ONSOLDERFLAG, text); SetTextBoundingBox (&PCB->Font, text); r_insert_entry (layer->text_tree, (BoxType *)text, 0); } ENDALL_LOOP; /* swap silkscreen layers */ swap = Buffer->Data->Layer[bottom_silk_layer]; Buffer->Data->Layer[bottom_silk_layer] = Buffer->Data->Layer[top_silk_layer]; Buffer->Data->Layer[top_silk_layer] = swap; /* swap layer groups when balanced */ top_group = GetLayerGroupNumberBySide (TOP_SIDE); bottom_group = GetLayerGroupNumberBySide (BOTTOM_SIDE); if (PCB->LayerGroups.Number[top_group] == PCB->LayerGroups.Number[bottom_group]) { for (j = k = 0; j < PCB->LayerGroups.Number[bottom_group]; j++) { int t1, t2; Cardinal top_number = PCB->LayerGroups.Entries[top_group][k]; Cardinal bottom_number = PCB->LayerGroups.Entries[bottom_group][j]; if (bottom_number >= max_copper_layer) continue; swap = Buffer->Data->Layer[bottom_number]; while (top_number >= max_copper_layer) { k++; top_number = PCB->LayerGroups.Entries[top_group][k]; } Buffer->Data->Layer[bottom_number] = Buffer->Data->Layer[top_number]; Buffer->Data->Layer[top_number] = swap; k++; /* move the thermal flags with the layers */ ALLPIN_LOOP (Buffer->Data); { t1 = TEST_THERM (bottom_number, pin); t2 = TEST_THERM (top_number, pin); ASSIGN_THERM (bottom_number, t2, pin); ASSIGN_THERM (top_number, t1, pin); } ENDALL_LOOP; VIA_LOOP (Buffer->Data); { t1 = TEST_THERM (bottom_number, via); t2 = TEST_THERM (top_number, via); ASSIGN_THERM (bottom_number, t2, via); ASSIGN_THERM (top_number, t1, via); } END_LOOP; } } SetBufferBoundingBox (Buffer); crosshair_update_range(); } /*! * \brief Moves the passed object to the passed buffer and removes it * from its original place. */ void * MoveObjectToBuffer (DataType *Destination, DataType *Src, int Type, void *Ptr1, void *Ptr2, void *Ptr3) { /* setup local identifiers used by move operations */ Dest = Destination; Source = Src; return (ObjectOperation (&MoveBufferFunctions, Type, Ptr1, Ptr2, Ptr3)); } /*! * \brief Adds the passed object to the passed buffer. */ void * CopyObjectToBuffer (DataType *Destination, DataType *Src, int Type, void *Ptr1, void *Ptr2, void *Ptr3) { /* setup local identifiers used by Add operations */ Dest = Destination; Source = Src; return (ObjectOperation (&AddBufferFunctions, Type, Ptr1, Ptr2, Ptr3)); } /* ---------------------------------------------------------------------- */ HID_Action rotate_action_list[] = { {"FreeRotateBuffer", 0, ActionFreeRotateBuffer, freerotatebuffer_syntax, freerotatebuffer_help}, {"LoadFootprint", 0, LoadFootprint, loadfootprint_syntax, loadfootprint_help} }; REGISTER_ACTIONS (rotate_action_list) pcb-4.3.0/src/res_lex.c0000664000175000017500000014755213773432532011630 00000000000000#line 2 "res_lex.c" #line 4 "res_lex.c" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define yy_create_buffer res_create_buffer #define yy_delete_buffer res_delete_buffer #define yy_scan_buffer res_scan_buffer #define yy_scan_string res_scan_string #define yy_scan_bytes res_scan_bytes #define yy_init_buffer res_init_buffer #define yy_flush_buffer res_flush_buffer #define yy_load_buffer_state res_load_buffer_state #define yy_switch_to_buffer res_switch_to_buffer #define yypush_buffer_state respush_buffer_state #define yypop_buffer_state respop_buffer_state #define yyensure_buffer_stack resensure_buffer_stack #define yy_flex_debug res_flex_debug #define yyin resin #define yyleng resleng #define yylex reslex #define yylineno reslineno #define yyout resout #define yyrestart resrestart #define yytext restext #define yywrap reswrap #define yyalloc resalloc #define yyrealloc resrealloc #define yyfree resfree #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 6 #define YY_FLEX_SUBMINOR_VERSION 4 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif #ifdef yy_create_buffer #define res_create_buffer_ALREADY_DEFINED #else #define yy_create_buffer res_create_buffer #endif #ifdef yy_delete_buffer #define res_delete_buffer_ALREADY_DEFINED #else #define yy_delete_buffer res_delete_buffer #endif #ifdef yy_scan_buffer #define res_scan_buffer_ALREADY_DEFINED #else #define yy_scan_buffer res_scan_buffer #endif #ifdef yy_scan_string #define res_scan_string_ALREADY_DEFINED #else #define yy_scan_string res_scan_string #endif #ifdef yy_scan_bytes #define res_scan_bytes_ALREADY_DEFINED #else #define yy_scan_bytes res_scan_bytes #endif #ifdef yy_init_buffer #define res_init_buffer_ALREADY_DEFINED #else #define yy_init_buffer res_init_buffer #endif #ifdef yy_flush_buffer #define res_flush_buffer_ALREADY_DEFINED #else #define yy_flush_buffer res_flush_buffer #endif #ifdef yy_load_buffer_state #define res_load_buffer_state_ALREADY_DEFINED #else #define yy_load_buffer_state res_load_buffer_state #endif #ifdef yy_switch_to_buffer #define res_switch_to_buffer_ALREADY_DEFINED #else #define yy_switch_to_buffer res_switch_to_buffer #endif #ifdef yypush_buffer_state #define respush_buffer_state_ALREADY_DEFINED #else #define yypush_buffer_state respush_buffer_state #endif #ifdef yypop_buffer_state #define respop_buffer_state_ALREADY_DEFINED #else #define yypop_buffer_state respop_buffer_state #endif #ifdef yyensure_buffer_stack #define resensure_buffer_stack_ALREADY_DEFINED #else #define yyensure_buffer_stack resensure_buffer_stack #endif #ifdef yylex #define reslex_ALREADY_DEFINED #else #define yylex reslex #endif #ifdef yyrestart #define resrestart_ALREADY_DEFINED #else #define yyrestart resrestart #endif #ifdef yylex_init #define reslex_init_ALREADY_DEFINED #else #define yylex_init reslex_init #endif #ifdef yylex_init_extra #define reslex_init_extra_ALREADY_DEFINED #else #define yylex_init_extra reslex_init_extra #endif #ifdef yylex_destroy #define reslex_destroy_ALREADY_DEFINED #else #define yylex_destroy reslex_destroy #endif #ifdef yyget_debug #define resget_debug_ALREADY_DEFINED #else #define yyget_debug resget_debug #endif #ifdef yyset_debug #define resset_debug_ALREADY_DEFINED #else #define yyset_debug resset_debug #endif #ifdef yyget_extra #define resget_extra_ALREADY_DEFINED #else #define yyget_extra resget_extra #endif #ifdef yyset_extra #define resset_extra_ALREADY_DEFINED #else #define yyset_extra resset_extra #endif #ifdef yyget_in #define resget_in_ALREADY_DEFINED #else #define yyget_in resget_in #endif #ifdef yyset_in #define resset_in_ALREADY_DEFINED #else #define yyset_in resset_in #endif #ifdef yyget_out #define resget_out_ALREADY_DEFINED #else #define yyget_out resget_out #endif #ifdef yyset_out #define resset_out_ALREADY_DEFINED #else #define yyset_out resset_out #endif #ifdef yyget_leng #define resget_leng_ALREADY_DEFINED #else #define yyget_leng resget_leng #endif #ifdef yyget_text #define resget_text_ALREADY_DEFINED #else #define yyget_text resget_text #endif #ifdef yyget_lineno #define resget_lineno_ALREADY_DEFINED #else #define yyget_lineno resget_lineno #endif #ifdef yyset_lineno #define resset_lineno_ALREADY_DEFINED #else #define yyset_lineno resset_lineno #endif #ifdef yywrap #define reswrap_ALREADY_DEFINED #else #define yywrap reswrap #endif #ifdef yyalloc #define resalloc_ALREADY_DEFINED #else #define yyalloc resalloc #endif #ifdef yyrealloc #define resrealloc_ALREADY_DEFINED #else #define yyrealloc resrealloc #endif #ifdef yyfree #define resfree_ALREADY_DEFINED #else #define yyfree resfree #endif #ifdef yytext #define restext_ALREADY_DEFINED #else #define yytext restext #endif #ifdef yyleng #define resleng_ALREADY_DEFINED #else #define yyleng resleng #endif #ifdef yyin #define resin_ALREADY_DEFINED #else #define yyin resin #endif #ifdef yyout #define resout_ALREADY_DEFINED #else #define yyout resout #endif #ifdef yy_flex_debug #define res_flex_debug_ALREADY_DEFINED #else #define yy_flex_debug res_flex_debug #endif #ifdef yylineno #define reslineno_ALREADY_DEFINED #else #define yylineno reslineno #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #ifndef SIZE_MAX #define SIZE_MAX (~(size_t)0) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ /* TODO: this is always defined, so inline it */ #define yyconst const #if defined(__GNUC__) && __GNUC__ >= 3 #define yynoreturn __attribute__((__noreturn__)) #else #define yynoreturn #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an * integer in range [0..255] for use as an array index. */ #define YY_SC_TO_UI(c) ((YY_CHAR) (c)) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart( yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k. * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. * Ditto for the __ia64__ case accordingly. */ #define YY_BUF_SIZE 32768 #else #define YY_BUF_SIZE 16384 #endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif extern int yyleng; extern FILE *yyin, *yyout; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires * access to the local variable yy_act. Since yyless() is a macro, it would break * existing scanners that call yyless() from OUTSIDE yylex. * One obvious solution it to make yy_act a global. I tried that, and saw * a 5% performance hit in a non-yylineno scanner, because yy_act is * normally declared as a register variable-- so it is not worth it. */ #define YY_LESS_LINENO(n) \ do { \ int yyl;\ for ( yyl = n; yyl < yyleng; ++yyl )\ if ( yytext[yyl] == '\n' )\ --yylineno;\ }while(0) #define YY_LINENO_REWIND_TO(dst) \ do {\ const char *p;\ for ( p = yy_cp-1; p >= (dst); --p)\ if ( *p == '\n' )\ --yylineno;\ }while(0) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ int yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* Stack of input buffers. */ static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] /* yy_hold_char holds the character lost when yytext is formed. */ static char yy_hold_char; static int yy_n_chars; /* number of characters read into yy_ch_buf */ int yyleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = NULL; static int yy_init = 0; /* whether we need to initialize */ static int yy_start = 0; /* start state number */ /* Flag which is used to allow yywrap()'s to do buffer switches * instead of setting up a fresh yyin. A bit of a hack ... */ static int yy_did_buffer_switch_on_eof; void yyrestart ( FILE *input_file ); void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); void yy_delete_buffer ( YY_BUFFER_STATE b ); void yy_flush_buffer ( YY_BUFFER_STATE b ); void yypush_buffer_state ( YY_BUFFER_STATE new_buffer ); void yypop_buffer_state ( void ); static void yyensure_buffer_stack ( void ); static void yy_load_buffer_state ( void ); static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file ); #define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER ) YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size ); YY_BUFFER_STATE yy_scan_string ( const char *yy_str ); YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len ); void *yyalloc ( yy_size_t ); void *yyrealloc ( void *, yy_size_t ); void yyfree ( void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ #define reswrap() (/*CONSTCOND*/1) #define YY_SKIP_YYWRAP typedef flex_uint8_t YY_CHAR; FILE *yyin = NULL, *yyout = NULL; typedef int yy_state_type; extern int yylineno; int yylineno = 1; extern char *yytext; #ifdef yytext_ptr #undef yytext_ptr #endif #define yytext_ptr yytext static yy_state_type yy_get_previous_state ( void ); static yy_state_type yy_try_NUL_trans ( yy_state_type current_state ); static int yy_get_next_buffer ( void ); static void yynoreturn yy_fatal_error ( const char* msg ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ yyleng = (int) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 8 #define YY_END_OF_BUFFER 9 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static const flex_int16_t yy_accept[28] = { 0, 0, 0, 9, 6, 4, 4, 7, 6, 7, 7, 7, 6, 6, 0, 0, 1, 6, 0, 3, 0, 0, 2, 0, 5, 0, 3, 0 } ; static const YY_CHAR yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 4, 5, 1, 1, 1, 6, 7, 8, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 1, 1, 1, 10, 1, 1, 11, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 1, 1, 1, 1, 9, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 1, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static const YY_CHAR yy_meta[12] = { 0, 1, 2, 2, 2, 1, 2, 1, 2, 1, 2, 1 } ; static const flex_int16_t yy_base[33] = { 0, 0, 0, 44, 34, 57, 57, 36, 11, 33, 30, 57, 16, 28, 25, 27, 57, 0, 25, 57, 34, 23, 57, 20, 0, 40, 19, 57, 23, 48, 50, 52, 54 } ; static const flex_int16_t yy_def[33] = { 0, 27, 1, 27, 28, 27, 27, 29, 27, 30, 31, 27, 28, 28, 31, 29, 27, 8, 8, 27, 32, 30, 27, 31, 12, 32, 31, 0, 27, 27, 27, 27, 27 } ; static const flex_int16_t yy_nxt[69] = { 0, 4, 5, 6, 7, 8, 9, 10, 11, 4, 11, 12, 17, 18, 19, 18, 17, 18, 20, 18, 17, 18, 17, 14, 13, 24, 18, 13, 13, 22, 18, 16, 18, 13, 18, 14, 18, 26, 13, 22, 16, 14, 17, 26, 27, 27, 27, 27, 17, 15, 15, 21, 21, 23, 23, 25, 25, 3, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27 } ; static const flex_int16_t yy_chk[69] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 28, 12, 18, 26, 23, 21, 18, 15, 18, 14, 18, 13, 18, 20, 10, 9, 7, 4, 20, 25, 3, 0, 0, 0, 25, 29, 29, 30, 30, 31, 31, 32, 32, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27 } ; /* Table of booleans, true if rule could match eol. */ static const flex_int32_t yy_rule_can_match_eol[9] = { 0, 1, 1, 1, 1, 0, 1, 0, 0, }; static yy_state_type yy_last_accepting_state; static char *yy_last_accepting_cpos; extern int yy_flex_debug; int yy_flex_debug = 0; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET char *yytext; #line 1 "res_lex.l" #line 2 "res_lex.l" #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_STRING_H #include #endif #include "global.h" #include "resource.h" #include "res_parse.h" #include "free_atexit.h" #ifdef HAVE_LIBDMALLOC #include #endif #define YY_NO_INPUT #define YY_INPUT(buf,result,max_size) { result = res_parse_getchars(buf, max_size); } #ifdef FLEX_SCANNER #define yyunput ATTRIBUTE_UNUSED yyunput #endif extern int res_lineno; extern int res_parse_getchars(char *buf, int max_size); #line 778 "res_lex.c" #line 779 "res_lex.c" #define INITIAL 0 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif static int yy_init_globals ( void ); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int yylex_destroy ( void ); int yyget_debug ( void ); void yyset_debug ( int debug_flag ); YY_EXTRA_TYPE yyget_extra ( void ); void yyset_extra ( YY_EXTRA_TYPE user_defined ); FILE *yyget_in ( void ); void yyset_in ( FILE * _in_str ); FILE *yyget_out ( void ); void yyset_out ( FILE * _out_str ); int yyget_leng ( void ); char *yyget_text ( void ); int yyget_lineno ( void ); void yyset_lineno ( int _line_number ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap ( void ); #else extern int yywrap ( void ); #endif #endif #ifndef YY_NO_UNPUT static void yyunput ( int c, char *buf_ptr ); #endif #ifndef yytext_ptr static void yy_flex_strncpy ( char *, const char *, int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen ( const char * ); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput ( void ); #else static int input ( void ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k */ #define YY_READ_BUF_SIZE 16384 #else #define YY_READ_BUF_SIZE 8192 #endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ int n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( yyin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else \ { \ errno=0; \ while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yyin); \ } \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex (void); #define YY_DECL int yylex (void) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK /*LINTED*/break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { yy_state_type yy_current_state; char *yy_cp, *yy_bp; int yy_act; if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_load_buffer_state( ); } { #line 41 "res_lex.l" #line 999 "res_lex.c" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_match: do { YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 28 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; ++yy_cp; } while ( yy_base[yy_current_state] != 57 ); yy_find_action: yy_act = yy_accept[yy_current_state]; if ( yy_act == 0 ) { /* have to back up */ yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_act = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] ) { int yyl; for ( yyl = 0; yyl < yyleng; ++yyl ) if ( yytext[yyl] == '\n' ) yylineno++; ; } do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: /* rule 1 can match eol */ YY_RULE_SETUP #line 43 "res_lex.l" { reslval.sval = leaky_strdup (yytext+1); reslval.sval[strlen(reslval.sval) - 1] = 0; return STRING; } YY_BREAK case 2: /* rule 2 can match eol */ YY_RULE_SETUP #line 47 "res_lex.l" { reslval.sval = leaky_strdup (yytext+1); reslval.sval[strlen(reslval.sval) - 1] = 0; return STRING; } YY_BREAK case 3: /* rule 3 can match eol */ YY_RULE_SETUP #line 51 "res_lex.l" { res_lineno++; } YY_BREAK case 4: /* rule 4 can match eol */ YY_RULE_SETUP #line 52 "res_lex.l" { if (yytext[0] == '\n') res_lineno++; } YY_BREAK case 5: YY_RULE_SETUP #line 54 "res_lex.l" { reslval.sval = leaky_strdup (yytext); return INCLUDE; } YY_BREAK case 6: /* rule 6 can match eol */ YY_RULE_SETUP #line 57 "res_lex.l" { reslval.sval = leaky_strdup (yytext); return STRING; } YY_BREAK case 7: YY_RULE_SETUP #line 60 "res_lex.l" { return yytext[0]; } YY_BREAK case 8: YY_RULE_SETUP #line 62 "res_lex.l" ECHO; YY_BREAK #line 1117 "res_lex.c" case YY_STATE_EOF(INITIAL): yyterminate(); case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_c_buf_p); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of user's declarations */ } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (void) { char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; char *source = (yytext_ptr); int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { int new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ yyrealloc( (void *) b->yy_ch_buf, (yy_size_t) (b->yy_buf_size + 2) ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = NULL; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart( yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); /* "- 2" to take care of EOB's */ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); } (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (void) { yy_state_type yy_current_state; char *yy_cp; yy_current_state = (yy_start); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 28 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) { int yy_is_jam; char *yy_cp = (yy_c_buf_p); YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 28 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; yy_is_jam = (yy_current_state == 27); return yy_is_jam ? 0 : yy_current_state; } #ifndef YY_NO_UNPUT static void yyunput (int c, char * yy_bp ) { char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up yytext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ int number_to_move = (yy_n_chars) + 2; char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; if ( c == '\n' ){ --yylineno; } (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void) #else static int input (void) #endif { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ int offset = (int) ((yy_c_buf_p) - (yytext_ptr)); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart( yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return 0; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); if ( c == '\n' ) yylineno++; ; return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyrestart (FILE * input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_init_buffer( YY_CURRENT_BUFFER, input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } static void yy_load_buffer_state (void) { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer( b, file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yy_delete_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) yyfree( (void *) b->yy_ch_buf ); yyfree( (void *) b ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) { int oerrno = errno; yy_flush_buffer( b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yy_flush_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void yyensure_buffer_stack (void) { yy_size_t num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ yy_size_t grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return NULL; b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = NULL; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; yy_switch_to_buffer( b ); return b; } /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * yy_scan_bytes() instead. */ YY_BUFFER_STATE yy_scan_string (const char * yystr ) { return yy_scan_bytes( yystr, (int) strlen(yystr) ); } /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. * @param yybytes the byte buffer to scan * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len ) { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = (yy_size_t) (_yybytes_len + 2); buf = (char *) yyalloc( n ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = yy_scan_buffer( buf, n ); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void yynoreturn yy_fatal_error (const char* msg ) { fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the current line number. * */ int yyget_lineno (void) { return yylineno; } /** Get the input stream. * */ FILE *yyget_in (void) { return yyin; } /** Get the output stream. * */ FILE *yyget_out (void) { return yyout; } /** Get the length of the current token. * */ int yyget_leng (void) { return yyleng; } /** Get the current token. * */ char *yyget_text (void) { return yytext; } /** Set the current line number. * @param _line_number line number * */ void yyset_lineno (int _line_number ) { yylineno = _line_number; } /** Set the input stream. This does not discard the current * input buffer. * @param _in_str A readable stream. * * @see yy_switch_to_buffer */ void yyset_in (FILE * _in_str ) { yyin = _in_str ; } void yyset_out (FILE * _out_str ) { yyout = _out_str ; } int yyget_debug (void) { return yy_flex_debug; } void yyset_debug (int _bdebug ) { yy_flex_debug = _bdebug ; } static int yy_init_globals (void) { /* Initialization is the same as for the non-reentrant scanner. * This function is called from yylex_destroy(), so don't allocate here. */ /* We do not touch yylineno unless the option is enabled. */ yylineno = 1; (yy_buffer_stack) = NULL; (yy_buffer_stack_top) = 0; (yy_buffer_stack_max) = 0; (yy_c_buf_p) = NULL; (yy_init) = 0; (yy_start) = 0; /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; yyout = stdout; #else yyin = NULL; yyout = NULL; #endif /* For future reference: Set errno on error, since we are called by * yylex_init() */ return 0; } /* yylex_destroy is for both reentrant and non-reentrant scanners. */ int yylex_destroy (void) { /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ yy_delete_buffer( YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; yypop_buffer_state(); } /* Destroy the stack itself. */ yyfree((yy_buffer_stack) ); (yy_buffer_stack) = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * yylex() is called, initialization will occur. */ yy_init_globals( ); return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, const char * s2, int n ) { int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (const char * s ) { int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *yyalloc (yy_size_t size ) { return malloc(size); } void *yyrealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return realloc(ptr, size); } void yyfree (void * ptr ) { free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 62 "res_lex.l" /* ' */ pcb-4.3.0/src/djopt.c0000664000175000017500000021032513773431044011271 00000000000000/*! * \file src/djopt.c * * \brief . * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 2003 DJ Delorie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * DJ Delorie, 334 North Road, Deerfield NH 03037-1110, USA * dj@delorie.com */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "global.h" #include #include #include "data.h" #include "create.h" #include "remove.h" #include "move.h" #include "draw.h" #include "undo.h" #include "strflags.h" #include "find.h" #include "pcb-printf.h" #ifdef HAVE_LIBDMALLOC #include #endif #ifndef HAVE_RINT #define rint(x) (ceil((x) - 0.5)) #endif #define dprintf if(0)pcb_printf #define selected(x) TEST_FLAG (SELECTEDFLAG, (x)) #define autorouted(x) TEST_FLAG (AUTOFLAG, (x)) #define SB (PCB->Bloat+1) /* must be 2^N-1 */ #define INC 7 #define O_HORIZ 0x10 #define O_VERT 0x20 #define LEFT 0x11 #define RIGHT 0x12 #define UP 0x24 #define DOWN 0x28 #define DIAGONAL 0xf0 #define ORIENT(x) ((x) & 0xf0) #define DIRECT(x) ((x) & 0x0f) #define LONGEST_FRECKLE 2 /*!< Manhattan length of the longest "freckle" */ struct line_s; typedef struct corner_s { int layer; struct corner_s *next; int x, y; int net; PinType *via; PadType *pad; PinType *pin; int miter; int n_lines; struct line_s **lines; } corner_s; typedef struct line_s { int layer; struct line_s *next; corner_s *s, *e; LineType *line; char is_pad; } line_s; typedef struct rect_s { int x1, y1, x2, y2; } rect_s; #define DELETE(q) (q)->layer = 0xdeadbeef #define DELETED(q) ((q)->layer == 0xdeadbeef) static corner_s *corners, *next_corner = 0; static line_s *lines; static int layer_groupings[MAX_LAYER]; static char layer_type[MAX_LAYER]; #define LT_TOP 1 #define LT_BOTTOM 2 static int autorouted_only = 1; static const char djopt_sao_syntax[] = "OptAutoOnly()"; static const char djopt_sao_help[] = "Toggles the optimize-only-autorouted flag."; /* %start-doc actions OptAutoOnly The original purpose of the trace optimizer was to clean up the traces created by the various autorouters that have been used with PCB. When a board has a mix of autorouted and carefully hand-routed traces, you don't normally want the optimizer to move your hand-routed traces. But, sometimes you do. By default, the optimizer only optimizes autorouted traces. This action toggles that setting, so that you can optimize hand-routed traces also. %end-doc */ int djopt_set_auto_only (int argc, char **argv, Coord x, Coord y) { autorouted_only = autorouted_only ? 0 : 1; return 0; } static int djopt_get_auto_only (void *data) { return autorouted_only; } HID_Flag djopt_flag_list[] = { {"optautoonly", djopt_get_auto_only, NULL} }; REGISTER_FLAGS (djopt_flag_list) static char * element_name_for (corner_s * c) { ELEMENT_LOOP (PCB->Data); { PIN_LOOP (element); { if (pin == c->pin) return element->Name[1].TextString; } END_LOOP; PAD_LOOP (element); { if (pad == c->pad) return element->Name[1].TextString; } END_LOOP; } END_LOOP; return "unknown"; } static char * corner_name (corner_s * c) { static char buf[4][100]; static int bn = 0; char *bp; size_t size_left; bn = (bn + 1) % 4; if (c->net == 0xf1eef1ee) { sprintf (buf[bn], "\033[31m[%p freed corner]\033[0m", (void *) c); return buf[bn]; } sprintf (buf[bn], "\033[%dm[%p ", (c->pin || c->pad || c->via) ? 33 : 34, (void *) c); bp = buf[bn] + strlen (buf[bn]); size_left = sizeof (buf[bn]) - strlen (buf[bn]); if (c->pin) pcb_snprintf (bp, size_left, "pin %s:%s at %#mD", element_name_for (c), c->pin->Number, c->x, c->y); else if (c->via) pcb_snprintf (bp, size_left, "via at %#mD", c->x, c->y); else if (c->pad) { pcb_snprintf (bp, size_left, "pad %s:%s at %#mD %#mD-%#mD", element_name_for (c), c->pad->Number, c->x, c->y, c->pad->Point1.X, c->pad->Point1.Y, c->pad->Point2.X, c->pad->Point2.Y); } else pcb_snprintf (bp, size_left, "at %#mD", c->x, c->y); sprintf (bp + strlen (bp), " n%d l%d]\033[0m", c->n_lines, c->layer); return buf[bn]; } static int solder_layer, component_layer; static void dj_abort (char *msg, ...) { va_list a; va_start (a, msg); vprintf (msg, a); va_end (a); fflush (stdout); abort (); } #if 1 #define check(c,l) #else #define check(c,l) check2(__LINE__,c,l) static void check2 (int srcline, corner_s * c, line_s * l) { int saw_c = 0, saw_l = 0; corner_s *cc; line_s *ll; int i; for (cc = corners; cc; cc = cc->next) { if (DELETED (cc)) continue; if (cc == c) saw_c = 1; for (i = 0; i < cc->n_lines; i++) if (cc->lines[i]->s != cc && cc->lines[i]->e != cc) dj_abort ("check:%d: cc has line without backref\n", srcline); if (cc->via && (cc->x != cc->via->X || cc->y != cc->via->Y)) dj_abort ("check:%d: via not at corner\n", srcline); if (cc->pin && (cc->x != cc->pin->X || cc->y != cc->pin->Y)) dj_abort ("check:%d: pin not at corner\n", srcline); } if (c && !saw_c) dj_abort ("check:%d: corner not in corners list\n", srcline); for (ll = lines; ll; ll = ll->next) { if (DELETED (ll)) continue; if (ll == l) saw_l = 1; for (i = 0; i < ll->s->n_lines; i++) if (ll->s->lines[i] == ll) break; if (i == ll->s->n_lines) dj_abort ("check:%d: ll->s has no backref\n", srcline); for (i = 0; i < ll->e->n_lines; i++) if (ll->e->lines[i] == ll) break; if (i == ll->e->n_lines) dj_abort ("check:%d: ll->e has no backref\n", srcline); if (!ll->is_pad && (ll->s->x != ll->line->Point1.X || ll->s->y != ll->line->Point1.Y || ll->e->x != ll->line->Point2.X || ll->e->y != ll->line->Point2.Y)) { pcb_printf ("line: %#mD to %#mD pcbline: %#mD to %#mD\n", ll->s->x, ll->s->y, ll->e->x, ll->e->y, ll->line->Point1.X, ll->line->Point1.Y, ll->line->Point2.X, ll->line->Point2.Y); dj_abort ("check:%d: line doesn't match pcbline\n", srcline); } } if (l && !saw_l) dj_abort ("check:%d: line not in lines list\n", srcline); } #endif #define SWAP(a,b) { a^=b; b^=a; a^=b; } static int gridsnap (Coord n) { if (n <= 0) return 0; return n - n % (Settings.Grid); } /* Avoid commonly used names. */ static int djabs (int x) { return x > 0 ? x : -x; } static int djmax (int x, int y) { return x > y ? x : y; } static int djmin (int x, int y) { return x < y ? x : y; } /*! * \brief Find distance between 2 points. * * We use floating point math here because we can fairly easily overflow * a 32 bit integer here. * In fact it only takes 0.46" to do so. */ static int dist (int x1, int y1, int x2, int y2) { double d; d = hypot ((double) x1 - (double) x2, (double) y1 - (double) y2); d = rint (d); return (int) d; } static int line_length (line_s * l) { if (l->s->x == l->e->x) return djabs (l->s->y - l->e->y); if (l->s->y == l->e->y) return djabs (l->s->x - l->e->x); return dist (l->s->x, l->s->y, l->e->x, l->e->y); } static int dist_ltp2 (int dx, int y, int y1, int y2) { if (y1 > y2) SWAP (y1, y2); if (y < y1) return dist (dx, y, 0, y1); if (y > y2) return dist (dx, y, 0, y2); return djabs (dx); } static int intersecting_layers (int l1, int l2) { if (l1 == -1 || l2 == -1) return 1; if (l1 == l2) return 1; if (layer_groupings[l1] == layer_groupings[l2]) return 1; return 0; } static int dist_line_to_point (line_s * l, corner_s * c) { double len, r, d; /* We can do this quickly if l is vertical or horizontal. */ if (l->s->x == l->e->x) return dist_ltp2 (l->s->x - c->x, c->y, l->s->y, l->e->y); if (l->s->y == l->e->y) return dist_ltp2 (l->s->y - c->y, c->x, l->s->x, l->e->x); /* Do it the hard way. See comments for IsPointOnLine() in search.c */ len = hypot (l->s->x - l->e->x, l->s->y - l->e->y); if (len == 0) return dist (l->s->x, l->s->y, c->x, c->y); r = (l->s->y - c->y) * (l->s->y - l->e->y) + (l->s->x - c->x) * (l->s->x - l->e->x); r /= len * len; if (r < 0) return dist (l->s->x, l->s->y, c->x, c->y); if (r > 1) return dist (l->e->x, l->e->y, c->x, c->y); d = (l->e->y - l->s->y) * (c->x * l->s->x) + (l->e->x - l->s->x) * (c->y - l->s->y); return (int) (d / len); } static int line_orient (line_s * l, corner_s * c) { int x1, y1, x2, y2; if (c == l->s) { x1 = l->s->x; y1 = l->s->y; x2 = l->e->x; y2 = l->e->y; } else { x1 = l->e->x; y1 = l->e->y; x2 = l->s->x; y2 = l->s->y; } if (x1 == x2) { if (y1 < y2) return DOWN; return UP; } else if (y1 == y2) { if (x1 < x2) return RIGHT; return LEFT; } return DIAGONAL; } #if 0 /* Not used */ static corner_s * common_corner (line_s * l1, line_s * l2) { if (l1->s == l2->s || l1->s == l2->e) return l1->s; if (l1->e == l2->s || l1->e == l2->e) return l1->e; dj_abort ("common_corner: no common corner found\n"); return NULL; } #endif static corner_s * other_corner (line_s * l, corner_s * c) { if (l->s == c) return l->e; if (l->e == c) return l->s; dj_abort ("other_corner: neither corner passed\n"); return NULL; } static corner_s * find_corner_if (int x, int y, int l) { corner_s *c; for (c = corners; c; c = c->next) { if (DELETED (c)) continue; if (c->x != x || c->y != y) continue; if (!(c->layer == -1 || intersecting_layers (c->layer, l))) continue; return c; } return 0; } static corner_s * find_corner (int x, int y, int l) { corner_s *c; for (c = corners; c; c = c->next) { if (DELETED (c)) continue; if (c->x != x || c->y != y) continue; if (!(c->layer == -1 || intersecting_layers (c->layer, l))) continue; return c; } c = (corner_s *) malloc (sizeof (corner_s)); c->next = corners; corners = c; c->x = x; c->y = y; c->net = 0; c->via = 0; c->pad = 0; c->pin = 0; c->layer = l; c->n_lines = 0; c->lines = (line_s **) malloc (INC * sizeof (line_s *)); return c; } static void add_line_to_corner (line_s * l, corner_s * c) { int n; n = (c->n_lines + 1 + INC) & ~INC; c->lines = (line_s **) realloc (c->lines, n * sizeof (line_s *)); c->lines[c->n_lines] = l; c->n_lines++; dprintf ("add_line_to_corner %#mD\n", c->x, c->y); } static LineType * create_pcb_line (int layer, int x1, int y1, int x2, int y2, int thick, int clear, FlagType flags) { char *from, *to; LineType *nl; LayerType *lyr = LAYER_PTR (layer); from = (char *) lyr->Line; nl = CreateNewLineOnLayer (PCB->Data->Layer + layer, x1, y1, x2, y2, thick, clear, flags); AddObjectToCreateUndoList (LINE_TYPE, lyr, nl, nl); to = (char *) lyr->Line; if (from != to) { line_s *lp; for (lp = lines; lp; lp = lp->next) { if (DELETED (lp)) continue; if ((char *) (lp->line) >= from && (char *) (lp->line) <= from + lyr->LineN * sizeof (LineType)) lp->line = (LineType *) ((char *) (lp->line) + (to - from)); } } return nl; } static void new_line (corner_s * s, corner_s * e, int layer, LineType * example) { line_s *ls; if (layer >= max_copper_layer) dj_abort ("layer %d\n", layer); if (example == NULL) dj_abort ("NULL example passed to new_line()\n", layer); if (s->x == e->x && s->y == e->y) return; ls = (line_s *) malloc (sizeof (line_s)); ls->next = lines; lines = ls; ls->is_pad = 0; ls->s = s; ls->e = e; ls->layer = layer; #if 0 if ((example->Point1.X == s->x && example->Point1.Y == s->y && example->Point2.X == e->x && example->Point2.Y == e->y) || (example->Point2.X == s->x && example->Point2.Y == s->y && example->Point1.X == e->x && example->Point1.Y == e->y)) { ls->line = example; } else #endif { LineType *nl; dprintf ("New line \033[35m%#mD to %#mD from l%d t%#mS c%#mS f%s\033[0m\n", s->x, s->y, e->x, e->y, layer, example->Thickness, example->Clearance, flags_to_string (example->Flags, LINE_TYPE)); nl = create_pcb_line (layer, s->x, s->y, e->x, e->y, example->Thickness, example->Clearance, example->Flags); if (!nl) dj_abort ("can't create new line!"); ls->line = nl; } add_line_to_corner (ls, s); add_line_to_corner (ls, e); check (s, ls); check (e, ls); } #if 0 /* Not used */ static int c_orth_to (corner_s * c, line_s * l, int o) { int i, o2; int rv = 0; for (i = 0; i < c->n_lines; i++) { if (c->lines[i] == l) continue; o2 = line_orient (c->lines[i], c); if (ORIENT (o) == ORIENT (o2) || o2 == DIAGONAL) return 0; rv++; } return rv; } #endif static line_s * other_line (corner_s * c, line_s * l) { int i; line_s *rv = 0; if (c->pin || c->pad || c->via) return 0; for (i = 0; i < c->n_lines; i++) { if (c->lines[i] == l) continue; if (rv) return 0; rv = c->lines[i]; } return rv; } static void empty_rect (rect_s * rect) { rect->x1 = rect->y1 = INT_MAX; rect->x2 = rect->y2 = INT_MIN; } static void add_point_to_rect (rect_s * rect, int x, int y, int w) { if (rect->x1 > x - w) rect->x1 = x - w; if (rect->x2 < x + w) rect->x2 = x + w; if (rect->y1 > y - w) rect->y1 = y - w; if (rect->y2 < y + w) rect->y2 = y + w; } static void add_line_to_rect (rect_s * rect, line_s * l) { add_point_to_rect (rect, l->s->x, l->s->y, 0); add_point_to_rect (rect, l->e->x, l->e->y, 0); } static int pin_in_rect (rect_s * r, int x, int y, int w) { if (x < r->x1 && x + w < r->x1) return 0; if (x > r->x2 && x - w > r->x2) return 0; if (y < r->y1 && y + w < r->y1) return 0; if (y > r->y2 && y - w > r->y2) return 0; return 1; } static int line_in_rect (rect_s * r, line_s * l) { rect_s lr; empty_rect (&lr); add_point_to_rect (&lr, l->s->x, l->s->y, l->line->Thickness / 2); add_point_to_rect (&lr, l->e->x, l->e->y, l->line->Thickness / 2); dprintf ("line_in_rect %#mD-%#mD vs %#mD-%#mD\n", r->x1, r->y1, r->x2, r->y2, lr.x1, lr.y1, lr.x2, lr.y2); /* simple intersection of rectangles */ if (lr.x1 < r->x1) lr.x1 = r->x1; if (lr.x2 > r->x2) lr.x2 = r->x2; if (lr.y1 < r->y1) lr.y1 = r->y1; if (lr.y2 > r->y2) lr.y2 = r->y2; if (lr.x1 < lr.x2 && lr.y1 < lr.y2) return 1; return 0; } static int corner_radius (corner_s * c) { int diam = 0; int i; if (c->pin) diam = djmax (c->pin->Thickness, diam); if (c->via) diam = djmax (c->via->Thickness, diam); for (i = 0; i < c->n_lines; i++) if (c->lines[i]->line) diam = djmax (c->lines[i]->line->Thickness, diam); diam = (diam + 1) / 2; return diam; } #if 0 /* Not used */ static int corner_layer (corner_s * c) { if (c->pin || c->via) return -1; if (c->n_lines < 1) return -1; return c->lines[0]->layer; } #endif static void add_corner_to_rect_if (rect_s * rect, corner_s * c, rect_s * e) { int diam = corner_radius (c); if (!pin_in_rect (e, c->x, c->y, diam)) return; if (c->x < e->x1 && c->y < e->y1 && dist (c->x, c->y, e->x1, e->y1) > diam) return; if (c->x > e->x2 && c->y < e->y1 && dist (c->x, c->y, e->x2, e->y1) > diam) return; if (c->x < e->x1 && c->y > e->y2 && dist (c->x, c->y, e->x1, e->y2) > diam) return; if (c->x > e->x2 && c->y > e->y2 && dist (c->x, c->y, e->x2, e->y2) > diam) return; /*pcb_printf("add point %#mD diam %#mS\n", c->x, c->y, diam); */ add_point_to_rect (rect, c->x, c->y, diam); } static void remove_line (line_s * l) { int i, j; LayerType *layer = &(PCB->Data->Layer[l->layer]); check (0, 0); if (l->line) RemoveLine (layer, l->line); DELETE (l); for (i = 0, j = 0; i < l->s->n_lines; i++) if (l->s->lines[i] != l) l->s->lines[j++] = l->s->lines[i]; l->s->n_lines = j; for (i = 0, j = 0; i < l->e->n_lines; i++) if (l->e->lines[i] != l) l->e->lines[j++] = l->e->lines[i]; l->e->n_lines = j; check (0, 0); } static void move_line_to_layer (line_s * l, int layer) { LayerType *ls, *ld; ls = LAYER_PTR (l->layer); ld = LAYER_PTR (layer); MoveObjectToLayer (LINE_TYPE, ls, l->line, 0, ld, 0); l->layer = layer; } static void remove_via_at (corner_s * c) { RemoveObject (VIA_TYPE, c->via, 0, 0); c->via = 0; } static void remove_corner (corner_s * c2) { corner_s *c; dprintf ("remove corner %s\n", corner_name (c2)); if (corners == c2) corners = c2->next; for (c = corners; c; c = c->next) { if (DELETED (c)) continue; if (c->next == c2) c->next = c2->next; } if (next_corner == c2) next_corner = c2->next; free (c2->lines); c2->lines = 0; DELETE (c2); } static void merge_corners (corner_s * c1, corner_s * c2) { int i; if (c1 == c2) abort (); dprintf ("merge corners %s %s\n", corner_name (c1), corner_name (c2)); for (i = 0; i < c2->n_lines; i++) { add_line_to_corner (c2->lines[i], c1); if (c2->lines[i]->s == c2) c2->lines[i]->s = c1; if (c2->lines[i]->e == c2) c2->lines[i]->e = c1; } if (c1->via && c2->via) remove_via_at (c2); else if (c2->via) c1->via = c2->via; if (c2->pad) c1->pad = c2->pad; if (c2->pin) c1->pin = c2->pin; if (c2->layer != c1->layer) c1->layer = -1; remove_corner (c2); } static void move_corner (corner_s * c, int x, int y) { PinType *via; int i; corner_s *pad; check (c, 0); if (c->pad || c->pin) dj_abort ("move_corner: has pin or pad\n"); dprintf ("move_corner %p from %#mD to %#mD\n", (void *) c, c->x, c->y, x, y); pad = find_corner_if (x, y, c->layer); c->x = x; c->y = y; via = c->via; if (via) { MoveObject (VIA_TYPE, via, via, via, x - via->X, y - via->Y); dprintf ("via move %#mD to %#mD\n", via->X, via->Y, x, y); } for (i = 0; i < c->n_lines; i++) { LineType *tl = c->lines[i]->line; if (tl) { if (c->lines[i]->s == c) { MoveObject (LINEPOINT_TYPE, LAYER_PTR (c->lines[i]->layer), tl, &tl->Point1, x - (tl->Point1.X), y - (tl->Point1.Y)); } else { MoveObject (LINEPOINT_TYPE, LAYER_PTR (c->lines[i]->layer), tl, &tl->Point2, x - (tl->Point2.X), y - (tl->Point2.Y)); } dprintf ("Line %p moved to %#mD %#mD\n", (void *) tl, tl->Point1.X, tl->Point1.Y, tl->Point2.X, tl->Point2.Y); } } if (pad && pad != c) merge_corners (c, pad); else for (i = 0; i < c->n_lines; i++) { if (c->lines[i]->s->x == c->lines[i]->e->x && c->lines[i]->s->y == c->lines[i]->e->y) { corner_s *c2 = other_corner (c->lines[i], c); dprintf ("move_corner: removing line %#mD %#mD %p %p\n", c->x, c->y, c2->x, c2->y, (void *) c, (void *) c2); remove_line (c->lines[i]); if (c != c2) merge_corners (c, c2); check (c, 0); i--; break; } } gui->progress (0, 0, 0); check (c, 0); } static int any_line_selected () { line_s *l; for (l = lines; l; l = l->next) { if (DELETED (l)) continue; if (l->line && selected (l->line)) return 1; } return 0; } static int trim_step (int s, int l1, int l2) { dprintf ("trim %d %d %d\n", s, l1, l2); if (s > l1) s = l1; if (s > l2) s = l2; if (s != l1 && s != l2) s = gridsnap (s); return s; } static int canonicalize_line (line_s * l); static int split_line (line_s * l, corner_s * c) { int i; LineType *pcbline; line_s *ls; if (!intersecting_layers (l->layer, c->layer)) return 0; if (l->is_pad) return 0; if (c->pad) { dprintf ("split on pad!\n"); if (l->s->pad == c->pad || l->e->pad == c->pad) return 0; dprintf ("splitting...\n"); } check (c, l); pcbline = create_pcb_line (l->layer, c->x, c->y, l->e->x, l->e->y, l->line->Thickness, l->line->Clearance, l->line->Flags); if (pcbline == 0) return 0; /* already a line there */ check (c, l); dprintf ("split line from %#mD to %#mD at %#mD\n", l->s->x, l->s->y, l->e->x, l->e->y, c->x, c->y); ls = (line_s *) malloc (sizeof (line_s)); ls->next = lines; lines = ls; ls->is_pad = 0; ls->s = c; ls->e = l->e; ls->line = pcbline; ls->layer = l->layer; for (i = 0; i < l->e->n_lines; i++) if (l->e->lines[i] == l) l->e->lines[i] = ls; l->e = c; add_line_to_corner (l, c); add_line_to_corner (ls, c); MoveObject (LINEPOINT_TYPE, LAYER_PTR (l->layer), l->line, &l->line->Point2, c->x - (l->line->Point2.X), c->y - (l->line->Point2.Y)); return 1; } static int canonicalize_line (line_s * l) { /* This could be faster */ corner_s *c; if (l->s->x == l->e->x) { int y1 = l->s->y; int y2 = l->e->y; int x1 = l->s->x - l->line->Thickness / 2; int x2 = l->s->x + l->line->Thickness / 2; if (y1 > y2) { int t = y1; y1 = y2; y2 = t; } for (c = corners; c; c = c->next) { if (DELETED (c)) continue; if ((y1 < c->y && c->y < y2) && intersecting_layers (l->layer, c->layer)) { if (c->x != l->s->x && c->x < x2 && c->x > x1 && !(c->pad || c->pin)) { move_corner (c, l->s->x, c->y); } if (c->x == l->s->x) { /* FIXME: if the line is split, we have to re-canonicalize both segments. */ return split_line (l, c); } } } } else if (l->s->y == l->e->y) { int x1 = l->s->x; int x2 = l->e->x; int y1 = l->s->y - l->line->Thickness / 2; int y2 = l->s->y + l->line->Thickness / 2; if (x1 > x2) { int t = x1; x1 = x2; x2 = t; } for (c = corners; c; c = c->next) { if (DELETED (c)) continue; if ((x1 < c->x && c->x < x2) && intersecting_layers (l->layer, c->layer)) { if (c->y != l->s->y && c->y < y2 && c->y > y1 && !(c->pad || c->pin)) { move_corner (c, c->x, l->s->y); } if (c->y == l->s->y) { /* FIXME: Likewise. */ return split_line (l, c); } } } } else { /* diagonal lines. Let's try to split them at pins/vias anyway. */ int x1 = l->s->x; int x2 = l->e->x; int y1 = l->s->y; int y2 = l->e->y; if (x1 > x2) { int t = x1; x1 = x2; x2 = t; } if (y1 > y2) { int t = y1; y1 = y2; y2 = t; } for (c = corners; c; c = c->next) { if (DELETED (c)) continue; if (!c->via && !c->pin) continue; if ((x1 < c->x && c->x < x2) && (y1 < c->y && c->y < y2) && intersecting_layers (l->layer, c->layer)) { int th = c->pin ? c->pin->Thickness : c->via->Thickness; th /= 2; if (dist (l->s->x, l->s->y, c->x, c->y) > th && dist (l->e->x, l->e->y, c->x, c->y) > th && PinLineIntersect (c->pin ? c->pin : c->via, l->line)) { return split_line (l, c); } } } } return 0; } /*! * \brief Make sure all vias are at line end points. */ static int canonicalize_lines () { int changes = 0; int count; line_s *l; while (1) { count = 0; for (l = lines; l; l = l->next) { if (DELETED (l)) continue; count += canonicalize_line (l); } changes += count; if (count == 0) break; } return changes; } static int simple_optimize_corner (corner_s * c) { int i; int rv = 0; check (c, 0); if (c->via) { /* see if no via is needed */ if (selected (c->via)) dprintf ("via check: line[0] layer %d at %#mD nl %d\n", c->lines[0]->layer, c->x, c->y, c->n_lines); /* We can't delete vias that connect to power planes, or vias that aren't tented (assume they're test points). */ if (!TEST_ANY_THERMS (c->via) && c->via->Mask == 0) { for (i = 1; i < c->n_lines; i++) { if (selected (c->via)) dprintf (" line[%d] layer %d %#mD to %#mD\n", i, c->lines[i]->layer, c->lines[i]->s->x, c->lines[i]->s->y, c->lines[i]->e->x, c->lines[i]->e->y); if (c->lines[i]->layer != c->lines[0]->layer) break; } if (i == c->n_lines) { if (selected (c->via)) dprintf (" remove it\n"); remove_via_at (c); rv++; } } } check (c, 0); if (c->n_lines == 2 && !c->via) { /* see if it is an unneeded corner */ int o = line_orient (c->lines[0], c); corner_s *c2 = other_corner (c->lines[1], c); corner_s *c0 = other_corner (c->lines[0], c); if (o == line_orient (c->lines[1], c2) && o != DIAGONAL) { dprintf ("straight %#mD to %#mD to %#mD\n", c0->x, c0->y, c->x, c->y, c2->x, c2->y); if (selected (c->lines[0]->line)) SET_FLAG (SELECTEDFLAG, c->lines[1]->line); if (selected (c->lines[1]->line)) SET_FLAG (SELECTEDFLAG, c->lines[0]->line); move_corner (c, c2->x, c2->y); } } check (c, 0); if (c->n_lines == 1 && !c->via) { corner_s *c0 = other_corner (c->lines[0], c); if (abs(c->x - c0->x) + abs(c->y - c0->y) <= LONGEST_FRECKLE) { /* * Remove this line, as it is a "freckle". A freckle is an extremely * short line (around 0.01 thou) that is unconnected at one end. * Freckles are almost insignificantly small, but are annoying as * they prevent the mitering optimiser from working. * Freckles sometimes arise because of a bug in the autorouter that * causes it to create small overshoots (typically 0.01 thou) at the * intersections of vertical and horizontal lines. These overshoots * are converted to freckles as a side effect of canonicalize_line(). * Note that canonicalize_line() is not at fault, the bug is in the * autorouter creating overshoots. * The autorouter bug arose some time between the 20080202 and 20091103 * releases. * This code is probably worth keeping even when the autorouter bug is * fixed, as "freckles" could conceivably arise in other ways. */ dprintf ("freckle %#mD to %#mD\n", c->x, c->y, c0->x, c0->y); move_corner (c, c0->x, c0->y); } } check (c, 0); return rv; } /* We always run these */ static int simple_optimizations () { corner_s *c; int rv = 0; /* Look for corners that aren't */ for (c = corners; c; c = c->next) { if (DELETED (c)) continue; if (c->pad || c->pin) continue; rv += simple_optimize_corner (c); } return rv; } static int is_hole (corner_s * c) { return c->pin || c->pad || c->via; } static int orthopull_1 (corner_s * c, int fdir, int rdir, int any_sel) { static corner_s **cs = 0; static int cm = 0; static line_s **ls = 0; static int lm = 0; int i, li, ln, cn, snap; line_s *l = 0; corner_s *c2, *cb; int adir = 0, sdir = 0, pull; int saw_sel = 0, saw_auto = 0; int max, len = 0, r1 = 0, r2; rect_s rr; int edir = 0, done; if (cs == 0) { cs = (corner_s **) malloc (10 * sizeof (corner_s)); cm = 10; ls = (line_s **) malloc (10 * sizeof (line_s)); lm = 10; } for (i = 0; i < c->n_lines; i++) { int o = line_orient (c->lines[i], c); if (o == rdir) return 0; } switch (fdir) { case RIGHT: adir = DOWN; sdir = UP; break; case DOWN: adir = RIGHT; sdir = LEFT; break; default: dj_abort ("fdir not right or down\n"); } c2 = c; cn = 0; ln = 0; pull = 0; while (c2) { if (c2->pad || c2->pin || c2->n_lines < 2) return 0; if (cn >= cm) { cm = cn + 10; cs = (corner_s **) realloc (cs, cm * sizeof (corner_s *)); } cs[cn++] = c2; r2 = corner_radius (c2); if (r1 < r2) r1 = r2; l = 0; for (i = 0; i < c2->n_lines; i++) { int o = line_orient (c2->lines[i], c2); if (o == DIAGONAL) return 0; if (o == fdir) { if (l) return 0; /* we don't support overlapping lines yet */ l = c2->lines[i]; } if (o == rdir && c2->lines[i] != ls[ln - 1]) return 0; /* likewise */ if (o == adir) pull++; if (o == sdir) pull--; } if (!l) break; if (selected (l->line)) saw_sel = 1; if (autorouted (l->line)) saw_auto = 1; if (ln >= lm) { lm = ln + 10; ls = (line_s **) realloc (ls, lm * sizeof (line_s *)); } ls[ln++] = l; c2 = other_corner (l, c2); } if (cn < 2 || pull == 0) return 0; if (any_sel && !saw_sel) return 0; if (!any_sel && autorouted_only && !saw_auto) return 0; /* Ok, now look for other blockages. */ empty_rect (&rr); add_point_to_rect (&rr, c->x, c->y, corner_radius (c)); add_point_to_rect (&rr, c2->x, c2->y, corner_radius (c2)); if (fdir == RIGHT && pull < 0) edir = UP; else if (fdir == RIGHT && pull > 0) edir = DOWN; else if (fdir == DOWN && pull < 0) edir = LEFT; else if (fdir == DOWN && pull > 0) edir = RIGHT; max = -1; for (i = 0; i < cn; i++) for (li = 0; li < cs[i]->n_lines; li++) { if (line_orient (cs[i]->lines[li], cs[i]) != edir) continue; len = line_length (cs[i]->lines[li]); if (max > len || max == -1) max = len; } dprintf ("c %s %4#mD cn %d pull %3d max %4#mS\n", fdir == RIGHT ? "right" : "down ", c->x, c->y, cn, pull, max); switch (edir) { case UP: rr.y1 = c->y - r1 - max; break; case DOWN: rr.y2 = c->y + r1 + max; break; case LEFT: rr.x1 = c->x - r1 - max; break; case RIGHT: rr.x2 = c->x + r1 + max; break; } rr.x1 -= SB + 1; rr.x2 += SB + 1; rr.y1 -= SB + 1; rr.y2 += SB + 1; snap = 0; for (cb = corners; cb; cb = cb->next) { int sep; if (DELETED (cb)) continue; r1 = corner_radius (cb); if (cb->net == c->net && !cb->pad) continue; if (!pin_in_rect (&rr, cb->x, cb->y, r1)) continue; switch (edir) { #define ECHK(X,Y,LT) \ for (i=0; ilayer, cb->layer)) \ continue; \ r2 = corner_radius(cs[i]); \ if (cb->X + r1 <= cs[i]->X - r2 - SB - 1) \ continue; \ if (cb->X - r1 >= cs[i]->X + r2 + SB + 1) \ continue; \ if (cb->Y LT cs[i]->Y) \ continue; \ sep = djabs(cb->Y - cs[i]->Y) - r1 - r2 - SB - 1; \ if (max > sep) \ { max = sep; snap = 1; }\ } \ for (i=0; ilayer, cb->layer)) \ continue; \ if (cb->X <= cs[i]->X || cb->X >= cs[i+1]->X) \ continue; \ sep = (djabs(cb->Y - cs[i]->Y) - ls[i]->line->Thickness/2 \ - r1 - SB - 1); \ if (max > sep) \ { max = sep; snap = 1; }\ } case UP: ECHK (x, y, >=); break; case DOWN: ECHK (x, y, <=); break; case LEFT: ECHK (y, x, >=); break; case RIGHT: ECHK (y, x, <=); break; } } /* We must now check every line segment against our corners. */ for (l = lines; l; l = l->next) { int o, x1, x2, y1, y2; if (DELETED (l)) continue; dprintf ("check line %#mD to %#mD\n", l->s->x, l->s->y, l->e->x, l->e->y); if (l->s->net == c->net) { dprintf (" same net\n"); continue; } o = line_orient (l, 0); /* We don't need to check perpendicular lines, because their corners already take care of it. */ if ((fdir == RIGHT && (o == UP || o == DOWN)) || (fdir == DOWN && (o == RIGHT || o == LEFT))) { dprintf (" perpendicular\n"); continue; } /* Choose so that x1,y1 is closest to corner C */ if ((fdir == RIGHT && l->s->x < l->e->x) || (fdir == DOWN && l->s->y < l->e->y)) { x1 = l->s->x; y1 = l->s->y; x2 = l->e->x; y2 = l->e->y; } else { x1 = l->e->x; y1 = l->e->y; x2 = l->s->x; y2 = l->s->y; } /* Eliminate all lines outside our range */ if ((fdir == RIGHT && (x2 < c->x || x1 > c2->x)) || (fdir == DOWN && (y2 < c->y || y1 > c2->y))) { dprintf (" outside our range\n"); continue; } /* Eliminate all lines on the wrong side of us */ if ((edir == UP && y1 > c->y && y2 > c->y) || (edir == DOWN && y1 < c->y && y2 < c->y) || (edir == LEFT && x1 > c->x && x2 > c->x) || (edir == RIGHT && x1 < c->x && x2 < c->x)) { dprintf (" wrong side\n"); continue; } /* For now, cheat on diagonals */ switch (edir) { case RIGHT: if (x1 > x2) x1 = x2; break; case LEFT: if (x1 < x2) x1 = x2; break; case DOWN: if (y1 > y2) y1 = y2; break; case UP: if (y1 < y2) y1 = y2; break; } /* Ok, now see how far we can get for each of our corners. */ for (i = 0; i < cn; i++) { int r = l->line->Thickness + SB + corner_radius (cs[i]) + 1; int len = 0; if ((fdir == RIGHT && (x2 < cs[i]->x || x1 > cs[i]->x)) || (fdir == DOWN && (y2 < cs[i]->y || y1 > cs[i]->y))) continue; if (!intersecting_layers (cs[i]->layer, l->layer)) continue; switch (edir) { case RIGHT: len = x1 - c->x; break; case LEFT: len = c->x - x1; break; case DOWN: len = y1 - c->y; break; case UP: len = c->y - y1; break; } len -= r; dprintf (" len is %#mS vs corner at %#mD\n", len, cs[i]->x, cs[i]->y); if (len <= 0) return 0; if (max > len) max = len; } } /* We must make sure that if a segment isn't being completely removed, that any vias and/or pads don't overlap. */ done = 0; while (!done) { done = 1; for (i = 0; i < cn; i++) for (li = 0; li < cs[i]->n_lines; li++) { line_s *l = cs[i]->lines[li]; corner_s *oc = other_corner (l, cs[i]); if (line_orient (l, cs[i]) != edir) continue; len = line_length (l); if (!oc->pad || !cs[i]->via) { if (!is_hole (l->s) || !is_hole (l->e)) continue; if (len == max) continue; } len -= corner_radius (l->s); len -= corner_radius (l->e); len -= SB + 1; if (max > len) { max = len; done = 0; } } } if (max <= 0) return 0; switch (edir) { case UP: len = c->y - max; break; case DOWN: len = c->y + max; break; case LEFT: len = c->x - max; break; case RIGHT: len = c->x + max; break; } if (snap && max > Settings.Grid) { if (pull < 0) len += Settings.Grid - 1; len = gridsnap (len); } if ((fdir == RIGHT && len == cs[0]->y) || (fdir == DOWN && len == cs[0]->x)) return 0; for (i = 0; i < cn; i++) { if (fdir == RIGHT) { max = len - cs[i]->y; move_corner (cs[i], cs[i]->x, len); } else { max = len - cs[i]->x; move_corner (cs[i], len, cs[i]->y); } } return max * pull; } /*! * \brief Look for straight runs which could be moved to reduce total * trace length. */ static int orthopull () { int any_sel = any_line_selected (); corner_s *c; int rv = 0; for (c = corners; c;) { if (DELETED (c)) continue; if (c->pin || c->pad) { c = c->next; continue; } next_corner = c; rv += orthopull_1 (c, RIGHT, LEFT, any_sel); if (c != next_corner) { c = next_corner; continue; } rv += orthopull_1 (c, DOWN, UP, any_sel); if (c != next_corner) { c = next_corner; continue; } c = c->next; } if (rv) pcb_printf ("orthopull: %ml mils saved\n", rv); return rv; } /*! * \brief Look for "U" shaped traces we can shorten (or eliminate). */ static int debumpify () { int rv = 0; int any_selected = any_line_selected (); line_s *l, *l1, *l2; corner_s *c, *c1, *c2; rect_s rr, rp; int o, o1, o2, step, w; for (l = lines; l; l = l->next) { if (DELETED (l)) continue; if (!l->line) continue; if (any_selected && !selected (l->line)) continue; if (!any_selected && autorouted_only && !autorouted (l->line)) continue; if (l->s->pin || l->s->pad || l->e->pin || l->e->pad) continue; o = line_orient (l, 0); if (o == DIAGONAL) continue; l1 = other_line (l->s, l); if (!l1) continue; o1 = line_orient (l1, l->s); l2 = other_line (l->e, l); if (!l2) continue; o2 = line_orient (l2, l->e); if (ORIENT (o) == ORIENT (o1) || o1 != o2 || o1 == DIAGONAL) continue; dprintf ("\nline: %#mD to %#mD\n", l->s->x, l->s->y, l->e->x, l->e->y); w = l->line->Thickness / 2 + SB + 1; empty_rect (&rr); add_line_to_rect (&rr, l1); add_line_to_rect (&rr, l2); if (rr.x1 != l->s->x && rr.x1 != l->e->x) rr.x1 -= w; if (rr.x2 != l->s->x && rr.x2 != l->e->x) rr.x2 += w; if (rr.y1 != l->s->y && rr.y1 != l->e->y) rr.y1 -= w; if (rr.y2 != l->s->y && rr.y2 != l->e->y) rr.y2 += w; dprintf ("range: x %#mS..%#mS y %#mS..%#mS\n", rr.x1, rr.x2, rr.y1, rr.y2); c1 = other_corner (l1, l->s); c2 = other_corner (l2, l->e); empty_rect (&rp); for (c = corners; c; c = c->next) { if (DELETED (c)) continue; if (c->net != l->s->net && intersecting_layers (c->layer, l->s->layer)) add_corner_to_rect_if (&rp, c, &rr); } if (rp.x1 == INT_MAX) { rp.x1 = rr.x2; rp.x2 = rr.x1; rp.y1 = rr.y2; rp.y2 = rr.y1; } dprintf ("pin r: x %#mS..%#mS y %#mS..%#mS\n", rp.x1, rp.x2, rp.y1, rp.y2); switch (o1) { case LEFT: step = l->s->x - rp.x2 - w; step = gridsnap (step); if (step > l->s->x - c1->x) step = l->s->x - c1->x; if (step > l->s->x - c2->x) step = l->s->x - c2->x; if (step > 0) { dprintf ("left step %#mS at %#mD\n", step, l->s->x, l->s->y); move_corner (l->s, l->s->x - step, l->s->y); move_corner (l->e, l->e->x - step, l->e->y); rv += step; } break; case RIGHT: step = rp.x1 - l->s->x - w; step = gridsnap (step); if (step > c1->x - l->s->x) step = c1->x - l->s->x; if (step > c2->x - l->s->x) step = c2->x - l->s->x; if (step > 0) { dprintf ("right step %#mS at %#mD\n", step, l->s->x, l->s->y); move_corner (l->s, l->s->x + step, l->s->y); move_corner (l->e, l->e->x + step, l->e->y); rv += step; } break; case UP: if (rp.y2 == INT_MIN) rp.y2 = rr.y1; step = trim_step (l->s->y - rp.y2 - w, l->s->y - c1->y, l->s->y - c2->y); if (step > 0) { dprintf ("up step %#mS at %#mD\n", step, l->s->x, l->s->y); move_corner (l->s, l->s->x, l->s->y - step); move_corner (l->e, l->e->x, l->e->y - step); rv += step; } break; case DOWN: step = rp.y1 - l->s->y - w; step = gridsnap (step); if (step > c1->y - l->s->y) step = c1->y - l->s->y; if (step > c2->y - l->s->y) step = c2->y - l->s->y; if (step > 0) { dprintf ("down step %#mS at %#mD\n", step, l->s->x, l->s->y); move_corner (l->s, l->s->x, l->s->y + step); move_corner (l->e, l->e->x, l->e->y + step); rv += step; } break; } check (0, l); } rv += simple_optimizations (); if (rv) pcb_printf ("debumpify: %ml mils saved\n", rv / 50); return rv; } static int simple_corner (corner_s * c) { int o1, o2; if (c->pad || c->pin || c->via) return 0; if (c->n_lines != 2) return 0; o1 = line_orient (c->lines[0], c); o2 = line_orient (c->lines[1], c); if (ORIENT (o1) == ORIENT (o2)) return 0; if (ORIENT (o1) == DIAGONAL || ORIENT (o2) == DIAGONAL) return 0; return 1; } /*! * \brief Look for sequences of simple corners we can reduce. */ static int unjaggy_once () { int rv = 0; corner_s *c, *c0, *c1, *cc; int l, w, sel = any_line_selected (); int o0, o1, s0, s1; rect_s rr, rp; for (c = corners; c; c = c->next) { if (DELETED (c)) continue; if (!simple_corner (c)) continue; if (!c->lines[0]->line || !c->lines[1]->line) continue; if (sel && !(selected (c->lines[0]->line) || selected (c->lines[1]->line))) continue; if (!sel && autorouted_only && !(autorouted (c->lines[0]->line) || autorouted (c->lines[1]->line))) continue; dprintf ("simple at %#mD\n", c->x, c->y); c0 = other_corner (c->lines[0], c); o0 = line_orient (c->lines[0], c); s0 = simple_corner (c0); c1 = other_corner (c->lines[1], c); o1 = line_orient (c->lines[1], c); s1 = simple_corner (c1); if (!s0 && !s1) continue; dprintf ("simples at %#mD\n", c->x, c->y); w = 1; for (l = 0; l < c0->n_lines; l++) if (c0->lines[l] != c->lines[0] && c0->lines[l]->layer == c->lines[0]->layer) { int o = line_orient (c0->lines[l], c0); if (o == o1) w = 0; } for (l = 0; l < c1->n_lines; l++) if (c1->lines[l] != c->lines[0] && c1->lines[l]->layer == c->lines[0]->layer) { int o = line_orient (c1->lines[l], c1); if (o == o0) w = 0; } if (!w) continue; dprintf ("orient ok\n"); w = c->lines[0]->line->Thickness / 2 + SB + 1; empty_rect (&rr); add_line_to_rect (&rr, c->lines[0]); add_line_to_rect (&rr, c->lines[1]); if (c->x != rr.x1) rr.x1 -= w; else rr.x2 += w; if (c->y != rr.y1) rr.y1 -= w; else rr.y2 += w; empty_rect (&rp); for (cc = corners; cc; cc = cc->next) { if (DELETED (cc)) continue; if (cc->net != c->net && intersecting_layers (cc->layer, c->layer)) add_corner_to_rect_if (&rp, cc, &rr); } dprintf ("rp x %#mS..%#mS y %#mS..%#mS\n", rp.x1, rp.x2, rp.y1, rp.y2); if (rp.x1 <= rp.x2) /* something triggered */ continue; dprintf ("unjaggy at %#mD layer %d\n", c->x, c->y, c->layer); if (c->x == c0->x) move_corner (c, c1->x, c0->y); else move_corner (c, c0->x, c1->y); rv++; check (c, 0); } rv += simple_optimizations (); check (c, 0); return rv; } static int unjaggy () { int i, r = 0, j; for (i = 0; i < 100; i++) { j = unjaggy_once (); if (j == 0) break; r += j; } if (r) printf ("%d unjagg%s \n", r, r == 1 ? "y" : "ies"); return r; } /*! * \brief Look for vias with all lines leaving the same way, try to * nudge via to eliminate one or more of them. */ static int vianudge () { int rv = 0; corner_s *c, *c2, *c3; line_s *l; unsigned char directions[MAX_LAYER]; unsigned char counts[MAX_LAYER]; memset (directions, 0, sizeof (directions)); memset (counts, 0, sizeof (counts)); for (c = corners; c; c = c->next) { int o, i, vr, cr, oboth; int len = 0, saved = 0; if (DELETED (c)) continue; if (!c->via) continue; memset (directions, 0, sizeof (directions)); memset (counts, 0, sizeof (counts)); for (i = 0; i < c->n_lines; i++) { o = line_orient (c->lines[i], c); counts[c->lines[i]->layer]++; directions[c->lines[i]->layer] |= o; } for (o = 0, i = 0; i < max_copper_layer; i++) if (counts[i] == 1) { o = directions[i]; break; } switch (o) { case LEFT: case RIGHT: oboth = LEFT | RIGHT; break; case UP: case DOWN: oboth = UP | DOWN; break; default: continue; } for (i = 0; i < max_copper_layer; i++) if (counts[i] && directions[i] != o && directions[i] != oboth) goto vianudge_continue; c2 = 0; for (i = 0; i < c->n_lines; i++) { int ll = line_length (c->lines[i]); if (line_orient (c->lines[i], c) != o) { saved--; continue; } saved++; if (c2 == 0 || len > ll) { len = ll; c2 = other_corner (c->lines[i], c); } } if (c2->pad || c2->pin || c2->via) continue; /* Now look for clearance in the new position */ vr = c->via->Thickness / 2 + SB + 1; for (c3 = corners; c3; c3 = c3->next) { if (DELETED (c3)) continue; if ((c3->net != c->net && (c3->pin || c3->via)) || c3->pad) { cr = corner_radius (c3); if (dist (c2->x, c2->y, c3->x, c3->y) < vr + cr) goto vianudge_continue; } } for (l = lines; l; l = l->next) { if (DELETED (l)) continue; if (l->s->net != c->net) { int ld = dist_line_to_point (l, c2); if (ld < l->line->Thickness / 2 + vr) goto vianudge_continue; } } /* at this point, we know we can move it */ dprintf ("vianudge: nudging via at %#mD by %#mS saving %#mS\n", c->x, c->y, len, saved); rv += len * saved; move_corner (c, c2->x, c2->y); check (c, 0); vianudge_continue: continue; } if (rv) pcb_printf ("vianudge: %ml mils saved\n", rv); return rv; } /*! * \brief Look for traces that can be moved to the other side of the * board, to reduce the number of vias needed. * * For now, we look for simple lines, not multi-segmented lines. */ static int viatrim () { line_s *l, *l2; int i, rv = 0, vrm = 0; int any_sel = any_line_selected (); for (l = lines; l; l = l->next) { rect_s r; int my_layer, other_layer; if (DELETED (l)) continue; if (!l->s->via) continue; if (!l->e->via) continue; if (any_sel && !selected (l->line)) continue; if (!any_sel && autorouted_only && !autorouted (l->line)) continue; my_layer = l->layer; other_layer = -1; dprintf ("line %p on layer %d from %#mD to %#mD\n", (void *) l, l->layer, l->s->x, l->s->y, l->e->x, l->e->y); for (i = 0; i < l->s->n_lines; i++) if (l->s->lines[i] != l) { if (other_layer == -1) { other_layer = l->s->lines[i]->layer; dprintf ("noting other line %p on layer %d\n", (void *) (l->s->lines[i]), my_layer); } else if (l->s->lines[i]->layer != other_layer) { dprintf ("saw other line %p on layer %d (not %d)\n", (void *) (l->s->lines[i]), l->s->lines[i]->layer, my_layer); other_layer = -1; goto viatrim_other_corner; } } viatrim_other_corner: if (other_layer == -1) for (i = 0; i < l->e->n_lines; i++) if (l->e->lines[i] != l) { if (other_layer == -1) { other_layer = l->s->lines[i]->layer; dprintf ("noting other line %p on layer %d\n", (void *) (l->s->lines[i]), my_layer); } else if (l->e->lines[i]->layer != other_layer) { dprintf ("saw end line on layer %d (not %d)\n", l->e->lines[i]->layer, other_layer); goto viatrim_continue; } } /* Now see if any other line intersects us. We don't need to check corners, because they'd either be pins/vias and already conflict, or pads, which we'll check here anyway. */ empty_rect (&r); add_point_to_rect (&r, l->s->x, l->s->y, l->line->Thickness); add_point_to_rect (&r, l->e->x, l->e->y, l->line->Thickness); for (l2 = lines; l2; l2 = l2->next) { if (DELETED (l2)) continue; if (l2->s->net != l->s->net && l2->layer == other_layer) { dprintf ("checking other line %#mD to %#mD\n", l2->s->x, l2->s->y, l2->e->x, l2->e->y); if (line_in_rect (&r, l2)) { dprintf ("line from %#mD to %#mD in the way\n", l2->s->x, l2->s->y, l2->e->x, l2->e->y); goto viatrim_continue; } } } if (l->layer == other_layer) continue; move_line_to_layer (l, other_layer); rv++; viatrim_continue: continue; } vrm = simple_optimizations (); if (rv > 0) printf ("viatrim: %d traces moved, %d vias removed\n", rv, vrm); return rv + vrm; } static int automagic () { int more = 1, oldmore = 0; int toomany = 100; while (more != oldmore && --toomany) { oldmore = more; more += debumpify (); more += unjaggy (); more += orthopull (); more += vianudge (); more += viatrim (); } return more - 1; } static int miter () { corner_s *c; int done, progress; int sel = any_line_selected (); int saved = 0; for (c = corners; c; c = c->next) { if (DELETED (c)) continue; c->miter = 0; if (c->n_lines == 2 && !c->via && !c->pin && !c->via) { int o1 = line_orient (c->lines[0], c); int o2 = line_orient (c->lines[1], c); if (ORIENT (o1) != ORIENT (o2) && o1 != DIAGONAL && o2 != DIAGONAL && c->lines[0]->line->Thickness == c->lines[1]->line->Thickness) c->miter = -1; } } done = 0; progress = 1; while (!done && progress) { done = 1; progress = 0; for (c = corners; c; c = c->next) { if (DELETED (c)) continue; if (c->miter == -1) { int max = line_length (c->lines[0]); int len = line_length (c->lines[1]); int bloat; int ref, dist; corner_s *closest_corner = 0, *c2, *oc1, *oc2; int mx = 0, my = 0, x, y; int o1 = line_orient (c->lines[0], c); int o2 = line_orient (c->lines[1], c); if (c->pad || c->pin || c->via) { c->miter = 0; progress = 1; continue; } oc1 = other_corner (c->lines[0], c); oc2 = other_corner (c->lines[1], c); #if 0 if (oc1->pad) oc1 = 0; if (oc2->pad) oc2 = 0; #endif if ((sel && !(selected (c->lines[0]->line) || selected (c->lines[1]->line))) || (!sel && autorouted_only && !(autorouted (c->lines[0]->line) || autorouted (c->lines[1]->line)))) { c->miter = 0; progress = 1; continue; } if (max > len) max = len; switch (o1) { case LEFT: mx = -1; break; case RIGHT: mx = 1; break; case UP: my = -1; break; case DOWN: my = 1; break; } switch (o2) { case LEFT: mx = -1; break; case RIGHT: mx = 1; break; case UP: my = -1; break; case DOWN: my = 1; break; } ref = c->x * mx + c->y * my; dist = max; bloat = (c->lines[0]->line->Thickness / 2 + SB + 1) * 3 / 2; for (c2 = corners; c2; c2 = c2->next) { if (DELETED (c2)) continue; if (c2 != c && c2 != oc1 && c2 != oc2 && c->x * mx <= c2->x * mx && c->y * my <= c2->y * my && c->net != c2->net && intersecting_layers (c->layer, c2->layer)) { int cr = corner_radius (c2); len = c2->x * mx + c2->y * my - ref - cr - bloat; if (c->x != c2->x && c->y != c2->y) len -= cr; if (len < dist || (len == dist && c->miter != -1)) { dist = len; closest_corner = c2; } } } if (closest_corner && closest_corner->miter == -1) { done = 0; continue; } #if 0 if (dist < Settings.Grid) { c->miter = 0; progress = 1; continue; } dist -= dist % Settings.Grid; #endif if (dist <= 0) { c->miter = 0; progress = 1; continue; } x = c->x; y = c->y; switch (o1) { case LEFT: x -= dist; break; case RIGHT: x += dist; break; case UP: y -= dist; break; case DOWN: y += dist; break; } c2 = find_corner (x, y, c->layer); if (c2 != other_corner (c->lines[0], c)) split_line (c->lines[0], c2); x = c->x; y = c->y; switch (o2) { case LEFT: x -= dist; break; case RIGHT: x += dist; break; case UP: y -= dist; break; case DOWN: y += dist; break; } move_corner (c, x, y); c->miter = 0; c2->miter = 0; progress = 1; saved++; } } } return saved; } static void classify_corner (corner_s * c, int this_net) { int i; if (c->net == this_net) return; c->net = this_net; for (i = 0; i < c->n_lines; i++) classify_corner (other_corner (c->lines[i], c), this_net); } static void classify_nets () { static int this_net = 1; corner_s *c; for (c = corners; c; c = c->next) { if (DELETED (c)) continue; if (c->net) continue; classify_corner (c, this_net); this_net++; } } #if 0 /* Not used */ static void dump_all () { corner_s *c; line_s *l; for (c = corners; c; c = c->next) { if (DELETED (c)) continue; printf ("%p corner %d,%d layer %d net %d\n", (void *) c, c->x, c->y, c->layer, c->net); } for (l = lines; l; l = l->next) { if (DELETED (l)) continue; printf ("%p line %p to %p layer %d\n", (void *) l, (void *) (l->s), (void *) (l->e), l->layer); } } #endif #if 0 static void nudge_corner (corner_s * c, int dx, int dy, corner_s * prev_corner) { int ox = c->x; int oy = c->y; int l; if (prev_corner && (c->pin || c->pad)) return; move_corner (c, ox + dx, oy + dy); for (l = 0; l < c->n_lines; l++) { corner_s *oc = other_corner (c->lines[l], c); if (oc == prev_corner) continue; if (dx && oc->x == ox) nudge_corner (oc, dx, 0, c); if (dy && oc->y == oy) nudge_corner (oc, 0, dy, c); } } #endif static line_s * choose_example_line (corner_s * c1, corner_s * c2) { int ci, li; corner_s *c[2]; c[0] = c1; c[1] = c2; dprintf ("choose_example_line\n"); for (ci = 0; ci < 2; ci++) for (li = 0; li < c[ci]->n_lines; li++) { dprintf (" try[%d,%d] \033[36m<%#mD-%#mD t%#mS c%#mS f%s>\033[0m\n", ci, li, c[ci]->lines[li]->s->x, c[ci]->lines[li]->s->y, c[ci]->lines[li]->e->x, c[ci]->lines[li]->e->y, c[ci]->lines[li]->line->Thickness, c[ci]->lines[li]->line->Clearance, flags_to_string (c[ci]->lines[li]->line->Flags, LINE_TYPE)); /* Pads are disqualified, as we want to mimic a trace line. */ if (c[ci]->lines[li]->line == (LineType *) c[ci]->pad) { dprintf (" bad, pad\n"); continue; } /* Lines on layers that don't connect to the other pad are bad too. */ if (!intersecting_layers (c[ci]->lines[li]->layer, c[1 - ci]->layer)) { dprintf (" bad, layers\n"); continue; } dprintf (" good\n"); return c[ci]->lines[li]; } dprintf ("choose_example_line: none found!\n"); return 0; } static int connect_corners (corner_s * c1, corner_s * c2) { int layer; line_s *ex = choose_example_line (c1, c2); LineType *example = ex->line; dprintf ("connect_corners \033[32m%#mD to %#mD, example line %#mD to %#mD l%d\033[0m\n", c1->x, c1->y, c2->x, c2->y, ex->s->x, ex->s->y, ex->e->x, ex->e->y, ex->layer); layer = ex->layer; /* Assume c1 is the moveable one. */ if (!(c1->pin || c1->pad || c1->via) && c1->n_lines == 1) { int nx, ny; /* Extend the line */ if (c1->lines[0]->s->x == c1->lines[0]->e->x) nx = c1->x, ny = c2->y; else nx = c2->x, ny = c1->y; if (nx != c2->x || ny != c2->y) { move_corner (c1, nx, ny); new_line (c1, c2, layer, example); return 1; } else { move_corner (c1, nx, ny); return 1; } } else { corner_s *nc = find_corner (c1->x, c2->y, layer); new_line (c1, nc, layer, example); new_line (nc, c2, layer, example); return 0; } } /*! * \brief Look for pins that have no connections. * * See if there's a corner close by that should be connected to it. * This usually happens when the MUCS router needs to route to an * off-grid pin. */ static void pinsnap () { corner_s *c; int best_dist[MAX_LAYER + 1]; corner_s *best_c[MAX_LAYER + 1]; int l, got_one; int left = 0, right = 0, top = 0, bottom = 0; PinType *pin; int again = 1; int close = 0; corner_s *c2; while (again) { again = 0; for (c = corners; c; c = c->next) { if (DELETED (c)) continue; if (!(c->pin || c->via || c->pad)) continue; pin = 0; dprintf ("\ncorner %s\n", corner_name (c)); if (c->pin || c->via) { pin = c->pin ? c->pin : c->via; close = pin->Thickness / 2; left = c->x - close; right = c->x + close; bottom = c->y - close; top = c->y + close; } else if (c->pad) { close = c->pad->Thickness / 2 + 1; left = djmin (c->pad->Point1.X, c->pad->Point2.X) - close; right = djmax (c->pad->Point1.X, c->pad->Point2.X) + close; bottom = djmin (c->pad->Point1.Y, c->pad->Point2.Y) - close; top = djmax (c->pad->Point1.Y, c->pad->Point2.Y) + close; if (c->pad->Point1.X == c->pad->Point2.X) { int hy = (c->pad->Point1.Y + c->pad->Point2.Y) / 2; dprintf ("pad y %#mS %#mS hy %#mS c %#mS\n", c->pad->Point1.Y, c->pad->Point2.Y, hy, c->y); if (c->y < hy) top = hy; else bottom = hy + 1; } else { int hx = (c->pad->Point1.X + c->pad->Point2.X) / 2; dprintf ("pad x %#mS %#mS hx %#mS c %#mS\n", c->pad->Point1.X, c->pad->Point2.X, hx, c->x); if (c->x < hx) right = hx; else left = hx + 1; } } dprintf ("%s x %#mS-%#mS y %#mS-%#mS\n", corner_name (c), left, right, bottom, top); for (l = 0; l <= max_copper_layer; l++) { best_dist[l] = close * 2; best_c[l] = 0; } got_one = 0; for (c2 = corners; c2; c2 = c2->next) { int lt; if (DELETED (c2)) continue; lt = corner_radius (c2); if (c2->n_lines && c2 != c && !(c2->pin || c2->pad || c2->via) && intersecting_layers (c->layer, c2->layer) && c2->x >= left - lt && c2->x <= right + lt && c2->y >= bottom - lt && c2->y <= top + lt) { int d = dist (c->x, c->y, c2->x, c2->y); if (pin && d > pin->Thickness / 2 + lt) continue; if (c2->n_lines == 1) { got_one++; dprintf ("found orphan %s vs %s\n", corner_name (c2), corner_name (c)); connect_corners (c, c2); again = 1; continue; } if (best_c[c2->layer] == 0 || c2->n_lines < best_c[c2->layer]->n_lines || (d < best_dist[c2->layer] && c2->n_lines <= best_c[c2->layer]->n_lines)) { best_dist[c2->layer] = d; best_c[c2->layer] = c2; dprintf ("layer %d best now %s\n", c2->layer, corner_name (c2)); } } if (!got_one && c->n_lines == (c->pad ? 1 : 0)) { for (l = 0; l <= max_copper_layer; l++) if (best_c[l]) dprintf ("best[%d] = %s\n", l, corner_name (best_c[l])); for (l = 0; l <= max_copper_layer; l++) if (best_c[l]) { dprintf ("move %s to %s\n", corner_name (best_c[l]), corner_name (c)); connect_corners (best_c[l], c); again = 1; continue; } } } } } /* Now look for line ends that don't connect, see if they need to be extended to intersect another line. */ for (c = corners; c; c = c->next) { line_s *l, *t; int lo; if (DELETED (c)) continue; if (c->pin || c->via || c->pad) continue; if (c->n_lines != 1) continue; l = c->lines[0]; lo = line_orient (l, c); dprintf ("line end %#mD orient %d\n", c->x, c->y, lo); for (t = lines; t; t = t->next) { if (DELETED (t)) continue; if (t->layer != c->lines[0]->layer) continue; switch (lo) /* remember, orient is for the line relative to the corner */ { case LEFT: if (t->s->x == t->e->x && c->x < t->s->x && t->s->x < c->x + (l->line->Thickness + t->line->Thickness) / 2 && ((t->s->y < c->y && c->y < t->e->y) || (t->e->y < c->y && c->y < t->s->y))) { dprintf ("found %#mD - %#mD\n", t->s->x, t->s->y, t->e->x, t->e->y); move_corner (c, t->s->x, c->y); } break; case RIGHT: if (t->s->x == t->e->x && c->x > t->s->x && t->s->x > c->x - (l->line->Thickness + t->line->Thickness) / 2 && ((t->s->y < c->y && c->y < t->e->y) || (t->e->y < c->y && c->y < t->s->y))) { dprintf ("found %#mD - %#mD\n", t->s->x, t->s->y, t->e->x, t->e->y); move_corner (c, t->s->x, c->y); } break; case UP: if (t->s->y == t->e->y && c->y < t->s->y && t->s->y < c->y + (l->line->Thickness + t->line->Thickness) / 2 && ((t->s->x < c->x && c->x < t->e->x) || (t->e->x < c->x && c->x < t->s->x))) { dprintf ("found %#mD - %#mD\n", t->s->x, t->s->y, t->e->x, t->e->y); move_corner (c, c->x, t->s->y); } break; case DOWN: if (t->s->y == t->e->y && c->y > t->s->y && t->s->y > c->y - (l->line->Thickness + t->line->Thickness) / 2 && ((t->s->x < c->x && c->x < t->e->x) || (t->e->x < c->x && c->x < t->s->x))) { dprintf ("found %#mD - %#mD\n", t->s->x, t->s->y, t->e->x, t->e->y); move_corner (c, c->x, t->s->y); } break; } } } } static int pad_orient (PadType * p) { if (p->Point1.X == p->Point2.X) return O_VERT; if (p->Point1.Y == p->Point2.Y) return O_HORIZ; return DIAGONAL; } static void padcleaner () { line_s *l, *nextl; int close; rect_s r; dprintf ("\ndj: padcleaner\n"); for (l = lines; l; l = nextl) { nextl = l->next; if (l->is_pad) continue; if (DELETED (l)) continue; dprintf ("dj: line %p\n", (void *) l); check (0, l); if (l->s->pad && l->s->pad == l->e->pad) continue; ALLPAD_LOOP (PCB->Data); { int layerflag = TEST_FLAG (ONSOLDERFLAG, element) ? LT_BOTTOM : LT_TOP; if (layer_type[l->layer] != layerflag) continue; empty_rect (&r); close = pad->Thickness / 2 + 1; add_point_to_rect (&r, pad->Point1.X, pad->Point1.Y, close - SB / 2); add_point_to_rect (&r, pad->Point2.X, pad->Point2.Y, close - SB / 2); if (pin_in_rect (&r, l->s->x, l->s->y, 0) && pin_in_rect (&r, l->e->x, l->e->y, 0) && ORIENT (line_orient (l, 0)) == pad_orient (pad)) { dprintf ("padcleaner %#mD-%#mD %#mS vs line %#mD-%#mD %#mS\n", pad->Point1.X, pad->Point1.Y, pad->Point2.X, pad->Point2.Y, pad->Thickness, l->s->x, l->s->y, l->e->x, l->e->y, l->line->Thickness); remove_line (l); goto next_line; } } ENDALL_LOOP; next_line:; } } static void grok_layer_groups () { int i, j, f; LayerGroupType *l = &(PCB->LayerGroups); solder_layer = component_layer = -1; for (i = 0; i < max_copper_layer; i++) { layer_type[i] = 0; layer_groupings[i] = 0; } for (i = 0; i < max_group; i++) { f = 0; for (j = 0; j < l->Number[i]; j++) { if (l->Entries[i][j] == bottom_silk_layer) f |= LT_BOTTOM; if (l->Entries[i][j] == top_silk_layer) f |= LT_TOP; } for (j = 0; j < l->Number[i]; j++) { if (l->Entries[i][j] < max_copper_layer) { layer_type[l->Entries[i][j]] |= f; layer_groupings[l->Entries[i][j]] = i; if (solder_layer == -1 && f == LT_BOTTOM) solder_layer = l->Entries[i][j]; if (component_layer == -1 && f == LT_TOP) component_layer = l->Entries[i][j]; } } } } static const char djopt_syntax[] = "djopt(debumpify|unjaggy|simple|vianudge|viatrim|orthopull|splitlines)\n" "djopt(auto) - all of the above\n" "djopt(miter)"; static const char djopt_help[] = "Perform various optimizations on the current board."; /* %start-doc actions djopt The different types of optimizations change your board in order to reduce the total trace length and via count. @table @code @item debumpify Looks for U-shaped traces that can be shortened or eliminated. Example: Before debumpify: @center @image{debumpify,,,Example pcb before debumpify,png} After debumpify: @center @image{debumpify.out,,,Example pcb after debumpify,png} @item unjaggy Looks for corners which could be flipped to eliminate one or more corners (i.e. jaggy lines become simpler). Example: Before unjaggy: @center @image{unjaggy,,,Example pcb before unjaggy,png} After unjaggy: @center @image{unjaggy.out,,,Example pcb after unjaggy,png} @item simple Removing uneeded vias, replacing two or more trace segments in a row with a single segment. This is usually performed automatically after other optimizations. @item vianudge Looks for vias where all traces leave in the same direction. Tries to move via in that direction to eliminate one of the traces (and thus a corner). Example: Before vianudge: @center @image{vianudge,,,Example pcb before vianudge,png} After vianudge: @center @image{vianudge.out,,,Example pcb after vianudge,png} @item viatrim Looks for traces that go from via to via, where moving that trace to a different layer eliminates one or both vias. Example: Before viatrim: @center @image{viatrim,,,Example pcb before viatrim,png} After viatrim: @center @image{viatrim.out,,,Example pcb after viatrim,png} @item orthopull Looks for chains of traces all going in one direction, with more traces orthogonal on one side than on the other. Moves the chain in that direction, causing a net reduction in trace length, possibly eliminating traces and/or corners. Example: Before orthopull: @center @image{orthopull,,,Example pcb before orthopull,png} After orthopull: @center @image{orthopull.out,,,Example pcb after orthopull,png} @item splitlines Looks for lines that pass through vias, pins, or pads, and splits them into separate lines so they can be managed separately. @item auto Performs the above options, repeating until no further optimizations can be made. @item miter Replaces 90 degree corners with a pair of 45 degree corners, to reduce RF losses and trace length. Example: Before miter: @center @image{miter,,,Example pcb before miter,png} After miter: @center @image{miter.out,,,Example pcb after miter,png} @end table %end-doc */ static int ActionDJopt (int argc, char **argv, Coord x, Coord y) { char *arg = argc > 0 ? argv[0] : 0; int layn, saved = 0; corner_s *c; hid_action("Busy"); lines = 0; corners = 0; grok_layer_groups (); ELEMENT_LOOP (PCB->Data); PIN_LOOP (element); { c = find_corner (pin->X, pin->Y, -1); c->pin = pin; } END_LOOP; PAD_LOOP (element); { int layern = TEST_FLAG (ONSOLDERFLAG, pad) ? solder_layer : component_layer; line_s *ls = (line_s *) malloc (sizeof (line_s)); ls->next = lines; lines = ls; ls->is_pad = 1; ls->s = find_corner (pad->Point1.X, pad->Point1.Y, layern); ls->s->pad = pad; ls->e = find_corner (pad->Point2.X, pad->Point2.Y, layern); ls->e->pad = pad; ls->layer = layern; ls->line = (LineType *) pad; add_line_to_corner (ls, ls->s); add_line_to_corner (ls, ls->e); } END_LOOP; END_LOOP; VIA_LOOP (PCB->Data); /* hace don't mess with vias that have thermals */ /* but then again don't bump into them if (!TEST_FLAG(ALLTHERMFLAGS, via)) */ { c = find_corner (via->X, via->Y, -1); c->via = via; } END_LOOP; check (0, 0); for (layn = 0; layn < max_copper_layer; layn++) { LayerType *layer = LAYER_PTR (layn); if (layer->Type != LT_COPPER) continue; LINE_LOOP (layer); { line_s *ls; if(autorouted_only && !autorouted (line)) continue; /* don't mess with thermals */ if (TEST_FLAG (USETHERMALFLAG, line)) continue; if (line->Point1.X == line->Point2.X && line->Point1.Y == line->Point2.Y) { RemoveLine (layer, line); continue; } ls = (line_s *) malloc (sizeof (line_s)); ls->next = lines; lines = ls; ls->is_pad = 0; ls->s = find_corner (line->Point1.X, line->Point1.Y, layn); ls->e = find_corner (line->Point2.X, line->Point2.Y, layn); ls->line = line; add_line_to_corner (ls, ls->s); add_line_to_corner (ls, ls->e); ls->layer = layn; } END_LOOP; } check (0, 0); if (NSTRCMP (arg, "splitlines") != 0) pinsnap (); saved += canonicalize_lines (); check (0, 0); classify_nets (); /*dump_all(); */ check (0, 0); if (NSTRCMP (arg, "debumpify") == 0) saved += debumpify (); else if (NSTRCMP (arg, "unjaggy") == 0) saved += unjaggy (); else if (NSTRCMP (arg, "simple") == 0) saved += simple_optimizations (); else if (NSTRCMP (arg, "vianudge") == 0) saved += vianudge (); else if (NSTRCMP (arg, "viatrim") == 0) saved += viatrim (); else if (NSTRCMP (arg, "orthopull") == 0) saved += orthopull (); else if (NSTRCMP (arg, "auto") == 0) saved += automagic (); else if (NSTRCMP (arg, "miter") == 0) saved += miter (); else if (NSTRCMP (arg, "splitlines") == 0) /* Just to call canonicalize_lines() above. */ ; else { printf ("unknown command: %s\n", arg); return 1; } padcleaner (); check (0, 0); if (saved) IncrementUndoSerialNumber (); return 0; } HID_Action djopt_action_list[] = { {"djopt", 0, ActionDJopt, djopt_help, djopt_syntax} , {"OptAutoOnly", 0, djopt_set_auto_only, djopt_sao_help, djopt_sao_syntax} }; REGISTER_ACTIONS (djopt_action_list) pcb-4.3.0/src/autoplace.h0000664000175000017500000000250313773431044012130 00000000000000/*! * \file src/autoplace.h * * \brief Prototypes for autoplace routines. * * \author this file, autoplace.h, was written and is * Copyright (c) 2001 C. Scott Ananian. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * Copyright (C) 1998,1999,2000,2001 harry eaton * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA * haceaton@aplcomm.jhuapl.edu */ #ifndef PCB_AUTOPLACE_H #define PCB_AUTOPLACE_H #include "global.h" bool AutoPlaceSelected (void); #endif pcb-4.3.0/src/lrealpath.h0000664000175000017500000000030313773431044012123 00000000000000/*! * \file src/lrealpath.h * * \brief Prototypes for Libiberty realpath. */ #ifndef PCB_LREALPATH_H #define PCB_LREALPATH_H char *lrealpath (const char *); #endif /* PCB_LREALPATH_H */ pcb-4.3.0/src/mymem.c0000664000175000017500000004720413773431044011301 00000000000000/*! * \file src/mymem.c * * \brief Memory management functions. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * * Thomas.Nau@rz.uni-ulm.de */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "global.h" #include #include "data.h" #include "error.h" #include "mymem.h" #include "misc.h" #include "rats.h" #include "rtree.h" #ifdef HAVE_LIBDMALLOC #include #endif /* --------------------------------------------------------------------------- * local prototypes */ static void DSRealloc (DynamicStringType *, size_t); /* This API is quite new, provide a version here */ #if !GLIB_CHECK_VERSION (2, 28, 0) static void g_list_free_full (GList *list, GDestroyNotify free_func) { g_list_foreach (list, (GFunc) free_func, NULL); g_list_free (list); } #endif /*! * \brief Get the next slot for a rubberband connection. * * Allocates memory if necessary. */ RubberbandType * GetRubberbandMemory (void) { RubberbandType *ptr = Crosshair.AttachedObject.Rubberband; /* realloc new memory if necessary and clear it */ if (Crosshair.AttachedObject.RubberbandN >= Crosshair.AttachedObject.RubberbandMax) { Crosshair.AttachedObject.RubberbandMax += STEP_RUBBERBAND; ptr = (RubberbandType *)realloc (ptr, Crosshair.AttachedObject.RubberbandMax * sizeof (RubberbandType)); Crosshair.AttachedObject.Rubberband = ptr; memset (ptr + Crosshair.AttachedObject.RubberbandN, 0, STEP_RUBBERBAND * sizeof (RubberbandType)); } return (ptr + Crosshair.AttachedObject.RubberbandN++); } void ** GetPointerMemory (PointerListType *list) { void **ptr = list->Ptr; /* realloc new memory if necessary and clear it */ if (list->PtrN >= list->PtrMax) { list->PtrMax = STEP_POINT + (2 * list->PtrMax); ptr = (void **)realloc (ptr, list->PtrMax * sizeof (void *)); list->Ptr = ptr; memset (ptr + list->PtrN, 0, (list->PtrMax - list->PtrN) * sizeof (void *)); } return (ptr + list->PtrN++); } void FreePointerListMemory (PointerListType *list) { free (list->Ptr); memset (list, 0, sizeof (PointerListType)); } /*! * \brief Get the next slot for a box. * * Allocates memory if necessary. */ BoxType * GetBoxMemory (BoxListType *Boxes) { BoxType *box = Boxes->Box; /* realloc new memory if necessary and clear it */ if (Boxes->BoxN >= Boxes->BoxMax) { Boxes->BoxMax = STEP_POINT + (2 * Boxes->BoxMax); box = (BoxType *)realloc (box, Boxes->BoxMax * sizeof (BoxType)); Boxes->Box = box; memset (box + Boxes->BoxN, 0, (Boxes->BoxMax - Boxes->BoxN) * sizeof (BoxType)); } return (box + Boxes->BoxN++); } /*! * \brief Get the next slot for a connection. * * Allocates memory if necessary. */ ConnectionType * GetConnectionMemory (NetType *Net) { ConnectionType *con = Net->Connection; /* realloc new memory if necessary and clear it */ if (Net->ConnectionN >= Net->ConnectionMax) { Net->ConnectionMax += STEP_POINT; con = (ConnectionType *)realloc (con, Net->ConnectionMax * sizeof (ConnectionType)); Net->Connection = con; memset (con + Net->ConnectionN, 0, STEP_POINT * sizeof (ConnectionType)); } return (con + Net->ConnectionN++); } /*! * \brief Get the next slot for a subnet. * * Allocates memory if necessary. */ NetType * GetNetMemory (NetListType *Netlist) { NetType *net = Netlist->Net; /* realloc new memory if necessary and clear it */ if (Netlist->NetN >= Netlist->NetMax) { Netlist->NetMax += STEP_POINT; net = (NetType *)realloc (net, Netlist->NetMax * sizeof (NetType)); Netlist->Net = net; memset (net + Netlist->NetN, 0, STEP_POINT * sizeof (NetType)); } return (net + Netlist->NetN++); } /*! * \brief Get the next slot for a net list. * * Allocates memory if necessary. */ NetListType * GetNetListMemory (NetListListType *Netlistlist) { NetListType *netlist = Netlistlist->NetList; /* realloc new memory if necessary and clear it */ if (Netlistlist->NetListN >= Netlistlist->NetListMax) { Netlistlist->NetListMax += STEP_POINT; netlist = (NetListType *)realloc (netlist, Netlistlist->NetListMax * sizeof (NetListType)); Netlistlist->NetList = netlist; memset (netlist + Netlistlist->NetListN, 0, STEP_POINT * sizeof (NetListType)); } return (netlist + Netlistlist->NetListN++); } /*! * \brief Get the next slot for a pin. * * Allocates memory if necessary. */ PinType * GetPinMemory (ElementType *element) { PinType *new_obj; new_obj = g_slice_new0 (PinType); element->Pin = g_list_append (element->Pin, new_obj); element->PinN ++; return new_obj; } static void FreePin (PinType *data) { g_slice_free (PinType, data); } /*! * \brief Get the next slot for a pad. * * Allocates memory if necessary. */ PadType * GetPadMemory (ElementType *element) { PadType *new_obj; new_obj = g_slice_new0 (PadType); element->Pad = g_list_append (element->Pad, new_obj); element->PadN ++; return new_obj; } static void FreePad (PadType *data) { g_slice_free (PadType, data); } /*! * \brief Get the next slot for a via. * * Allocates memory if necessary. */ PinType * GetViaMemory (DataType *data) { PinType *new_obj; new_obj = g_slice_new0 (PinType); data->Via = g_list_append (data->Via, new_obj); data->ViaN ++; return new_obj; } static void FreeVia (PinType *data) { g_slice_free (PinType, data); } /*! * \brief Get the next slot for a Rat. * * Allocates memory if necessary. */ RatType * GetRatMemory (DataType *data) { RatType *new_obj; new_obj = g_slice_new0 (RatType); data->Rat = g_list_append (data->Rat, new_obj); data->RatN ++; return new_obj; } static void FreeRat (RatType *data) { g_slice_free (RatType, data); } /*! * \brief Get the next slot for a line. * * Allocates memory if necessary. */ LineType * GetLineMemory (LayerType *layer) { LineType *new_obj; new_obj = g_slice_new0 (LineType); layer->Line = g_list_append (layer->Line, new_obj); layer->LineN ++; return new_obj; } static void FreeLine (LineType *data) { g_slice_free (LineType, data); } /*! * \brief Get the next slot for an arc. * * Allocates memory if necessary. */ ArcType * GetArcMemory (LayerType *layer) { ArcType *new_obj; new_obj = g_slice_new0 (ArcType); layer->Arc = g_list_append (layer->Arc, new_obj); layer->ArcN ++; return new_obj; } static void FreeArc (ArcType *data) { g_slice_free (ArcType, data); } /*! * \brief Get the next slot for a text object. * * Allocates memory if necessary. */ TextType * GetTextMemory (LayerType *layer) { TextType *new_obj; new_obj = g_slice_new0 (TextType); layer->Text = g_list_append (layer->Text, new_obj); layer->TextN ++; return new_obj; } static void FreeText (TextType *data) { g_slice_free (TextType, data); } /*! * \brief Get the next slot for a polygon object. * * Allocates memory if necessary. */ PolygonType * GetPolygonMemory (LayerType *layer) { PolygonType *new_obj; new_obj = g_slice_new0 (PolygonType); layer->Polygon = g_list_append (layer->Polygon, new_obj); layer->PolygonN ++; return new_obj; } static void FreePolygon (PolygonType *data) { g_slice_free (PolygonType, data); } /*! * \brief Get the next slot for a point in a polygon struct. * * Allocates memory if necessary. */ PointType * GetPointMemoryInPolygon (PolygonType *Polygon) { PointType *points = Polygon->Points; /* realloc new memory if necessary and clear it */ if (Polygon->PointN >= Polygon->PointMax) { Polygon->PointMax += STEP_POLYGONPOINT; points = (PointType *)realloc (points, Polygon->PointMax * sizeof (PointType)); Polygon->Points = points; memset (points + Polygon->PointN, 0, STEP_POLYGONPOINT * sizeof (PointType)); } return (points + Polygon->PointN++); } /*! * \brief Gets the next slot for a point in a polygon struct. * * Allocates memory if necessary. */ Cardinal * GetHoleIndexMemoryInPolygon (PolygonType *Polygon) { Cardinal *holeindex = Polygon->HoleIndex; /* realloc new memory if necessary and clear it */ if (Polygon->HoleIndexN >= Polygon->HoleIndexMax) { Polygon->HoleIndexMax += STEP_POLYGONHOLEINDEX; holeindex = (Cardinal *)realloc (holeindex, Polygon->HoleIndexMax * sizeof (int)); Polygon->HoleIndex = holeindex; memset (holeindex + Polygon->HoleIndexN, 0, STEP_POLYGONHOLEINDEX * sizeof (int)); } return (holeindex + Polygon->HoleIndexN++); } /*! * \brief Get the next slot for an element. * * Allocates memory if necessary. */ ElementType * GetElementMemory (DataType *data) { ElementType *new_obj; new_obj = g_slice_new0 (ElementType); if (data != NULL) { data->Element = g_list_append (data->Element, new_obj); data->ElementN ++; } return new_obj; } static void FreeElement (ElementType *data) { g_slice_free (ElementType, data); } /*! * \brief Get the next slot for a library menu. * * Allocates memory if necessary. */ LibraryMenuType * GetLibraryMenuMemory (LibraryType *lib) { LibraryMenuType *menu = lib->Menu; /* realloc new memory if necessary and clear it */ if (lib->MenuN >= lib->MenuMax) { lib->MenuMax += STEP_LIBRARYMENU; menu = (LibraryMenuType *)realloc (menu, lib->MenuMax * sizeof (LibraryMenuType)); lib->Menu = menu; memset (menu + lib->MenuN, 0, STEP_LIBRARYMENU * sizeof (LibraryMenuType)); } return (menu + lib->MenuN++); } /*! * \brief Get the next slot for a library entry. * * Allocates memory if necessary. */ LibraryEntryType * GetLibraryEntryMemory (LibraryMenuType *Menu) { LibraryEntryType *entry = Menu->Entry; /* realloc new memory if necessary and clear it */ if (Menu->EntryN >= Menu->EntryMax) { Menu->EntryMax += STEP_LIBRARYENTRY; entry = (LibraryEntryType *)realloc (entry, Menu->EntryMax * sizeof (LibraryEntryType)); Menu->Entry = entry; memset (entry + Menu->EntryN, 0, STEP_LIBRARYENTRY * sizeof (LibraryEntryType)); } return (entry + Menu->EntryN++); } /*! * \brief Get the next slot for a DrillElement. * * Allocates memory if necessary. */ ElementType ** GetDrillElementMemory (DrillType *Drill) { ElementType **element; element = Drill->Element; /* realloc new memory if necessary and clear it */ if (Drill->ElementN >= Drill->ElementMax) { Drill->ElementMax += STEP_ELEMENT; element = (ElementType **)realloc (element, Drill->ElementMax * sizeof (ElementType *)); Drill->Element = element; memset (element + Drill->ElementN, 0, STEP_ELEMENT * sizeof (ElementType *)); } return (element + Drill->ElementN++); } /*! * \brief Get the next slot for a DrillPoint. * * Allocates memory if necessary. */ PinType ** GetDrillPinMemory (DrillType *Drill) { PinType **pin; pin = Drill->Pin; /* realloc new memory if necessary and clear it */ if (Drill->PinN >= Drill->PinMax) { Drill->PinMax += STEP_POINT; pin = (PinType **)realloc (pin, Drill->PinMax * sizeof (PinType *)); Drill->Pin = pin; memset (pin + Drill->PinN, 0, STEP_POINT * sizeof (PinType *)); } return (pin + Drill->PinN++); } /*! * \brief Get the next slot for a Drill. * * Allocates memory if necessary. */ DrillType * GetDrillInfoDrillMemory (DrillInfoType *DrillInfo) { DrillType *drill = DrillInfo->Drill; /* realloc new memory if necessary and clear it */ if (DrillInfo->DrillN >= DrillInfo->DrillMax) { DrillInfo->DrillMax += STEP_DRILL; drill = (DrillType *)realloc (drill, DrillInfo->DrillMax * sizeof (DrillType)); DrillInfo->Drill = drill; memset (drill + DrillInfo->DrillN, 0, STEP_DRILL * sizeof (DrillType)); } return (drill + DrillInfo->DrillN++); } /*! * \brief Free the memory used by a polygon. */ void FreePolygonMemory (PolygonType *polygon) { if (polygon == NULL) return; free (polygon->Points); free (polygon->HoleIndex); if (polygon->Clipped) poly_Free (&polygon->Clipped); poly_FreeContours (&polygon->NoHoles); memset (polygon, 0, sizeof (PolygonType)); } /*! * \brief Free the memory used by a box list. */ void FreeBoxListMemory (BoxListType *Boxlist) { if (Boxlist) { free (Boxlist->Box); memset (Boxlist, 0, sizeof (BoxListType)); } } /*! * \brief Free the memory used by a net. */ void FreeNetListMemory (NetListType *Netlist) { if (Netlist) { NET_LOOP (Netlist); { FreeNetMemory (net); } END_LOOP; free (Netlist->Net); memset (Netlist, 0, sizeof (NetListType)); } } /*! * \brief Free the memory used by a net list. */ void FreeNetListListMemory (NetListListType *Netlistlist) { if (Netlistlist) { NETLIST_LOOP (Netlistlist); { FreeNetListMemory (netlist); } END_LOOP; free (Netlistlist->NetList); memset (Netlistlist, 0, sizeof (NetListListType)); } } /*! * \brief Free the memory used by a subnet. */ void FreeNetMemory (NetType *Net) { if (Net) { free (Net->Connection); memset (Net, 0, sizeof (NetType)); } } /*! * \brief Free the memory used by an attribute list. */ static void FreeAttributeListMemory (AttributeListType *list) { int i; for (i = 0; i < list->Number; i++) { free (list->List[i].name); free (list->List[i].value); } free (list->List); list->List = NULL; list->Max = 0; } /*! * \brief Free the memory used by an element. */ void FreeElementMemory (ElementType *element) { if (element == NULL) return; ELEMENTNAME_LOOP (element); { free (textstring); } END_LOOP; PIN_LOOP (element); { free (pin->Name); free (pin->Number); } END_LOOP; PAD_LOOP (element); { free (pad->Name); free (pad->Number); } END_LOOP; g_list_free_full (element->Pin, (GDestroyNotify)FreePin); g_list_free_full (element->Pad, (GDestroyNotify)FreePad); g_list_free_full (element->Line, (GDestroyNotify)FreeLine); g_list_free_full (element->Arc, (GDestroyNotify)FreeArc); FreeAttributeListMemory (&element->Attributes); memset (element, 0, sizeof (ElementType)); } /*! * \brief Free the memory used by PCB. */ void FreePCBMemory (PCBType *pcb) { int i; if (pcb == NULL) return; free (pcb->Name); free (pcb->Filename); free (pcb->PrintFilename); FreeDataMemory (pcb->Data); free (pcb->Data); /* release font symbols */ for (i = 0; i <= MAX_FONTPOSITION; i++) free (pcb->Font.Symbol[i].Line); FreeLibraryMemory (&pcb->NetlistLib); NetlistChanged (0); FreeAttributeListMemory (&pcb->Attributes); /* clear struct */ memset (pcb, 0, sizeof (PCBType)); } /*! * \brief Free the memory used by data struct. */ void FreeDataMemory (DataType *data) { LayerType *layer; int i; if (data == NULL) return; VIA_LOOP (data); { free (via->Name); } END_LOOP; g_list_free_full (data->Via, (GDestroyNotify)FreeVia); ELEMENT_LOOP (data); { FreeElementMemory (element); } END_LOOP; g_list_free_full (data->Element, (GDestroyNotify)FreeElement); g_list_free_full (data->Rat, (GDestroyNotify)FreeRat); for (layer = data->Layer, i = 0; i < MAX_ALL_LAYER; layer++, i++) { FreeAttributeListMemory (&layer->Attributes); TEXT_LOOP (layer); { free (text->TextString); } END_LOOP; if (layer->Name) free (layer->Name); LINE_LOOP (layer); { if (line->Number) free (line->Number); } END_LOOP; g_list_free_full (layer->Line, (GDestroyNotify)FreeLine); g_list_free_full (layer->Arc, (GDestroyNotify)FreeArc); g_list_free_full (layer->Text, (GDestroyNotify)FreeText); POLYGON_LOOP (layer); { FreePolygonMemory (polygon); } END_LOOP; g_list_free_full (layer->Polygon, (GDestroyNotify)FreePolygon); if (layer->line_tree) r_destroy_tree (&layer->line_tree); if (layer->arc_tree) r_destroy_tree (&layer->arc_tree); if (layer->text_tree) r_destroy_tree (&layer->text_tree); if (layer->polygon_tree) r_destroy_tree (&layer->polygon_tree); } if (data->element_tree) r_destroy_tree (&data->element_tree); for (i = 0; i < MAX_ELEMENTNAMES; i++) if (data->name_tree[i]) r_destroy_tree (&data->name_tree[i]); if (data->via_tree) r_destroy_tree (&data->via_tree); if (data->pin_tree) r_destroy_tree (&data->pin_tree); if (data->pad_tree) r_destroy_tree (&data->pad_tree); if (data->rat_tree) r_destroy_tree (&data->rat_tree); /* clear struct */ memset (data, 0, sizeof (DataType)); } /*! * \brief Free the memory that's allocated by the library. */ void FreeLibraryMemory (LibraryType *lib) { MENU_LOOP (lib); { ENTRY_LOOP (menu); { free (entry->AllocatedMemory); free (entry->ListEntry); } END_LOOP; free (menu->Entry); free (menu->Name); } END_LOOP; free (lib->Menu); /* clear struct */ memset (lib, 0, sizeof (LibraryType)); } /*! * \brief Reallocates memory for a dynamic length string if necessary. */ static void DSRealloc (DynamicStringType *Ptr, size_t Length) { int input_null = (Ptr->Data == NULL); if (input_null || Length >= Ptr->MaxLength) { Ptr->MaxLength = Length + 512; Ptr->Data = (char *)realloc (Ptr->Data, Ptr->MaxLength); if (input_null) Ptr->Data[0] = '\0'; } } /*! * \brief Adds one character to a dynamic string. */ void DSAddCharacter (DynamicStringType *Ptr, char Char) { size_t position = Ptr->Data ? strlen (Ptr->Data) : 0; DSRealloc (Ptr, position + 1); Ptr->Data[position++] = Char; Ptr->Data[position] = '\0'; } /*! * \brief Add a string to a dynamic string. */ void DSAddString (DynamicStringType *Ptr, const char *S) { size_t position = Ptr->Data ? strlen (Ptr->Data) : 0; if (S && *S) { DSRealloc (Ptr, position + 1 + strlen (S)); strcat (&Ptr->Data[position], S); } } /*! * \brief Clear a dynamic string. */ void DSClearString (DynamicStringType *Ptr) { if (Ptr->Data) Ptr->Data[0] = '\0'; } /*! * \brief Strips leading and trailing blanks from the passed string. * * \return a pointer to the new 'duped' one or NULL if the old one * holds only white space characters. */ char * StripWhiteSpaceAndDup (const char *S) { const char *p1, *p2; char *copy; size_t length; if (!S || !*S) return (NULL); /* strip leading blanks */ for (p1 = S; *p1 && isspace ((int) *p1); p1++); /* strip trailing blanks and get string length */ length = strlen (p1); for (p2 = p1 + length - 1; length && isspace ((int) *p2); p2--, length--); /* string is not empty -> allocate memory */ if (length) { copy = (char *)realloc (NULL, length + 1); strncpy (copy, p1, length); copy[length] = '\0'; return (copy); } else return (NULL); } pcb-4.3.0/src/edif_parse.h0000664000175000017500000000166413773431044012263 00000000000000/* * COPYRIGHT * * Copyright (C) 2006 Jeffry C Bailey * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #ifndef PCB_EDIF_PARSE_H #define PCB_EDIF_PARSE_H void ParseEDIF(char* filename,FILE* err); #endif /* PCB_EDIF_PARSE_H */ pcb-4.3.0/src/icons/0000775000175000017500000000000014017001275011164 500000000000000pcb-4.3.0/src/icons/Makefile.in0000664000175000017500000004011414017000757013155 00000000000000# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = src/icons ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_gl.m4 \ $(top_srcdir)/m4/ax_check_glu.m4 \ $(top_srcdir)/m4/ax_lang_compiler_ms.m4 \ $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/codeset.m4 \ $(top_srcdir)/m4/extern-inline.m4 $(top_srcdir)/m4/fcntl-o.m4 \ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/glibc2.m4 \ $(top_srcdir)/m4/glibc21.m4 $(top_srcdir)/m4/iconv.m4 \ $(top_srcdir)/m4/intdiv0.m4 $(top_srcdir)/m4/intl.m4 \ $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/intmax.m4 \ $(top_srcdir)/m4/inttypes-pri.m4 \ $(top_srcdir)/m4/inttypes_h.m4 $(top_srcdir)/m4/lcmessage.m4 \ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/lock.m4 \ $(top_srcdir)/m4/longlong.m4 $(top_srcdir)/m4/nls.m4 \ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/printf-posix.m4 \ $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/size_max.m4 \ $(top_srcdir)/m4/stdint_h.m4 $(top_srcdir)/m4/threadlib.m4 \ $(top_srcdir)/m4/uintmax_t.m4 $(top_srcdir)/m4/visibility.m4 \ $(top_srcdir)/m4/wchar_t.m4 $(top_srcdir)/m4/wint_t.m4 \ $(top_srcdir)/m4/xsize.m4 $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/m4/m4_ax_func_mkdir.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BTNMOD = @BTNMOD@ BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@ CAIRO_CFLAGS = @CAIRO_CFLAGS@ CAIRO_LIBS = @CAIRO_LIBS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CC_OR_CXX = @CC_OR_CXX@ CFLAGS = @CFLAGS@ CFLAG_VISIBILITY = @CFLAG_VISIBILITY@ CONVERT = @CONVERT@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIRNAME = @DATADIRNAME@ DBUS_CFLAGS = @DBUS_CFLAGS@ DBUS_LIBS = @DBUS_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOC = @DOC@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FONTFILENAME = @FONTFILENAME@ GAFDATADIR = @GAFDATADIR@ GDLIB_CFLAGS = @GDLIB_CFLAGS@ GDLIB_CONFIG = @GDLIB_CONFIG@ GDLIB_LIBS = @GDLIB_LIBS@ GENCAT = @GENCAT@ GERBV = @GERBV@ GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ GLIBC2 = @GLIBC2@ GLIBC21 = @GLIBC21@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GLU_CFLAGS = @GLU_CFLAGS@ GLU_LIBS = @GLU_LIBS@ GL_CFLAGS = @GL_CFLAGS@ GL_LIBS = @GL_LIBS@ GMSGFMT = @GMSGFMT@ GMSGFMT_015 = @GMSGFMT_015@ GNUM4 = @GNUM4@ GREP = @GREP@ GSCHEM = @GSCHEM@ GTKGLEXT_CFLAGS = @GTKGLEXT_CFLAGS@ GTKGLEXT_LIBS = @GTKGLEXT_LIBS@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_LIBS = @GTK_LIBS@ GTK_UPDATE_ICON_CACHE_BIN = @GTK_UPDATE_ICON_CACHE_BIN@ HAVE_ASPRINTF = @HAVE_ASPRINTF@ HAVE_NEWLOCALE = @HAVE_NEWLOCALE@ HAVE_POSIX_PRINTF = @HAVE_POSIX_PRINTF@ HAVE_SNPRINTF = @HAVE_SNPRINTF@ HAVE_VISIBILITY = @HAVE_VISIBILITY@ HAVE_WPRINTF = @HAVE_WPRINTF@ HIDLIBS = @HIDLIBS@ HIDLIST = @HIDLIST@ IM_ANIMATE = @IM_ANIMATE@ IM_COMPARE = @IM_COMPARE@ IM_COMPOSITE = @IM_COMPOSITE@ IM_CONVERT = @IM_CONVERT@ IM_DISPLAY = @IM_DISPLAY@ IM_MONTAGE = @IM_MONTAGE@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTOBJEXT = @INSTOBJEXT@ INTLBISON = @INTLBISON@ INTLLIBS = @INTLLIBS@ INTLOBJS = @INTLOBJS@ INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ INTLTOOL_MERGE = @INTLTOOL_MERGE@ INTLTOOL_PERL = @INTLTOOL_PERL@ INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@ INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@ INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@ INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ INTL_DEFAULT_VERBOSITY = @INTL_DEFAULT_VERBOSITY@ INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ KDEDATADIR = @KDEDATADIR@ KPSEWHICH = @KPSEWHICH@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LEX_PATH = @LEX_PATH@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBMULTITHREAD = @LIBMULTITHREAD@ LIBOBJS = @LIBOBJS@ LIBPTH = @LIBPTH@ LIBPTH_PREFIX = @LIBPTH_PREFIX@ LIBRARYFILENAME = @LIBRARYFILENAME@ LIBS = @LIBS@ LIBTHREAD = @LIBTHREAD@ LTLIBC = @LTLIBC@ LTLIBICONV = @LTLIBICONV@ LTLIBINTL = @LTLIBINTL@ LTLIBMULTITHREAD = @LTLIBMULTITHREAD@ LTLIBOBJS = @LTLIBOBJS@ LTLIBPTH = @LTLIBPTH@ LTLIBTHREAD = @LTLIBTHREAD@ M4 = @M4@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MKINFO = @MKINFO@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCB = @PCB@ PCBLIBDIR = @PCBLIBDIR@ PCBTREEDIR = @PCBTREEDIR@ PCBTREEPATH = @PCBTREEPATH@ PDFLATEX = @PDFLATEX@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POSUB = @POSUB@ PPMTOWINICON = @PPMTOWINICON@ PRI_MACROS_BROKEN = @PRI_MACROS_BROKEN@ PS2PDF = @PS2PDF@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SETENV = @SETENV@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TEXI2DVI = @TEXI2DVI@ TOPDIRS = @TOPDIRS@ UPDATE_DESKTOP_DATABASE = @UPDATE_DESKTOP_DATABASE@ UPDATE_MIME_DATABASE = @UPDATE_MIME_DATABASE@ USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ WIN32 = @WIN32@ WINDRES = @WINDRES@ WISH = @WISH@ WITHGUI = @WITHGUI@ WOE32 = @WOE32@ WOE32DLL = @WOE32DLL@ XDGDATADIR = @XDGDATADIR@ XGETTEXT = @XGETTEXT@ XGETTEXT_015 = @XGETTEXT_015@ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ XHOST = @XHOST@ XMKMF = @XMKMF@ XPMTOPPM = @XPMTOPPM@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ YACC = @YACC@ YACC_PATH = @YACC_PATH@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intltool__v_merge_options_ = @intltool__v_merge_options_@ intltool__v_merge_options_0 = @intltool__v_merge_options_0@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = hand.dat hcurs.dat lcurs.dat lock.dat all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/icons/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/icons/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic cscopelist-am \ ctags-am distclean distclean-generic distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: pcb-4.3.0/src/icons/lock.dat0000664000175000017500000000073713773431044012546 00000000000000#define lock_width 21 #define lock_height 21 static unsigned char lock_bits[] = { 0x00, 0x1f, 0x00, 0x80, 0x31, 0x00, 0x80, 0x20, 0x00, 0xc0, 0x60, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, 0x00, 0xf0, 0xff, 0x01, 0x10, 0x00, 0x01, 0xf0, 0xff, 0x01, 0x10, 0x00, 0x01, 0xf0, 0xff, 0x01, 0x10, 0x00, 0x01, 0xf0, 0xff, 0x01, 0x00, 0x00, 0x00, 0x84, 0xb1, 0x04, 0x44, 0x8a, 0x04, 0x44, 0x8a, 0x02, 0x44, 0x8a, 0x01, 0x44, 0x8a, 0x02, 0x44, 0x8a, 0x04, 0x9c, 0xb1, 0x04}; pcb-4.3.0/src/icons/lcurs.dat0000664000175000017500000000043713773431044012743 00000000000000#define lcurs_width 16 #define lcurs_height 16 static unsigned char lcurs_bits[] = { 0xf0, 0x0f, 0xf0, 0x0f, 0xf8, 0x1f, 0x38, 0x1c, 0x1c, 0x3c, 0x1c, 0x38, 0x1c, 0x30, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f}; pcb-4.3.0/src/icons/hcurs.dat0000664000175000017500000000051313773431044012732 00000000000000#define hcurs_width 16 #define hcurs_height 16 #define hcurs_x_hot 7 #define hcurs_y_hot 9 static unsigned char hcurs_bits[] = { 0x80, 0x00, 0xc8, 0x09, 0xdc, 0x1d, 0xdc, 0x1d, 0xdc, 0x1d, 0xfc, 0xcf, 0x38, 0xee, 0x1f, 0x78, 0x0f, 0x78, 0x07, 0x30, 0x07, 0x30, 0x0e, 0x38, 0x1e, 0x3c, 0x3c, 0x1e, 0xf8, 0x0f, 0xf0, 0x0f}; pcb-4.3.0/src/icons/Makefile.am0000664000175000017500000000006313773431044013150 00000000000000EXTRA_DIST= hand.dat hcurs.dat lcurs.dat lock.dat pcb-4.3.0/src/icons/hand.dat0000664000175000017500000000073713773431044012530 00000000000000#define hand_width 21 #define hand_height 21 static unsigned char hand_bits[] = { 0x00, 0x02, 0x00, 0x20, 0x25, 0x00, 0x50, 0x55, 0x02, 0x50, 0x55, 0x05, 0x50, 0x55, 0x05, 0xd3, 0xd4, 0x06, 0x95, 0x48, 0x02, 0x19, 0x40, 0x01, 0x12, 0x00, 0x01, 0x04, 0x80, 0x00, 0x08, 0x80, 0x00, 0x10, 0x80, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x38, 0x26, 0x02, 0x48, 0x69, 0x02, 0x48, 0xe9, 0x02, 0x38, 0xaf, 0x02, 0x08, 0xa9, 0x03, 0x08, 0x29, 0x03, 0x08, 0x29, 0x02}; pcb-4.3.0/src/resource.h0000664000175000017500000000203513773431044012002 00000000000000#ifndef PCB_RESOURCE_H #define PCB_RESOURCE_H #include #ifdef __cplusplus extern "C" { #endif struct Resource; typedef struct ResourceVal { char *name; char *value; struct Resource *subres; } ResourceVal; #define FLAG_V 1 #define FLAG_NV 2 #define FLAG_S 4 #define FLAG_NS 8 typedef struct Resource { struct Resource *parent; void *user_ptr; int flags; int c; /* number of v[i] */ ResourceVal *v; } Resource; #define resource_type(resval) (((resval).name?100:0)+((resval).value?10:0)+((resval).subres?1:0)) /* res_parse.y */ /* Pass either filename OR stringtab. */ Resource *resource_parse (const char *filename, const char **stringtab); char *resource_value (const Resource * res, char *name); Resource *resource_subres (const Resource * res, const char *name); Resource *resource_create (Resource * parent); void resource_add_val (Resource * n, char *name, char *value, Resource * subres); void resource_dump (Resource * res); #ifdef __cplusplus } #endif #endif pcb-4.3.0/src/undo.h0000664000175000017500000000574513773431044011133 00000000000000/*! * \file src/undo.h * * \brief Prototypes for undo routines. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * * Thomas.Nau@rz.uni-ulm.de */ #ifndef PCB_UNDO_H #define PCB_UNDO_H #include "global.h" #define DRAW_FLAGS (RATFLAG | SELECTEDFLAG | SQUAREFLAG | \ HIDENAMEFLAG | HOLEFLAG | OCTAGONFLAG | \ CONNECTEDFLAG | FOUNDFLAG | CLEARLINEFLAG) /* different layers */ int Undo (bool); int Redo (bool); int IncrementUndoSerialNumber (void); int SaveUndoSerialNumber (void); int RestoreUndoSerialNumber (void); int MergeUndoSerialRange (int, int); void ClearUndoList (bool); void MoveObjectToRemoveUndoList (int, void *, void *, void *); void AddObjectToRemovePointUndoList (int, void *, void *, Cardinal); void AddObjectToInsertPointUndoList (int, void *, void *, void *); void AddObjectToRemoveContourUndoList (int, LayerType *, PolygonType *); void AddObjectToInsertContourUndoList (int, LayerType *, PolygonType *); void AddObjectToMoveUndoList (int, void *, void *, void *, Coord, Coord); void AddObjectToChangeNameUndoList (int, void *, void *, void *, char *); void AddObjectToRotateUndoList (int, void *, void *, void *, Coord, Coord, BYTE); void AddObjectToCreateUndoList (int, void *, void *, void *); void AddObjectToMirrorUndoList (int, void *, void *, void *, Coord); void AddObjectToMoveToLayerUndoList (int, void *, void *, void *); void AddObjectToFlagUndoList (int, void *, void *, void *); void AddObjectToSizeUndoList (int, void *, void *, void *); void AddObjectTo2ndSizeUndoList (int, void *, void *, void *); void AddObjectToClearSizeUndoList (int, void *, void *, void *); void AddObjectToMaskSizeUndoList (int, void *, void *, void *); void AddObjectToChangeAnglesUndoList (int, void *, void *, void *); void AddObjectToClearPolyUndoList (int, void *, void *, void *, bool); void AddObjectToSetViaLayersUndoList (void *ptr1, void *ptr2, void *ptr3); void AddLayerChangeToUndoList (int, int); void AddNetlistLibToUndoList (LibraryType *); void LockUndo (void); void UnlockUndo (void); bool Undoing (void); #endif pcb-4.3.0/src/buffer.h0000664000175000017500000000370113773431044011425 00000000000000/*! * \file src/buffer.h * * \brief Prototypes for buffer handling routines. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * Thomas.Nau@rz.uni-ulm.de */ #ifndef PCB_BUFFER_H #define PCB_BUFFER_H #include "global.h" /* --------------------------------------------------------------------------- * prototypes */ void SetBufferBoundingBox (BufferType *); void ClearBuffer (BufferType *); void AddSelectedToBuffer (BufferType *, Coord, Coord, bool); bool LoadElementToBuffer (BufferType *, char *, bool); bool ConvertBufferToElement (BufferType *); bool SmashBufferElement (BufferType *); bool LoadLayoutToBuffer (BufferType *, char *); void RotateBuffer (BufferType *, BYTE); void SelectPasteBuffer (int); void SwapBuffers (void); void MirrorBuffer (BufferType *); void InitBuffers (void); void UninitBuffers (void); void *MoveObjectToBuffer (DataType *, DataType *, int, void *, void *, void *); void *CopyObjectToBuffer (DataType *, DataType *, int, void *, void *, void *); int LoadFootprint (int argc, char **argv, Coord x, Coord y); #endif pcb-4.3.0/src/dbus-pcbmain.h0000664000175000017500000000225013773431044012516 00000000000000/*! * \file src/dbus-pacbmain.h * * \brief D-Bus IPC logic * * PCB, an interactive printed circuit board editor * * Copyright (C) 2006 University of Cambridge * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef PCB_DBUS_PCBMAIN_H #define PCB_DBUS_PCBMAIN_H #define DBUS_API_SUBJECT_TO_CHANGE #include void pcb_dbus_connection_setup_with_mainloop (DBusConnection * connection); void pcb_dbus_connection_finish_with_mainloop (DBusConnection * connection); #endif /* !PCB_DBUS_PCBMAIN_H */ pcb-4.3.0/src/pcb-menu.res.in0000664000175000017500000004704513773431044012642 00000000000000# -*- c -*- # Note - pcb-menu.res is used to build pcb-menu.h # Note - parameters are sensitive to extra spaces around the commas Mouse = { Left = { Mode(Notify) up = Mode(Release) } Right = { { Mode(Save) Mode(Rotate) Mode(Notify) Mode(Release) Mode(Restore) } ctrl = Display(CycleCrosshair) } Middle = { Pan(1) up = Pan(0) ctrl = Pan(thumb,1) ctrl-up = Pan(thumb,0) } Up = Zoom(0.8) Down = Zoom(1.25) # If you want zoom to center, do this instead. #Up = { {Zoom(0.8) Center()} } #Down = { {Zoom(1.25) Center()} } } MainMenu = { {File {"About..." About()} {"Save layout" Save(Layout) m=S a={"Ctrl-S" "Ctrls"}} {"Save layout as..." Save(LayoutAs) m=A a={"Shift Ctrl-S" "Shift Ctrls"}} {"Revert" Load(Revert,none)} - {"Import Schematics" {"gschem" Import() } {"TinyCAD" ImportTinyCAD() } } {"Load layout" Load(Layout)} {"Load element data to paste-buffer" PasteBuffer(Clear) Load(ElementTobuffer)} {"Load layout data to paste-buffer" PasteBuffer(Clear) Load(LayoutTobuffer)} {"Load netlist file" Load(Netlist)} {"Load vendor resource file" LoadVendor()} {"Print layout..." Print()} {"Export layout..." Export()} {"Calibrate Printer..." PrintCalibrate()} - {"Save connection data of..." foreground=grey50 sensitive=false} {" a single element" GetXY(Click to set the element mark <>) Save(ElementConnections)} {" all elements" Save(AllConnections)} {" unused pins" Save(AllUnusedPins)} - {"Start new layout" New() a={"Ctrl-N" "Ctrln"}} - {"Quit Program" Quit() m=Q a={"Ctrl-Q" "Ctrlq"}} } {View {"Flip up/down" checked=flip_y SwapSides(V) a={"Tab" "Tab"}} {"Flip left/right" checked=flip_x SwapSides(H) a={"Shift-Tab" "ShiftTab"}} {"Spin 180°" SwapSides(R) a={"Ctrl-Tab" "CtrlTab"}} {"Swap Sides" SwapSides() a={"Ctrl-Shift-Tab" "Ctrl ShiftTab"}} {"Center cursor" Center() a={"C" "c"}} {"Show soldermask" checked=showmask Display(ToggleMask)} - {"Displayed element-name..." foreground=grey50 sensitive=false} {"Description" Display(Description) checked=elementname,1} {"Reference Designator" Display(NameOnPCB) checked=elementname,2} {"Value" Display(Value) checked=elementname,3} {"Lock Names" checked=locknames Display(ToggleLockNames)} {"Only Names" checked=onlynames Display(ToggleOnlyNames)} {"Hide Names" checked=hidenames Display(ToggleHideNames)} - {"Pinout shows number" checked=shownumber Display(ToggleName)} {"Open pinout menu" Display(Pinout) a={"Shift-D" "Shiftd"}} - {Zoom {"Zoom In 2X" Zoom(-2)} {"Zoom In 20%" Zoom(-1.2) m=Z a={"Z" "z"}} {"Zoom Out 20%" Zoom(+1.2) m=O a={"Shift-Z" "Shiftz"}} # If you want zoom to center, do this instead. #{"Zoom In 20%" Zoom(-1.2) Center() m=Z a={"Z" "z"}} #{"Zoom Out 20%" Zoom(+1.2) Center() m=O a={"Shift-Z" "Shiftz"}} {"Zoom Out 2X" Zoom(+2)} {"Zoom Max" Zoom() m=M a={"V" "v"}} {"Zoom Toggle" Zoom(Toggle) a={"`" "`"}} - {"Zoom to 0.1mil/px" Zoom(=0.1mil)} {"Zoom to 0.01mm/px" Zoom(=0.01mil)} {"Zoom to 1mil/px" Zoom(=1mil)} {"Zoom to 0.05mm/px" Zoom(=0.05mm)} {"Zoom to 2.5mil/px" Zoom(=2.5mil)} {"Zoom to 0.1mm/px" Zoom(=0.1mm)} {"Zoom to 10mil/px" Zoom(=10mil)} } {Grid {"mil" checked=grid_units_mil,1 SetUnits(mil)} {"mm" checked=grid_units_mm,1 SetUnits(mm)} {"Display grid" checked=drawgrid Display(Grid)} {"Realign grid" GetXY(Click to set the grid origin) Display(ToggleGrid)} {"No Grid" checked=grid,0 SetValue(Grid,1)} - { "0.1 mil" checked=gridsize,0.1mil SetUnits(mil) SetValue(Grid,0.1mil)} { "1 mil" checked=gridsize,1mil SetUnits(mil) SetValue(Grid,1mil)} { "5 mil" checked=gridsize,5mil SetUnits(mil) SetValue(Grid,5mil)} { "10 mil" checked=gridsize,10mil SetUnits(mil) SetValue(Grid,10mil)} { "25 mil" checked=gridsize,25mil SetUnits(mil) SetValue(Grid,25mil)} { "50 mil" checked=gridsize,50mil SetUnits(mil) SetValue(Grid,50mil)} {"100 mil" checked=gridsize,100mil SetUnits(mil) SetValue(Grid,100mil)} - {"0.01 mm" checked=gridsize,0.01mm SetUnits(mm) SetValue(Grid,0.01mm)} {"0.05 mm" checked=gridsize,0.05mm SetUnits(mm) SetValue(Grid,0.05mm)} {"0.1 mm" checked=gridsize,0.10mm SetUnits(mm) SetValue(Grid,0.1mm)} {"0.25 mm" checked=gridsize,0.25mm SetUnits(mm) SetValue(Grid,0.25mm)} {"0.5 mm" checked=gridsize,0.50mm SetUnits(mm) SetValue(Grid,0.5mm)} {"1 mm" checked=gridsize,1mm SetUnits(mm) SetValue(Grid,1mm)} - {"Grid -" SetValue(Grid,-) a={"Shift-G" "Shiftg"}} {"Grid +" SetValue(Grid,+) a={"G" "g"}} } - {"Shown Layers" @layerview - {"Edit Layer Groups" EditLayerGroups()} } {"Current Layer" @layerpick - {"Delete current layer" MoveLayer(c,-1)} {"Add new layer" MoveLayer(-1,c)} {"Move current layer up" MoveLayer(c,up)} {"Move current layer down" MoveLayer(c,down)} } } {Edit {"Undo last operation" Undo() a={"U" "u"}} {"Redo last undone operation" Redo() a={"Shift-R" "Shiftr"}} {"Clear undo-buffer" Undo(ClearList) a={"Shift-Ctrl-U" "Shift Ctrlu"}} - {"Cut selection to buffer" GetXY(Click to set the snap point for this buffer) PasteBuffer(Clear) PasteBuffer(AddSelected) RemoveSelected() Mode(PasteBuffer) a={"Ctrl-X" "Ctrlx"}} {"Copy selection to buffer" GetXY(Click to set the snap point for this buffer) PasteBuffer(Clear) PasteBuffer(AddSelected) Mode(PasteBuffer) a={"Ctrl-C" "Ctrlc"}} {"Paste buffer to layout" Mode(PasteBuffer) a={"Ctrl-V" "Ctrlv"}} - {"Unselect all" Unselect(All) a={"Shift-Alt-A" "Shift Alta"}} {"Select all visible" Select(All) a={"Alt-A" "Alta"}} - {"Edit Names..." foreground=grey50 sensitive=false} {" Change text on layout" ChangeName(Object) a={"N" "n"}} {" Edit name of layout" ChangeName(Layout)} {" Edit name of active layer" ChangeName(Layer)} {"Edit Attributes..." foreground=grey50 sensitive=false} {" Layout" Attributes(Layout)} {" CurrentLayer" Attributes(Layer)} {" Element" Attributes(Element)} - {"Board Sizes" AdjustSizes()} {"Route Styles" @routestyles - {"Edit..." AdjustStyle(0)} } - {"Via type" {"Through-hole" a={"Xtrl-Shift-P" "Ctrl Shiftp"} SetViaLayers(Object,th)} {"Buried from" a={"Xtrl-Shift-F" "Ctrl Shiftf"} SetViaLayers(Object,c,-)} {"Buried to" a={"Xtrl-Shift-T" "Ctrl Shiftt"} SetViaLayers(Object,-,c)} } } {Tools {"None" checked=nomode,1 Mode(None)} {"Via" checked=viamode,1 Mode(Via) a={"F1" "F1"}} {"Line" checked=linemode,1 Mode(Line) a={"F2" "F2"}} {"Arc" checked=arcmode,1 Mode(Arc) a={"F3" "F3"}} {"Text" checked=textmode,1 Mode(Text) a={"F4" "F4"}} {"Rectangle" checked=rectanglemode,1 Mode(Rectangle) a={"F5" "F5"}} {"Polygon" checked=polygonmode,1 Mode(Polygon) a={"F6" "F6"}} {"Polygon Hole" checked=polygonholemode,1 Mode(PolygonHole)} {"Buffer" checked=pastebuffermode,1 Mode(PasteBuffer) a={"F7" "F7"}} {"Remove" checked=removemode,1 Mode(Remove) a={"F8" "F8"}} {"Rotate" checked=rotatemode,1 Mode(Rotate) a={"F9" "F9"}} {"Thermal" checked=thermalmode,1 Mode(Thermal) a={"F10" "F10"}} {"Arrow" checked=arrowmode,1 Mode(Arrow) a={"F11" "F11"}} {"Insert Point" checked=insertpointmode,1 Mode(InsertPoint) a={"Insert" "Insert"}} {"Move" checked=movemode,1 Mode(Move)} {"Copy" checked=copymode,1 Mode(Copy)} {"Lock" checked=lockmode,1 Mode(Lock) a={"F12" "F12"}} {"Cancel" Mode(Cancel) a={"Esc" "Escape"}} - {"Command" Command() a={":" ":"}} } {Settings {"Layer groups" foreground=grey50 sensitive=false} {"Edit layer groupings" EditLayerGroups()} - {"'All-direction' lines" checked=alldirection Display(Toggle45Degree) a={"." "."}} {"Auto swap line start angle" checked=swapstartdir Display(ToggleStartDirection)} {"Orthogonal moves" checked=orthomove Display(ToggleOrthoMove)} {"Crosshair snaps to pins and pads" checked=snappin Display(ToggleSnapPin)} {"Crosshair shows DRC clearance" checked=showdrc Display(ToggleShowDRC)} {"Auto enforce DRC clearance" checked=autodrc Display(ToggleAutoDRC)} - {"Rubber band mode" checked=rubberband Display(ToggleRubberBandMode)} {"Require unique element names" checked=uniquename Display(ToggleUniqueNames)} {"Auto-zero delta measurements" checked=localref Display(ToggleLocalRef)} {"New lines, arcs clear polygons" checked=clearnew Display(ToggleClearLine)} {"New polygons are full ones" checked=newfullpoly Display(ToggleFullPoly)} {"Show autorouter trials" checked=liveroute Display(ToggleLiveRoute)} {"Thin draw" checked=thindraw Display(ToggleThindraw) a={"|" "|"}} {"Thin draw poly" checked=thindrawpoly Display(ToggleThindrawPoly) a={"Ctrl-Shift-P" "Ctrl Shiftp"}} {"Check polygons" checked=checkplanes Display(ToggleCheckPlanes)} - {"Pinout shows number" checked=shownumber Display(ToggleName)} {"Pins/Via show Name/Number" Display(PinOrPadName) a={"D" "d"}} {"Enable vendor drill mapping" ToggleVendor() checked=VendorMapOn} {"Import Settings" {"New elements added at..." foreground=grey50 sensitive=false} {" Center" Import(setnewpoint,center)} {" Mark" Import(setnewpoint,mark)} {" Crosshair" Import(setnewpoint)} - {"Set Dispersion" Import(setdisperse)} } } {Select {"Select all visible objects" Select(All)} {"Select all found objects" Select(Found)} {"Select all connected objects" Select(Connection)} - {"Unselect all objects" Unselect(All)} {"unselect all found objects" Unselect(Found)} {"unselect all connected objects" Unselect(Connection)} - {"Select by name" foreground=grey50 sensitive=false} {"All objects" Select(ObjectByName) active=have_regex} {"Elements" Select(ElementByName) active=have_regex} {"Pads" Select(PadByName) active=have_regex} {"Pins" Select(PinByName) active=have_regex} {"Text Objects" Select(TextByName) active=have_regex} {"Vias" Select(ViaByName) active=have_regex} - {"Auto-place selected elements" AutoPlaceSelected() a={"Ctrl-P" "Ctrlp"}} {"Disperse all elements" DisperseElements(All)} {"Move selected elements to other side" Flip(SelectedElements) a={"Shift-B" "Shiftb"}} {"Move selected to current layer" MoveToCurrentLayer(Selected) a={"Shift-M" "Shiftm"}} {"Delete selected objects" Delete(Selected) a={"Delete" "Delete"}} {"Convert selection to element" Select(Convert)} - {"Optimize selected rats" DeleteRats(SelectedRats) AddRats(SelectedRats)} {"Auto-route selected rats" AutoRoute(SelectedRats) a={"Alt-R" "Altr"}} {"Rip up selected auto-routed tracks" RipUp(Selected)} - {"Change size of selected objects" foreground=grey50 sensitive=false} {"Lines -10 mil" ChangeSize(SelectedLines,-10,mil) ChangeSize(SelectedArcs,-10,mil)} {"Lines +10 mil" ChangeSize(SelectedLines,+10,mil) ChangeSize(SelectedArcs,+10,mil)} {"Pads -10 mil" ChangeSize(SelectedPads,-10,mil)} {"Pads +10 mil" ChangeSize(SelectedPads,+10,mil)} {"Pins -10 mil" ChangeSize(SelectedPins,-10,mil)} {"Pins +10 mil" ChangeSize(SelectedPins,+10,mil)} {"Texts -10 mil" ChangeSize(SelectedTexts,-10,mil)} {"Texts +10 mil" ChangeSize(SelectedTexts,+10,mil)} {"Vias -10 mil" ChangeSize(SelectedVias,-10,mil)} {"Vias +10 mil" ChangeSize(SelectedVias,+10,mil)} - {"Change drilling hole of selected objects" foreground=grey50 sensitive=false} {"Vias -10 mil" ChangeDrillSize(SelectedVias,-10,mil)} {"Vias +10 mil" ChangeDrillSize(SelectedVias,+10,mil)} {"Pins -10 mil" ChangeDrillSize(SelectedPins,-10,mil)} {"Pins +10 mil" ChangeDrillSize(SelectedPins,+10,mil)} - {"Change square-flag of selected objects" foreground=grey50 sensitive=false} {"Elements" ChangeSquare(SelectedElements)} {"Pins" ChangeSquare(SelectedPins)} } {Buffer {"Copy selection to buffer" GetXY(Click to set the snap point for this buffer) PasteBuffer(Clear) PasteBuffer(AddSelected) Mode(PasteBuffer)} {"Cut selection to buffer" GetXY(Click to set the snap point for this buffer) PasteBuffer(Clear) PasteBuffer(AddSelected) RemoveSelected() Mode(PasteBuffer)} {"Paste buffer to layout" Mode(PasteBuffer)} - {"Rotate buffer 90 deg CCW" Mode(PasteBuffer) PasteBuffer(Rotate,1) a={"Shift-F7" "ShiftF7"}} {"Rotate buffer 90 deg CW" Mode(PasteBuffer) PasteBuffer(Rotate,3)} {"Arbitrarily Rotate Buffer" Mode(PasteBuffer) FreeRotateBuffer()} {"Mirror buffer (up/down)" Mode(PasteBuffer) PasteBuffer(Mirror)} {"Mirror buffer (left/right)" Mode(PasteBuffer) PasteBuffer(Rotate,1) PasteBuffer(Mirror) PasteBuffer(Rotate,3)} - {"Clear buffer" PasteBuffer(Clear)} {"Convert buffer to element" PasteBuffer(Convert)} {"Break buffer elements to pieces" PasteBuffer(Restore)} {"Save buffer elements to file" Save(PasteBuffer)} - {"Select current buffer" foreground=grey50 sensitive=false} {"#1" checked=buffer,1 PasteBuffer(1) a={"Shift-1" "Shift1"}} {"#2" checked=buffer,2 PasteBuffer(2) a={"Shift-2" "Shift2"}} {"#3" checked=buffer,3 PasteBuffer(3) a={"Shift-3" "Shift3"}} {"#4" checked=buffer,4 PasteBuffer(4) a={"Shift-4" "Shift4"}} {"#5" checked=buffer,5 PasteBuffer(5) a={"Shift-5" "Shift5"}} } {Connects {"Lookup connection to object" GetXY(Click on the object) Connection(Find) a={"Ctrl-F" "Ctrlf"}} {"Reset scanned pads/pins/vias" Connection(ResetPinsViasAndPads) Display(Redraw)} {"Reset scanned lines/polygons" Connection(ResetLinesAndPolygons) Display(Redraw)} {"Reset all connections" Connection(Reset) Display(Redraw) a={"Shift-F" "Shiftf"}} - {"Optimize rats-nest" Atomic(Save) DeleteRats(AllRats) Atomic(Restore) AddRats(AllRats) Atomic(Block) a={"O" "o"}} {"Erase rats-nest" DeleteRats(AllRats) a={"E" "e"}} {"Erase selected rats" DeleteRats(SelectedRats) a={"Shift-E" "Shifte"}} - {"Auto-route selected rats" AutoRoute(Selected)} {"Auto-route all rats" AutoRoute(AllRats)} {"Toporouter" Toporouter()} {"Rip up all auto-routed tracks" RipUp(All)} - {"Auto-Optimize" djopt(auto) a={"Shift-=" "Shift="}} {"Debumpify" djopt(debumpify) } {"Unjaggy" djopt(unjaggy) } {"Vianudge" djopt(vianudge) } {"Viatrim" djopt(viatrim) } {"Orthopull" djopt(orthopull) } {"SimpleOpts" djopt(simple) a={"=" "="}} {"Miter" djopt(miter) } {"Puller" a={"Y" "y"} Puller() } {"Global Puller" {"Selected" GlobalPuller(selected) } {"Found" GlobalPuller(found) } {"All" GlobalPuller() } } {"Only autorouted nets" OptAutoOnly() checked=optautoonly} - {"Design Rule Checker" DRC() DRCReview()} - {"Apply vendor drill mapping" ApplyVendor()} } {Info {"Generate object report" ReportObject() a={"Ctrl-R" "Ctrlr"}} {"Generate drill summary" Report(DrillReport)} {"Report found pins/pads" Report(FoundPins)} {"Report net length" Report(NetLength) a={"R" "r"}} {"Key Bindings" {"Remove" a={"Backspace" "BackSpace"} Delete(Selected) } {"Remove Connected" a={"Shift-Backspace" "ShiftBackSpace"} Atomic(Save) Connection(Reset) Atomic(Restore) Unselect(All) Atomic(Restore) Connection(Find) Atomic(Restore) Select(Connection) Atomic(Restore) RemoveSelected() Atomic(Restore) Connection(Reset) Atomic(Restore) Unselect(All) Atomic(Block) } {"Remove Connected" a={"Shift-Delete" "ShiftDelete"} Atomic(Save) Connection(Reset) Atomic(Restore) Unselect(All) Atomic(Restore) Connection(Find) Atomic(Restore) Select(Connection) Atomic(Restore) RemoveSelected() Atomic(Restore) Connection(Reset) Atomic(Restore) Unselect(All) Atomic(Block) } {"Set Same" a={"A" "a"} SetSame()} {"Flip Object" a={"B" "b"} Flip(Object)} {"Find Connections" a={"F" "f"} Connection(Reset) Connection(Find)} {"ToggleHideName Object" a={"H" "h"} ToggleHideName(Object)} {"ToggleHideName SelectedElement" a={"Shift-H" "Shifth"} ToggleHideName(SelectedElements)} {"ChangeHole Object" a={"Ctrl-H" "Ctrlh"} ChangeHole(Object)} {"ChangeJoin Object" a={"J" "j"} ChangeJoin(Object)} {"ChangeJoin SelectedObject" a={"Shift-J" "Shiftj"} ChangeJoin(SelectedObjects)} {"Clear Object +" a={"K" "k"} ChangeClearSize(Object,+)} {"Clear Object -" a={"Shift-K" "Shiftk"} ChangeClearSize(Object,-)} {"Clear Selected +" a={"Ctrl-K" "Ctrlk"} ChangeClearSize(SelectedObjects,+)} {"Clear Selected -" a={"Shift-Ctrl-K" "Shift Ctrlk"} ChangeClearSize(SelectedObjects,-)} {"Line Tool size +" a={"L" "l"} SetValue(LineSize,+)} {"Line Tool size -" a={"Shift-L" "Shiftl"} SetValue(LineSize,-)} {"Move Object to current layer" a={"M" "m"} MoveToCurrentLayer(Object)} {"MarkCrosshair" a={"Ctrl-M" "Ctrlm"} MarkCrosshair()} {"Select shortest rat" a={"Shift-N" "Shiftn"} AddRats(Close)} {"AddRats to selected pins" a={"Shift-O" "Shifto"} Atomic(Save) DeleteRats(AllRats) Atomic(Restore) AddRats(SelectedRats) Atomic(Block) } {"ChangeOctagon Object" a={"Ctrl-O" "Ctrlo"} ChangeOctagon(Object)} {"Polygon PreviousPoint" a={"P" "p"} Polygon(PreviousPoint)} {"Polygon Close" a={"Shift-P" "Shiftp"} Polygon(Close)} {"ChangeSquare Object" a={"Q" "q"} ChangeSquare(Object)} {"ChangeSize +" a={"S" "s"} ChangeSize(Object,+)} {"ChangeSize -" a={"Shift-S" "Shifts"} ChangeSize(Object,-)} {"ChangeDrill +5 mil" a={"Alt-S" "Alts"} ChangeDrillSize(Object,+5,mil)} {"ChangeDrill -5 mil" a={"Alt-Shift-S" "Alt Shifts"} ChangeDrillSize(Object,-5,mil)} {"Text Tool scale +10 mil" a={"T" "t"} SetValue(TextScale,+10,mil)} {"Text Tool scale -10 mil" a={"Shift-T" "Shiftt"} SetValue(TextScale,-10,mil)} {"Via Tool size +5 mil" a={"Shift-V" "Shiftv"} SetValue(ViaSize,+5,mil)} {"Via Tool size -5 mil" a={"Shift-Ctrl-V" "Shift Ctrlv"} SetValue(ViaSize,-5,mil)} {"Via Tool drill +5 mil" a={"Alt-V" "Altv"} SetValue(ViaDrillingHole,+5,mil)} {"Via Tool drill -5 mil" a={"Alt-Shift-V" "Alt Shiftv"} SetValue(ViaDrillingHole,-5,mil)} {"AddRats Selected" a={"Shift-W" "Shiftw"} AddRats(SelectedRats)} {"Add All Rats" a={"W" "w"} AddRats(AllRats)} {"Undo" a={"Alt-Z" "Altz"} Undo()} {"Cycle Clip" a={"/" "/"} Display(CycleClip)} {"Arrow" a={"Space" "space"} Mode(Arrow) checked=arrowmode,1} {"Temp Arrow ON" a={"[" "["} Mode(Save) Mode(Arrow) Mode(Notify)} {"Temp Arrow OFF" a={"]" "]"} Mode(Release) Mode(Restore)} {"Step Up" a={"Up" "Up"} Cursor(Warp,0,1,grid)} {"Step Down" a={"Down" "Down"} Cursor(Warp,0,-1,grid)} {"Step Left" a={"Left" "Left"} Cursor(Warp,-1,0,grid)} {"Step Right" a={"Right" "Right"} Cursor(Warp,1,0,grid)} {"Step +Up" a={"Up" "ShiftUp"} Cursor(Pan,0,50,view)} {"Step +Down" a={"Down" "ShiftDown"} Cursor(Pan,0,-50,view)} {"Step +Left" a={"Left" "ShiftLeft"} Cursor(Pan,-50,0,view)} {"Step +Right" a={"Right" "ShiftRight"} Cursor(Pan,50,0,view)} {'"Click"' a={"Enter" "Enter"} Mode(Notify) Mode(Release) } } } {Window {"Board Layout" DoWindows(Layout)} {"Library" DoWindows(Library)} {"Message Log" DoWindows(Log)} {"Netlist" DoWindows(Netlist)} {"Pinout" Display(Pinout) a={"Shift-D" "Shiftd"}} } } pcb-4.3.0/src/netlist.c0000664000175000017500000003001413773431044011626 00000000000000/*! * \file src/netlist.c * * \brief Generic netlist operations. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996, 2005 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * * Thomas.Nau@rz.uni-ulm.de */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #ifdef HAVE_STRING_H #include #endif #include #include #ifdef HAVE_REGEX_H #include #endif #include "global.h" #include "action.h" #include "buffer.h" #include "data.h" #include "djopt.h" #include "error.h" #include "file.h" #include "find.h" #include "mymem.h" #include "misc.h" #include "rats.h" #include "set.h" #include "vendor.h" #include "create.h" #ifdef HAVE_REGCOMP #undef HAVE_RE_COMP #endif #if defined(HAVE_REGCOMP) || defined(HAVE_RE_COMP) #define USE_RE #endif #ifdef HAVE_LIBDMALLOC #include #endif /* int PCB->NetlistLib.MenuN char * PCB->NetlistLib.Menu[i].Name [0] == '*' (ok for rats) or ' ' (skip for rats) [1] == unused [2..] actual name char * PCB->NetlistLib.Menu[i].Style int PCB->NetlistLib.Menu[i].EntryN char * PCB->NetlistLib.Menu[i].Entry[j].ListEntry */ typedef void (*NFunc) (LibraryMenuType *, LibraryEntryType *); int netlist_frozen = 0; static int netlist_needs_update = 0; void NetlistChanged (int force_unfreeze) { if (force_unfreeze) netlist_frozen = 0; if (netlist_frozen) netlist_needs_update = 1; else { netlist_needs_update = 0; hid_action ("NetlistChanged"); } } LibraryMenuType * netnode_to_netname (char *nodename) { int i, j; /*printf("nodename [%s]\n", nodename);*/ for (i=0; iNetlistLib.MenuN; i++) { for (j=0; jNetlistLib.Menu[i].EntryN; j++) { if (strcmp (PCB->NetlistLib.Menu[i].Entry[j].ListEntry, nodename) == 0) { /*printf(" in [%s]\n", PCB->NetlistLib.Menu[i].Name);*/ return & (PCB->NetlistLib.Menu[i]); } } } return 0; } LibraryMenuType * netname_to_netname (char *netname) { int i; if ((netname[0] == '*' || netname[0] == ' ') && netname[1] == ' ') { /* Looks like we were passed an internal netname, skip the prefix */ netname += 2; } for (i=0; iNetlistLib.MenuN; i++) { if (strcmp (PCB->NetlistLib.Menu[i].Name + 2, netname) == 0) { return & (PCB->NetlistLib.Menu[i]); } } return 0; } static int pin_name_to_xy (LibraryEntryType * pin, int *x, int *y) { ConnectionType conn; if (!SeekPad (pin, &conn, false)) return 1; switch (conn.type) { case PIN_TYPE: *x = ((PinType *) (conn.ptr2))->X; *y = ((PinType *) (conn.ptr2))->Y; return 0; case PAD_TYPE: *x = ((PadType *) (conn.ptr2))->Point1.X; *y = ((PadType *) (conn.ptr2))->Point1.Y; return 0; } return 1; } static void netlist_find (LibraryMenuType * net, LibraryEntryType * pin) { int x, y; if (pin_name_to_xy (net->Entry, &x, &y)) return; LookupConnection (x, y, 1, 1, FOUNDFLAG, true); } static void netlist_select (LibraryMenuType * net, LibraryEntryType * pin) { int x, y; if (pin_name_to_xy (net->Entry, &x, &y)) return; LookupConnection (x, y, 1, 1, SELECTEDFLAG, true); } static void netlist_rats (LibraryMenuType * net, LibraryEntryType * pin) { net->Name[0] = ' '; net->flag = 1; NetlistChanged (0); } static void netlist_norats (LibraryMenuType * net, LibraryEntryType * pin) { net->Name[0] = '*'; net->flag = 0; NetlistChanged (0); } /*! * \brief The primary purpose of this action is to remove the netlist * completely so that a new one can be loaded, usually via a gsch2pcb * style script. */ static void netlist_clear (LibraryMenuType * net, LibraryEntryType * pin) { LibraryType *netlist = &PCB->NetlistLib; int ni, pi; if (net == 0) { /* Clear the entire netlist. */ FreeLibraryMemory (&PCB->NetlistLib); } else if (pin == 0) { /* Remove a net from the netlist. */ ni = net - netlist->Menu; if (ni >= 0 && ni < netlist->MenuN) { /* if there is exactly one item, MenuN is 1 and ni is 0 */ if (netlist->MenuN - ni > 1) memmove (net, net+1, (netlist->MenuN - ni - 1) * sizeof (*net)); netlist->MenuN --; } } else { /* Remove a pin from the given net. Note that this may leave an empty net, which is different than removing the net (above). */ pi = pin - net->Entry; if (pi >= 0 && pi < net->EntryN) { /* if there is exactly one item, MenuN is 1 and ni is 0 */ if (net->EntryN - pi > 1) memmove (pin, pin+1, (net->EntryN - pi - 1) * sizeof (*pin)); net->EntryN --; } } NetlistChanged (0); } static void netlist_style (LibraryMenuType *net, const char *style) { free (net->Style); net->Style = STRDUP ((char *)style); } /*! * \brief The primary purpose of this action is to rebuild a netlist * from a script, in conjunction with the clear action above. */ static int netlist_add (const char *netname, const char *pinname) { int ni, pi; LibraryType *netlist = &PCB->NetlistLib; LibraryMenuType *net = NULL; LibraryEntryType *pin = NULL; for (ni=0; niMenuN; ni++) if (strcmp (netlist->Menu[ni].Name+2, netname) == 0) { net = & (netlist->Menu[ni]); break; } if (net == NULL) { net = CreateNewNet (netlist, (char *)netname, NULL); } for (pi=0; piEntryN; pi++) if (strcmp (net->Entry[pi].ListEntry, pinname) == 0) { pin = & (net->Entry[pi]); break; } if (pin == NULL) { pin = CreateNewConnection (net, (char *)pinname); } NetlistChanged (0); return 0; } static const char netlist_syntax[] = "Net(find|select|rats|norats|clear[,net[,pin]])\n" "Net(freeze|thaw|forcethaw)\n" "Net(add,net,pin)"; static const char netlist_help[] = "Perform various actions on netlists."; /* %start-doc actions Netlist Each of these actions apply to a specified set of nets. @var{net} and @var{pin} are patterns which match one or more nets or pins; these patterns may be full names or regular expressions. If an exact match is found, it is the only match; if no exact match is found, @emph{then} the pattern is tried as a regular expression. If neither @var{net} nor @var{pin} are specified, all nets apply. If @var{net} is specified but not @var{pin}, all nets matching @var{net} apply. If both are specified, nets which match @var{net} and contain a pin matching @var{pin} apply. @table @code @item find Nets which apply are marked @emph{found} and are drawn in the @code{connected-color} color. @item select Nets which apply are selected. @item rats Nets which apply are marked as available for the rats nest. @item norats Nets which apply are marked as not available for the rats nest. @item clear Clears the netlist. @item add Add the given pin to the given netlist, creating either if needed. @item sort Called after a list of add's, this sorts the netlist. @item freeze @itemx thaw @itemx forcethaw Temporarily prevents changes to the netlist from being reflected in the GUI. For example, if you need to make multiple changes, you freeze the netlist, make the changes, then thaw it. Note that freeze/thaw requests may nest, with the netlist being fully thawed only when all pending freezes are thawed. You can bypass the nesting by using forcethaw, which resets the freeze count and immediately updates the GUI. @end table %end-doc */ static int Netlist (int argc, char **argv, Coord x, Coord y) { NFunc func; int i, j; LibraryMenuType *net; LibraryEntryType *pin; int net_found = 0; int pin_found = 0; #if defined(USE_RE) int use_re = 0; #endif #if defined(HAVE_REGCOMP) regex_t elt_pattern; regmatch_t match; #endif #if defined(HAVE_RE_COMP) char *elt_pattern; #endif if (!PCB) return 1; if (argc == 0) { Message (netlist_syntax); return 1; } if (strcasecmp (argv[0], "find") == 0) func = netlist_find; else if (strcasecmp (argv[0], "select") == 0) func = netlist_select; else if (strcasecmp (argv[0], "rats") == 0) func = netlist_rats; else if (strcasecmp (argv[0], "norats") == 0) func = netlist_norats; else if (strcasecmp (argv[0], "clear") == 0) { func = netlist_clear; if (argc == 1) { netlist_clear (NULL, NULL); return 0; } } else if (strcasecmp (argv[0], "style") == 0) func = (NFunc)netlist_style; else if (strcasecmp (argv[0], "add") == 0) { /* Add is different, because the net/pin won't already exist. */ return netlist_add (ARG(1), ARG(2)); } else if (strcasecmp (argv[0], "sort") == 0) { sort_netlist (); return 0; } else if (strcasecmp (argv[0], "freeze") == 0) { netlist_frozen ++; return 0; } else if (strcasecmp (argv[0], "thaw") == 0) { if (netlist_frozen > 0) { netlist_frozen --; if (netlist_needs_update) NetlistChanged (0); } return 0; } else if (strcasecmp (argv[0], "forcethaw") == 0) { netlist_frozen = 0; if (netlist_needs_update) NetlistChanged (0); return 0; } else { Message (netlist_syntax); return 1; } #if defined(USE_RE) if (argc > 1) { int result; use_re = 1; for (i = 0; i < PCB->NetlistLib.MenuN; i++) { net = PCB->NetlistLib.Menu + i; if (strcasecmp (argv[1], net->Name + 2) == 0) use_re = 0; } if (use_re) { #if defined(HAVE_REGCOMP) result = regcomp (&elt_pattern, argv[1], REG_EXTENDED | REG_ICASE | REG_NOSUB); if (result) { char errorstring[128]; regerror (result, &elt_pattern, errorstring, 128); Message (_("regexp error: %s\n"), errorstring); regfree (&elt_pattern); return (1); } #endif #if defined(HAVE_RE_COMP) if ((elt_pattern = re_comp (argv[1])) != NULL) { Message (_("re_comp error: %s\n"), elt_pattern); return (false); } #endif } } #endif for (i = PCB->NetlistLib.MenuN-1; i >= 0; i--) { net = PCB->NetlistLib.Menu + i; if (argc > 1) { #if defined(USE_RE) if (use_re) { #if defined(HAVE_REGCOMP) if (regexec (&elt_pattern, net->Name + 2, 1, &match, 0) != 0) continue; #endif #if defined(HAVE_RE_COMP) if (re_exec (net->Name + 2) != 1) continue; #endif } else #endif if (strcasecmp (net->Name + 2, argv[1])) continue; } net_found = 1; pin = 0; if (func == (void *)netlist_style) { netlist_style (net, ARG(2)); } else if (argc > 2) { int l = strlen (argv[2]); for (j = net->EntryN-1; j >= 0 ; j--) if (strcasecmp (net->Entry[j].ListEntry, argv[2]) == 0 || (strncasecmp (net->Entry[j].ListEntry, argv[2], l) == 0 && net->Entry[j].ListEntry[l] == '-')) { pin = net->Entry + j; pin_found = 1; func (net, pin); } } else func (net, 0); } if (argc > 2 && !pin_found) { gui->log ("Net %s has no pin %s\n", argv[1], argv[2]); return 1; } else if (!net_found) { gui->log ("No net named %s\n", argv[1]); } #ifdef HAVE_REGCOMP if (use_re) regfree (&elt_pattern); #endif return 0; } HID_Action netlist_action_list[] = { {"net", 0, Netlist, netlist_help, netlist_syntax} , {"netlist", 0, Netlist, netlist_help, netlist_syntax} }; REGISTER_ACTIONS (netlist_action_list) pcb-4.3.0/src/gettext.h0000664000175000017500000002333413773431044011644 00000000000000/*! * \file src/gettext.c * * \brief Convenience header for conditional use of GNU . * *
* *

Copyright.

\n * * Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published * by the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. */ #ifndef _LIBGETTEXT_H #define _LIBGETTEXT_H 1 /* NLS can be disabled through the configure --disable-nls option. */ #if ENABLE_NLS /* Get declarations of GNU message catalog functions. */ # include #ifdef HAVE_LOCALE_H # include #endif /* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by the gettext() and ngettext() macros. This is an alternative to calling textdomain(), and is useful for libraries. */ # ifdef DEFAULT_TEXT_DOMAIN # undef gettext # define gettext(Msgid) \ dgettext (DEFAULT_TEXT_DOMAIN, Msgid) # undef ngettext # define ngettext(Msgid1, Msgid2, N) \ dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N) # endif #else /* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which chokes if dcgettext is defined as a macro. So include it now, to make later inclusions of a NOP. We don't include as well because people using "gettext.h" will not include , and also including would fail on SunOS 4, whereas is OK. */ #if defined(__sun) # include #endif /* Many header files from the libstdc++ coming with g++ 3.3 or newer include , which chokes if dcgettext is defined as a macro. So include it now, to make later inclusions of a NOP. */ #if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3) # include # if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H # include # endif #endif /* Disabled NLS. The casts to 'const char *' serve the purpose of producing warnings for invalid uses of the value returned from these functions. On pre-ANSI systems without 'const', the config.h file is supposed to contain "#define const". */ # undef gettext # define gettext(Msgid) ((const char *) (Msgid)) # undef dgettext # define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid)) # undef dcgettext # define dcgettext(Domainname, Msgid, Category) \ ((void) (Category), dgettext (Domainname, Msgid)) # undef ngettext # define ngettext(Msgid1, Msgid2, N) \ ((N) == 1 \ ? ((void) (Msgid2), (const char *) (Msgid1)) \ : ((void) (Msgid1), (const char *) (Msgid2))) # undef dngettext # define dngettext(Domainname, Msgid1, Msgid2, N) \ ((void) (Domainname), ngettext (Msgid1, Msgid2, N)) # undef dcngettext # define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ ((void) (Category), dngettext(Domainname, Msgid1, Msgid2, N)) # undef textdomain # define textdomain(Domainname) ((const char *) (Domainname)) # undef bindtextdomain # define bindtextdomain(Domainname, Dirname) \ ((void) (Domainname), (const char *) (Dirname)) # undef bind_textdomain_codeset # define bind_textdomain_codeset(Domainname, Codeset) \ ((void) (Domainname), (const char *) (Codeset)) #endif /* A pseudo function call that serves as a marker for the automated extraction of messages, but does not call gettext(). The run-time translation is done at a different place in the code. The argument, String, should be a literal string. Concatenated strings and other string expressions won't work. The macro's expansion is not parenthesized, so that it is suitable as initializer for static 'char[]' or 'const char[]' variables. */ #define gettext_noop(String) String /* The separator between msgctxt and msgid in a .mo file. */ #define GETTEXT_CONTEXT_GLUE "\004" /* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be short and rarely need to change. The letter 'p' stands for 'particular' or 'special'. */ #ifdef DEFAULT_TEXT_DOMAIN # define pgettext(Msgctxt, Msgid) \ pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) #else # define pgettext(Msgctxt, Msgid) \ pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) #endif #define dpgettext(Domainname, Msgctxt, Msgid) \ pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) #define dcpgettext(Domainname, Msgctxt, Msgid, Category) \ pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category) #ifdef DEFAULT_TEXT_DOMAIN # define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) #else # define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) #endif #define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) #define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \ npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category) #ifdef __GNUC__ __inline #else #ifdef __cplusplus inline #endif #endif static const char * pgettext_aux (const char *domain, const char *msg_ctxt_id, const char *msgid, int category) { const char *translation = dcgettext (domain, msg_ctxt_id, category); if (translation == msg_ctxt_id) return msgid; else return translation; } #ifdef __GNUC__ __inline #else #ifdef __cplusplus inline #endif #endif static const char * npgettext_aux (const char *domain, const char *msg_ctxt_id, const char *msgid, const char *msgid_plural, unsigned long int n, int category) { const char *translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); if (translation == msg_ctxt_id || translation == msgid_plural) return (n == 1 ? msgid : msgid_plural); else return translation; } /* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID can be arbitrary expressions. But for string literals these macros are less efficient than those above. */ #include #define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \ (((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \ /* || __STDC_VERSION__ >= 199901L */ ) #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS #include #endif #define pgettext_expr(Msgctxt, Msgid) \ dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES) #define dpgettext_expr(Domainname, Msgctxt, Msgid) \ dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES) #ifdef __GNUC__ __inline #else #ifdef __cplusplus inline #endif #endif static const char * dcpgettext_expr (const char *domain, const char *msgctxt, const char *msgid, int category) { size_t msgctxt_len = strlen (msgctxt) + 1; size_t msgid_len = strlen (msgid) + 1; const char *translation; #if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS char msg_ctxt_id[msgctxt_len + msgid_len]; #else char buf[1024]; char *msg_ctxt_id = (msgctxt_len + msgid_len <= sizeof (buf) ? buf : (char *) malloc (msgctxt_len + msgid_len)); if (msg_ctxt_id != NULL) #endif { memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); msg_ctxt_id[msgctxt_len - 1] = '\004'; memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); translation = dcgettext (domain, msg_ctxt_id, category); #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS if (msg_ctxt_id != buf) free (msg_ctxt_id); #endif if (translation != msg_ctxt_id) return translation; } return msgid; } #define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \ dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) #define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) #ifdef __GNUC__ __inline #else #ifdef __cplusplus inline #endif #endif static const char * dcnpgettext_expr (const char *domain, const char *msgctxt, const char *msgid, const char *msgid_plural, unsigned long int n, int category) { size_t msgctxt_len = strlen (msgctxt) + 1; size_t msgid_len = strlen (msgid) + 1; const char *translation; #if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS char msg_ctxt_id[msgctxt_len + msgid_len]; #else char buf[1024]; char *msg_ctxt_id = (msgctxt_len + msgid_len <= sizeof (buf) ? buf : (char *) malloc (msgctxt_len + msgid_len)); if (msg_ctxt_id != NULL) #endif { memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); msg_ctxt_id[msgctxt_len - 1] = '\004'; memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS if (msg_ctxt_id != buf) free (msg_ctxt_id); #endif if (!(translation == msg_ctxt_id || translation == msgid_plural)) return translation; } return (n == 1 ? msgid : msgid_plural); } #endif /* _LIBGETTEXT_H */ pcb-4.3.0/src/global.h0000664000175000017500000007254213773431044011425 00000000000000/*! * \file src/global.h * * \brief Definition of types. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996, 2004 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Contact addresses for paper mail and Email: * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * Thomas.Nau@rz.uni-ulm.de * *
* * Change History: * * 10/11/96 11:37 AJF Added support for a Text() driver function. * This was done out of a pressing need to force text to be printed on the * silkscreen layer. Perhaps the design is not the best. */ #ifndef PCB_GLOBAL_H #define PCB_GLOBAL_H #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "const.h" #include "macro.h" #include "flags.h" #include #ifdef HAVE_STDINT_H #include #endif #include #include #include #include #include #include #include #include #include #include /* Forward declarations for structures the HIDs need. */ typedef struct BoxType BoxType; typedef struct polygon_st PolygonType; typedef struct pad_st PadType; typedef struct pin_st PinType; typedef struct rtree rtree_t; typedef struct AttributeListType AttributeListType; typedef struct unit Unit; typedef struct increments Increments; typedef COORD_TYPE Coord; /*!< pcb base unit. */ typedef double Angle; /*!< Degrees. */ #include "hid.h" #include "polyarea.h" /* Internationalization support. */ #include "gettext.h" #if defined (ENABLE_NLS) /* When an empty string is used for msgid, the functions may return a nonempty string. */ # define _(S) (S[0] != '\0') ? gettext(S) : S # define N_(S) gettext_noop(S) # define C_(C, S) pgettext(C, S) #else # define _(S) S # define N_(S) S # define C_(C, S) S #endif /* ENABLE_NLS */ /*! * \brief This is used by the lexer/parser. */ typedef struct { int ival; Coord bval; double dval; char has_units; } PLMeasure; #ifndef XtSpecificationRelease typedef unsigned int Cardinal; /*typedef unsigned int Pixel;*/ typedef char *String; typedef short Position; typedef short Dimension; #endif typedef unsigned char BYTE; #ifndef __GNUC__ #define __FUNCTION1(a,b) a ":" #b #define __FUNCTION2(a,b) __FUNCTION1(a,b) #define __FUNCTION__ __FUNCTION2(__FILE__,__LINE__) #endif /* --------------------------------------------------------------------------- * Macros to annotate branch-prediction information. * Taken from GLib 2.16.3 (LGPL 2).G_ / g_ prefixes have * been removed to avoid namespace clashes. */ /* The LIKELY and UNLIKELY macros let the programmer give hints to * the compiler about the expected result of an expression. Some compilers * can use this information for optimizations. * * The PCB_BOOLEAN_EXPR macro is intended to trigger a gcc warning when * putting assignments inside the test. */ #if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) #define PCB_BOOLEAN_EXPR(expr) \ __extension__ ({ \ int _boolean_var_; \ if (expr) \ _boolean_var_ = 1; \ else \ _boolean_var_ = 0; \ _boolean_var_; \ }) #define LIKELY(expr) (__builtin_expect (PCB_BOOLEAN_EXPR(expr), 1)) #define UNLIKELY(expr) (__builtin_expect (PCB_BOOLEAN_EXPR(expr), 0)) #else #define LIKELY(expr) (expr) #define UNLIKELY(expr) (expr) #endif /* --------------------------------------------------------------------------- * Do not change the following definitions even if they're not very * nice. It allows us to have functions act on these "base types" and * not need to know what kind of actual object they're working on. */ /* Any object that uses the "object flags" defined in const.h, or exists as an object on the pcb, MUST be defined using this as the first fields, either directly or through ANYLINEFIELDS. */ #define ANYOBJECTFIELDS \ BoxType BoundingBox; \ long int ID; \ FlagType Flags; \ // struct LibraryEntryType *net /* Lines, pads, and rats all use this so they can be cross-cast. */ #define ANYLINEFIELDS \ ANYOBJECTFIELDS; \ Coord Thickness, \ Clearance; \ PointType Point1, \ Point2 /* --------------------------------------------------------------------------- * some useful values of our widgets */ /*! * \brief Holds information about output window. */ typedef struct { hidGC bgGC, /*!< Background; changed from some routines. */ fgGC, /*!< Foreground; changed from some routines. */ pmGC; /*!< Depth 1 pixmap GC to store clip. */ } OutputType; /*! * \brief Layer group. * * A layer group identifies layers which are always switched on/off * together. */ typedef struct { Cardinal Number[MAX_GROUP], /*!< Number of entries per groups. */ Entries[MAX_GROUP][MAX_ALL_LAYER]; } LayerGroupType; /*! * \brief A bounding box. */ struct BoxType { Coord X1, Y1; /*!< Upper left corner. */ Coord X2, Y2; /*!< Lower right corner. */ }; typedef struct { Coord x, y; Coord width, height; } RectangleType; typedef struct { char *name; char *value; } AttributeType; struct AttributeListType { int Number, Max; AttributeType *List; }; /* --------------------------------------------------------------------------- * the basic object types supported by PCB */ /*! * \brief All on-pcb objects (elements, lines, pads, vias, rats, etc) * are based on this. */ typedef struct { ANYOBJECTFIELDS; } AnyObjectType; /*! * \brief A line/polygon point. */ typedef struct { Coord X, Y, X2, Y2; /*!< So Point type can be cast as BoxType. */ long int ID; } PointType; /*! * \brief Lines, rats, pads, etc. */ typedef struct { ANYLINEFIELDS; } AnyLineObjectType; /*! * \brief Holds information about one line. */ typedef struct { ANYLINEFIELDS; char *Number; } LineType; typedef struct { ANYOBJECTFIELDS; int Scale; /*!< Text scaling in percent. */ Coord X; /*!< X-coordinate of origin. */ Coord Y; /*!< Y-coordinate of origin. */ BYTE Direction; char *TextString; /*!< String. */ void *Element; } TextType; /*! * \brief Holds information about a polygon. */ struct polygon_st { ANYOBJECTFIELDS; Cardinal PointN; /*!< Number of points in polygon. */ Cardinal PointMax; /*!< Max number from malloc(). */ POLYAREA *Clipped; /*!< The clipped region of this polygon. */ PLINE *NoHoles; /*!< The polygon broken into hole-less regions */ int NoHolesValid; /*!< Is the NoHoles polygon up to date? */ PointType *Points; /*!< Data. */ Cardinal *HoleIndex; /*!< Index of hole data within the Points array. */ Cardinal HoleIndexN; /*!< Number of holes in polygon. */ Cardinal HoleIndexMax; /*!< Max number from malloc(). */ }; /*! * \brief Holds information about arcs. */ typedef struct { ANYOBJECTFIELDS; Coord Thickness, Clearance; PointType Point1; PointType Point2; Coord Width; /*!< Length of axis */ Coord Height; /*!< Width of axis */ Coord X; /*!< X-value of the center coordinates. */ Coord Y; /*!< Y-value of the center coordinates. */ Angle StartAngle; /*!< The start angle in degrees. */ Angle Delta; /*!< The described angle in degrees. */ } ArcType; struct rtree { struct rtree_node *root; int size; /*!< Number of entries in tree */ }; /*! * \brief Holds information about one layer. */ typedef struct { LayertypeType Type; /*!< LT_* from hid.h */ char *Name; /*!< Layer name. */ Cardinal LineN; /*!< Number of lines. */ Cardinal TextN; /*!< Labels. */ Cardinal PolygonN; /*!< Polygons. */ Cardinal ArcN; /*!< Arcs. */ GList *Line; GList *Text; GList *Polygon; GList *Arc; rtree_t *line_tree, *text_tree, *polygon_tree, *arc_tree; bool On; /*!< Visible flag. */ char *Color, /*!< Color. */ *SelectedColor; AttributeListType Attributes; int no_drc; /*!< Whether to ignore the layer when checking the design rules */ } LayerType; /*! * \brief A rat line. */ typedef struct { ANYLINEFIELDS; Cardinal group1; /*!< The layer group each point is on. */ Cardinal group2; /*!< The layer group each point is on. */ } RatType; /*! * \brief A SMD pad. */ struct pad_st { ANYLINEFIELDS; Coord Mask; char *Name, *Number; /*!< 'Line'. */ void *Element; void *Spare; }; /*! * \brief A pin. */ struct pin_st { ANYOBJECTFIELDS; Coord Thickness; Coord Clearance; Coord Mask; Coord DrillingHole; /*!< Diameter of the drill hole. */ Coord X; /*!< X-value of the center coordinates. */ Coord Y; /*!< Y-value of the center coordinates. */ char *Name; char *Number; void *Element; void *Spare; Cardinal BuriedFrom; Cardinal BuriedTo; }; /* This is the extents of a Pin or Via, depending on whether it's a hole or not. */ #define PIN_SIZE(pinptr) (TEST_FLAG(HOLEFLAG, (pinptr)) \ ? (pinptr)->DrillingHole \ : (pinptr)->Thickness) /*! * \brief An element. */ typedef struct { ANYOBJECTFIELDS; TextType Name[MAX_ELEMENTNAMES]; /*!< The elements names; * - description text, * - name on PCB second, * - value third. * see macro.h. */ Coord MarkX; /*!< X-value of the position mark. */ Coord MarkY; /*!< Y-value of the position mark. */ Cardinal PinN; /*!< Number of pins. */ Cardinal PadN; /*!< Number of pads. */ Cardinal LineN; /*!< Number of lines. */ Cardinal ArcN; /*!< Number of arcs. */ GList *Pin; GList *Pad; GList *Line; GList *Arc; BoxType VBox; AttributeListType Attributes; } ElementType; /* --------------------------------------------------------------------------- * symbol and font related stuff */ /*! * \brief A single symbol. */ typedef struct { LineType *Line; bool Valid; Cardinal LineN; /*!< Number of lines. */ Cardinal LineMax; Coord Width; /*!< Width of cell. */ Coord Height; /*!< Height of cell. */ Coord Delta; /*!< Distance to next symbol. */ } SymbolType; /*! * \brief Complete set of symbols. */ typedef struct { Coord MaxHeight; /*!< Maximum cell width. */ Coord MaxWidth; /*!< Maximum cell height. */ BoxType DefaultSymbol; /*!< The default symbol is a filled box. */ SymbolType Symbol[MAX_FONTPOSITION + 1]; bool Valid; } FontType; /*! * \brief Holds all objects. */ typedef struct { Cardinal ViaN; /*!< Number of vias. */ Cardinal ElementN; /*!< Number of elements. */ Cardinal RatN; /*!< Number of rat-lines. */ int LayerN; /*!< Number of layers in this board. */ GList *Via; GList *Element; GList *Rat; rtree_t *via_tree, *element_tree, *pin_tree, *pad_tree, *name_tree[3], /* for element names */ *rat_tree; struct PCBType *pcb; LayerType Layer[MAX_ALL_LAYER]; int polyClip; } DataType; /*! * \brief Holds drill information. */ typedef struct { Coord DrillSize; /*!< This drill's diameter. */ Cardinal ElementN; /*!< The number of elements using this drill size. */ Cardinal ElementMax; /*!< Max. number of elements from malloc(). */ Cardinal PinCount; /*!< Number of pins drilled this size. */ Cardinal ViaCount; /*!< Number of vias drilled this size. */ Cardinal UnplatedCount; /*!< Number of these holes that are unplated. */ Cardinal PinN; /*!< Number of drill coordinates in the list. */ Cardinal PinMax; /*!< Max. number of coordinates from malloc(). */ PinType **Pin; /*!< Coordinates to drill. */ ElementType **Element; /*!< A pointer to an array of element pointers. */ } DrillType; /*! * \brief Holds a range of Drill Infos. */ typedef struct { Cardinal DrillN; /*!< Number of drill sizes. */ Cardinal DrillMax; /*!< Max. number from malloc(). */ DrillType *Drill; /*!< Plated holes. */ } DrillInfoType; typedef struct { Coord Thick; /*!< Line thickness. */ Coord Diameter; /*!< Via diameter. */ Coord Hole; /*!< Via drill hole. */ Coord ViaMask; /*!< Solder mask clearance. */ Coord Keepaway; /*!< Min. separation from other nets. */ char *Name; int index; } RouteStyleType; /*! * \brief Structure used by library routines. */ typedef struct { char *ListEntry; /*!< The string for the selection box. */ char *AllocatedMemory; /*!< Pointer to allocated memory; all others point to parts of the string. */ char *Template; /*!< m4 template name. */ char *Package; /*!< Package. */ char *Value; /*!< The value field. */ char *Description; /*!< Some descriptional text. */ } LibraryEntryType; /*! * \brief . * * If the internal flag is set, the only field that is valid is Name, * and the struct is allocated with malloc instead of * CreateLibraryEntry. These "internal" entries are used for * electrical paths that aren't yet assigned to a real net. */ typedef struct { char *Name; /*!< Name of the menu entry. */ char *directory; /*!< Directory name library elements are from. */ char *Style; /*!< Routing style. */ Cardinal EntryN; /*!< Number of objects. */ Cardinal EntryMax; /*!< Number of reserved memory locations. */ LibraryEntryType *Entry; /*!< The entries. */ char flag; /*!< Used by the netlist window to enable/disable nets. */ char internal; /*!< If set, this is an internal-only entry, not * part of the global netlist. */ } LibraryMenuType; typedef struct { Cardinal MenuN; /*!< Number of objects. */ Cardinal MenuMax; /*!< Number of reserved memory locations. */ LibraryMenuType *Menu; /*!< The entries. */ } LibraryType; /*! * \brief The PCBType struct holds information about board layout most * of which is saved with the layout. * * A new PCB layout struct is first initialized with values from the * user configurable \c Settings struct and then reset to the saved * layout values when a layout is loaded. * * This struct is also used for the remove list and for buffer handling. */ typedef struct PCBType { long ID; /*!< See macro.h. */ FlagType Flags; char *Name, /*!< Name of board. */ *Filename, /*!< Name of file (from load). */ *PrintFilename, /*!< From print dialog. */ *Netlistname, /*!< Name of netlist file. */ ThermStyle; /*!< Type of thermal to place with thermal tool. */ bool Changed, /*!< Layout has been changed. */ ViaOn, /*!< Visibility flag for vias. */ ElementOn, /*!< Visibility flag for elements. */ RatOn, /*!< Visibility flag for rat lines. */ InvisibleObjectsOn, PinOn, /*!< Visibility flag for pins. */ SilkActive, /*!< Active layer is actually silk. */ RatDraw; /*!< We're drawing rats. */ char *ViaColor, /*!< Via color. */ *ViaSelectedColor, /*!< Selected via color. */ *PinColor, /*!< Pin color. */ *PinSelectedColor, /*!< Selected pin color. */ *PinNameColor, /*!< Pin name color. */ *ElementColor, /*!< Element color. */ *RatColor, /*!< Rat line color. */ *InvisibleObjectsColor, /*!< Invisible objects color. */ *InvisibleMarkColor, /*!< Invisible mark color. */ *ElementSelectedColor, /*!< Selected elements color. */ *RatSelectedColor, /*!< Selected rat line color. */ *ConnectedColor, /*!< Connected color. */ *FoundColor, /*!< Found color. */ *WarnColor, /*!< Warning color. */ *MaskColor; /*!< Mask color. */ long CursorX, /*!< Cursor position as saved with layout (X value). */ CursorY, /*!< Cursor position as saved with layout (Y value). */ Clipping; Coord Bloat, /*!< DRC bloat size saved with layout. */ Shrink, /*!< DRC shrink size saved with layout. */ minWid, /*!< DRC minimum width size saved with layout. */ minSlk, /*!< DRC minimum silk size saved with layout. */ minDrill, /*!< DRC minimum drill size saved with layout. */ minRing; /*!< DRC minimum annular ring size saved with layout. */ Coord GridOffsetX, /*!< As saved with layout (X value). */ GridOffsetY, /*!< As saved with layout (Y value). */ MaxWidth, /*!< Maximum allowed width size. */ MaxHeight; /*!< Maximum allowed height size. */ Coord Grid; /*!< Used grid with offsets. */ double IsleArea, /*!< Minimum poly island to retain. */ ThermScale; /*!< Scale factor used with thermals. */ FontType Font; LayerGroupType LayerGroups; RouteStyleType RouteStyle[NUM_STYLES]; LibraryType NetlistLib; AttributeListType Attributes; DataType *Data; /*!< Entire database. */ bool is_footprint; /*!< If set, the user has loaded a footprint, not a pcb. */ } PCBType; /*! * \brief Information about the paste buffer. */ typedef struct { Coord X; /*!< Offset (X value). */ Coord Y; /*!< Offset (Y value). */ BoxType BoundingBox; DataType *Data; /*!< Data; not all members of PCBType are used. */ } BufferType; /* --------------------------------------------------------------------------- * some types for cursor drawing, setting of block and lines * as well as for merging of elements */ /*! * \brief Rubberband lines for element moves. */ typedef struct { LayerType *Layer; /*!< Layer that holds the line. */ LineType *Line; /*!< The line itself. */ PointType *MovedPoint; /*!< And finally the point. */ } RubberbandType; /*! * \brief Current marked line. */ typedef struct { PointType Point1; /*!< Start position. */ PointType Point2; /*!< End position. */ long int State; bool draw; } AttachedLineType; /*! * \brief Currently marked block. */ typedef struct { PointType Point1; /*!< Start position. */ PointType Point2; /*!< End position. */ long int State; bool otherway; } AttachedBoxType; /*! * \brief Currently attached object. */ typedef struct { Coord X; /*!< Saved position when MOVE_MODE (X value). */ Coord Y; /*!< Saved position when MOVE_MODE (Y value). */ BoxType BoundingBox; long int Type, /*!< Object type. */ State; void *Ptr1; /*!< Pointer to data, see search.c. */ void *Ptr2; /*!< Pointer to data, see search.c. */ void *Ptr3; /*!< Pointer to data, see search.c. */ Cardinal RubberbandN, /*!< Number of lines in array. */ RubberbandMax; RubberbandType *Rubberband; } AttachedObjectType; enum crosshair_shape { Basic_Crosshair_Shape = 0, /*!< 4-ray. */ Union_Jack_Crosshair_Shape, /*!< 8-ray. */ Dozen_Crosshair_Shape, /*!< 12-ray. */ Crosshair_Shapes_Number }; /*! * \brief Holds cursor information. */ typedef struct { hidGC GC; /*!< GC for cursor drawing. */ hidGC AttachGC; /*!< GC for displaying buffer contents. */ Coord X; /*!< Position in PCB coordinates (X value). */ Coord Y; /*!< Position in PCB coordinates (Y value). */ Coord MinX; /*!< Lowest coordinates (X value). */ Coord MinY; /*!< Lowest coordinates (Y value). */ Coord MaxX; /*!< Highest coordinates (X value). */ Coord MaxY; /*!< Highest coordinates (Y value). */ AttachedLineType AttachedLine; /*!< Data of new lines. */ AttachedBoxType AttachedBox; PolygonType AttachedPolygon; AttachedObjectType AttachedObject; /*!< Data of attached objects. */ enum crosshair_shape shape; /*!< Shape of Crosshair. */ } CrosshairType; typedef struct { bool status; Coord X, Y; } MarkType; /*! * \brief Our resources. * * Most of them are used as default when a new design is started. */ typedef struct { const Unit *grid_unit; Increments *increments; int verbose; char *BlackColor, *WhiteColor, *BackgroundColor, /*!< Background color. */ *CrosshairColor, /*!< Crosshair color. */ *CrossColor, /*!< Cross color. */ *ViaColor, /*!< Via color. */ *ViaSelectedColor, /*!< Selected via color. */ *PinColor, /*!< Pin color. */ *PinSelectedColor, /*!< Selected pin color. */ *PinNameColor, /*!< Pin name color. */ *ElementColor, /*!< Element color. */ *RatColor, /*!< Rat color. */ *InvisibleObjectsColor, /*!< Invisible objects color. */ *InvisibleMarkColor, /*!< Invisible mark color. */ *ElementSelectedColor, /*!< Selected element color. */ *RatSelectedColor, /*!< Selected rat color. */ *ConnectedColor, /*!< Connected color. */ *FoundColor, /*!< Found color. */ *OffLimitColor, *GridColor, /*!< Grid color. */ *LayerColor[MAX_LAYER], *LayerSelectedColor[MAX_LAYER], *WarnColor, /*!< Warning color. */ *MaskColor; /*!< Mask color. */ Coord ViaThickness, /*!< Default via thickness value. */ ViaDrillingHole, /*!< Default via drill hole value. */ ViaMaskAperture, /*!< Default solder mask aperture value. */ LineThickness, /*!< Default line thickness value. */ RatThickness, /*!< Default rat thickness value. */ Keepaway, /*!< Default keepaway value. */ MaxWidth, /*!< Default size of a new layout (X value). */ MaxHeight, /*!< Default size of a new layout (Y value). */ AlignmentDistance, Bloat, /*!< Default drc size for bloat. */ Shrink, /*!< Default drc size for shrink. */ minWid, /*!< Default drc size for minimum trace width. */ minSlk, /*!< Default drc size for minumum silk width. */ minDrill, /*!< Default drc size for minimum drill size. */ minRing; /*!< Default drc size for minimum annular ring. */ int TextScale; /*!< Text scaling in %. */ Coord Grid; /*!< Grid in pcb-units. */ double IsleArea; /*!< Polygon min area. */ Coord PasteAdjust; /*!< Paste adjustment. */ int PinoutNameLength, /*!< Max displayed length of a pinname. */ Volume, /*!< The speakers volume -100 .. 100. */ CharPerLine, /*!< Width of an output line in characters. */ Mode, /*!< Currently active mode. */ BufferNumber; /*!< Number of the current buffer. */ int BackupInterval; /*!< Time between two backups in seconds. */ char *DefaultLayerName[MAX_LAYER], *FontCommand, /*!< Command for font file loading. */ *FileCommand, /*!< Command for file loading. */ *ElementCommand, /*!< Command for element file loading. */ *PrintFile, *LibraryCommandDir, *LibraryCommand, *LibraryContentsCommand, *LibraryTree, /*!< Path to library tree. */ *SaveCommand, *LibraryFilename, *FontFile, /*!< Name of default font file. */ *Groups, /*!< String with layergroups. */ *Routes, /*!< String with route styles. */ *FilePath, *RatPath, *RatCommand, *FontPath, *PinoutFont, *ElementPath, *LibraryPath, *Size, /*!< Geometry string for size. */ *BackgroundImage, /*!< PPM file for board background. */ *ScriptFilename, /*!< PCB Actions script to execute on startup. */ *ActionString, /*!< PCB Actions string to execute on startup. */ *FabAuthor, /*!< Full name of author for FAB drawings. */ *GnetlistProgram, /*!< gnetlist program name. */ *MakeProgram, /*!< make program name. */ *InitialLayerStack; /*!< If set, the initial layer stack is set to this. */ Coord PinoutOffsetX; /*!< Offset of origin (X value). */ Coord PinoutOffsetY; /*!< Offset of origin (Y value). */ Coord PinoutTextOffsetX; /*!< Offset of text from pin center (X value). */ Coord PinoutTextOffsetY; /*!< Offset of text from pin center (Y value). */ RouteStyleType RouteStyle[NUM_STYLES]; /*!< Default routing styles. */ LayerGroupType LayerGroups; /*!< Default layer groups. */ bool ClearLine, FullPoly, UniqueNames, /*!< Force unique names. */ SnapPin, /*!< Snap to pins and pads. */ ShowBottomSide, /*!< Mirror output. */ SaveLastCommand, /*!< Save the last command entered by user. */ SaveInTMP, /*!< Always save data in /tmp. */ SaveMetricOnly, /*!< Save with mm suffix only, not mil/mm hybrid. */ DrawGrid, /*!< Draw grid points. */ RatWarn, /*!< Rats nest has set warnings. */ StipplePolygons, /*!< Draw polygons with stipple. */ AllDirectionLines, /*!< Enable lines to all directions. */ RubberBandMode, /*!< Move, rotate use rubberband connections. */ SwapStartDirection,/*!< Change starting direction after each click. */ ShowDRC, /*!< Show drc region on crosshair. */ AutoDRC, /*!< . */ ShowNumber, /*!< Pinout shows number. */ OrthogonalMoves, /*!< . */ ResetAfterElement, /*!< Reset connections after each element. */ liveRouting, /*!< Autorouter shows tracks in progress. */ AutoBuriedVias, RingBellWhenFinished, /*!< flag if a signal should be produced when searching of * connections is done. */ AutoPlace; /*!< Flag which says we should force placement of the windows on * startup. */ } SettingType; /*! * \brief Pointer to low-level copy, move and rotate functions. */ typedef struct { void *(*Line) (LayerType *, LineType *); void *(*Text) (LayerType *, TextType *); void *(*Polygon) (LayerType *, PolygonType *); void *(*Via) (PinType *); void *(*Element) (ElementType *); void *(*ElementName) (ElementType *); void *(*Pin) (ElementType *, PinType *); void *(*Pad) (ElementType *, PadType *); void *(*LinePoint) (LayerType *, LineType *, PointType *); void *(*Point) (LayerType *, PolygonType *, PointType *); void *(*Arc) (LayerType *, ArcType *); void *(*Rat) (RatType *); } ObjectFunctionType; /* --------------------------------------------------------------------------- * structure used by device drivers */ /*! * \brief Holds a connection. */ typedef struct { Coord X; /*!< Coordinate of connection (X value). */ Coord Y; /*!< Coordinate of connection (Y value). */ long int type; /*!< Type of object in ptr1 - 3. */ void *ptr1; /*!< The object of the connection. */ void *ptr2; /*!< The object of the connection. */ Cardinal group; /*!< The layer group of the connection. */ LibraryMenuType *menu; /*!< The netmenu this *SHOULD* belong to. */ } ConnectionType; /*! * \brief Holds a net of connections. */ typedef struct { Cardinal ConnectionN; /*!< The number of connections contained. */ Cardinal ConnectionMax; /*!< Max connections from malloc. */ ConnectionType *Connection; RouteStyleType *Style; } NetType; /*! * \brief Holds a list of nets. */ typedef struct { Cardinal NetN; /*!< The number of subnets contained. */ Cardinal NetMax; /*!< Max subnets from malloc. */ NetType *Net; } NetListType; /*! * \brief Holds a list of net lists. */ typedef struct { Cardinal NetListN; /*!< The number of net lists contained. */ Cardinal NetListMax; /*!< Max net lists from malloc. */ NetListType *NetList; } NetListListType; /*! * \brief Holds a generic list of pointers. */ typedef struct { Cardinal PtrN; /*!< The number of pointers contained. */ Cardinal PtrMax; /*!< Max subnets from malloc. */ void **Ptr; } PointerListType; typedef struct { Cardinal BoxN; /*!< The number of boxes contained. */ Cardinal BoxMax; /*!< Max boxes from malloc. */ BoxType *Box; } BoxListType; /* --------------------------------------------------------------------------- * define supported types of undo operations * note these must be separate bits now */ #define UNDO_CHANGENAME 0x0001 /*!< Change of names. */ #define UNDO_MOVE 0x0002 /*!< Moving objects. */ #define UNDO_REMOVE 0x0004 /*!< Removing objects. */ #define UNDO_REMOVE_POINT 0x0008 /*!< Removing polygon/... points. */ #define UNDO_INSERT_POINT 0x0010 /*!< Inserting polygon/... points. */ #define UNDO_REMOVE_CONTOUR 0x0020 /*!< Removing a contour from a polygon. */ #define UNDO_INSERT_CONTOUR 0x0040 /*!< Inserting a contour from a polygon. */ #define UNDO_ROTATE 0x0080 /*!< Rotations. */ #define UNDO_CREATE 0x0100 /*!< Creation of objects. */ #define UNDO_MOVETOLAYER 0x0200 /*!< Moving objects to. */ #define UNDO_FLAG 0x0400 /*!< Toggling SELECTED flag. */ #define UNDO_CHANGESIZE 0x0800 /*!< Change size of object. */ #define UNDO_CHANGE2NDSIZE 0x1000 /*!< Change 2ndSize of object. */ #define UNDO_MIRROR 0x2000 /*!< Change side of board. */ #define UNDO_CHANGECLEARSIZE 0x4000 /*!< Change clearance size. */ #define UNDO_CHANGEMASKSIZE 0x8000 /*!< Change mask size. */ #define UNDO_CHANGEANGLES 0x10000 /*!< Change arc angles. */ #define UNDO_LAYERCHANGE 0x20000 /*!< Layer new/delete/move. */ #define UNDO_CLEAR 0x40000 /*!< Clear/restore to polygons. */ #define UNDO_NETLISTCHANGE 0x80000 /*!< Netlist change. */ #define UNDO_CHANGESETVIALAYERS 0x100000 /*!< Buried data change. */ /* --------------------------------------------------------------------------- */ #if (__GNUC__ * 1000 + __GNUC_MINOR__) > 2007 #define ATTRIBUTE_UNUSED __attribute__((unused)) #else #define ATTRIBUTE_UNUSED #endif /* --------------------------------------------------------------------------- * Macros called by various action routines to show usage or to report * a syntax error and fail */ #define AUSAGE(x) Message (_("Usage:\n%s\n"), _(x##_syntax)) #define AFAIL(x) { Message (_("Syntax error. Usage:\n%s\n"), _(x##_syntax)); return 1; } /* --------------------------------------------------------------------------- * Variables with absolute paths to various directories. These are deduced * at runtime to allow pcb to be relocatable */ extern char *bindir; /*!< The dir in which PCB installation was found. */ extern char *pcblibdir; /*!< The system M4 fp directory. */ extern char *pcblibpath; /*!< The search path for M4 fps. */ extern char *pcbtreedir; /*!< The system newlib fp directory. */ extern char *pcbtreepath; /*!< The search path for newlib fps. */ extern char *exec_prefix; extern char *homedir; #endif /* PCB_GLOBAL_H */ pcb-4.3.0/src/crosshair.c0000664000175000017500000012076513773431044012156 00000000000000/*! * \file src/crosshair.c * * \brief Crosshair stuff. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * Thomas.Nau@rz.uni-ulm.de */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "global.h" #include "hid_draw.h" #include "crosshair.h" #include "buffer.h" #include "data.h" #include "draw.h" #include "error.h" #include "line.h" #include "misc.h" #include "mymem.h" #include "search.h" #include "polygon.h" #ifdef HAVE_LIBDMALLOC #include #endif typedef struct { int x, y; } point; /*! * \brief Make a copy of the pin structure, moved to the correct * position */ static void thindraw_moved_pv (hidGC gc, PinType *pv, Coord x, Coord y) { PinType moved_pv = *pv; moved_pv.X += x; moved_pv.Y += y; gui->graphics->thindraw_pcb_pv (gc, gc, &moved_pv, true, false); } /*! * \brief Draw a dashed line. */ static void draw_dashed_line (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2) { /*! \todo we need a real geometrical library, using double here is * plain wrong. */ double dx = x2-x1; double dy = y2-y1; double len_squared = dx*dx + dy*dy; int n; const int segs = 11; /* must be odd */ if (len_squared < 1000000) { /*! \todo line too short, just draw it -> magic value; * with a proper geo lib this would be gone anyway. */ gui->graphics->draw_line (gc, x1, y1, x2, y2); return; } /* first seg is drawn from x1, y1 with no rounding error due to n-1 == 0 */ for (n = 1; n < segs; n += 2) gui->graphics->draw_line (gc, x1 + (dx * (double) (n-1) / (double) segs), y1 + (dy * (double) (n-1) / (double) segs), x1 + (dx * (double) n / (double) segs), y1 + (dy * (double) n / (double) segs)); /* make sure the last segment is drawn properly to x2 and y2, * don't leave room for rounding errors. */ gui->graphics->draw_line (gc, x2 - (dx / (double) segs), y2 - (dy / (double) segs), x2, y2); } /*! * \brief Creates a tmp polygon with coordinates converted to screen * system. */ static void XORPolygon (hidGC gc, PolygonType *polygon, Coord dx, Coord dy, int dash_last) { Cardinal i; for (i = 0; i < polygon->PointN; i++) { Cardinal next = next_contour_point (polygon, i); if (next == 0) { /* last line: sometimes the implicit closing line */ if (i == 1) /* corner case: don't draw two lines on top of * each other - with XOR it looks bad */ continue; if (dash_last) { draw_dashed_line (gc, polygon->Points[i].X + dx, polygon->Points[i].Y + dy, polygon->Points[next].X + dx, polygon->Points[next].Y + dy); break; /* skip normal line draw below */ } } /* normal contour line */ gui->graphics->draw_line (gc, polygon->Points[i].X + dx, polygon->Points[i].Y + dy, polygon->Points[next].X + dx, polygon->Points[next].Y + dy); } } /*! * \brief Draws the outline of an arc. */ static void XORDrawAttachedArc (hidGC gc, Coord thick) { ArcType arc; BoxType *bx; Coord wx, wy; Angle sa, dir; Coord wid = thick / 2; wx = Crosshair.X - Crosshair.AttachedBox.Point1.X; wy = Crosshair.Y - Crosshair.AttachedBox.Point1.Y; if (wx == 0 && wy == 0) return; arc.X = Crosshair.AttachedBox.Point1.X; arc.Y = Crosshair.AttachedBox.Point1.Y; if (XOR (Crosshair.AttachedBox.otherway, abs (wy) > abs (wx))) { arc.X = Crosshair.AttachedBox.Point1.X + abs (wy) * SGNZ (wx); sa = (wx >= 0) ? 0 : 180; #ifdef ARC45 if (abs (wy) >= 2 * abs (wx)) dir = (SGNZ (wx) == SGNZ (wy)) ? 45 : -45; else #endif dir = (SGNZ (wx) == SGNZ (wy)) ? 90 : -90; } else { arc.Y = Crosshair.AttachedBox.Point1.Y + abs (wx) * SGNZ (wy); sa = (wy >= 0) ? -90 : 90; #ifdef ARC45 if (abs (wx) >= 2 * abs (wy)) dir = (SGNZ (wx) == SGNZ (wy)) ? -45 : 45; else #endif dir = (SGNZ (wx) == SGNZ (wy)) ? -90 : 90; wy = wx; } wy = abs (wy); arc.StartAngle = sa; arc.Delta = dir; arc.Width = arc.Height = wy; bx = GetArcEnds (&arc); /* sa = sa - 180; */ gui->graphics->draw_arc (gc, arc.X, arc.Y, wy + wid, wy + wid, sa, dir); if (wid > pixel_slop) { gui->graphics->draw_arc (gc, arc.X, arc.Y, wy - wid, wy - wid, sa, dir); gui->graphics->draw_arc (gc, bx->X1, bx->Y1, wid, wid, sa, -180 * SGN (dir)); gui->graphics->draw_arc (gc, bx->X2, bx->Y2, wid, wid, sa + dir, 180 * SGN (dir)); } } /*! * \brief Draws the outline of a line. */ static void XORDrawAttachedLine (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2, Coord thick) { Coord dx, dy, ox, oy; double h; dx = x2 - x1; dy = y2 - y1; if (dx != 0 || dy != 0) h = 0.5 * thick / hypot (dx, dy); else h = 0.0; ox = dy * h + 0.5 * SGN (dy); oy = -(dx * h + 0.5 * SGN (dx)); gui->graphics->draw_line (gc, x1 + ox, y1 + oy, x2 + ox, y2 + oy); if (abs (ox) >= pixel_slop || abs (oy) >= pixel_slop) { Angle angle = atan2 (dx, dy) * 57.295779; gui->graphics->draw_line (gc, x1 - ox, y1 - oy, x2 - ox, y2 - oy); gui->graphics->draw_arc (gc, x1, y1, thick / 2, thick / 2, angle - 180, 180); gui->graphics->draw_arc (gc, x2, y2, thick / 2, thick / 2, angle, 180); } } /*! * \brief Draws the elements of a loaded circuit which is to be merged * in. */ static void XORDrawElement (hidGC gc, ElementType *Element, Coord DX, Coord DY) { /* if no silkscreen, draw the bounding box */ if (Element->ArcN == 0 && Element->LineN == 0) { gui->graphics->draw_line (gc, DX + Element->BoundingBox.X1, DY + Element->BoundingBox.Y1, DX + Element->BoundingBox.X1, DY + Element->BoundingBox.Y2); gui->graphics->draw_line (gc, DX + Element->BoundingBox.X1, DY + Element->BoundingBox.Y2, DX + Element->BoundingBox.X2, DY + Element->BoundingBox.Y2); gui->graphics->draw_line (gc, DX + Element->BoundingBox.X2, DY + Element->BoundingBox.Y2, DX + Element->BoundingBox.X2, DY + Element->BoundingBox.Y1); gui->graphics->draw_line (gc, DX + Element->BoundingBox.X2, DY + Element->BoundingBox.Y1, DX + Element->BoundingBox.X1, DY + Element->BoundingBox.Y1); } else { ELEMENTLINE_LOOP (Element); { gui->graphics->draw_line (gc, DX + line->Point1.X, DY + line->Point1.Y, DX + line->Point2.X, DY + line->Point2.Y); } END_LOOP; /* arc coordinates and angles have to be converted to X11 notation */ ARC_LOOP (Element); { gui->graphics->draw_arc (gc, DX + arc->X, DY + arc->Y, arc->Width, arc->Height, arc->StartAngle, arc->Delta); } END_LOOP; } /* pin coordinates and angles have to be converted to X11 notation */ PIN_LOOP (Element); { thindraw_moved_pv (gc, pin, DX, DY); } END_LOOP; /* pads */ PAD_LOOP (Element); { if (PCB->InvisibleObjectsOn || (TEST_FLAG (ONSOLDERFLAG, pad) != 0) == Settings.ShowBottomSide) { /* Make a copy of the pad structure, moved to the correct position */ PadType moved_pad = *pad; moved_pad.Point1.X += DX; moved_pad.Point1.Y += DY; moved_pad.Point2.X += DX; moved_pad.Point2.Y += DY; gui->graphics->thindraw_pcb_pad (gc, &moved_pad, false, false); } } END_LOOP; /* mark */ gui->graphics->draw_line (gc, Element->MarkX + DX - EMARK_SIZE, Element->MarkY + DY, Element->MarkX + DX, Element->MarkY + DY - EMARK_SIZE); gui->graphics->draw_line (gc, Element->MarkX + DX + EMARK_SIZE, Element->MarkY + DY, Element->MarkX + DX, Element->MarkY + DY - EMARK_SIZE); gui->graphics->draw_line (gc, Element->MarkX + DX - EMARK_SIZE, Element->MarkY + DY, Element->MarkX + DX, Element->MarkY + DY + EMARK_SIZE); gui->graphics->draw_line (gc, Element->MarkX + DX + EMARK_SIZE, Element->MarkY + DY, Element->MarkX + DX, Element->MarkY + DY + EMARK_SIZE); } /*! * \brief Draws all visible and attached objects of the pastebuffer. */ static void XORDrawBuffer (hidGC gc, BufferType *Buffer) { Cardinal i; Coord x, y; /* set offset */ x = Crosshair.X - Buffer->X; y = Crosshair.Y - Buffer->Y; /* draw all visible layers */ for (i = 0; i < max_copper_layer + SILK_LAYER; i++) if (PCB->Data->Layer[i].On) { LayerType *layer = &Buffer->Data->Layer[i]; LINE_LOOP (layer); { /* XORDrawAttachedLine(x +line->Point1.X, y +line->Point1.Y, x +line->Point2.X, y +line->Point2.Y, line->Thickness); */ gui->graphics->draw_line (gc, x + line->Point1.X, y + line->Point1.Y, x + line->Point2.X, y + line->Point2.Y); } END_LOOP; ARC_LOOP (layer); { gui->graphics->draw_arc (gc, x + arc->X, y + arc->Y, arc->Width, arc->Height, arc->StartAngle, arc->Delta); } END_LOOP; TEXT_LOOP (layer); { BoxType *box = &text->BoundingBox; gui->graphics->draw_rect (gc, x + box->X1, y + box->Y1, x + box->X2, y + box->Y2); } END_LOOP; /* the tmp polygon has n+1 points because the first * and the last one are set to the same coordinates */ POLYGON_LOOP (layer); { XORPolygon (gc, polygon, x, y, 0); } END_LOOP; } /* draw elements if visible */ if (PCB->PinOn && PCB->ElementOn) ELEMENT_LOOP (Buffer->Data); { if (FRONT (element) || PCB->InvisibleObjectsOn) XORDrawElement (gc, element, x, y); } END_LOOP; /* and the vias */ if (PCB->ViaOn) VIA_LOOP (Buffer->Data); { thindraw_moved_pv (gc, via, x, y); } END_LOOP; } /*! * \brief Draws the rubberband to insert points into polygons/lines/... */ static void XORDrawInsertPointObject (hidGC gc) { LineType *line = (LineType *) Crosshair.AttachedObject.Ptr2; PointType *point = (PointType *) Crosshair.AttachedObject.Ptr3; if (Crosshair.AttachedObject.Type != NO_TYPE) { gui->graphics->draw_line (gc, point->X, point->Y, line->Point1.X, line->Point1.Y); gui->graphics->draw_line (gc, point->X, point->Y, line->Point2.X, line->Point2.Y); } } /*! * \brief Draws the attached object while in MOVE_MODE or COPY_MODE. */ static void XORDrawMoveOrCopyObject (hidGC gc) { RubberbandType *ptr; Cardinal i; Coord dx = Crosshair.X - Crosshair.AttachedObject.X, dy = Crosshair.Y - Crosshair.AttachedObject.Y; switch (Crosshair.AttachedObject.Type) { case VIA_TYPE: { PinType *via = (PinType *) Crosshair.AttachedObject.Ptr1; thindraw_moved_pv (gc, via, dx, dy); break; } case LINE_TYPE: { LineType *line = (LineType *) Crosshair.AttachedObject.Ptr2; XORDrawAttachedLine (gc, line->Point1.X + dx, line->Point1.Y + dy, line->Point2.X + dx, line->Point2.Y + dy, line->Thickness); break; } case ARC_TYPE: { ArcType *Arc = (ArcType *) Crosshair.AttachedObject.Ptr2; gui->graphics->draw_arc (gc, Arc->X + dx, Arc->Y + dy, Arc->Width, Arc->Height, Arc->StartAngle, Arc->Delta); break; } case POLYGON_TYPE: { PolygonType *polygon = (PolygonType *) Crosshair.AttachedObject.Ptr2; /* the tmp polygon has n+1 points because the first * and the last one are set to the same coordinates */ XORPolygon (gc, polygon, dx, dy, 0); break; } case LINEPOINT_TYPE: { LineType *line; PointType *point; line = (LineType *) Crosshair.AttachedObject.Ptr2; point = (PointType *) Crosshair.AttachedObject.Ptr3; if (point == &line->Point1) XORDrawAttachedLine (gc, point->X + dx, point->Y + dy, line->Point2.X, line->Point2.Y, line->Thickness); else XORDrawAttachedLine (gc, point->X + dx, point->Y + dy, line->Point1.X, line->Point1.Y, line->Thickness); break; } case POLYGONPOINT_TYPE: { PolygonType *polygon; PointType *point; Cardinal point_idx, prev, next; polygon = (PolygonType *) Crosshair.AttachedObject.Ptr2; point = (PointType *) Crosshair.AttachedObject.Ptr3; point_idx = polygon_point_idx (polygon, point); /* get previous and following point */ prev = prev_contour_point (polygon, point_idx); next = next_contour_point (polygon, point_idx); /* draw the two segments */ gui->graphics->draw_line (gc, polygon->Points[prev].X, polygon->Points[prev].Y, point->X + dx, point->Y + dy); gui->graphics->draw_line (gc, point->X + dx, point->Y + dy, polygon->Points[next].X, polygon->Points[next].Y); break; } case ELEMENTNAME_TYPE: { /* locate the element "mark" and draw an association line from crosshair to it */ ElementType *element = (ElementType *) Crosshair.AttachedObject.Ptr1; gui->graphics->draw_line (gc, element->MarkX, element->MarkY, Crosshair.X, Crosshair.Y); /* fall through to move the text as a box outline */ } case TEXT_TYPE: { TextType *text = (TextType *) Crosshair.AttachedObject.Ptr2; BoxType *box = &text->BoundingBox; gui->graphics->draw_rect (gc, box->X1 + dx, box->Y1 + dy, box->X2 + dx, box->Y2 + dy); break; } /* pin/pad movements result in moving an element */ case PAD_TYPE: case PIN_TYPE: case ELEMENT_TYPE: XORDrawElement (gc, (ElementType *) Crosshair.AttachedObject.Ptr2, dx, dy); break; } /* draw the attached rubberband lines too */ i = Crosshair.AttachedObject.RubberbandN; ptr = Crosshair.AttachedObject.Rubberband; while (i) { PointType *point1, *point2; if (TEST_FLAG (VIAFLAG, ptr->Line)) { /* this is a rat going to a polygon. do not draw for rubberband */; } else if (TEST_FLAG (RUBBERENDFLAG, ptr->Line)) { /* 'point1' is always the fix-point */ if (ptr->MovedPoint == &ptr->Line->Point1) { point1 = &ptr->Line->Point2; point2 = &ptr->Line->Point1; } else { point1 = &ptr->Line->Point1; point2 = &ptr->Line->Point2; } XORDrawAttachedLine (gc, point1->X, point1->Y, point2->X + dx, point2->Y + dy, ptr->Line->Thickness); } else if (ptr->MovedPoint == &ptr->Line->Point1) XORDrawAttachedLine (gc, ptr->Line->Point1.X + dx, ptr->Line->Point1.Y + dy, ptr->Line->Point2.X + dx, ptr->Line->Point2.Y + dy, ptr->Line->Thickness); ptr++; i--; } } /*! * \brief Draws additional stuff that follows the crosshair. */ void DrawAttached (hidGC gc) { gui->graphics->set_color (gc, Settings.CrosshairColor); gui->graphics->set_draw_xor (gc, 1); gui->graphics->set_line_cap (gc, Trace_Cap); gui->graphics->set_line_width (gc, 1); switch (Settings.Mode) { case VIA_MODE: { /* Make a dummy via structure to draw from */ PinType via; via.X = Crosshair.X; via.Y = Crosshair.Y; via.Thickness = Settings.ViaThickness; via.Clearance = 2 * Settings.Keepaway; via.DrillingHole = Settings.ViaDrillingHole; via.Mask = 0; via.Flags = NoFlags (); gui->graphics->thindraw_pcb_pv (gc, gc, &via, true, false); if (TEST_FLAG (SHOWDRCFLAG, PCB)) { Coord mask_r = Settings.ViaThickness / 2 + PCB->Bloat; gui->graphics->set_color (gc, Settings.CrossColor); gui->graphics->set_line_cap (gc, Round_Cap); gui->graphics->set_line_width (gc, 0); gui->graphics->draw_arc (gc, via.X, via.Y, mask_r, mask_r, 0, 360); gui->graphics->set_color (gc, Settings.CrosshairColor); } break; } /* the attached line is used by both LINEMODE, POLYGON_MODE and POLYGONHOLE_MODE*/ case POLYGON_MODE: case POLYGONHOLE_MODE: /* draw only if starting point is set */ if (Crosshair.AttachedLine.State != STATE_FIRST) gui->graphics->draw_line (gc, Crosshair.AttachedLine.Point1.X, Crosshair.AttachedLine.Point1.Y, Crosshair.AttachedLine.Point2.X, Crosshair.AttachedLine.Point2.Y); /* draw attached polygon only if in POLYGON_MODE or POLYGONHOLE_MODE */ if (Crosshair.AttachedPolygon.PointN > 1) { XORPolygon (gc, &Crosshair.AttachedPolygon, 0, 0, 1); } break; case ARC_MODE: if (Crosshair.AttachedBox.State != STATE_FIRST) { XORDrawAttachedArc (gc, Settings.LineThickness); if (TEST_FLAG (SHOWDRCFLAG, PCB)) { gui->graphics->set_color (gc, Settings.CrossColor); XORDrawAttachedArc (gc, Settings.LineThickness + 2 * PCB->Bloat); gui->graphics->set_color (gc, Settings.CrosshairColor); } } break; case LINE_MODE: /* draw only if starting point exists and the line has length */ if (Crosshair.AttachedLine.State != STATE_FIRST && Crosshair.AttachedLine.draw) { XORDrawAttachedLine (gc, Crosshair.AttachedLine.Point1.X, Crosshair.AttachedLine.Point1.Y, Crosshair.AttachedLine.Point2.X, Crosshair.AttachedLine.Point2.Y, PCB->RatDraw ? 10 : Settings.LineThickness); /* draw two lines ? */ if (PCB->Clipping) XORDrawAttachedLine (gc, Crosshair.AttachedLine.Point2.X, Crosshair.AttachedLine.Point2.Y, Crosshair.X, Crosshair.Y, PCB->RatDraw ? 10 : Settings.LineThickness); if (TEST_FLAG (SHOWDRCFLAG, PCB)) { gui->graphics->set_color (gc, Settings.CrossColor); XORDrawAttachedLine (gc, Crosshair.AttachedLine.Point1.X, Crosshair.AttachedLine.Point1.Y, Crosshair.AttachedLine.Point2.X, Crosshair.AttachedLine.Point2.Y, PCB->RatDraw ? 10 : Settings.LineThickness + 2 * PCB->Bloat); if (PCB->Clipping) XORDrawAttachedLine (gc, Crosshair.AttachedLine.Point2.X, Crosshair.AttachedLine.Point2.Y, Crosshair.X, Crosshair.Y, PCB->RatDraw ? 10 : Settings. LineThickness + 2 * PCB->Bloat); gui->graphics->set_color (gc, Settings.CrosshairColor); } } break; case PASTEBUFFER_MODE: XORDrawBuffer (gc, PASTEBUFFER); break; case COPY_MODE: case MOVE_MODE: XORDrawMoveOrCopyObject (gc); break; case INSERTPOINT_MODE: XORDrawInsertPointObject (gc); break; } /* an attached box does not depend on a special mode */ if (Crosshair.AttachedBox.State == STATE_SECOND || Crosshair.AttachedBox.State == STATE_THIRD) { Coord x1, y1, x2, y2; x1 = Crosshair.AttachedBox.Point1.X; y1 = Crosshair.AttachedBox.Point1.Y; x2 = Crosshair.AttachedBox.Point2.X; y2 = Crosshair.AttachedBox.Point2.Y; gui->graphics->draw_rect (gc, x1, y1, x2, y2); } } /*! * \brief Draw the marker position. */ void DrawMark (hidGC gc) { gui->graphics->set_color (gc, Settings.CrosshairColor); gui->graphics->set_draw_xor (gc, 1); gui->graphics->set_line_cap (gc, Trace_Cap); gui->graphics->set_line_width (gc, 1); /* Mark is not drawn when it is not set */ if (!Marked.status) return; gui->graphics->draw_line (gc, Marked.X - MARK_SIZE, Marked.Y - MARK_SIZE, Marked.X + MARK_SIZE, Marked.Y + MARK_SIZE); gui->graphics->draw_line (gc, Marked.X + MARK_SIZE, Marked.Y - MARK_SIZE, Marked.X - MARK_SIZE, Marked.Y + MARK_SIZE); } /*! * \brief Returns the nearest grid-point to the given Coord. */ Coord GridFit (Coord x, Coord grid_spacing, Coord grid_offset) { x -= grid_offset; x = grid_spacing * round ((double) x / grid_spacing); x += grid_offset; return x; } /*! * \brief Notify the GUI that data relating to the crosshair is being * changed. * * The argument passed is false to notify "changes are about to happen", * and true to notify "changes have finished". * * Each call with a 'false' parameter must be matched with a following one * with a 'true' parameter. Unmatched 'true' calls are currently not permitted, * but might be allowed in the future. * * GUIs should not complain if they receive extra calls with 'true' as parameter. * They should initiate a redraw of the crosshair attached objects - which may * (if necessary) mean repainting the whole screen if the GUI hasn't tracked the * location of existing attached drawing. */ void notify_crosshair_change (bool changes_complete) { if (gui->notify_crosshair_change) gui->notify_crosshair_change (changes_complete); } /*! * \brief Notify the GUI that data relating to the mark is being changed. * * The argument passed is false to notify "changes are about to happen", * and true to notify "changes have finished". * * Each call with a 'false' parameter must be matched with a following one * with a 'true' parameter. Unmatched 'true' calls are currently not permitted, * but might be allowed in the future. * * GUIs should not complain if they receive extra calls with 'true' as parameter. * They should initiate a redraw of the mark - which may (if necessary) mean * repainting the whole screen if the GUI hasn't tracked the mark's location. */ void notify_mark_change (bool changes_complete) { if (gui->notify_mark_change) gui->notify_mark_change (changes_complete); } /*! * \brief Convenience for plugins using the old {Hide,Restore}Crosshair * API. * * This links up to notify the GUI of the expected changes using the new APIs. * * Use of this old API is deprecated, as the names don't necessarily reflect * what all GUIs may do in response to the notifications. Keeping these APIs * is aimed at easing transition to the newer API, they will emit a harmless * warning at the time of their first use. * */ void HideCrosshair (void) { static bool warned_old_api = false; if (!warned_old_api) { Message (_("WARNING: A plugin is using the deprecated API HideCrosshair().\n" " This API may be removed in a future release of PCB.\n")); warned_old_api = true; } notify_crosshair_change (false); notify_mark_change (false); } void RestoreCrosshair (void) { static bool warned_old_api = false; if (!warned_old_api) { Message (_("WARNING: A plugin is using the deprecated API RestoreCrosshair().\n" " This API may be removed in a future release of PCB.\n")); warned_old_api = true; } notify_crosshair_change (true); notify_mark_change (true); } /*! * \brief Returns the square of the given number. */ static double square (double x) { return x * x; } static double crosshair_sq_dist (CrosshairType *crosshair, Coord x, Coord y) { return square (x - crosshair->X) + square (y - crosshair->Y); } struct snap_data { CrosshairType *crosshair; double nearest_sq_dist; bool nearest_is_grid; Coord x, y; }; /*! * \brief Snap to a given location if it is the closest thing we found * so far. * * If "prefer_to_grid" is set, the passed location will take preference * over a closer grid points we already snapped to UNLESS the user is * pressing the SHIFT key. If the SHIFT key is pressed, the closest object * (including grid points), is always preferred. */ static void check_snap_object (struct snap_data *snap_data, Coord x, Coord y, bool prefer_to_grid) { double sq_dist; sq_dist = crosshair_sq_dist (snap_data->crosshair, x, y); if (sq_dist <= snap_data->nearest_sq_dist || (prefer_to_grid && snap_data->nearest_is_grid && !gui->shift_is_pressed())) { snap_data->x = x; snap_data->y = y; snap_data->nearest_sq_dist = sq_dist; snap_data->nearest_is_grid = false; } } static void check_snap_offgrid_line (struct snap_data *snap_data, Coord nearest_grid_x, Coord nearest_grid_y) { void *ptr1, *ptr2, *ptr3; int ans; LineType *line; Coord try_x, try_y; double dx, dy; double dist; if (!TEST_FLAG (SNAPPINFLAG, PCB)) return; /* Code to snap at some sensible point along a line */ /* Pick the nearest grid-point in the x or y direction * to align with, then adjust until we hit the line */ ans = SearchObjectByLocation (LINE_TYPE, &ptr1, &ptr2, &ptr3, Crosshair.X, Crosshair.Y, PCB->Grid / 2); if (ans == NO_TYPE) return; line = (LineType *)ptr2; /* Allow snapping to off-grid lines when drawing new lines (on * the same layer), and when moving a line end-point * (but don't snap to the same line) */ if ((Settings.Mode != LINE_MODE || CURRENT != ptr1) && (Settings.Mode != MOVE_MODE || Crosshair.AttachedObject.Ptr1 != ptr1 || Crosshair.AttachedObject.Type != LINEPOINT_TYPE || Crosshair.AttachedObject.Ptr2 == line)) return; dx = line->Point2.X - line->Point1.X; dy = line->Point2.Y - line->Point1.Y; /* Try snapping along the X axis */ if (dy != 0.) { /* Move in the X direction until we hit the line */ try_x = (nearest_grid_y - line->Point1.Y) / dy * dx + line->Point1.X; try_y = nearest_grid_y; check_snap_object (snap_data, try_x, try_y, true); } /* Try snapping along the Y axis */ if (dx != 0.) { try_x = nearest_grid_x; try_y = (nearest_grid_x - line->Point1.X) / dx * dy + line->Point1.Y; check_snap_object (snap_data, try_x, try_y, true); } if (dx != dy) /* If line not parallel with dX = dY direction.. */ { /* Try snapping diagonally towards the line in the dX = dY direction */ if (dy == 0) dist = line->Point1.Y - nearest_grid_y; else dist = ((line->Point1.X - nearest_grid_x) - (line->Point1.Y - nearest_grid_y) * dx / dy) / (1 - dx / dy); try_x = nearest_grid_x + dist; try_y = nearest_grid_y + dist; check_snap_object (snap_data, try_x, try_y, true); } if (dx != -dy) /* If line not parallel with dX = -dY direction.. */ { /* Try snapping diagonally towards the line in the dX = -dY direction */ if (dy == 0) dist = nearest_grid_y - line->Point1.Y; else dist = ((line->Point1.X - nearest_grid_x) - (line->Point1.Y - nearest_grid_y) * dx / dy) / (1 + dx / dy); try_x = nearest_grid_x + dist; try_y = nearest_grid_y - dist; check_snap_object (snap_data, try_x, try_y, true); } } /*! * \brief Recalculates the passed coordinates to fit the current grid * setting. */ void FitCrosshairIntoGrid (Coord X, Coord Y) { Coord nearest_grid_x, nearest_grid_y; void *ptr1, *ptr2, *ptr3; struct snap_data snap_data; int ans; /* limit the crosshair location to the board area */ Crosshair.X = CLAMP (X, Crosshair.MinX, Crosshair.MaxX); Crosshair.Y = CLAMP (Y, Crosshair.MinY, Crosshair.MaxY); /* * GRID SNAPPING * * First figure out where the nearest grid point that would snap to is. Then * if we don't find an object that we would prefer, snap to the grid point. * */ /* if we're drawing rats, don't snap to the grid */ if (PCB->RatDraw) { /* set the "nearest grid" somewhere off the board so that everything else is closer */ nearest_grid_x = -MIL_TO_COORD (6); nearest_grid_y = -MIL_TO_COORD (6); } else { /* not drawing rats */ /* find the closest grid point */ nearest_grid_x = GridFit (Crosshair.X, PCB->Grid, PCB->GridOffsetX); nearest_grid_y = GridFit (Crosshair.Y, PCB->Grid, PCB->GridOffsetY); /* if something is marked and we're forcing orthogonal moves... */ if (Marked.status && TEST_FLAG (ORTHOMOVEFLAG, PCB)) { Coord dx = Crosshair.X - Marked.X; Coord dy = Crosshair.Y - Marked.Y; /* restrict motion along the x or y axis this assumes we're always snapped to a grid point... */ if (ABS (dx) > ABS (dy)) nearest_grid_y = Marked.Y; else nearest_grid_x = Marked.X; } } /* The snap_data structure contains all of the information about where we're * going to snap to. */ snap_data.crosshair = &Crosshair; snap_data.nearest_sq_dist = crosshair_sq_dist (&Crosshair, nearest_grid_x, nearest_grid_y); snap_data.nearest_is_grid = true; snap_data.x = nearest_grid_x; snap_data.y = nearest_grid_y; ans = NO_TYPE; /* if we're not drawing rats, check for elements first */ if (!PCB->RatDraw) ans = SearchObjectByLocation (ELEMENT_TYPE, &ptr1, &ptr2, &ptr3, Crosshair.X, Crosshair.Y, PCB->Grid / 2); if (ans & ELEMENT_TYPE) { /* if we found an element, check to see if we should snap to it */ ElementType *el = (ElementType *) ptr1; check_snap_object (&snap_data, el->MarkX, el->MarkY, false); } /* try snapping to a pad if we're drawing rats, or pad snapping is turned on */ ans = NO_TYPE; if (PCB->RatDraw || TEST_FLAG (SNAPPINFLAG, PCB)) ans = SearchObjectByLocation (PAD_TYPE, &ptr1, &ptr2, &ptr3, Crosshair.X, Crosshair.Y, PCB->Grid / 2); /* Avoid self-snapping when moving */ if (ans != NO_TYPE && Settings.Mode == MOVE_MODE && Crosshair.AttachedObject.Type == ELEMENT_TYPE && ptr1 == Crosshair.AttachedObject.Ptr1) ans = NO_TYPE; if (ans != NO_TYPE && /* we found a pad */ ( Settings.Mode == LINE_MODE || /* we're in line drawing mode, or... */ Settings.Mode == ARC_MODE || /* we're in arc drawing mode, or... */ (Settings.Mode == MOVE_MODE && /* we're moving something and ... */ ((Crosshair.AttachedObject.Type == LINEPOINT_TYPE) || /* it's a line */ (Crosshair.AttachedObject.Type == ARCPOINT_TYPE))))) /* it's an arc */ { /* we found a pad and we're drawing or moving a line */ PadType *pad = (PadType *) ptr2; LayerType *desired_layer; Cardinal desired_group; Cardinal bottom_group, top_group; int found_our_layer = false; /* the layer we'd like to snap to, start with the current layer */ desired_layer = CURRENT; if (Settings.Mode == MOVE_MODE && Crosshair.AttachedObject.Type == LINEPOINT_TYPE) { /* if we're moving something, the desired layer is the layer it's on */ desired_layer = (LayerType *)Crosshair.AttachedObject.Ptr1; } /* pads must be on the top or bottom sides. * find layer groups of the top and bottom sides */ top_group = GetLayerGroupNumberBySide (TOP_SIDE); bottom_group = GetLayerGroupNumberBySide (BOTTOM_SIDE); desired_group = TEST_FLAG (ONSOLDERFLAG, pad) ? bottom_group : top_group; GROUP_LOOP (PCB->Data, desired_group); { if (layer == desired_layer) { /* the layer the pad is on is the same as the layer of the line * that we're moving. */ found_our_layer = true; break; } } END_LOOP; if (found_our_layer == false) /* different layers, so don't snap */ ans = NO_TYPE; } if (ans != NO_TYPE) { /* we found a pad we want to snap to, check to see if we should */ PadType *pad = (PadType *)ptr2; check_snap_object (&snap_data, pad->Point1.X + (pad->Point2.X - pad->Point1.X) / 2, pad->Point1.Y + (pad->Point2.Y - pad->Point1.Y) / 2, true); } /* try snapping to a pin * similar to snapping to a pad, but without the layer restriction */ ans = NO_TYPE; if (PCB->RatDraw || TEST_FLAG (SNAPPINFLAG, PCB)) ans = SearchObjectByLocation (PIN_TYPE, &ptr1, &ptr2, &ptr3, Crosshair.X, Crosshair.Y, PCB->Grid / 2); /* Avoid self-snapping when moving */ if (ans != NO_TYPE && Settings.Mode == MOVE_MODE && Crosshair.AttachedObject.Type == ELEMENT_TYPE && ptr1 == Crosshair.AttachedObject.Ptr1) ans = NO_TYPE; if (ans != NO_TYPE) { /* we found a pin, try to snap to it */ PinType *pin = (PinType *)ptr2; check_snap_object (&snap_data, pin->X, pin->Y, true); } /* if snapping to pins and pads is turned on, try snapping to vias */ ans = NO_TYPE; if (TEST_FLAG (SNAPPINFLAG, PCB)) ans = SearchObjectByLocation (VIA_TYPE, &ptr1, &ptr2, &ptr3, Crosshair.X, Crosshair.Y, PCB->Grid / 2); /* Avoid snapping vias to any other vias */ if (Settings.Mode == MOVE_MODE && Crosshair.AttachedObject.Type == VIA_TYPE && (ans & PIN_TYPES)) ans = NO_TYPE; if (ans != NO_TYPE) { /* found a via, try snapping to it */ PinType *pin = (PinType *)ptr2; check_snap_object (&snap_data, pin->X, pin->Y, true); } /* try snapping to the end points of lines and arcs */ ans = NO_TYPE; if (TEST_FLAG (SNAPPINFLAG, PCB)) ans = SearchObjectByLocation (LINEPOINT_TYPE | ARCPOINT_TYPE, &ptr1, &ptr2, &ptr3, Crosshair.X, Crosshair.Y, PCB->Grid / 2); if (ans != NO_TYPE) { /* found an end point, try to snap to it */ PointType *pnt = (PointType *)ptr3; check_snap_object (&snap_data, pnt->X, pnt->Y, true); } /* try snapping to a point on a line that's not on the grid */ check_snap_offgrid_line (&snap_data, nearest_grid_x, nearest_grid_y); /* try snapping to a point defining a polygon */ ans = NO_TYPE; if (TEST_FLAG (SNAPPINFLAG, PCB)) ans = SearchObjectByLocation (POLYGONPOINT_TYPE, &ptr1, &ptr2, &ptr3, Crosshair.X, Crosshair.Y, PCB->Grid / 2); if (ans != NO_TYPE) { /* found a polygon point, try snapping to it */ PointType *pnt = (PointType *)ptr3; check_snap_object (&snap_data, pnt->X, pnt->Y, true); } /* if snap_data.[x,y] are >= 0, then we found something, * so move the crosshair */ if (snap_data.x >= 0 && snap_data.y >= 0) { Crosshair.X = snap_data.x; Crosshair.Y = snap_data.y; } /* If we're in arrow mode and we're over the end point of a line, * change the cursor to the "draped box" to indicate that clicking would * grab the line endpoint */ if (Settings.Mode == ARROW_MODE) { ans = SearchObjectByLocation (LINEPOINT_TYPE | ARCPOINT_TYPE, &ptr1, &ptr2, &ptr3, Crosshair.X, Crosshair.Y, PCB->Grid / 2); if (ans == NO_TYPE) hid_action("PointCursor"); else if (!TEST_FLAG(SELECTEDFLAG, (LineType *)ptr2)) hid_actionl("PointCursor","True", NULL); } if (Settings.Mode == LINE_MODE && Crosshair.AttachedLine.State != STATE_FIRST && TEST_FLAG (AUTODRCFLAG, PCB)) EnforceLineDRC (); gui->set_crosshair (Crosshair.X, Crosshair.Y, HID_SC_DO_NOTHING); } /*! * \brief Move crosshair absolute. * * \return true if the crosshair was moved from its existing position. */ bool MoveCrosshairAbsolute (Coord X, Coord Y) { Coord old_x = Crosshair.X; Coord old_y = Crosshair.Y; FitCrosshairIntoGrid (X, Y); if (Crosshair.X != old_x || Crosshair.Y != old_y) { Coord new_x = Crosshair.X; Coord new_y = Crosshair.Y; /* back up to old position to notify the GUI * (which might want to erase the old crosshair) */ Crosshair.X = old_x; Crosshair.Y = old_y; notify_crosshair_change (false); /* Our caller notifies when it has done */ /* now move forward again */ Crosshair.X = new_x; Crosshair.Y = new_y; return true; } return false; } /*! * \brief Update the valid range for the crosshair cursor */ void crosshair_update_range(void) { Coord xmin, xmax, ymin, ymax; BoxType *box; /* limit the crosshair to being on the working area */ xmin = 0; xmax = PCB->MaxWidth; ymin = 0; ymax = PCB->MaxHeight; /* limit the crosshair so attached objects stay on the working area */ /* note: There are presently two ways this is done in the code, the first uses * the pastebuffer bounding box, the second uses the attached object * bounding box. */ if (Settings.Mode == PASTEBUFFER_MODE) { SetBufferBoundingBox(PASTEBUFFER); xmin = MAX(xmin, PASTEBUFFER->X - PASTEBUFFER->BoundingBox.X1); ymin = MAX(ymin, PASTEBUFFER->Y - PASTEBUFFER->BoundingBox.Y1); xmax = MIN(xmax, PCB->MaxWidth - (PASTEBUFFER->BoundingBox.X2 - PASTEBUFFER->X)); ymax = MIN(ymax, PCB->MaxHeight - (PASTEBUFFER->BoundingBox.Y2 - PASTEBUFFER->Y)); } /* if there's an attached object, */ if (Crosshair.AttachedObject.Type != NO_TYPE) { box = GetObjectBoundingBox (Crosshair.AttachedObject.Type, Crosshair.AttachedObject.Ptr1, Crosshair.AttachedObject.Ptr2, Crosshair.AttachedObject.Ptr3); xmin = MAX(xmin, Crosshair.AttachedObject.X - box->X1); ymin = MAX(ymin, Crosshair.AttachedObject.Y - box->Y1); xmax = MIN(xmax, PCB->MaxWidth - (box->X2 - Crosshair.AttachedObject.X)); ymax = MIN(ymax, PCB->MaxHeight - (box->Y2 - Crosshair.AttachedObject.Y)); } SetCrosshairRange(xmin, ymin, xmax, ymax); } /*! * \brief Sets the valid range for the crosshair cursor. */ void SetCrosshairRange (Coord MinX, Coord MinY, Coord MaxX, Coord MaxY) { Crosshair.MinX = MAX (0, MinX); Crosshair.MinY = MAX (0, MinY); Crosshair.MaxX = MIN (PCB->MaxWidth, MaxX); Crosshair.MaxY = MIN (PCB->MaxHeight, MaxY); /* force update of position */ FitCrosshairIntoGrid (Crosshair.X, Crosshair.Y); } /*! * \brief Initializes crosshair stuff. * * Clears the struct, allocates to graphical contexts. */ void InitCrosshair (void) { /* set initial shape */ Crosshair.shape = Basic_Crosshair_Shape; /* set default limits */ Crosshair.MinX = Crosshair.MinY = 0; Crosshair.MaxX = PCB->MaxWidth; Crosshair.MaxY = PCB->MaxHeight; /* clear the mark */ Marked.status = false; } /*! * \brief Exits crosshair routines, release GCs. */ void DestroyCrosshair (void) { FreePolygonMemory (&Crosshair.AttachedPolygon); } pcb-4.3.0/src/report.h0000664000175000017500000000241113773431044011464 00000000000000/*! * \file src/report.h * * \brief . * *
* * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * * Thomas.Nau@rz.uni-ulm.de */ #ifndef PCB_REPORT_H #define PCB_REPORT_H #include "global.h" #define REPORT_TYPES \ (VIA_TYPE | LINE_TYPE | TEXT_TYPE | POLYGON_TYPE | ELEMENT_TYPE | \ RATLINE_TYPE | PIN_TYPE | PAD_TYPE | ELEMENTNAME_TYPE | ARC_TYPE \ | POLYGONPOINT_TYPE | LINEPOINT_TYPE) #endif pcb-4.3.0/src/djopt.h0000664000175000017500000000225413773431044011276 00000000000000/*! * \file src/djopt.h * * \brief . * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 2003 DJ Delorie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * DJ Delorie, 334 North Road, Deerfield NH 03037-1110, USA * dj@delorie.com */ #ifndef PCB_DJOPT_H #define PCB_DJOPT_H #include "global.h" int ActionDJopt (int, char **, Coord, Coord); int djopt_set_auto_only (int, char **, Coord, Coord); #endif pcb-4.3.0/src/toporouter.c0000664000175000017500000066234213773431044012405 00000000000000/*! * \file src/toporouter.c * * \brief Topological Autorouter for PCB. * *
* *

Copyright.

\n * * Topological Autorouter for * PCB, interactive printed circuit board design * * Copyright (C) 2009 Anthony Blake * * Copyright (C) 2009-2011 PCB Contributors (see ChangeLog for details) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for email: * Anthony Blake, tonyb33@gmail.com * * * * \warning This is *EXPERIMENTAL* code. * * As the code is experimental, the algorithms and code * are likely to change. Which means it isn't documented * or optimized. If you would like to learn about Topological * Autorouters, the following papers are good starting points: * *This file implements a topological autorouter, and uses techniques from the *following publications: * * Dayan, T. and Dai, W.W.M., "Layer Assignment for a Rubber Band Router" Tech * Report UCSC-CRL-92-50, Univ. of California, Santa Cruz, 1992. * * Dai, W.W.M and Dayan, T. and Staepelaere, D., "Topological Routing in SURF: * Generating a Rubber-Band Sketch" Proc. 28th ACM/IEEE Design Automation * Conference, 1991, pp. 39-44. * * David Staepelaere, Jeffrey Jue, Tal Dayan, Wayne Wei-Ming Dai, "SURF: * Rubber-Band Routing System for Multichip Modules," IEEE Design and Test of * Computers ,vol. 10, no. 4, pp. 18-26, October/December, 1993. * * Dayan, T., "Rubber-band based topological router" PhD Thesis, Univ. of * California, Santa Cruz, 1997. * * David Staepelaere, "Geometric transformations for a rubber-band sketch" * Master's thesis, Univ. of California, Santa Cruz, September 1992. */ #include "flags.h" #include "toporouter.h" #include "pcb-printf.h" #define BOARD_EDGE_RESOLUTION MIL_TO_COORD (100.) #define VIA_COST_AS_DISTANCE MIL_TO_COORD (100.) #define ROAR_DETOUR_THRESHOLD MIL_TO_COORD (10.) /*! * \brief Initialise an edge. */ static void toporouter_edge_init (toporouter_edge_t *edge) { edge->routing = NULL; edge->flags = 0; } toporouter_edge_class_t * toporouter_edge_class(void) { static toporouter_edge_class_t *klass = NULL; if (klass == NULL) { GtsObjectClassInfo constraint_info = { "toporouter_edge_t", sizeof (toporouter_edge_t), sizeof (toporouter_edge_class_t), (GtsObjectClassInitFunc) NULL, (GtsObjectInitFunc) toporouter_edge_init, (GtsArgSetFunc) NULL, (GtsArgGetFunc) NULL }; klass = (toporouter_edge_class_t *)gts_object_class_new (GTS_OBJECT_CLASS (gts_edge_class ()), &constraint_info); } return klass; } /*! * \brief Initialise a bounding box. */ static void toporouter_bbox_init (toporouter_bbox_t *box) { box->data = NULL; box->type = OTHER; box->constraints = NULL; box->cluster = NULL; } toporouter_bbox_class_t * toporouter_bbox_class(void) { static toporouter_bbox_class_t *klass = NULL; if (klass == NULL) { GtsObjectClassInfo constraint_info = { "toporouter_bbox_t", sizeof (toporouter_bbox_t), sizeof (toporouter_bbox_class_t), (GtsObjectClassInitFunc) NULL, (GtsObjectInitFunc) toporouter_bbox_init, (GtsArgSetFunc) NULL, (GtsArgGetFunc) NULL }; klass = (toporouter_bbox_class_t *)gts_object_class_new (GTS_OBJECT_CLASS (gts_bbox_class ()), &constraint_info); } return klass; } /*! * \brief Initialise a vertex class. */ static void toporouter_vertex_class_init (toporouter_vertex_class_t *klass) { } /*! * \brief Initialise a vertex. */ static void toporouter_vertex_init (toporouter_vertex_t *vertex) { vertex->bbox = NULL; vertex->parent = NULL; vertex->child = NULL; vertex->flags = 0; vertex->routingedge = NULL; vertex->arc = NULL; vertex->oproute = NULL; vertex->route = NULL; vertex->gcost = 0.; vertex->hcost = 0.; vertex->gn = 0; } toporouter_vertex_class_t * toporouter_vertex_class(void) { static toporouter_vertex_class_t *klass = NULL; if (klass == NULL) { GtsObjectClassInfo constraint_info = { "toporouter_vertex_t", sizeof (toporouter_vertex_t), sizeof (toporouter_vertex_class_t), (GtsObjectClassInitFunc) toporouter_vertex_class_init, (GtsObjectInitFunc) toporouter_vertex_init, (GtsArgSetFunc) NULL, (GtsArgGetFunc) NULL }; klass = (toporouter_vertex_class_t *)gts_object_class_new (GTS_OBJECT_CLASS (gts_vertex_class ()), &constraint_info); } return klass; } /*! * \brief Initialise a constraint class. */ static void toporouter_constraint_class_init (toporouter_constraint_class_t *klass) { } /*! * \brief Initialise a constraint. */ static void toporouter_constraint_init (toporouter_constraint_t *constraint) { constraint->box = NULL; constraint->routing = NULL; } toporouter_constraint_class_t * toporouter_constraint_class(void) { static toporouter_constraint_class_t *klass = NULL; if (klass == NULL) { GtsObjectClassInfo constraint_info = { "toporouter_constraint_t", sizeof (toporouter_constraint_t), sizeof (toporouter_constraint_class_t), (GtsObjectClassInitFunc) toporouter_constraint_class_init, (GtsObjectInitFunc) toporouter_constraint_init, (GtsArgSetFunc) NULL, (GtsArgGetFunc) NULL }; klass = (toporouter_constraint_class_t *)gts_object_class_new (GTS_OBJECT_CLASS (gts_constraint_class ()), &constraint_info); } return klass; } /*! * \brief Initialise an arc. */ static void toporouter_arc_init (toporouter_arc_t *arc) { arc->x0 = -1.; arc->y0 = -1.; arc->x1 = -1.; arc->y1 = -1.; arc->centre = NULL; arc->v = NULL; arc->v1 = NULL; arc->v2 = NULL; arc->r = -1.; arc->dir = 31337; arc->clearance = NULL; arc->oproute = NULL; } toporouter_arc_class_t * toporouter_arc_class(void) { static toporouter_arc_class_t *klass = NULL; if (klass == NULL) { GtsObjectClassInfo constraint_info = { "toporouter_arc_t", sizeof (toporouter_arc_t), sizeof (toporouter_arc_class_t), (GtsObjectClassInitFunc) NULL, (GtsObjectInitFunc) toporouter_arc_init, (GtsArgSetFunc) NULL, (GtsArgGetFunc) NULL }; klass = (toporouter_arc_class_t *)gts_object_class_new (GTS_OBJECT_CLASS (gts_constraint_class ()), &constraint_info); } return klass; } #define MARGIN 10.0f /*! * \brief Initialise output. */ drawing_context_t * toporouter_output_init(int w, int h, char *filename) { drawing_context_t *dc; dc = (drawing_context_t *)malloc(sizeof(drawing_context_t)); dc->iw = w; dc->ih = h; dc->filename = filename; /* Calculate scaling to maintain aspect ratio */ if(PCB->MaxWidth > PCB->MaxHeight) { /* Scale board width to match image width minus 2xMARGIN */ dc->s = ((double)dc->iw - (2 * MARGIN)) / (double)PCB->MaxWidth; dc->ih = (double)PCB->MaxHeight * dc->s + (2 * MARGIN); }else{ /* Scale board height to match image height minus 2xMARGIN */ dc->s = ((double)dc->ih - (2 * MARGIN)) / (double)PCB->MaxHeight; dc->iw = (double)PCB->MaxWidth * dc->s + (2 * MARGIN); } #if TOPO_OUTPUT_ENABLED dc->surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, dc->iw, dc->ih); dc->cr = cairo_create (dc->surface); cairo_rectangle (dc->cr, 0, 0, dc->iw, dc->ih); cairo_set_source_rgb (dc->cr, 0, 0, 0); cairo_fill (dc->cr); #endif return dc; } /*! * \brief Close output. */ void toporouter_output_close(drawing_context_t *dc) { #if TOPO_OUTPUT_ENABLED cairo_surface_write_to_png (dc->surface, dc->filename); cairo_destroy (dc->cr); cairo_surface_destroy (dc->surface); #endif } /*! * \brief Lookup a keepaway. */ gdouble lookup_keepaway(char *name) { if(name) STYLE_LOOP(PCB); { // if(!strcmp(style->Name, name)) return style->Keepaway + 1.; if(!strcmp(style->Name, name)) return style->Keepaway; } END_LOOP; // return Settings.Keepaway + 1.; return Settings.Keepaway ; } /*! * \brief Lookup thickness. */ gdouble lookup_thickness(char *name) { if(name) STYLE_LOOP(PCB); { if(!strcmp(style->Name, name)) return style->Thick; } END_LOOP; return Settings.LineThickness; } static inline gdouble cluster_keepaway(toporouter_cluster_t *cluster) { if(cluster) return lookup_keepaway(cluster->netlist->style); return lookup_keepaway(NULL); } static inline gdouble cluster_thickness(toporouter_cluster_t *cluster) { if(cluster) return lookup_thickness(cluster->netlist->style); return lookup_thickness(NULL); } /*! * \brief Draw a vertex. */ gint toporouter_draw_vertex(gpointer item, gpointer data) { #if TOPO_OUTPUT_ENABLED drawing_context_t *dc = (drawing_context_t *) data; toporouter_vertex_t *tv; PinType *pin; PadType *pad; gdouble blue; if(TOPOROUTER_IS_VERTEX((GtsObject*)item)) { tv = TOPOROUTER_VERTEX((GtsObject*)item); if(tv->flags & VERTEX_FLAG_RED) { cairo_set_source_rgba(dc->cr, 1., 0., 0., 0.8f); cairo_arc(dc->cr, tv->v.p.x * dc->s + MARGIN, tv->v.p.y * dc->s + MARGIN, MIL_TO_COORD (5.) * dc->s, 0, 2 * M_PI); cairo_fill(dc->cr); }else if(tv->flags & VERTEX_FLAG_GREEN) { cairo_set_source_rgba(dc->cr, 0., 1., 0., 0.8f); cairo_arc(dc->cr, tv->v.p.x * dc->s + MARGIN, tv->v.p.y * dc->s + MARGIN, MIL_TO_COORD (5.) * dc->s, 0, 2 * M_PI); cairo_fill(dc->cr); }else if(tv->flags & VERTEX_FLAG_BLUE) { cairo_set_source_rgba(dc->cr, 0., 0., 1., 0.8f); cairo_arc(dc->cr, tv->v.p.x * dc->s + MARGIN, tv->v.p.y * dc->s + MARGIN, MIL_TO_COORD (5.) * dc->s, 0, 2 * M_PI); cairo_fill(dc->cr); } //printf("tv->type = %d\n", tv->type); if(!dc->mode) { if(tv->bbox) { pin = (PinType*) tv->bbox->data; pad = (PadType*) tv->bbox->data; blue = 0.0f; switch(tv->bbox->type) { case PIN: cairo_set_source_rgba(dc->cr, 1.0f, 0., 0.0f, 0.2f); cairo_arc(dc->cr, tv->v.p.x * dc->s + MARGIN, tv->v.p.y * dc->s + MARGIN, (((gdouble)pin->Thickness / 2.0f) + (gdouble)lookup_keepaway(pin->Name) ) * dc->s, 0, 2 * M_PI); cairo_fill(dc->cr); cairo_set_source_rgba(dc->cr, 1.0f, 0., 0., 0.4f); cairo_arc(dc->cr, tv->v.p.x * dc->s + MARGIN, tv->v.p.y * dc->s + MARGIN, (gdouble)(pin->Thickness) / 2.0f * dc->s, 0, 2 * M_PI); cairo_fill(dc->cr); break; case VIA: cairo_set_source_rgba(dc->cr, 0.0f, 0., 1., 0.2f); cairo_arc(dc->cr, tv->v.p.x * dc->s + MARGIN, tv->v.p.y * dc->s + MARGIN, (((gdouble)pin->Thickness / 2.0f) + (gdouble)lookup_keepaway(pin->Name) ) * dc->s, 0, 2 * M_PI); cairo_fill(dc->cr); cairo_set_source_rgba(dc->cr, 0.0f, 0., 1., 0.4f); cairo_arc(dc->cr, tv->v.p.x * dc->s + MARGIN, tv->v.p.y * dc->s + MARGIN, (gdouble)(pin->Thickness) / 2.0f * dc->s, 0, 2 * M_PI); cairo_fill(dc->cr); break; case PAD: cairo_set_source_rgba(dc->cr, 0.0f, 1., 0., 0.5f); cairo_arc(dc->cr, tv->v.p.x * dc->s + MARGIN, tv->v.p.y * dc->s + MARGIN, MIL_TO_COORD (4.) * dc->s, 0, 2 * M_PI); cairo_fill(dc->cr); break; default: break; } } }else{ if(tv->flags & VERTEX_FLAG_BLUE) { cairo_set_source_rgba(dc->cr, 0., 0., 1., 0.8f); cairo_arc(dc->cr, tv->v.p.x * dc->s + MARGIN, tv->v.p.y * dc->s + MARGIN, MIL_TO_COORD (5.) * dc->s, 0, 2 * M_PI); cairo_fill(dc->cr); }else if(tv->flags & VERTEX_FLAG_RED) { cairo_set_source_rgba(dc->cr, 1., 0., 0., 0.8f); cairo_arc(dc->cr, tv->v.p.x * dc->s + MARGIN, tv->v.p.y * dc->s + MARGIN, MIL_TO_COORD (5.) * dc->s, 0, 2 * M_PI); cairo_fill(dc->cr); }else if(tv->flags & VERTEX_FLAG_GREEN) { cairo_set_source_rgba(dc->cr, 0., 1., 0., 0.8f); cairo_arc(dc->cr, tv->v.p.x * dc->s + MARGIN, tv->v.p.y * dc->s + MARGIN, MIL_TO_COORD (5.) * dc->s, 0, 2 * M_PI); cairo_fill(dc->cr); } } }else{ fprintf(stderr, "Unknown data passed to toporouter_draw_vertex, aborting foreach\n"); return -1; } return 0; #else return -1; #endif } /*! * \brief Draw an edge. */ gint toporouter_draw_edge(gpointer item, gpointer data) { #if TOPO_OUTPUT_ENABLED drawing_context_t *dc = (drawing_context_t *) data; toporouter_edge_t *te; toporouter_constraint_t *tc; if(TOPOROUTER_IS_EDGE((GtsObject*)item)) { te = TOPOROUTER_EDGE((GtsObject*)item); cairo_set_source_rgba(dc->cr, 1.0f, 1.0f, 1.0f, 0.5f); cairo_move_to(dc->cr, te->e.segment.v1->p.x * dc->s + MARGIN, te->e.segment.v1->p.y * dc->s + MARGIN); cairo_line_to(dc->cr, te->e.segment.v2->p.x * dc->s + MARGIN, te->e.segment.v2->p.y * dc->s + MARGIN); cairo_stroke(dc->cr); }else if(TOPOROUTER_IS_CONSTRAINT((GtsObject*)item)) { tc = TOPOROUTER_CONSTRAINT((GtsObject*)item); if(tc->box) { switch(tc->box->type) { case BOARD: cairo_set_source_rgba(dc->cr, 1.0f, 0.0f, 1.0f, 0.9f); cairo_move_to(dc->cr, tc->c.edge.segment.v1->p.x * dc->s + MARGIN, tc->c.edge.segment.v1->p.y * dc->s + MARGIN); cairo_line_to(dc->cr, tc->c.edge.segment.v2->p.x * dc->s + MARGIN, tc->c.edge.segment.v2->p.y * dc->s + MARGIN); cairo_stroke(dc->cr); break; case PIN: case PAD: cairo_set_source_rgba(dc->cr, 1.0f, 0.0f, 0.0f, 0.9f); cairo_move_to(dc->cr, tc->c.edge.segment.v1->p.x * dc->s + MARGIN, tc->c.edge.segment.v1->p.y * dc->s + MARGIN); cairo_line_to(dc->cr, tc->c.edge.segment.v2->p.x * dc->s + MARGIN, tc->c.edge.segment.v2->p.y * dc->s + MARGIN); cairo_stroke(dc->cr); break; case LINE: cairo_set_source_rgba(dc->cr, 0.0f, 1.0f, 0.0f, 0.9f); cairo_move_to(dc->cr, tc->c.edge.segment.v1->p.x * dc->s + MARGIN, tc->c.edge.segment.v1->p.y * dc->s + MARGIN); cairo_line_to(dc->cr, tc->c.edge.segment.v2->p.x * dc->s + MARGIN, tc->c.edge.segment.v2->p.y * dc->s + MARGIN); cairo_stroke(dc->cr); break; default: cairo_set_source_rgba(dc->cr, 1.0f, 1.0f, 0.0f, 0.9f); cairo_move_to(dc->cr, tc->c.edge.segment.v1->p.x * dc->s + MARGIN, tc->c.edge.segment.v1->p.y * dc->s + MARGIN); cairo_line_to(dc->cr, tc->c.edge.segment.v2->p.x * dc->s + MARGIN, tc->c.edge.segment.v2->p.y * dc->s + MARGIN); cairo_stroke(dc->cr); break; } }else{ printf("CONSTRAINT without box\n"); } }else{ fprintf(stderr, "Unknown data passed to toporouter_draw_edge, aborting foreach\n"); return -1; } return 0; #else return -1; #endif } //#define vertex_bbox(v) (v->bbox) ///* toporouter_bbox_t * vertex_bbox(toporouter_vertex_t *v) { return v ? v->bbox : NULL; } //*/ char * vertex_netlist(toporouter_vertex_t *v) { toporouter_bbox_t *box = vertex_bbox(v); if(box && box->cluster) return box->cluster->netlist->netlist; return NULL; } char * constraint_netlist(toporouter_constraint_t *c) { toporouter_bbox_t *box = c->box; if(box && box->cluster) return box->cluster->netlist->netlist; return NULL; } static inline guint epsilon_equals(gdouble a, gdouble b) { if(a > b - EPSILON && a < b + EPSILON) return 1; return 0; } /*! * \brief Print a bounding box. */ void print_bbox(toporouter_bbox_t *box) { printf("[BBOX "); switch(box->type) { case PAD: printf("PAD "); break; case PIN: printf("PIN "); break; case VIA: printf("VIA "); break; case LINE: printf("LINE "); break; case BOARD: printf("BOARD "); break; case POLYGON: printf("POLYGON "); break; default: printf("UNKNOWN "); break; } if(box->point) printf("P: %f,%f,%f ", vx(box->point), vy(box->point), vz(box->point)); else printf("P: NONE "); printf("LAYER: %d ", box->layer); printf("CLUSTER: %d]\n", box->cluster ? box->cluster->c : -1); } /*! * \brief Print a vertex. */ void print_vertex(toporouter_vertex_t *v) { if(v) printf("[V %f,%f,%f ", vx(v), vy(v), vz(v)); else printf("[V (null) "); printf("%s ", vertex_netlist(v)); if(v->route && v->route->netlist) printf("%s ", v->route->netlist->netlist); if(v->routingedge) { guint n = g_list_length(edge_routing(v->routingedge)); guint pos = g_list_index(edge_routing(v->routingedge), v); if(TOPOROUTER_IS_CONSTRAINT(v->routingedge)) printf("[CONST "); else printf("[EDGE "); printf("%d/%d] ", pos, n); } if(v->flags & VERTEX_FLAG_TEMP) printf("TEMP "); if(v->flags & VERTEX_FLAG_ROUTE) printf("ROUTE "); if(v->flags & VERTEX_FLAG_SPECCUT) printf("SPECCUT "); if(v->flags & VERTEX_FLAG_FAKE) printf("FAKE "); printf("]\n"); } gdouble vertex_net_thickness(toporouter_vertex_t *v) { toporouter_bbox_t *box = vertex_bbox(v); if(!box) { while(v && (v->flags & VERTEX_FLAG_TEMP || v->flags & VERTEX_FLAG_ROUTE)) { v = v->parent; } box = vertex_bbox(v); }else{ if(box->type == PIN || box->type == VIA) { PinType *pin = (PinType *)box->data; if(TEST_FLAG(SQUAREFLAG, pin) || TEST_FLAG(OCTAGONFLAG, pin)) { return 0.; } // return ((PinType *)box->data)->Thickness + 1.; return ((PinType *)box->data)->Thickness; }else if(box->type == PAD) { PadType *pad = (PadType *)box->data; if(pad->Point1.X == pad->Point2.X && pad->Point1.Y == pad->Point2.Y && !TEST_FLAG(SQUAREFLAG, pad)) { return pad->Thickness; } return 0.; }else if(box->type == BOARD) { return 0.; }else if(box->type == LINE) { LineType *line = (LineType *) box->data; return line->Thickness; }else if(box->type == POLYGON) { return 0.; } printf("Unrecognized type in thickness lookup..\n"); } // if(!box || !box->cluster) return Settings.LineThickness + 1.; if(!box || !box->cluster) return Settings.LineThickness; return cluster_thickness(box->cluster); } gdouble vertex_net_keepaway(toporouter_vertex_t *v) { toporouter_bbox_t *box = vertex_bbox(v); if(!box) { while(v && (v->flags & VERTEX_FLAG_TEMP || v->flags & VERTEX_FLAG_ROUTE)) { v = v->parent; } box = vertex_bbox(v); } else{ // if(box->type == PIN || box->type == VIA) // return ((PinType *)box->data)->Clearance; // else if(box->type == PAD) // return ((PadType *)box->data)->Clearance; } // if(!box || !box->cluster) return Settings.Keepaway + 1.; if(!box || !box->cluster) return Settings.Keepaway; return cluster_keepaway(box->cluster); } /*! * \brief Fills in x and y with coordinates of point from a towards b of * distance d. */ static void point_from_point_to_point (toporouter_vertex_t *a, toporouter_vertex_t *b, double d, double *x, double *y) { double theta = atan2 (vy(b) - vy(a), vx(b) - vx(a)); *x = vx(a) + d * cos (theta); *y = vy(a) + d * sin (theta); } static inline gint coord_wind(gdouble ax, gdouble ay, gdouble bx, gdouble by, gdouble cx, gdouble cy) { gdouble rval, dx1, dx2, dy1, dy2; dx1 = bx - ax; dy1 = by - ay; dx2 = cx - bx; dy2 = cy - by; rval = (dx1*dy2)-(dy1*dx2); return (rval > EPSILON) ? 1 : ((rval < -EPSILON) ? -1 : 0); } /*! * \brief . * * wind_v: * * \return 1, 0, -1 for counterclockwise, collinear or clockwise, * respectively. */ int point_wind(GtsPoint *a, GtsPoint *b, GtsPoint *c) { gdouble rval, dx1, dx2, dy1, dy2; dx1 = b->x - a->x; dy1 = b->y - a->y; dx2 = c->x - b->x; dy2 = c->y - b->y; rval = (dx1*dy2)-(dy1*dx2); return (rval > EPSILON) ? 1 : ((rval < -EPSILON) ? -1 : 0); } static inline int vertex_wind(GtsVertex *a, GtsVertex *b, GtsVertex *c) { return point_wind(GTS_POINT(a), GTS_POINT(b), GTS_POINT(c)); } static inline int tvertex_wind(toporouter_vertex_t *a, toporouter_vertex_t *b, toporouter_vertex_t *c) { return point_wind(GTS_POINT(a), GTS_POINT(b), GTS_POINT(c)); } /*! * \brief Moves vertex v d units in the direction of vertex p. */ static void coord_move_towards_coord_values (double ax, double ay, double px, double py, double d, double *x, double *y) { double theta = atan2 (py - ay, px - ax); *x = ax + d * cos (theta); *y = ay + d * sin (theta); } /*! * \brief Moves vertex v d units in the direction of vertex p. */ static void vertex_move_towards_vertex_values (GtsVertex *v, GtsVertex *p, double d, double *x, double *y) { double theta = atan2 (GTS_POINT(p)->y - GTS_POINT(v)->y, GTS_POINT(p)->x - GTS_POINT(v)->x); *x = GTS_POINT(v)->x + d * cos (theta); *y = GTS_POINT(v)->y + d * sin (theta); } #define tv_on_layer(v,l) (l == TOPOROUTER_BBOX(TOPOROUTER_VERTEX(v)->boxes->data)->layer) static inline gdouble min_spacing(toporouter_vertex_t *v1, toporouter_vertex_t *v2) { gdouble v1halfthick, v2halfthick, v1keepaway, v2keepaway, ms; // toporouter_edge_t *e = v1->routingedge; v1halfthick = vertex_net_thickness(TOPOROUTER_VERTEX(v1)) / 2.; v2halfthick = vertex_net_thickness(TOPOROUTER_VERTEX(v2)) / 2.; v1keepaway = vertex_net_keepaway(TOPOROUTER_VERTEX(v1)); v2keepaway = vertex_net_keepaway(TOPOROUTER_VERTEX(v2)); ms = v1halfthick + v2halfthick + MAX(v1keepaway, v2keepaway); #ifdef SPACING_DEBUG printf("v1halfthick = %f v2halfthick = %f v1keepaway = %f v2keepaway = %f ms = %f\n", v1halfthick, v2halfthick, v1keepaway, v2keepaway, ms); #endif return ms; } // v1 is a vertex in the CDT, and v2 is a net... other way around? static inline gdouble min_vertex_net_spacing(toporouter_vertex_t *v1, toporouter_vertex_t *v2) { gdouble v1halfthick, v2halfthick, v1keepaway, v2keepaway, ms; v1halfthick = vertex_net_thickness(TOPOROUTER_VERTEX(v1)) / 2.; v2halfthick = cluster_thickness(vertex_bbox(v2)->cluster) / 2.; v1keepaway = vertex_net_keepaway(TOPOROUTER_VERTEX(v1)); v2keepaway = cluster_keepaway(vertex_bbox(v2)->cluster); ms = v1halfthick + v2halfthick + MAX(v1keepaway, v2keepaway); return ms; } static inline gdouble min_oproute_vertex_spacing(toporouter_oproute_t *oproute, toporouter_vertex_t *v2) { gdouble v1halfthick, v2halfthick, v1keepaway, v2keepaway, ms; v1halfthick = lookup_thickness(oproute->style) / 2.; v2halfthick = vertex_net_thickness(v2) / 2.; v1keepaway = lookup_keepaway(oproute->style); v2keepaway = vertex_net_keepaway(v2); ms = v1halfthick + v2halfthick + MAX(v1keepaway, v2keepaway); return ms; } gdouble min_oproute_net_spacing(toporouter_oproute_t *oproute, toporouter_vertex_t *v2) { gdouble v1halfthick, v2halfthick, v1keepaway, v2keepaway, ms; v1halfthick = lookup_thickness(oproute->style) / 2.; v2halfthick = cluster_thickness(v2->route->src) / 2.; v1keepaway = lookup_keepaway(oproute->style); v2keepaway = cluster_keepaway(v2->route->src); ms = v1halfthick + v2halfthick + MAX(v1keepaway, v2keepaway); return ms; } gdouble min_net_net_spacing(toporouter_vertex_t *v1, toporouter_vertex_t *v2) { gdouble v1halfthick, v2halfthick, v1keepaway, v2keepaway, ms; v1halfthick = cluster_thickness(v1->route->src) / 2.; v2halfthick = cluster_thickness(v2->route->src) / 2.; v1keepaway = cluster_keepaway(v1->route->src); v2keepaway = cluster_keepaway(v2->route->src); ms = v1halfthick + v2halfthick + MAX(v1keepaway, v2keepaway); return ms; } void toporouter_draw_cluster(toporouter_t *r, drawing_context_t *dc, toporouter_cluster_t *cluster, gdouble red, gdouble green, gdouble blue, guint layer) { #if TOPO_OUTPUT_ENABLED //GList *i = cluster->i; //while(i) { // toporouter_bbox_t *box = TOPOROUTER_BBOX(i->data); // if(box->point && vz(box->point) == layer) { // cairo_set_source_rgba(dc->cr, red, green, blue, 0.8f); // cairo_arc(dc->cr, vx(box->point) * dc->s + MARGIN, vy(box->point) * dc->s + MARGIN, MIL_TO_COORD (5.) * dc->s, 0, 2 * M_PI); // cairo_fill(dc->cr); // } // i = i->next; //} #endif } void toporouter_draw_surface(toporouter_t *r, GtsSurface *s, char *filename, int w, int h, int mode, GList *datas, int layer, GList *candidatepoints) { #if TOPO_OUTPUT_ENABLED drawing_context_t *dc; GList *i; toporouter_vertex_t *tv, *tv2 = NULL; dc = toporouter_output_init(w, h, filename); dc->mode = mode; dc->data = NULL; gts_surface_foreach_edge(s, toporouter_draw_edge, dc); gts_surface_foreach_vertex(s, toporouter_draw_vertex, dc); i = r->routednets; while(i) { GList *j = TOPOROUTER_ROUTE(i->data)->path; tv2 = NULL; while(j) { tv = TOPOROUTER_VERTEX(j->data); if(GTS_POINT(tv)->z == layer) { if(tv && tv2) { cairo_set_source_rgba(dc->cr, 0.0f, 1.0f, 0.0f, 0.8f); cairo_move_to(dc->cr, GTS_POINT(tv)->x * dc->s + MARGIN, GTS_POINT(tv)->y * dc->s + MARGIN); cairo_line_to(dc->cr, GTS_POINT(tv2)->x * dc->s + MARGIN, GTS_POINT(tv2)->y * dc->s + MARGIN); cairo_stroke(dc->cr); } if(tv->flags & VERTEX_FLAG_RED) { cairo_set_source_rgba(dc->cr, 1., 0., 0., 0.8f); cairo_arc(dc->cr, tv->v.p.x * dc->s + MARGIN, tv->v.p.y * dc->s + MARGIN, MIL_TO_COORD (5.) * dc->s, 0, 2 * M_PI); cairo_fill(dc->cr); }else if(tv->flags & VERTEX_FLAG_GREEN) { cairo_set_source_rgba(dc->cr, 0., 1., 0., 0.8f); cairo_arc(dc->cr, tv->v.p.x * dc->s + MARGIN, tv->v.p.y * dc->s + MARGIN, MIL_TO_COORD (5.) * dc->s, 0, 2 * M_PI); cairo_fill(dc->cr); }else if(tv->flags & VERTEX_FLAG_BLUE) { cairo_set_source_rgba(dc->cr, 0., 0., 1., 0.8f); cairo_arc(dc->cr, tv->v.p.x * dc->s + MARGIN, tv->v.p.y * dc->s + MARGIN, MIL_TO_COORD (5.) * dc->s, 0, 2 * M_PI); cairo_fill(dc->cr); } else { cairo_set_source_rgba(dc->cr, 1., 1., 1., 0.8f); cairo_arc(dc->cr, tv->v.p.x * dc->s + MARGIN, tv->v.p.y * dc->s + MARGIN, MIL_TO_COORD (5.) * dc->s, 0, 2 * M_PI); cairo_fill(dc->cr); } if(tv->routingedge && !TOPOROUTER_IS_CONSTRAINT(tv->routingedge)) { gdouble tempx, tempy, nms, pms; GList *i = g_list_find(edge_routing(tv->routingedge), tv); toporouter_vertex_t *nextv, *prevv; nextv = edge_routing_next(tv->routingedge,i); prevv = edge_routing_prev(tv->routingedge,i); nms = min_spacing(tv,nextv); pms = min_spacing(tv,prevv); g_assert(isfinite(nms)); g_assert(isfinite(pms)); point_from_point_to_point(tv, nextv, nms, &tempx, &tempy); cairo_set_source_rgba(dc->cr, 0.0f, 1.0f, 1.0f, 0.8f); cairo_move_to(dc->cr, vx(tv) * dc->s + MARGIN, vy(tv) * dc->s + MARGIN); cairo_line_to(dc->cr, tempx * dc->s + MARGIN, tempy * dc->s + MARGIN); cairo_stroke(dc->cr); point_from_point_to_point(tv, prevv, pms, &tempx, &tempy); cairo_move_to(dc->cr, vx(tv) * dc->s + MARGIN, vy(tv) * dc->s + MARGIN); cairo_line_to(dc->cr, tempx * dc->s + MARGIN, tempy * dc->s + MARGIN); cairo_stroke(dc->cr); } } tv2 = tv; j = j->next; } i = i->next; } while(datas) { toporouter_route_t *routedata = (toporouter_route_t *) datas->data; GList *i;//, *k; toporouter_draw_cluster(r, dc, routedata->src, 1., 0., 0., layer); toporouter_draw_cluster(r, dc, routedata->dest, 0., 0., 1., layer); tv2 = NULL; i = routedata->path; while(i) { tv = TOPOROUTER_VERTEX(i->data); if(GTS_POINT(tv)->z == layer) { if(tv && tv2) { cairo_set_source_rgba(dc->cr, 0.0f, 1.0f, 0.0f, 0.8f); cairo_move_to(dc->cr, GTS_POINT(tv)->x * dc->s + MARGIN, GTS_POINT(tv)->y * dc->s + MARGIN); cairo_line_to(dc->cr, GTS_POINT(tv2)->x * dc->s + MARGIN, GTS_POINT(tv2)->y * dc->s + MARGIN); cairo_stroke(dc->cr); } } tv2 = tv; i = i->next; } if(routedata->alltemppoints) { GList *i, *j; i = j = g_hash_table_get_keys (routedata->alltemppoints); while(i) { toporouter_vertex_t *tv = TOPOROUTER_VERTEX(i->data); if(GTS_POINT(tv)->z != layer) { i = i->next; continue; } if(tv->flags & VERTEX_FLAG_BLUE) { cairo_set_source_rgba(dc->cr, 0., 0., 1., 0.8f); cairo_arc(dc->cr, tv->v.p.x * dc->s + MARGIN, tv->v.p.y * dc->s + MARGIN, MIL_TO_COORD (5.) * dc->s, 0, 2 * M_PI); cairo_fill(dc->cr); }else if(tv->flags & VERTEX_FLAG_RED) { cairo_set_source_rgba(dc->cr, 1., 0., 0., 0.8f); cairo_arc(dc->cr, tv->v.p.x * dc->s + MARGIN, tv->v.p.y * dc->s + MARGIN, MIL_TO_COORD (5.) * dc->s, 0, 2 * M_PI); cairo_fill(dc->cr); }else if(tv->flags & VERTEX_FLAG_GREEN) { cairo_set_source_rgba(dc->cr, 0., 1., 0., 0.8f); cairo_arc(dc->cr, tv->v.p.x * dc->s + MARGIN, tv->v.p.y * dc->s + MARGIN, MIL_TO_COORD (5.) * dc->s, 0, 2 * M_PI); cairo_fill(dc->cr); }else{ cairo_set_source_rgba(dc->cr, 1., 1., 1., 0.8f); cairo_arc(dc->cr, tv->v.p.x * dc->s + MARGIN, tv->v.p.y * dc->s + MARGIN, MIL_TO_COORD (5.) * dc->s, 0, 2 * M_PI); cairo_fill(dc->cr); } i = i->next; } g_list_free(j); } datas = datas->next; } toporouter_output_close(dc); #endif } /*! * \brief Free a layer. */ void toporouter_layer_free(toporouter_layer_t *l) { g_list_free(l->vertices); g_list_free(l->constraints); } guint groupcount(void) { int group; guint count = 0; for (group = 0; group < max_group; group++) { if(PCB->LayerGroups.Number[group] > 0) count++; } return count; } void toporouter_free(toporouter_t *r) { struct timeval endtime; double time_delta; int i; for(i=0;ilayers[i]); } gettimeofday (&endtime, NULL); time_delta = endtime.tv_sec - r->starttime.tv_sec + (endtime.tv_usec - r->starttime.tv_usec) / 1000000.; Message(_("Elapsed time: %.2f seconds\n"), time_delta); free(r->layers); free(r); } /*! * \brief . * * wind: * * \return 1, 0, -1 for counterclockwise, collinear or clockwise, * respectively. */ int wind(toporouter_spoint_t *p1, toporouter_spoint_t *p2, toporouter_spoint_t *p3) { double rval, dx1, dx2, dy1, dy2; dx1 = p2->x - p1->x; dy1 = p2->y - p1->y; dx2 = p3->x - p2->x; dy2 = p3->y - p2->y; rval = (dx1*dy2)-(dy1*dx2); return (rval > 0.0001) ? 1 : ((rval < -0.0001) ? -1 : 0); /* XXX: Depends on PCB coordinate scaling */ } static inline void print_toporouter_constraint(toporouter_constraint_t *tc) { printf("%f,%f -> %f,%f ", tc->c.edge.segment.v1->p.x, tc->c.edge.segment.v1->p.y, tc->c.edge.segment.v2->p.x, tc->c.edge.segment.v2->p.y); } static inline void print_toporouter_vertex(toporouter_vertex_t *tv) { printf("%f,%f ", tv->v.p.x, tv->v.p.y); } /*! * \brief . * * vertices_on_line: * Given vertex a, gradient m, and radius r: * * \return vertices on line of a & m at r from a. */ static void vertices_on_line (toporouter_spoint_t *a, double m, double r, toporouter_spoint_t *b0, toporouter_spoint_t *b1) { double c, dx; if (m == INFINITY || m == -INFINITY) { b0->x = a->x; b0->y = a->y + r; b1->x = a->x; b1->y = a->y - r; return; } c = a->y - m * a->x; dx = r / hypot (1, m); b0->x = a->x + dx; b0->y = m * b0->x + c; b1->x = a->x - dx; b1->y = m * b1->x + c; } /*! * \brief . * * coords_on_line: * Given coordinates ax, ay, gradient m, and radius r: * * \return coordinates on line of a & m at r from a. */ static void coords_on_line (double ax, gdouble ay, double m, double r, double *b0x, double *b0y, double *b1x, double *b1y) { double c, dx; if (m == INFINITY || m == -INFINITY) { *b0x = ax; *b0y = ay + r; *b1x = ax; *b1y = ay - r; return; } c = ay - m * ax; dx = r / hypot (1, m); *b0x = ax + dx; *b0y = m * *b0x + c; *b1x = ax - dx; *b1y = m * *b1x + c; } /*! * \brief Returns gradient of segment given by a & b. */ gdouble vertex_gradient(toporouter_spoint_t *a, toporouter_spoint_t *b) { if(a->x == b->x) return INFINITY; return ((b->y - a->y) / (b->x - a->x)); } /*! * \brief Returns gradient of segment given by (x0,y0) & (x1,y1). */ static inline gdouble cartesian_gradient(gdouble x0, gdouble y0, gdouble x1, gdouble y1) { if(epsilon_equals(x0,x1)) return INFINITY; return ((y1 - y0) / (x1 - x0)); } /*! * \brief Returns gradient of segment given by (x0,y0) & (x1,y1). */ static inline gdouble point_gradient(GtsPoint *a, GtsPoint *b) { return cartesian_gradient(a->x, a->y, b->x, b->y); } gdouble segment_gradient(GtsSegment *s) { return cartesian_gradient( GTS_POINT(s->v1)->x, GTS_POINT(s->v1)->y, GTS_POINT(s->v2)->x, GTS_POINT(s->v2)->y); } /*! * \brief Returns gradient perpendicular to m. */ gdouble perpendicular_gradient(gdouble m) { if(isinf(m)) return 0.0f; if(m < EPSILON && m > -EPSILON) return INFINITY; return -1.0f/m; } /*! * \brief Returns the distance between two vertices in the x-y plane. */ gdouble vertices_plane_distance(toporouter_spoint_t *a, toporouter_spoint_t *b) { return hypot(a->x - b->x, a->y - b->y); } /*! * \brief Finds the point p distance r away from a on the line segment * of a & b. */ static inline void vertex_outside_segment(toporouter_spoint_t *a, toporouter_spoint_t *b, gdouble r, toporouter_spoint_t *p) { toporouter_spoint_t temp[2]; vertices_on_line(a, vertex_gradient(a,b), r, &temp[0], &temp[1]); if(vertices_plane_distance(&temp[0], b) > vertices_plane_distance(&temp[1], b)) { p->x = temp[0].x; p->y = temp[0].y; }else{ p->x = temp[1].x; p->y = temp[1].y; } } /*! * \brief . * * Proper intersection: * AB and CD must share a point interior to both segments. * * \return TRUE if AB properly intersects CD. */ static bool coord_intersect_prop (double ax, double ay, double bx, double by, double cx, double cy, double dx, double dy) { int wind_abc = coord_wind (ax, ay, bx, by, cx, cy); int wind_abd = coord_wind (ax, ay, bx, by, dx, dy); int wind_cda = coord_wind (cx, cy, dx, dy, ax, ay); int wind_cdb = coord_wind (cx, cy, dx, dy, bx, by); /* If any of the line end-points are colinear with the other line, return false */ if (wind_abc == 0 || wind_abd == 0 || wind_cda == 0 || wind_cdb == 0) return false; return (wind_abc != wind_abd) && (wind_cda != wind_cdb); } /*! * \brief . * * proper intersection: * AB and CD must share a point interior to both segments. * * \return TRUE if AB properly intersects CD. */ static bool point_intersect_prop (GtsPoint *a, GtsPoint *b, GtsPoint *c, GtsPoint *d) { int wind_abc = point_wind (a, b, c); int wind_abd = point_wind (a, b, d); int wind_cda = point_wind (c, d, a); int wind_cdb = point_wind (c, d, b); /* If any of the line end-points are colinear with the other line, return false */ if (wind_abc == 0 || wind_abd == 0 || wind_cda == 0 || wind_cdb == 0) return false; return (wind_abc != wind_abd) && (wind_cda != wind_cdb); } /*! * \brief . */ static inline int vertex_intersect_prop(GtsVertex *a, GtsVertex *b, GtsVertex *c, GtsVertex *d) { return point_intersect_prop(GTS_POINT(a), GTS_POINT(b), GTS_POINT(c), GTS_POINT(d)); } /*! * \brief . * * intersection vertex: * AB and CD must share a point interior to both segments. * * \return vertex at intersection of AB and CD. */ GtsVertex * vertex_intersect(GtsVertex *a, GtsVertex *b, GtsVertex *c, GtsVertex *d) { GtsVertexClass *vertex_class = GTS_VERTEX_CLASS (toporouter_vertex_class ()); GtsVertex *rval; gdouble ua_top, ua_bot, ua, rx, ry; /* TODO: this could be done more efficiently without duplicating computation */ if(!vertex_intersect_prop(a, b, c, d)) return NULL; ua_top = ((d->p.x - c->p.x) * (a->p.y - c->p.y)) - ((d->p.y - c->p.y) * (a->p.x - c->p.x)); ua_bot = ((d->p.y - c->p.y) * (b->p.x - a->p.x)) - ((d->p.x - c->p.x) * (b->p.y - a->p.y)); ua = ua_top / ua_bot; rx = a->p.x + (ua * (b->p.x - a->p.x)); ry = a->p.y + (ua * (b->p.y - a->p.y)); rval = gts_vertex_new (vertex_class, rx, ry, 0.0f); return rval; } /*! * \brief . * * intersection vertex: * AB and CD must share a point interior to both segments. * * \return vertex at intersection of AB and CD. */ void coord_intersect(gdouble ax, gdouble ay, gdouble bx, gdouble by, gdouble cx, gdouble cy, gdouble dx, gdouble dy, gdouble *rx, gdouble *ry) { gdouble ua_top, ua_bot, ua; ua_top = ((dx - cx) * (ay - cy)) - ((dy - cy) * (ax - cx)); ua_bot = ((dy - cy) * (bx - ax)) - ((dx - cx) * (by - ay)); ua = ua_top / ua_bot; *rx = ax + (ua * (bx - ax)); *ry = ay + (ua * (by - ay)); } /*! * \brief . * * \return true if c is between a and b. */ int point_between(GtsPoint *a, GtsPoint *b, GtsPoint *c) { if( point_wind(a, b, c) != 0 ) return 0; if( a->x != b->x ) { return ((a->x <= c->x) && (c->x <= b->x)) || ((a->x >= c->x) && (c->x >= b->x)); } return ((a->y <= c->y) && (c->y <= b->y)) || ((a->y >= c->y) && (c->y >= b->y)); } static inline int vertex_between(GtsVertex *a, GtsVertex *b, GtsVertex *c) { return point_between(GTS_POINT(a), GTS_POINT(b), GTS_POINT(c)); } void delaunay_create_from_vertices(GList *vertices, GtsSurface **surface, GtsTriangle **t) { GList *i = vertices; GtsVertex *v1, *v2, *v3; GSList *vertices_slist = NULL; while (i) { vertices_slist = g_slist_prepend(vertices_slist, i->data); i = i->next; } // TODO: just work this out from the board outline *t = gts_triangle_enclosing (gts_triangle_class (), vertices_slist, 100000.0f); gts_triangle_vertices (*t, &v1, &v2, &v3); *surface = gts_surface_new (gts_surface_class (), gts_face_class (), GTS_EDGE_CLASS(toporouter_edge_class ()), GTS_VERTEX_CLASS(toporouter_vertex_class ()) ); gts_surface_add_face (*surface, gts_face_new (gts_face_class (), (*t)->e1, (*t)->e2, (*t)->e3)); i = vertices; while (i) { toporouter_vertex_t *v = TOPOROUTER_VERTEX(gts_delaunay_add_vertex (*surface, (GtsVertex *)i->data, NULL)); if(v) { printf("ERROR: vertex could not be added to CDT "); print_vertex(v); } i = i->next; } gts_allow_floating_vertices = TRUE; gts_object_destroy (GTS_OBJECT (v1)); gts_object_destroy (GTS_OBJECT (v2)); gts_object_destroy (GTS_OBJECT (v3)); gts_allow_floating_vertices = FALSE; g_slist_free(vertices_slist); // return surface; } GSList * list_to_slist(GList *i) { GSList *rval = NULL; while(i) { rval = g_slist_prepend(rval, i->data); i = i->next; } return rval; } toporouter_bbox_t * toporouter_bbox_create_from_points(int layer, GList *vertices, toporouter_term_t type, gpointer data) { toporouter_bbox_t *bbox; GSList *vertices_slist = list_to_slist(vertices); // delaunay_create_from_vertices(vertices, &s, &t); bbox = TOPOROUTER_BBOX( gts_bbox_points(GTS_BBOX_CLASS(toporouter_bbox_class()), vertices_slist) ); bbox->type = type; bbox->data = data; bbox->surface = NULL; bbox->enclosing = NULL; bbox->layer = layer; bbox->point = NULL; bbox->realpoint = NULL; g_slist_free(vertices_slist); return bbox; } toporouter_bbox_t * toporouter_bbox_create(int layer, GList *vertices, toporouter_term_t type, gpointer data) { toporouter_bbox_t *bbox; GtsSurface *s; GtsTriangle *t; delaunay_create_from_vertices(vertices, &s, &t); bbox = TOPOROUTER_BBOX( gts_bbox_surface(GTS_BBOX_CLASS(toporouter_bbox_class()), s) ); bbox->type = type; bbox->data = data; bbox->surface = s; bbox->enclosing = t; bbox->layer = layer; return bbox; } GtsVertex * insert_vertex(toporouter_t *r, toporouter_layer_t *l, gdouble x, gdouble y, toporouter_bbox_t *box) { GtsVertexClass *vertex_class = GTS_VERTEX_CLASS (toporouter_vertex_class ()); GtsVertex *v; GList *i; i = l->vertices; while (i) { v = (GtsVertex *)i->data; if(v->p.x == x && v->p.y == y) { TOPOROUTER_VERTEX(v)->bbox = box; return v; } i = i->next; } v = gts_vertex_new (vertex_class , x, y, l - r->layers); TOPOROUTER_VERTEX(v)->bbox = box; l->vertices = g_list_prepend(l->vertices, v); return v; } GList * insert_constraint_edge(toporouter_t *r, toporouter_layer_t *l, gdouble x1, gdouble y1, guint flags1, gdouble x2, gdouble y2, guint flags2, toporouter_bbox_t *box) { GtsVertexClass *vertex_class = GTS_VERTEX_CLASS (toporouter_vertex_class ()); GtsEdgeClass *edge_class = GTS_EDGE_CLASS (toporouter_constraint_class ()); GtsVertex *p[2]; GtsVertex *v; GList *i; GtsEdge *e; p[0] = p[1] = NULL; /* insert or find points */ i = l->vertices; while (i) { v = (GtsVertex *)i->data; if(v->p.x == x1 && v->p.y == y1) p[0] = v; if(v->p.x == x2 && v->p.y == y2) p[1] = v; i = i->next; } if(p[0] == NULL) { p[0] = gts_vertex_new (vertex_class, x1, y1, l - r->layers); TOPOROUTER_VERTEX(p[0])->bbox = box; l->vertices = g_list_prepend(l->vertices, p[0]); } if(p[1] == NULL) { p[1] = gts_vertex_new (vertex_class, x2, y2, l - r->layers); TOPOROUTER_VERTEX(p[1])->bbox = box; l->vertices = g_list_prepend(l->vertices, p[1]); } TOPOROUTER_VERTEX(p[0])->flags = flags1; TOPOROUTER_VERTEX(p[1])->flags = flags2; e = gts_edge_new (edge_class, p[0], p[1]); TOPOROUTER_CONSTRAINT(e)->box = box; l->constraints = g_list_prepend (l->constraints, e); // return insert_constraint_edge_rec(r, l, p, box); return g_list_prepend(NULL, e); } void insert_constraints_from_list(toporouter_t *r, toporouter_layer_t *l, GList *vlist, toporouter_bbox_t *box) { GList *i = vlist; toporouter_vertex_t *pv = NULL, *v; while(i) { v = TOPOROUTER_VERTEX(i->data); if(pv) { box->constraints = g_list_concat(box->constraints, insert_constraint_edge(r, l, vx(v), vy(v), v->flags, vx(pv), vy(pv), pv->flags, box)); } pv = v; i = i->next; } v = TOPOROUTER_VERTEX(vlist->data); box->constraints = g_list_concat(box->constraints, insert_constraint_edge(r, l, vx(v), vy(v), v->flags, vx(pv), vy(pv), pv->flags, box)); } void insert_centre_point(toporouter_t *r, toporouter_layer_t *l, gdouble x, gdouble y) { GList *i; GtsVertexClass *vertex_class = GTS_VERTEX_CLASS (toporouter_vertex_class ()); i = l->vertices; while (i) { GtsPoint *p = GTS_POINT(i->data); if(p->x == x && p->y == y) return; i = i->next; } l->vertices = g_list_prepend(l->vertices, gts_vertex_new(vertex_class, x, y, 0.0f)); } GtsPoint * midpoint(GtsPoint *a, GtsPoint *b) { return gts_point_new(gts_point_class(), (a->x + b->x) / 2., (a->y + b->y) / 2., 0.); } static inline gdouble pad_rad(PadType *pad) { return (lookup_thickness(pad->Name) / 2.) + lookup_keepaway(pad->Name); } static inline gdouble pin_rad(PinType *pin) { return (lookup_thickness(pin->Name) / 2.) + lookup_keepaway(pin->Name); } GList * rect_with_attachments(gdouble rad, gdouble x0, gdouble y0, gdouble x1, gdouble y1, gdouble x2, gdouble y2, gdouble x3, gdouble y3, gdouble z) { GtsVertexClass *vertex_class = GTS_VERTEX_CLASS (toporouter_vertex_class ()); GList *r = NULL, *rr = NULL, *i; toporouter_vertex_t *curpoint, *temppoint; curpoint = TOPOROUTER_VERTEX(gts_vertex_new (vertex_class, x0, y0, z)); r = g_list_prepend(NULL, curpoint); r = g_list_prepend(r, gts_vertex_new (vertex_class, x1, y1, z)); r = g_list_prepend(r, gts_vertex_new (vertex_class, x2, y2, z)); r = g_list_prepend(r, gts_vertex_new (vertex_class, x3, y3, z)); i = r; while(i) { temppoint = TOPOROUTER_VERTEX(i->data); rr = g_list_prepend(rr, curpoint); curpoint = temppoint; i = i->next; } g_list_free(r); return rr; } #define VERTEX_CENTRE(x) TOPOROUTER_VERTEX( vertex_bbox(x)->point ) /*! * \brief Read pad data from layer into toporouter_layer_t struct. * * Inserts points and constraints into GLists. */ int read_pads(toporouter_t *r, toporouter_layer_t *l, guint layer) { toporouter_spoint_t p[2], rv[5]; gdouble x[2], y[2], t, m; GList *vlist = NULL; toporouter_bbox_t *bbox = NULL; guint front = GetLayerGroupNumberBySide (TOP_SIDE); guint back = GetLayerGroupNumberBySide (BOTTOM_SIDE); // printf("read_pads: front = %d back = %d layer = %d\n", // front, back, layer); /* If its not the top or bottom layer, there are no pads to read */ if(l - r->layers != front && l - r->layers != back) return 0; ELEMENT_LOOP(PCB->Data); { PAD_LOOP(element); { if( (l - r->layers == back && TEST_FLAG(ONSOLDERFLAG, pad)) || (l - r->layers == front && !TEST_FLAG(ONSOLDERFLAG, pad)) ) { t = (gdouble)pad->Thickness / 2.0f; x[0] = pad->Point1.X; x[1] = pad->Point2.X; y[0] = pad->Point1.Y; y[1] = pad->Point2.Y; if(TEST_FLAG(SQUAREFLAG, pad)) { /* Square or oblong pad. Four points and four constraint edges are * used */ if(x[0] == x[1] && y[0] == y[1]) { /* Pad is square */ // vlist = g_list_prepend(NULL, gts_vertex_new (vertex_class, x[0]-t, y[0]-t, 0.)); // vlist = g_list_prepend(vlist, gts_vertex_new (vertex_class, x[0]-t, y[0]+t, 0.)); // vlist = g_list_prepend(vlist, gts_vertex_new (vertex_class, x[0]+t, y[0]+t, 0.)); // vlist = g_list_prepend(vlist, gts_vertex_new (vertex_class, x[0]+t, y[0]-t, 0.)); vlist = rect_with_attachments(pad_rad(pad), x[0]-t, y[0]-t, x[0]-t, y[0]+t, x[0]+t, y[0]+t, x[0]+t, y[0]-t, l - r->layers); bbox = toporouter_bbox_create(l - r->layers, vlist, PAD, pad); r->bboxes = g_slist_prepend(r->bboxes, bbox); insert_constraints_from_list(r, l, vlist, bbox); g_list_free(vlist); //bbox->point = GTS_POINT( gts_vertex_new(vertex_class, x[0], y[0], 0.) ); bbox->point = GTS_POINT( insert_vertex(r, l, x[0], y[0], bbox) ); g_assert(TOPOROUTER_VERTEX(bbox->point)->bbox == bbox); }else { /* Pad is diagonal oblong or othogonal oblong */ m = cartesian_gradient(x[0], y[0], x[1], y[1]); p[0].x = x[0]; p[0].y = y[0]; p[1].x = x[1]; p[1].y = y[1]; vertex_outside_segment(&p[0], &p[1], t, &rv[0]); vertices_on_line(&rv[0], perpendicular_gradient(m), t, &rv[1], &rv[2]); vertex_outside_segment(&p[1], &p[0], t, &rv[0]); vertices_on_line(&rv[0], perpendicular_gradient(m), t, &rv[3], &rv[4]); if(wind(&rv[1], &rv[2], &rv[3]) != wind(&rv[2], &rv[3], &rv[4])) { rv[0].x = rv[3].x; rv[0].y = rv[3].y; rv[3].x = rv[4].x; rv[3].y = rv[4].y; rv[4].x = rv[0].x; rv[4].y = rv[0].y; } // vlist = g_list_prepend(NULL, gts_vertex_new (vertex_class, rv[1].x, rv[1].y, 0.)); // vlist = g_list_prepend(vlist, gts_vertex_new (vertex_class, rv[2].x, rv[2].y, 0.)); // vlist = g_list_prepend(vlist, gts_vertex_new (vertex_class, rv[3].x, rv[3].y, 0.)); // vlist = g_list_prepend(vlist, gts_vertex_new (vertex_class, rv[4].x, rv[4].y, 0.)); vlist = rect_with_attachments(pad_rad(pad), rv[1].x, rv[1].y, rv[2].x, rv[2].y, rv[3].x, rv[3].y, rv[4].x, rv[4].y, l - r->layers); bbox = toporouter_bbox_create(l - r->layers, vlist, PAD, pad); r->bboxes = g_slist_prepend(r->bboxes, bbox); insert_constraints_from_list(r, l, vlist, bbox); g_list_free(vlist); //bbox->point = GTS_POINT( gts_vertex_new(vertex_class, (x[0] + x[1]) / 2., (y[0] + y[1]) / 2., 0.) ); bbox->point = GTS_POINT( insert_vertex(r, l, (x[0] + x[1]) / 2., (y[0] + y[1]) / 2., bbox) ); g_assert(TOPOROUTER_VERTEX(bbox->point)->bbox == bbox); } }else { /* Either round pad or pad with curved edges */ if(x[0] == x[1] && y[0] == y[1]) { /* One point */ /* bounding box same as square pad */ vlist = rect_with_attachments(pad_rad(pad), x[0]-t, y[0]-t, x[0]-t, y[0]+t, x[0]+t, y[0]+t, x[0]+t, y[0]-t, l - r->layers); bbox = toporouter_bbox_create(l - r->layers, vlist, PAD, pad); r->bboxes = g_slist_prepend(r->bboxes, bbox); g_list_free(vlist); //bbox->point = GTS_POINT( insert_vertex(r, l, x[0], y[0], bbox) ); bbox->point = GTS_POINT( insert_vertex(r, l, x[0], y[0], bbox) ); }else{ /* Two points and one constraint edge */ /* the rest is just for bounding box */ m = cartesian_gradient(x[0], y[0], x[1], y[1]); p[0].x = x[0]; p[0].y = y[0]; p[1].x = x[1]; p[1].y = y[1]; vertex_outside_segment(&p[0], &p[1], t, &rv[0]); vertices_on_line(&rv[0], perpendicular_gradient(m), t, &rv[1], &rv[2]); vertex_outside_segment(&p[1], &p[0], t, &rv[0]); vertices_on_line(&rv[0], perpendicular_gradient(m), t, &rv[3], &rv[4]); if(wind(&rv[1], &rv[2], &rv[3]) != wind(&rv[2], &rv[3], &rv[4])) { rv[0].x = rv[3].x; rv[0].y = rv[3].y; rv[3].x = rv[4].x; rv[3].y = rv[4].y; rv[4].x = rv[0].x; rv[4].y = rv[0].y; } vlist = rect_with_attachments(pad_rad(pad), rv[1].x, rv[1].y, rv[2].x, rv[2].y, rv[3].x, rv[3].y, rv[4].x, rv[4].y, l - r->layers); bbox = toporouter_bbox_create(l - r->layers, vlist, PAD, pad); r->bboxes = g_slist_prepend(r->bboxes, bbox); insert_constraints_from_list(r, l, vlist, bbox); g_list_free(vlist); //bbox->point = GTS_POINT( gts_vertex_new(vertex_class, (x[0] + x[1]) / 2., (y[0] + y[1]) / 2., 0.) ); bbox->point = GTS_POINT( insert_vertex(r, l, (x[0] + x[1]) / 2., (y[0] + y[1]) / 2., bbox) ); //bbox->constraints = g_list_concat(bbox->constraints, insert_constraint_edge(r, l, x[0], y[0], x[1], y[1], bbox)); } } } } END_LOOP; } END_LOOP; return 0; } /*! * \brief Read points data (all layers) into GList. * * Inserts pin and via points. */ int read_points(toporouter_t *r, toporouter_layer_t *l, int layer) { gdouble x, y, t; GList *vlist = NULL; toporouter_bbox_t *bbox = NULL; ELEMENT_LOOP(PCB->Data); { PIN_LOOP(element); { t = (gdouble)pin->Thickness / 2.0f; x = pin->X; y = pin->Y; if(TEST_FLAG (SQUAREFLAG, pin)) { vlist = rect_with_attachments(pin_rad(pin), x-t, y-t, x-t, y+t, x+t, y+t, x+t, y-t, l - r->layers); bbox = toporouter_bbox_create(l - r->layers, vlist, PIN, pin); r->bboxes = g_slist_prepend(r->bboxes, bbox); insert_constraints_from_list(r, l, vlist, bbox); g_list_free(vlist); bbox->point = GTS_POINT( insert_vertex(r, l, x, y, bbox) ); }else if(TEST_FLAG(OCTAGONFLAG, pin)){ /* TODO: Handle octagon pins */ fprintf(stderr, "No support for octagon pins yet\n"); }else{ vlist = rect_with_attachments(pin_rad(pin), x-t, y-t, x-t, y+t, x+t, y+t, x+t, y-t, l - r->layers); bbox = toporouter_bbox_create(l - r->layers, vlist, PIN, pin); r->bboxes = g_slist_prepend(r->bboxes, bbox); g_list_free(vlist); bbox->point = GTS_POINT( insert_vertex(r, l, x, y, bbox) ); } } END_LOOP; } END_LOOP; VIA_LOOP(PCB->Data); { t = (gdouble)via->Thickness / 2.0f; x = via->X; y = via->Y; if(TEST_FLAG (SQUAREFLAG, via)) { vlist = rect_with_attachments(pin_rad((PinType*)via), x-t, y-t, x-t, y+t, x+t, y+t, x+t, y-t, l - r->layers); bbox = toporouter_bbox_create(l - r->layers, vlist, VIA, via); r->bboxes = g_slist_prepend(r->bboxes, bbox); insert_constraints_from_list(r, l, vlist, bbox); g_list_free(vlist); bbox->point = GTS_POINT( insert_vertex(r, l, x, y, bbox) ); }else if(TEST_FLAG(OCTAGONFLAG, via)){ /* TODO: Handle octagon vias */ fprintf(stderr, "No support for octagon vias yet\n"); }else{ vlist = rect_with_attachments(pin_rad((PinType*)via), x-t, y-t, x-t, y+t, x+t, y+t, x+t, y-t, l - r->layers); bbox = toporouter_bbox_create(l - r->layers, vlist, VIA, via); r->bboxes = g_slist_prepend(r->bboxes, bbox); g_list_free(vlist); bbox->point = GTS_POINT( insert_vertex(r, l, x, y, bbox) ); } } END_LOOP; return 0; } /*! * \brief Read line data from layer into toporouter_layer_t struct. * * Inserts points and constraints into GLists. */ int read_lines(toporouter_t *r, toporouter_layer_t *l, LayerType *layer, int ln) { gdouble xs[2], ys[2]; GList *vlist = NULL; toporouter_bbox_t *bbox = NULL; GtsVertexClass *vertex_class = GTS_VERTEX_CLASS (toporouter_vertex_class ()); LINE_LOOP(layer); { xs[0] = line->Point1.X; xs[1] = line->Point2.X; ys[0] = line->Point1.Y; ys[1] = line->Point2.Y; if(!(xs[0] == xs[1] && ys[0] == ys[1])) { vlist = g_list_prepend(NULL, gts_vertex_new (vertex_class, xs[0], ys[0], l - r->layers)); vlist = g_list_prepend(vlist, gts_vertex_new (vertex_class, xs[1], ys[1], l - r->layers)); // TODO: replace this with surface version bbox = toporouter_bbox_create_from_points(GetLayerGroupNumberByNumber(ln), vlist, LINE, line); r->bboxes = g_slist_prepend(r->bboxes, bbox); //new;; //insert_constraints_from_list(r, l, vlist, bbox); g_list_free(vlist); // bbox->point = GTS_POINT( insert_vertex(r, l, (xs[0]+xs[1])/2., (ys[0]+ys[1])/2., bbox) ); bbox->constraints = g_list_concat(bbox->constraints, insert_constraint_edge(r, l, xs[0], ys[0], 0, xs[1], ys[1], 0, bbox)); } } END_LOOP; return 0; } static void create_board_edge (double x0, double y0, double x1, double y1, int layer, GList **vlist) { GtsVertexClass *vertex_class = GTS_VERTEX_CLASS (toporouter_vertex_class ()); double edge_length = hypot (x0 - x1, y0 - y1); unsigned int vertices_per_edge = MIN (1, edge_length / BOARD_EDGE_RESOLUTION); unsigned int count; double inc = edge_length / vertices_per_edge; double x = x0, y = y0; *vlist = g_list_prepend (*vlist, gts_vertex_new (vertex_class, x, y, layer)); for (count = 1; count < vertices_per_edge; count ++) { coord_move_towards_coord_values (x, y, x1, y1, inc, &x, &y); *vlist = g_list_prepend (*vlist, gts_vertex_new (vertex_class, x, y, layer)); } } static void read_board_constraints (toporouter_t *r, toporouter_layer_t *l, int layer) { GList *vlist = NULL; toporouter_bbox_t *bbox; /* Create points for the board edges and constrain those edges */ create_board_edge (0., 0., PCB->MaxWidth, 0., layer, &vlist); create_board_edge (PCB->MaxWidth, 0., PCB->MaxWidth, PCB->MaxHeight, layer, &vlist); create_board_edge (PCB->MaxWidth, PCB->MaxHeight, 0., PCB->MaxHeight, layer, &vlist); create_board_edge (0., PCB->MaxHeight, 0., 0., layer, &vlist); bbox = toporouter_bbox_create (layer, vlist, BOARD, NULL); r->bboxes = g_slist_prepend (r->bboxes, bbox); insert_constraints_from_list (r, l, vlist, bbox); g_list_free (vlist); } gdouble triangle_cost(GtsTriangle *t, gpointer *data){ gdouble *min_quality = (gdouble *)data[0]; gdouble *max_area = (gdouble *)data[1]; gdouble quality = gts_triangle_quality(t); gdouble area = gts_triangle_area(t); if (quality < *min_quality || area > *max_area) return quality; return 0.0; } void print_constraint(toporouter_constraint_t *e) { printf("CONSTRAINT:\n"); print_vertex(tedge_v1(e)); print_vertex(tedge_v2(e)); } void print_edge(toporouter_edge_t *e) { GList *i = edge_routing(e); printf("EDGE:\n"); print_vertex(tedge_v1(e)); while(i) { toporouter_vertex_t *v = TOPOROUTER_VERTEX(i->data); print_vertex(v); i = i->next; } print_vertex(tedge_v2(e)); } static void pick_first_face (GtsFace * f, GtsFace ** first) { if (*first == NULL) *first = f; } void unconstrain(toporouter_layer_t *l, toporouter_constraint_t *c) { toporouter_edge_t *e; gts_allow_floating_vertices = TRUE; e = TOPOROUTER_EDGE(gts_edge_new (GTS_EDGE_CLASS (toporouter_edge_class ()), GTS_SEGMENT(c)->v1, GTS_SEGMENT(c)->v2)); gts_edge_replace(GTS_EDGE(c), GTS_EDGE(e)); l->constraints = g_list_remove(l->constraints, c); c->box->constraints = g_list_remove(c->box->constraints, c); c->box = NULL; gts_object_destroy (GTS_OBJECT (c)); gts_allow_floating_vertices = FALSE; } void build_cdt(toporouter_t *r, toporouter_layer_t *l) { /* TODO: generalize into surface *cdt_create(vertices, constraints) */ GList *i; //GtsEdge *temp; //GtsVertex *v; GtsTriangle *t; GtsVertex *v1, *v2, *v3; GSList *vertices_slist; vertices_slist = list_to_slist(l->vertices); if(l->surface) { GtsFace * first = NULL; gts_surface_foreach_face (l->surface, (GtsFunc) pick_first_face, &first); gts_surface_traverse_destroy(gts_surface_traverse_new (l->surface, first)); } t = gts_triangle_enclosing (gts_triangle_class (), vertices_slist, 1000.0f); gts_triangle_vertices (t, &v1, &v2, &v3); g_slist_free(vertices_slist); l->surface = gts_surface_new (gts_surface_class (), gts_face_class (), GTS_EDGE_CLASS(toporouter_edge_class ()), GTS_VERTEX_CLASS(toporouter_vertex_class ()) ); gts_surface_add_face (l->surface, gts_face_new (gts_face_class (), t->e1, t->e2, t->e3)); // fprintf(stderr, "ADDED VERTICES\n"); /* GtsFace *debugface; if((debugface = gts_delaunay_check(l->surface))) { fprintf(stderr, "WARNING: Delaunay check failed\n"); fprintf(stderr, "\tViolating triangle:\n"); fprintf(stderr, "\t%f,%f %f,%f\n", debugface->triangle.e1->segment.v1->p.x, debugface->triangle.e1->segment.v1->p.y, debugface->triangle.e1->segment.v2->p.x, debugface->triangle.e1->segment.v2->p.y ); fprintf(stderr, "\t%f,%f %f,%f\n", debugface->triangle.e2->segment.v1->p.x, debugface->triangle.e2->segment.v1->p.y, debugface->triangle.e2->segment.v2->p.x, debugface->triangle.e2->segment.v2->p.y ); fprintf(stderr, "\t%f,%f %f,%f\n", debugface->triangle.e3->segment.v1->p.x, debugface->triangle.e3->segment.v1->p.y, debugface->triangle.e3->segment.v2->p.x, debugface->triangle.e3->segment.v2->p.y ); // toporouter_draw_surface(r, l->surface, "debug.png", 4096, 4096); { int i; for(i=0;ilayers[i].surface, buffer, 2048, 2048, 2, NULL, i, NULL); } } } */ check_cons_continuation: i = l->constraints; while (i) { toporouter_constraint_t *c1 = TOPOROUTER_CONSTRAINT(i->data); GList *j = i->next; // printf("adding cons: "); print_constraint(c1); while(j) { toporouter_constraint_t *c2 = TOPOROUTER_CONSTRAINT(j->data); guint rem = 0; GList *temp; // printf("\tconflict: "); print_constraint(c2); toporouter_bbox_t *c1box = c1->box, *c2box = c2->box; toporouter_vertex_t *c1v1 = tedge_v1(c1); toporouter_vertex_t *c1v2 = tedge_v2(c1); toporouter_vertex_t *c2v1 = tedge_v1(c2); toporouter_vertex_t *c2v2 = tedge_v2(c2); if(gts_segments_are_intersecting(GTS_SEGMENT(c1), GTS_SEGMENT(c2)) == GTS_IN) { toporouter_vertex_t *v; unconstrain(l, c1); unconstrain(l, c2); rem = 1; // proper intersection v = TOPOROUTER_VERTEX(vertex_intersect( GTS_VERTEX(c1v1), GTS_VERTEX(c1v2), GTS_VERTEX(c2v1), GTS_VERTEX(c2v2))); // remove both constraints // replace with 4x constraints // insert new intersection vertex GTS_POINT(v)->z = vz(c1v1); l->vertices = g_list_prepend(l->vertices, v); // gts_delaunay_add_vertex (l->surface, GTS_VERTEX(v), NULL); v->bbox = c1box; temp = insert_constraint_edge(r, l, vx(c1v1), vy(c1v1), 0, vx(v), vy(v), 0, c1box); c1box->constraints = g_list_concat(c1box->constraints, temp); temp = insert_constraint_edge(r, l, vx(c1v2), vy(c1v2), 0, vx(v), vy(v), 0, c1box); c1box->constraints = g_list_concat(c1box->constraints, temp); temp = insert_constraint_edge(r, l, vx(c2v1), vy(c2v1), 0, vx(v), vy(v), 0, c2box); c2box->constraints = g_list_concat(c2box->constraints, temp); temp = insert_constraint_edge(r, l, vx(c2v2), vy(c2v2), 0, vx(v), vy(v), 0, c2box); c2box->constraints = g_list_concat(c2box->constraints, temp); }else if(gts_segments_are_intersecting(GTS_SEGMENT(c1), GTS_SEGMENT(c2)) == GTS_ON || gts_segments_are_intersecting(GTS_SEGMENT(c2), GTS_SEGMENT(c1)) == GTS_ON) { if(vertex_between(edge_v1(c2), edge_v2(c2), edge_v1(c1)) && vertex_between(edge_v1(c2), edge_v2(c2), edge_v2(c1))) { unconstrain(l, c1); unconstrain(l, c2); rem = 1; // remove c1 temp = insert_constraint_edge(r, l, vx(c2v1), vy(c2v1), 0, vx(c2v2), vy(c2v2), 0, c2box); c2box->constraints = g_list_concat(c2box->constraints, temp); }else if(vertex_between(edge_v1(c1), edge_v2(c1), edge_v1(c2)) && vertex_between(edge_v1(c1), edge_v2(c1), edge_v2(c2))) { unconstrain(l, c1); unconstrain(l, c2); rem = 1; // remove c2 temp = insert_constraint_edge(r, l, vx(c1v1), vy(c1v1), 0, vx(c1v2), vy(c1v2), 0, c1box); c1box->constraints = g_list_concat(c1box->constraints, temp); //}else if(!vertex_wind(edge_v1(c1), edge_v2(c1), edge_v1(c2)) && !vertex_wind(edge_v1(c1), edge_v2(c1), edge_v2(c2))) { /* }else if(vertex_between(edge_v1(c1), edge_v2(c1), edge_v1(c2)) || vertex_between(edge_v1(c1), edge_v2(c1), edge_v2(c2))) { unconstrain(l, c1); unconstrain(l, c2); rem = 1; printf("all colinear\n"); // exit(1); temp = insert_constraint_edge(r, l, vx(c1v1), vy(c1v1), 0, vx(c1v2), vy(c1v2), 0, c1box); c1box->constraints = g_list_concat(c1box->constraints, temp); if(vertex_between(GTS_VERTEX(c1v1), GTS_VERTEX(c1v2), GTS_VERTEX(c2v2))) { // v2 of c2 is inner if(vertex_between(GTS_VERTEX(c2v1), GTS_VERTEX(c2v2), GTS_VERTEX(c1v2))) { // v2 of c1 is inner // c2 = c1.v2 -> c2.v1 temp = insert_constraint_edge(r, l, vx(c1v2), vy(c1v2), 0, vx(c2v1), vy(c2v1), 0, c2box); c2box->constraints = g_list_concat(c2box->constraints, temp); }else{ // v1 of c1 is inner // c2 = c1.v1 -> c2.v1 temp = insert_constraint_edge(r, l, vx(c1v1), vy(c1v1), 0, vx(c2v1), vy(c2v1), 0, c2box); c2box->constraints = g_list_concat(c2box->constraints, temp); } }else{ // v1 of c2 is inner if(vertex_between(GTS_VERTEX(c2v1), GTS_VERTEX(c2v2), GTS_VERTEX(c1v2))) { // v2 of c1 is inner // c2 = c1.v2 -> c2.v2 temp = insert_constraint_edge(r, l, vx(c1v2), vy(c1v2), 0, vx(c2v2), vy(c2v2), 0, c2box); c2box->constraints = g_list_concat(c2box->constraints, temp); }else{ // v1 of c1 is inner // c2 = c1.v1 -> c2.v2 temp = insert_constraint_edge(r, l, vx(c1v1), vy(c1v1), 0, vx(c2v2), vy(c2v2), 0, c2box); c2box->constraints = g_list_concat(c2box->constraints, temp); } }*/ }else if(vertex_between(edge_v1(c2), edge_v2(c2), edge_v1(c1)) && c1v1 != c2v1 && c1v1 != c2v2) { unconstrain(l, c1); unconstrain(l, c2); rem = 1; //v1 of c1 is on c2 printf("v1 of c1 on c2\n"); // replace with 2x constraints temp = insert_constraint_edge(r, l, vx(c2v1), vy(c2v1), 0, vx(c1v1), vy(c1v1), 0, c2box); c2box->constraints = g_list_concat(c2box->constraints, temp); temp = insert_constraint_edge(r, l, vx(c2v2), vy(c2v2), 0, vx(c1v1), vy(c1v1), 0, c2box); c2box->constraints = g_list_concat(c2box->constraints, temp); temp = insert_constraint_edge(r, l, vx(c1v1), vy(c1v1), 0, vx(c1v2), vy(c1v2), 0, c1box); c1box->constraints = g_list_concat(c1box->constraints, temp); // restore c1 //temp = insert_constraint_edge(r, l, vx(tedge_v2(c1)), vy(tedge_v2(c1)), 0, vx(tedge_v1(c1)), vy(tedge_v1(c1)), 0, c1->box); //c2->box->constraints = g_list_concat(c2->box->constraints, temp); }else if(vertex_between(edge_v1(c2), edge_v2(c2), edge_v2(c1)) && c1v2 != c2v1 && c1v2 != c2v2) { unconstrain(l, c1); unconstrain(l, c2); rem = 1; //v2 of c1 is on c2 printf("v2 of c1 on c2\n"); // replace with 2x constraints temp = insert_constraint_edge(r, l, vx(c2v1), vy(c2v1), 0, vx(c1v2), vy(c1v2), 0, c2box); c2box->constraints = g_list_concat(c2box->constraints, temp); temp = insert_constraint_edge(r, l, vx(c2v2), vy(c2v2), 0, vx(c1v2), vy(c1v2), 0, c2box); c2box->constraints = g_list_concat(c2box->constraints, temp); temp = insert_constraint_edge(r, l, vx(c1v1), vy(c1v1), 0, vx(c1v2), vy(c1v2), 0, c1box); c1box->constraints = g_list_concat(c1box->constraints, temp); }else if(vertex_between(edge_v1(c1), edge_v2(c1), edge_v1(c2)) && c2v1 != c1v1 && c2v1 != c1v2) { unconstrain(l, c1); unconstrain(l, c2); rem = 1; //v1 of c2 is on c1 printf("v1 of c2 on c1\n"); // replace with 2x constraints temp = insert_constraint_edge(r, l, vx(c1v1), vy(c1v1), 0, vx(c2v1), vy(c2v1), 0, c1box); c1box->constraints = g_list_concat(c1box->constraints, temp); temp = insert_constraint_edge(r, l, vx(c1v2), vy(c1v2), 0, vx(c2v1), vy(c2v1), 0, c1box); c1box->constraints = g_list_concat(c1box->constraints, temp); temp = insert_constraint_edge(r, l, vx(c2v1), vy(c2v1), 0, vx(c2v2), vy(c2v2), 0, c2box); c2box->constraints = g_list_concat(c2box->constraints, temp); }else if(vertex_between(edge_v1(c1), edge_v2(c1), edge_v2(c2)) && c2v2 != c1v1 && c2v2 != c1v2) { unconstrain(l, c1); unconstrain(l, c2); rem = 1; //v2 of c2 is on c1 printf("v2 of c2 on c1\n"); // replace with 2x constraints temp = insert_constraint_edge(r, l, vx(c1v1), vy(c1v1), 0, vx(c2v2), vy(c2v2), 0, c1box); c1box->constraints = g_list_concat(c1box->constraints, temp); temp = insert_constraint_edge(r, l, vx(c1v2), vy(c1v2), 0, vx(c2v2), vy(c2v2), 0, c1box); c1box->constraints = g_list_concat(c1box->constraints, temp); temp = insert_constraint_edge(r, l, vx(c2v1), vy(c2v1), 0, vx(c2v2), vy(c2v2), 0, c2box); c2box->constraints = g_list_concat(c2box->constraints, temp); } } if(rem) goto check_cons_continuation; j = j->next; } i = i->next; } i = l->vertices; while (i) { //v = i->data; //if(r->flags & TOPOROUTER_FLAG_DEBUG_CDTS) // fprintf(stderr, "\tadding vertex %f,%f\n", v->p.x, v->p.y); toporouter_vertex_t *v = TOPOROUTER_VERTEX(gts_delaunay_add_vertex (l->surface, (GtsVertex *)i->data, NULL)); if(v) { printf("conflict: "); print_vertex(v); } i = i->next; } i = l->constraints; while (i) { // toporouter_constraint_t *c1 = TOPOROUTER_CONSTRAINT(i->data); // printf("adding cons: "); print_constraint(c1); GSList *conflicts = gts_delaunay_add_constraint (l->surface, (GtsConstraint *)i->data); GSList *j = conflicts; while(j) { if(TOPOROUTER_IS_CONSTRAINT(j->data)) { toporouter_constraint_t *c2 = TOPOROUTER_CONSTRAINT(j->data); printf("\tconflict: "); print_constraint(c2); } j = j->next; } g_slist_free(conflicts); i = i->next; } // if(rerun) // goto build_cdt_continuation; // fprintf(stderr, "ADDED CONSTRAINTS\n"); gts_allow_floating_vertices = TRUE; gts_object_destroy (GTS_OBJECT (v1)); gts_object_destroy (GTS_OBJECT (v2)); gts_object_destroy (GTS_OBJECT (v3)); gts_allow_floating_vertices = FALSE; /* { gpointer data[2]; gdouble quality = 0.50, area = G_MAXDOUBLE; guint num = gts_delaunay_conform(l->surface, -1, (GtsEncroachFunc) gts_vertex_encroaches_edge, NULL); if (num == 0){ data[0] = &quality; data[1] = &area; num = gts_delaunay_refine(l->surface, -1, (GtsEncroachFunc) gts_vertex_encroaches_edge, NULL, (GtsKeyFunc) triangle_cost, data); } } */ #ifdef DEBUG_IMPORT gts_surface_print_stats(l->surface, stderr); #endif #if 0 { char buffer[64]; FILE *fout2; sprintf(buffer, "surface%d.gts", l - r->layers); fout2 = fopen(buffer, "w"); gts_surface_write(l->surface, fout2); } #endif } gint visited_cmp(gconstpointer a, gconstpointer b) { if(ab) return 1; return 0; } static double coord_angle (double ax, double ay, double bx, double by) { return atan2 (by - ay, bx - ax); } GList * cluster_vertices(toporouter_t *r, toporouter_cluster_t *c) { GList *rval = NULL; if(!c) return NULL; FOREACH_CLUSTER(c->netlist->clusters) { if((r->flags & TOPOROUTER_FLAG_AFTERRUBIX && cluster->c == c->c) || (!(r->flags & TOPOROUTER_FLAG_AFTERRUBIX) && cluster == c)) { FOREACH_BBOX(cluster->boxes) { if(box->type == LINE) { g_assert(box->constraints->data); rval = g_list_prepend(rval, tedge_v1(box->constraints->data)); rval = g_list_prepend(rval, tedge_v2(box->constraints->data)); }else if(box->point) { rval = g_list_prepend(rval, TOPOROUTER_VERTEX(box->point)); //g_assert(vertex_bbox(TOPOROUTER_VERTEX(box->point)) == box); }else { printf("WARNING: cluster_vertices: unhandled bbox type\n"); } } FOREACH_END; } } FOREACH_END; return rval; } void print_cluster(toporouter_cluster_t *c) { if(!c) { printf("[CLUSTER (NULL)]\n"); return; } printf("CLUSTER %d: NETLIST = %s STYLE = %s\n", c->c, c->netlist->netlist, c->netlist->style); FOREACH_BBOX(c->boxes) { print_bbox(box); } FOREACH_END; } toporouter_cluster_t * cluster_create(toporouter_t *r, toporouter_netlist_t *netlist) { toporouter_cluster_t *c = (toporouter_cluster_t *)malloc(sizeof(toporouter_cluster_t)); c->c = c->pc = netlist->clusters->len; g_ptr_array_add(netlist->clusters, c); c->netlist = netlist; c->boxes = g_ptr_array_new(); return c; } toporouter_bbox_t * toporouter_bbox_locate(toporouter_t *r, toporouter_term_t type, void *data, gdouble x, gdouble y, guint layergroup) { GtsPoint *p = gts_point_new(gts_point_class(), x, y, layergroup); GSList *boxes = gts_bb_tree_stabbed(r->bboxtree, p), *i = boxes; gts_object_destroy(GTS_OBJECT(p)); while(i) { toporouter_bbox_t *box = TOPOROUTER_BBOX(i->data); if(box->type == type && box->data == data) { g_slist_free(boxes); return box; } i = i->next; } g_slist_free(boxes); return NULL; } void cluster_join_bbox(toporouter_cluster_t *cluster, toporouter_bbox_t *box) { if(box) { g_ptr_array_add(cluster->boxes, box); box->cluster = cluster; } } toporouter_netlist_t * netlist_create(toporouter_t *r, char *netlist, char *style) { toporouter_netlist_t *nl = (toporouter_netlist_t *)malloc(sizeof(toporouter_netlist_t)); nl->netlist = netlist; nl->style = style; nl->clusters = g_ptr_array_new(); nl->routes = g_ptr_array_new(); nl->routed = NULL; nl->pair = NULL; g_ptr_array_add(r->netlists, nl); return nl; } void import_clusters(toporouter_t *r) { NetListListType nets; nets = CollectSubnets(false); NETLIST_LOOP(&nets); { if(netlist->NetN > 0) { toporouter_netlist_t *nl = netlist_create(r, netlist->Net->Connection->menu->Name, netlist->Net->Connection->menu->Style); NET_LOOP(netlist); { toporouter_cluster_t *cluster = cluster_create(r, nl); #ifdef DEBUG_MERGING printf("NET:\n"); #endif CONNECTION_LOOP (net); { if(connection->type == LINE_TYPE) { LineType *line = (LineType *) connection->ptr2; toporouter_bbox_t *box = toporouter_bbox_locate(r, LINE, line, connection->X, connection->Y, connection->group); cluster_join_bbox(cluster, box); #ifdef DEBUG_MERGING pcb_printf("\tLINE %#mD\n", connection->X, connection->Y); #endif }else if(connection->type == PAD_TYPE) { PadType *pad = (PadType *) connection->ptr2; toporouter_bbox_t *box = toporouter_bbox_locate(r, PAD, pad, connection->X, connection->Y, connection->group); cluster_join_bbox(cluster, box); #ifdef DEBUG_MERGING pcb_printf("\tPAD %#mD\n", connection->X, connection->Y); #endif }else if(connection->type == PIN_TYPE) { for(guint m=0;mptr2; toporouter_bbox_t *box = toporouter_bbox_locate(r, PIN, pin, connection->X, connection->Y, m); cluster_join_bbox(cluster, box); } #ifdef DEBUG_MERGING pcb_printf("\tPIN %#mD\n", connection->X, connection->Y); #endif }else if(connection->type == VIA_TYPE) { for(guint m=0;mptr2; toporouter_bbox_t *box = toporouter_bbox_locate(r, VIA, pin, connection->X, connection->Y, m); cluster_join_bbox(cluster, box); } #ifdef DEBUG_MERGING pcb_printf("\tVIA %#mD\n", connection->X, connection->Y); #endif }else if(connection->type == POLYGON_TYPE) { PolygonType *polygon = (PolygonType *) connection->ptr2; toporouter_bbox_t *box = toporouter_bbox_locate(r, POLYGON, polygon, connection->X, connection->Y, connection->group); cluster_join_bbox(cluster, box); #ifdef DEBUG_MERGING pcb_printf("\tPOLYGON %#mD\n", connection->X, connection->Y); #endif } } END_LOOP; #ifdef DEBUG_MERGING printf("\n"); #endif } END_LOOP; } } END_LOOP; FreeNetListListMemory(&nets); } void import_geometry(toporouter_t *r) { toporouter_layer_t *cur_layer; int group; #ifdef DEBUG_IMPORT for (group = 0; group < max_group; group++) { printf("Group %d: Number %d:\n", group, PCB->LayerGroups.Number[group]); for (int entry = 0; entry < PCB->LayerGroups.Number[group]; entry++) { printf("\tEntry %d\n", PCB->LayerGroups.Entries[group][entry]); } } #endif /* Allocate space for per layer struct */ cur_layer = r->layers = (toporouter_layer_t *)malloc(groupcount() * sizeof(toporouter_layer_t)); /* Foreach layer, read in pad vertices and constraints, and build CDT */ for (group = 0; group < max_group; group++) { #ifdef DEBUG_IMPORT printf("*** LAYER GROUP %d ***\n", group); #endif if(PCB->LayerGroups.Number[group] > 0){ cur_layer->vertices = NULL; cur_layer->constraints = NULL; #ifdef DEBUG_IMPORT printf("reading board constraints from layer %d into group %d\n", PCB->LayerGroups.Entries[group][0], group); #endif read_board_constraints(r, cur_layer, PCB->LayerGroups.Entries[group][0]); #ifdef DEBUG_IMPORT printf("reading points from layer %d into group %d \n",PCB->LayerGroups.Entries[group][0], group); #endif read_points(r, cur_layer, PCB->LayerGroups.Entries[group][0]); //#ifdef DEBUG_IMPORT // printf("reading pads from layer %d into group %d\n", number, group); //#endif read_pads(r, cur_layer, group); GROUP_LOOP(PCB->Data, group) { #ifdef DEBUG_IMPORT printf("reading lines from layer %d into group %d\n", number, group); #endif read_lines(r, cur_layer, layer, number); } END_LOOP; #ifdef DEBUG_IMPORT printf("building CDT\n"); #endif build_cdt(r, cur_layer); printf("finished\n"); /* { int i; for(i=0;ilayers[i].surface, buffer, 2048, 2048, 2, NULL, i, NULL); } }*/ #ifdef DEBUG_IMPORT printf("finished building CDT\n"); #endif cur_layer++; } } r->bboxtree = gts_bb_tree_new(r->bboxes); import_clusters(r); #ifdef DEBUG_IMPORT printf("finished import!\n"); #endif } gint compare_points(gconstpointer a, gconstpointer b) { GtsPoint *i = GTS_POINT(a); GtsPoint *j = GTS_POINT(b); if(i->x == j->x) { if(i->y == j->y) return 0; if(i->y < j->y) return -1; return 1; } if(i->x < j->x) return -1; return 1; } gint compare_segments(gconstpointer a, gconstpointer b) { if(a == b) return 0; if(a < b) return -1; return 1; } #define DEBUG_CLUSTER_FIND 1 toporouter_cluster_t * cluster_find(toporouter_t *r, gdouble x, gdouble y, gdouble z) { GtsPoint *p = gts_point_new(gts_point_class(), x, y, z); GSList *hits = gts_bb_tree_stabbed(r->bboxtree, p); toporouter_cluster_t *rval = NULL; #ifdef DEBUG_CLUSTER_FIND printf("FINDING %f,%f,%f\n\n", x, y, z); #endif while(hits) { toporouter_bbox_t *box = TOPOROUTER_BBOX(hits->data); #ifdef DEBUG_CLUSTER_FIND printf("HIT BOX: "); print_bbox(box); #endif if(box->layer == (int)z) { if(box->type != BOARD) { if(box->type == LINE) { LineType *line = (LineType *)box->data; gint linewind = coord_wind(line->Point1.X, line->Point1.Y, x, y, line->Point2.X, line->Point2.Y); if(line->Point1.X > x - EPSILON && line->Point1.X < x + EPSILON && line->Point1.Y > y - EPSILON && line->Point1.Y < y + EPSILON) { rval = box->cluster; // break; } if(line->Point2.X > x - EPSILON && line->Point2.X < x + EPSILON && line->Point2.Y > y - EPSILON && line->Point2.Y < y + EPSILON) { rval = box->cluster; // break; } if(!linewind) { rval = box->cluster; // break; } }else if(box->surface) { if(gts_point_locate(p, box->surface, NULL)) { rval = box->cluster; break; } } } } hits = hits->next; } gts_object_destroy(GTS_OBJECT(p)); #ifdef DEBUG_CLUSTER_FIND printf("cluster_find: %f,%f,%f: ", x, y, z); print_cluster(rval); #endif return rval; } gdouble simple_h_cost(toporouter_t *r, toporouter_vertex_t *curpoint, toporouter_vertex_t *destpoint) { gdouble layerpenalty = (vz(curpoint) == vz(destpoint)) ? 0. : r->viacost; return gts_point_distance(GTS_POINT(curpoint), GTS_POINT(destpoint)) + layerpenalty; } #define FCOST(x) (x->gcost + x->hcost) gdouble route_heap_cmp(gpointer item, gpointer data) { return FCOST(TOPOROUTER_VERTEX(item)); } #define closelist_insert(p) closelist = g_list_prepend(closelist, p) typedef struct { toporouter_vertex_t *key; toporouter_vertex_t *result; }toporouter_heap_search_data_t; void toporouter_heap_search(gpointer data, gpointer user_data) { toporouter_vertex_t *v = TOPOROUTER_VERTEX(data); toporouter_heap_search_data_t *heap_search_data = (toporouter_heap_search_data_t *)user_data; if(v == heap_search_data->key) heap_search_data->result = v; } /* void toporouter_heap_color(gpointer data, gpointer user_data) { toporouter_vertex_t *v = TOPOROUTER_VERTEX(data); v->flags |= (guint) user_data; } */ static inline gdouble angle_span(gdouble a1, gdouble a2) { if(a1 > a2) return ((2*M_PI)-a1 + a2); return a2-a1; } gdouble edge_capacity(toporouter_edge_t *e) { return gts_point_distance(GTS_POINT(edge_v1(e)), GTS_POINT(edge_v2(e))); } gdouble edge_flow(toporouter_edge_t *e, toporouter_vertex_t *v1, toporouter_vertex_t *v2, toporouter_vertex_t *dest) { GList *i = edge_routing(e); toporouter_vertex_t *pv = tedge_v1(e), *v = NULL; gdouble flow = 0.; guint waiting = 1; if((pv == v1 || pv == v2) && waiting) { flow += min_vertex_net_spacing(pv, dest); pv = dest; waiting = 0; } g_assert(v1 != v2); while(i) { v = TOPOROUTER_VERTEX(i->data); if(pv == dest) flow += min_vertex_net_spacing(v, pv); else flow += min_spacing(v, pv); if((v == v1 || v == v2) && waiting) { flow += min_vertex_net_spacing(v, dest); pv = dest; waiting = 0; }else{ pv = v; } i = i->next; } if(pv == dest) flow += min_vertex_net_spacing(tedge_v2(e), pv); else flow += min_spacing(tedge_v2(e), pv); return flow; } void print_path(GList *path) { GList *i = path; printf("PATH:\n"); while(i) { toporouter_vertex_t *v = TOPOROUTER_VERTEX(i->data); // printf("[V %f,%f,%f]\n", vx(v), vy(v), vz(v)); print_vertex(v); if(v->child && !g_list_find(path, v->child)) printf("\t CHILD NOT IN LIST\n"); if(v->parent && !g_list_find(path, v->parent)) printf("\t parent NOT IN LIST\n"); i = i->next; } } GList * split_path(GList *path) { toporouter_vertex_t *pv = NULL; GList *curpath = NULL, *i, *paths = NULL; #ifdef DEBUG_ROUTE printf("PATH:\n"); #endif i = path; while(i) { toporouter_vertex_t *v = TOPOROUTER_VERTEX(i->data); #ifdef DEBUG_ROUTE printf("v = %f,%f ", vx(v), vy(v)); if(v->parent) printf("parent = %f,%f ", vx(v->parent), vy(v->parent)); if(v->child) printf("child = %f,%f ", vx(v->child), vy(v->child)); printf("\n"); #endif // printf("***\n"); // if(v) printf("v = %f,%f\n", GTS_POINT(v)->x, GTS_POINT(v)->y); // if(pv) printf("pv = %f,%f\n", GTS_POINT(pv)->x, GTS_POINT(pv)->y); if(pv) if(GTS_POINT(v)->x == GTS_POINT(pv)->x && GTS_POINT(v)->y == GTS_POINT(pv)->y) { if(g_list_length(curpath) > 1) paths = g_list_prepend(paths, curpath); curpath = NULL; pv->child = NULL; v->parent = NULL; } curpath = g_list_append(curpath, v); pv = v; i = i->next; } if(g_list_length(curpath) > 1) paths = g_list_prepend(paths, curpath); return paths; } #define edge_gradient(e) (cartesian_gradient(GTS_POINT(GTS_SEGMENT(e)->v1)->x, GTS_POINT(GTS_SEGMENT(e)->v1)->y, \ GTS_POINT(GTS_SEGMENT(e)->v2)->x, GTS_POINT(GTS_SEGMENT(e)->v2)->y)) /*! * \brief Sorting into ascending distance from v1. */ gint routing_edge_insert(gconstpointer a, gconstpointer b, gpointer user_data) { GtsPoint *v1 = GTS_POINT(edge_v1(user_data)); if(gts_point_distance2(v1, GTS_POINT(a)) < gts_point_distance2(v1, GTS_POINT(b)) - EPSILON) return -1; if(gts_point_distance2(v1, GTS_POINT(a)) > gts_point_distance2(v1, GTS_POINT(b)) + EPSILON) return 1; /* printf("a = %x b = %x\n", (int) a, (int) b); printf("WARNING: routing_edge_insert() with same points..\n \ v1 @ %f,%f\n\ a @ %f,%f\n\ b @ %f,%f\n", v1->x, v1->y, vx(a), vy(a), vx(a), vy(b)); printf("A: "); print_vertex(TOPOROUTER_VERTEX(a)); printf("B: "); print_vertex(TOPOROUTER_VERTEX(b)); TOPOROUTER_VERTEX(a)->flags |= VERTEX_FLAG_RED; TOPOROUTER_VERTEX(b)->flags |= VERTEX_FLAG_RED; */ return 0; } toporouter_vertex_t * new_temp_toporoutervertex(gdouble x, gdouble y, toporouter_edge_t *e) { GtsVertexClass *vertex_class = GTS_VERTEX_CLASS (toporouter_vertex_class ()); GList *i = edge_routing(e); toporouter_vertex_t *r; ///* while(i) { r = TOPOROUTER_VERTEX(i->data); if(epsilon_equals(vx(r),x) && epsilon_equals(vy(r),y)) { if(r->flags & VERTEX_FLAG_TEMP) return r; } i = i->next; } //*/ r = TOPOROUTER_VERTEX( gts_vertex_new (vertex_class, x, y, vz(edge_v1(e))) ); r->flags |= VERTEX_FLAG_TEMP; r->routingedge = e; if(TOPOROUTER_IS_CONSTRAINT(e)) TOPOROUTER_CONSTRAINT(e)->routing = g_list_insert_sorted_with_data(edge_routing(e), r, routing_edge_insert, e); else e->routing = g_list_insert_sorted_with_data(edge_routing(e), r, routing_edge_insert, e); return r; } /*! * \brief Create vertex on edge e at radius r from v, closest to ref. */ toporouter_vertex_t * new_temp_toporoutervertex_in_segment(toporouter_edge_t *e, toporouter_vertex_t *v, gdouble r, toporouter_vertex_t *ref) { gdouble m = edge_gradient(e); toporouter_spoint_t p, np1, np2; // toporouter_vertex_t *b = TOPOROUTER_VERTEX((GTS_VERTEX(v) == edge_v1(e)) ? edge_v2(e) : edge_v1(e)); toporouter_vertex_t *rval = NULL; p.x = vx(v); p.y = vy(v); vertices_on_line(&p, m, r, &np1, &np2); if( (pow(np1.x - vx(ref), 2) + pow(np1.y - vy(ref), 2)) < (pow(np2.x - vx(ref), 2) + pow(np2.y - vy(ref), 2)) ) rval = new_temp_toporoutervertex(np1.x, np1.y, e); else rval = new_temp_toporoutervertex(np2.x, np2.y, e); return rval; } gint vertex_keepout_test(toporouter_t *r, toporouter_vertex_t *v) { GList *i = r->keepoutlayers; while(i) { gdouble keepout = *((double *) i->data); if(vz(v) == keepout) return 1; i = i->next; } return 0; } void closest_cluster_pair(toporouter_t *r, GList *src_vertices, GList *dest_vertices, toporouter_vertex_t **a, toporouter_vertex_t **b) { GList *i = src_vertices, *j = dest_vertices; gdouble min = 0.; *a = NULL; *b = NULL; i = src_vertices; while(i) { toporouter_vertex_t *v1 = TOPOROUTER_VERTEX(i->data); if(vertex_keepout_test(r, v1)) { i = i->next; continue; } j = dest_vertices; while(j) { toporouter_vertex_t *v2 = TOPOROUTER_VERTEX(j->data); if(vertex_keepout_test(r, v2) || vz(v2) != vz(v1)) { j = j->next; continue; } if(!*a) { *a = v1; *b = v2; min = simple_h_cost(r, *a, *b); }else{ gdouble tempd = simple_h_cost(r, v1, v2); if(r->flags & TOPOROUTER_FLAG_GOFAR && tempd > min) { *a = v1; *b = v2; min = tempd; }else if(tempd < min) { *a = v1; *b = v2; min = tempd; } } j = j->next; } i = i->next; } // g_list_free(src_vertices); // g_list_free(dest_vertices); } toporouter_vertex_t * closest_dest_vertex(toporouter_t *r, toporouter_vertex_t *v, toporouter_route_t *routedata) { GList //*vertices = cluster_vertices(r, routedata->dest), *i = routedata->destvertices; toporouter_vertex_t *closest = NULL; gdouble closest_distance = 0.; // if(routedata->flags & TOPOROUTER_FLAG_FLEX) i = r->destboxes; while(i) { toporouter_vertex_t *cv = TOPOROUTER_VERTEX(i->data); if(vz(cv) != vz(v)) { i = i->next; continue; } if(!closest) { closest = cv; closest_distance = simple_h_cost(r, v, closest); }else{ gdouble tempd = simple_h_cost(r, v, cv); if(r->flags & TOPOROUTER_FLAG_GOFAR && tempd > closest_distance) { closest = cv; closest_distance = tempd; }else if(tempd < closest_distance) { closest = cv; closest_distance = tempd; } } i = i->next; } // g_list_free(vertices); #ifdef DEBUG_ROUTE printf("CLOSEST = %f,%f,%f\n", vx(closest), vy(closest), vz(closest)); #endif return closest; } #define toporouter_edge_gradient(e) (cartesian_gradient(vx(edge_v1(e)), vy(edge_v1(e)), vx(edge_v2(e)), vy(edge_v2(e)))) /*! * \brief Returns the capacity of the triangle cut through v. */ gdouble triangle_interior_capacity(GtsTriangle *t, toporouter_vertex_t *v) { toporouter_edge_t *e = TOPOROUTER_EDGE(gts_triangle_edge_opposite(t, GTS_VERTEX(v))); gdouble x, y, m1, m2, c2, c1; #ifdef DEBUG_ROUTE gdouble len; #endif g_assert(e); m1 = toporouter_edge_gradient(e); m2 = perpendicular_gradient(m1); c2 = (isinf(m2)) ? vx(v) : vy(v) - (m2 * vx(v)); c1 = (isinf(m1)) ? vx(edge_v1(e)) : vy(edge_v1(e)) - (m1 * vx(edge_v1(e))); if(isinf(m2)) x = vx(v); else if(isinf(m1)) x = vx(edge_v1(e)); else x = (c2 - c1) / (m1 - m2); y = (isinf(m2)) ? vy(edge_v1(e)) : (m2 * x) + c2; #ifdef DEBUG_ROUTE len = gts_point_distance2(GTS_POINT(edge_v1(e)), GTS_POINT(edge_v2(e))); printf("%f,%f len = %f v = %f,%f\n", x, y, len, vx(v), vy(v)); #endif if(epsilon_equals(x,vx(edge_v1(e))) && epsilon_equals(y,vy(edge_v1(e)))) return INFINITY; if(epsilon_equals(x,vx(edge_v2(e))) && epsilon_equals(y,vy(edge_v2(e)))) return INFINITY; if(x >= MIN(vx(edge_v1(e)),vx(edge_v2(e))) && x <= MAX(vx(edge_v1(e)),vx(edge_v2(e))) && y >= MIN(vy(edge_v1(e)),vy(edge_v2(e))) && y <= MAX(vy(edge_v1(e)),vy(edge_v2(e)))) // if( (pow(vx(edge_v1(e)) - x, 2) + pow(vy(edge_v1(e)) - y, 2)) < len && (pow(vx(edge_v2(e)) - x, 2) + pow(vy(edge_v2(e)) - y, 2)) < len ) return hypot(vx(v) - x, vy(v) - y); return INFINITY; } static inline toporouter_vertex_t * segment_common_vertex(GtsSegment *s1, GtsSegment *s2) { if(!s1 || !s2) return NULL; if(s1->v1 == s2->v1) return TOPOROUTER_VERTEX(s1->v1); if(s1->v2 == s2->v1) return TOPOROUTER_VERTEX(s1->v2); if(s1->v1 == s2->v2) return TOPOROUTER_VERTEX(s1->v1); if(s1->v2 == s2->v2) return TOPOROUTER_VERTEX(s1->v2); return NULL; } static inline toporouter_vertex_t * route_vertices_common_vertex(toporouter_vertex_t *v1, toporouter_vertex_t *v2) { return segment_common_vertex(GTS_SEGMENT(v1->routingedge), GTS_SEGMENT(v2->routingedge)); } static inline guint edges_third_edge(GtsSegment *s1, GtsSegment *s2, toporouter_vertex_t **v1, toporouter_vertex_t **v2) { if(!s1 || !s2) return 0; if(s1->v1 == s2->v1) { *v1 = TOPOROUTER_VERTEX(s1->v2); *v2 = TOPOROUTER_VERTEX(s2->v2); return 1; } if(s1->v2 == s2->v1) { *v1 = TOPOROUTER_VERTEX(s1->v1); *v2 = TOPOROUTER_VERTEX(s2->v2); return 1; } if(s1->v1 == s2->v2) { *v1 = TOPOROUTER_VERTEX(s1->v2); *v2 = TOPOROUTER_VERTEX(s2->v1); return 1; } if(s1->v2 == s2->v2) { *v1 = TOPOROUTER_VERTEX(s1->v1); *v2 = TOPOROUTER_VERTEX(s2->v1); return 1; } return 0; } /*! * \brief Returns the flow from e1 to e2, and the flow from the vertex * oppisate e1 to e1 and the vertex oppisate e2 to e2. */ gdouble flow_from_edge_to_edge(GtsTriangle *t, toporouter_edge_t *e1, toporouter_edge_t *e2, toporouter_vertex_t *common_v, toporouter_vertex_t *curpoint) { gdouble r = 0.; toporouter_vertex_t *pv = common_v, *v; toporouter_edge_t *op_edge; GList *i = edge_routing(e1); while(i) { v = TOPOROUTER_VERTEX(i->data); if(v == curpoint) { r += min_spacing(v, pv); pv = v; i = i->next; continue; } // if(!(v->flags & VERTEX_FLAG_TEMP)) { if((v->flags & VERTEX_FLAG_ROUTE)) { if(v->parent) if(v->parent->routingedge == e2) { r += min_spacing(v, pv); pv = v; i = i->next; continue; } if(v->child) if(v->child->routingedge == e2) { r += min_spacing(v, pv); pv = v; i = i->next; continue; } } i = i->next; } op_edge = TOPOROUTER_EDGE(gts_triangle_edge_opposite(t, GTS_VERTEX(common_v))); g_assert(op_edge); g_assert(e1); g_assert(e2); v = segment_common_vertex(GTS_SEGMENT(e2), GTS_SEGMENT(op_edge)); g_assert(v); //v = TOPOROUTER_VERTEX(gts_triangle_vertex_opposite(t, GTS_EDGE(e1))); if(v->flags & VERTEX_FLAG_ROUTE && v->parent && v->parent->routingedge) { if(v->parent->routingedge == e1) r += min_spacing(v, pv); } v = segment_common_vertex(GTS_SEGMENT(e1), GTS_SEGMENT(op_edge)); g_assert(v); //v = TOPOROUTER_VERTEX(gts_triangle_vertex_opposite(t, GTS_EDGE(e2))); if(v->flags & VERTEX_FLAG_ROUTE && v->parent && v->parent->routingedge) { if(v->parent->routingedge == e1) r += min_spacing(v, pv); } if(TOPOROUTER_IS_CONSTRAINT(op_edge)) { toporouter_bbox_t *box = vertex_bbox(TOPOROUTER_VERTEX(edge_v1(op_edge))); r += vertex_net_thickness(v) / 2.; if(box) { r += MAX(vertex_net_keepaway(v), cluster_keepaway(box->cluster)); r += cluster_thickness(box->cluster) / 2.; }else{ r += vertex_net_keepaway(v); } } return r; } guint check_triangle_interior_capacity(GtsTriangle *t, toporouter_vertex_t *v, toporouter_vertex_t *curpoint, toporouter_edge_t *op_edge, toporouter_edge_t *adj_edge1, toporouter_edge_t *adj_edge2) { gdouble ic = triangle_interior_capacity(t, v); gdouble flow = flow_from_edge_to_edge(t, adj_edge1, adj_edge2, v, curpoint); if(TOPOROUTER_IS_CONSTRAINT(adj_edge1) || TOPOROUTER_IS_CONSTRAINT(adj_edge2)) return 1; if(flow > ic) { #ifdef DEBUG_ROUTE printf("fail interior capacity flow = %f ic = %f\n", flow, ic); #endif return 0; } return 1; } toporouter_vertex_t * edge_routing_next_not_temp(toporouter_edge_t *e, GList *list) { if(!TOPOROUTER_IS_CONSTRAINT(e)) { while(list) { toporouter_vertex_t *v = TOPOROUTER_VERTEX(list->data); if(!(v->flags & VERTEX_FLAG_TEMP)) return v; list = list->next; } } return tedge_v2(e); } toporouter_vertex_t * edge_routing_prev_not_temp(toporouter_edge_t *e, GList *list) { if(!TOPOROUTER_IS_CONSTRAINT(e)) { while(list) { toporouter_vertex_t *v = TOPOROUTER_VERTEX(list->data); if(!(v->flags & VERTEX_FLAG_TEMP)) return v; list = list->prev; } } return tedge_v1(e); } void edge_adjacent_vertices(toporouter_edge_t *e, toporouter_vertex_t *v, toporouter_vertex_t **v1, toporouter_vertex_t **v2) { GList *r = g_list_find(edge_routing(e), v); if(v == tedge_v1(e)) { *v1 = NULL; *v2 = edge_routing_next_not_temp(e, edge_routing(e)); }else if(v == tedge_v2(e)) { *v1 = edge_routing_prev_not_temp(e, g_list_last(edge_routing(e))); *v2 = NULL; }else{ // r = g_list_find(r, v); *v1 = edge_routing_prev_not_temp(e, r); *v2 = edge_routing_next_not_temp(e, r); } } GList * candidate_vertices(toporouter_vertex_t *v1, toporouter_vertex_t *v2, toporouter_vertex_t *dest, toporouter_edge_t *e) { gdouble totald, v1ms, v2ms, flow, capacity, ms; GList *vs = NULL; g_assert(v1); g_assert(v2); g_assert(dest); g_assert(!(v1->flags & VERTEX_FLAG_TEMP)); g_assert(!(v2->flags & VERTEX_FLAG_TEMP)); #ifdef DEBUG_ROUTE printf("starting candidate vertices\n"); printf("v1 = %f,%f v2 = %f,%f dest = %f,%f\n", vx(v1), vy(v1), vx(v2), vy(v2), vx(dest), vy(dest)); #endif totald = gts_point_distance(GTS_POINT(v1), GTS_POINT(v2)); v1ms = min_spacing(v1, dest); v2ms = min_spacing(v2, dest); ms = min_spacing(dest, dest); flow = TOPOROUTER_IS_CONSTRAINT(e) ? 0. : edge_flow(e, v1, v2, dest); capacity = edge_capacity(e); #ifdef DEBUG_ROUTE g_assert(totald > 0); printf("v1ms = %f v2ms = %f totald = %f ms = %f capacity = %f flow = %f\n", v1ms, v2ms, totald, ms, capacity, flow); #endif if(flow >= capacity) return NULL; if(v1ms + v2ms + ms >= totald) { vs = g_list_prepend(vs, new_temp_toporoutervertex((vx(v1)+vx(v2)) / 2., (vy(v1)+vy(v2)) / 2., e)); }else{ gdouble x0, y0, x1, y1, d; vertex_move_towards_vertex_values(GTS_VERTEX(v1), GTS_VERTEX(v2), v1ms, &x0, &y0); vs = g_list_prepend(vs, new_temp_toporoutervertex(x0, y0, e)); vertex_move_towards_vertex_values(GTS_VERTEX(v2), GTS_VERTEX(v1), v2ms, &x1, &y1); vs = g_list_prepend(vs, new_temp_toporoutervertex(x1, y1, e)); d = hypot(x0-x1,y0-y1); if(ms < d) { // guint nint = d / ms; // gdouble dif = d / (nint + 1); gdouble dif = d / 2; // for(guint j=0;jdata); if(!(v->flags & VERTEX_FLAG_TEMP)) return i; i = i->next; } return NULL; } GList * edge_routing_last_not_temp(toporouter_edge_t *e) { GList *i = edge_routing(e), *last = NULL; toporouter_vertex_t *v; while(i) { v = TOPOROUTER_VERTEX(i->data); if(!(v->flags & VERTEX_FLAG_TEMP)) last = i; i = i->next; } return last; } void delete_vertex(toporouter_vertex_t *v) { if(v->flags & VERTEX_FLAG_TEMP) { if(v->routingedge) { if(TOPOROUTER_IS_CONSTRAINT(v->routingedge)) TOPOROUTER_CONSTRAINT(v->routingedge)->routing = g_list_remove(TOPOROUTER_CONSTRAINT(v->routingedge)->routing, v); else v->routingedge->routing = g_list_remove(v->routingedge->routing, v); } gts_object_destroy ( GTS_OBJECT(v) ); } } #define edge_is_blocked(e) (TOPOROUTER_IS_EDGE(e) ? (e->flags & EDGE_FLAG_DIRECTCONNECTION) : 0) GList * triangle_candidate_points_from_vertex(GtsTriangle *t, toporouter_vertex_t *v, toporouter_vertex_t *dest, toporouter_route_t *routedata) { toporouter_edge_t *op_e = TOPOROUTER_EDGE(gts_triangle_edge_opposite(t, GTS_VERTEX(v))); toporouter_vertex_t *vv1, *vv2, *constraintv = NULL; toporouter_edge_t *e1, *e2; GList *i; GList *rval = NULL; #ifdef DEBUG_ROUTE printf("\tTRIANGLE CAND POINT FROM VERTEX\n"); g_assert(op_e); #endif e1 = TOPOROUTER_EDGE(gts_vertices_are_connected(GTS_VERTEX(v), edge_v1(op_e))); e2 = TOPOROUTER_EDGE(gts_vertices_are_connected(GTS_VERTEX(v), edge_v2(op_e))); if(TOPOROUTER_IS_CONSTRAINT(op_e)) { if(TOPOROUTER_CONSTRAINT(op_e)->box->type == BOARD) { #ifdef DEBUG_ROUTE printf("BOARD constraint\n"); #endif return NULL; } if(constraint_netlist(TOPOROUTER_CONSTRAINT(op_e)) != vertex_netlist(dest)) { // || TOPOROUTER_CONSTRAINT(op_e)->routing) { #ifdef DEBUG_ROUTE printf("op_e routing:\n"); print_edge(op_e); #endif return NULL; } #ifdef DEBUG_ROUTE printf("RETURNING CONSTRAINT POING\n"); #endif constraintv = new_temp_toporoutervertex_in_segment(op_e, TOPOROUTER_VERTEX(edge_v1(op_e)), gts_point_distance(GTS_POINT(edge_v1(op_e)), GTS_POINT(edge_v2(op_e))) / 2., TOPOROUTER_VERTEX(edge_v2(op_e))); // return g_list_prepend(NULL, vv1); } if(edge_is_blocked(op_e)) { goto triangle_candidate_points_from_vertex_exit; } // v1 = tedge_v1(op_e); // v2 = tedge_v2(op_e); if(v == tedge_v1(e1)) { i = edge_routing_first_not_temp(e1); }else{ i = edge_routing_last_not_temp(e1); } if(i) { toporouter_vertex_t *temp = TOPOROUTER_VERTEX(i->data); if(temp->parent == tedge_v2(op_e) || temp->child == tedge_v2(op_e)) { #ifdef DEBUG_ROUTE printf("temp -> op_e->v2\n"); #endif goto triangle_candidate_points_from_vertex_exit; } if(temp->parent->routingedge == op_e) { vv1 = temp->parent; #ifdef DEBUG_ROUTE printf("vv1->parent\n"); #endif }else if(temp->child->routingedge == op_e) { vv1 = temp->child; #ifdef DEBUG_ROUTE printf("vv1->child\n"); #endif }else{ // must be to e2 #ifdef DEBUG_ROUTE printf("temp -> e2?\n"); printf("op_e = %f,%f\t\t%f,%f\n", vx(edge_v1(op_e)), vy(edge_v1(op_e)), vx(edge_v2(op_e)), vy(edge_v2(op_e)) ); if(temp->parent->routingedge) printf("temp->parent->routingedge = %f,%f \t\t %f,%f\n", vx(edge_v1(temp->parent->routingedge)), vy(edge_v1(temp->parent->routingedge)), vx(edge_v2(temp->parent->routingedge)), vy(edge_v2(temp->parent->routingedge)) ); else printf("temp->parent->routingedge = NULL\n"); if(temp->child->routingedge) printf("temp->child->routingedge = %f,%f \t\t %f,%f\n", vx(edge_v1(temp->child->routingedge)), vy(edge_v1(temp->child->routingedge)), vx(edge_v2(temp->child->routingedge)), vy(edge_v2(temp->child->routingedge)) ); else printf("temp->child->routingedge = NULL\n"); #endif goto triangle_candidate_points_from_vertex_exit; } }else{ vv1 = tedge_v1(op_e); #ifdef DEBUG_ROUTE printf("nothing on e1\n"); #endif } if(v == tedge_v1(e2)) { i = edge_routing_first_not_temp(e2); }else{ i = edge_routing_last_not_temp(e2); } if(i) { toporouter_vertex_t *temp = TOPOROUTER_VERTEX(i->data); if(temp->parent == tedge_v1(op_e) || temp->child == tedge_v1(op_e)) { #ifdef DEBUG_ROUTE printf("temp -> op_e->v2\n"); #endif goto triangle_candidate_points_from_vertex_exit; } if(temp->parent->routingedge == op_e) { vv2 = temp->parent; #ifdef DEBUG_ROUTE printf("vv2->parent\n"); #endif }else if(temp->child->routingedge == op_e) { vv2 = temp->child; #ifdef DEBUG_ROUTE printf("vv2->child\n"); #endif }else{ // must be to e1 #ifdef DEBUG_ROUTE printf("temp -> e1?\n"); printf("op_e = %f,%f\t\t%f,%f\n", vx(edge_v1(op_e)), vy(edge_v1(op_e)), vx(edge_v2(op_e)), vy(edge_v2(op_e)) ); if(temp->parent->routingedge) printf("temp->parent->routingedge = %f,%f \t\t %f,%f\n", vx(edge_v1(temp->parent->routingedge)), vy(edge_v1(temp->parent->routingedge)), vx(edge_v2(temp->parent->routingedge)), vy(edge_v2(temp->parent->routingedge)) ); else printf("temp->parent->routingedge = NULL\n"); if(temp->child->routingedge) printf("temp->child->routingedge = %f,%f \t\t %f,%f\n", vx(edge_v1(temp->child->routingedge)), vy(edge_v1(temp->child->routingedge)), vx(edge_v2(temp->child->routingedge)), vy(edge_v2(temp->child->routingedge)) ); else printf("temp->child->routingedge = NULL\n"); #endif goto triangle_candidate_points_from_vertex_exit; } }else{ vv2 = tedge_v2(op_e); #ifdef DEBUG_ROUTE printf("nothing on e2\n"); #endif } #ifdef DEBUG_ROUTE printf("size of e1 routing = %d e2 routing = %d op_e routing = %d\n", g_list_length(edge_routing(e1)), g_list_length(edge_routing(e2)), g_list_length(edge_routing(op_e))); #endif if(constraintv) { #ifdef DEBUG_ROUTE print_vertex(constraintv); printf("constraintv %f,%f returning\n", vx(constraintv), vy(constraintv)); #endif return g_list_prepend(NULL, constraintv); } i = edge_routing(op_e); while(i) { toporouter_vertex_t *temp = TOPOROUTER_VERTEX(i->data); if(temp->parent == v || temp->child == v) { rval = g_list_concat(rval, candidate_vertices(vv1, temp, dest, op_e)); vv1 = temp; } i = i->next; } rval = g_list_concat(rval, candidate_vertices(vv1, vv2, dest, op_e)); return rval; triangle_candidate_points_from_vertex_exit: if(constraintv) //delete_vertex(constraintv); g_hash_table_insert(routedata->alltemppoints, constraintv, constraintv); g_list_free(rval); return NULL; } void routedata_insert_temppoints(toporouter_route_t *data, GList *temppoints) { GList *j = temppoints; while(j) { g_hash_table_insert(data->alltemppoints, j->data, j->data); j = j->next; } } static inline gint constraint_route_test(toporouter_constraint_t *c, toporouter_route_t *routedata) { if(c->box->cluster && c->box->cluster->netlist == routedata->src->netlist) { if(c->box->cluster->c == routedata->dest->c || c->box->cluster->c == routedata->src->c) return 1; } return 0; } GList * all_candidates_on_edge(toporouter_edge_t *e, toporouter_route_t *routedata) { GList *rval = NULL; if(edge_is_blocked(e)) return NULL; if(!TOPOROUTER_IS_CONSTRAINT(e)) { GList *i = edge_routing(e); toporouter_vertex_t *pv = tedge_v1(e); while(i) { toporouter_vertex_t *v = TOPOROUTER_VERTEX(i->data); if(!(v->flags & VERTEX_FLAG_TEMP)) { rval = g_list_concat(rval, candidate_vertices(pv, v, TOPOROUTER_VERTEX(routedata->destvertices->data), e)); pv = v; } i = i->next; } rval = g_list_concat(rval, candidate_vertices(pv, tedge_v2(e), TOPOROUTER_VERTEX(routedata->destvertices->data), e)); }else if(TOPOROUTER_CONSTRAINT(e)->box->type == BOARD) { return NULL; }else if(constraint_route_test(TOPOROUTER_CONSTRAINT(e), routedata)) { toporouter_vertex_t *consv = new_temp_toporoutervertex_in_segment(e, tedge_v1(e), tvdistance(tedge_v1(e), tedge_v2(e)) / 2., tedge_v2(e)); rval = g_list_prepend(rval, consv); // g_hash_table_insert(routedata->alltemppoints, consv, consv); } return rval; } GList * triangle_all_candidate_points_from_vertex(GtsTriangle *t, toporouter_vertex_t *v, toporouter_route_t *routedata) { toporouter_edge_t *op_e = TOPOROUTER_EDGE(gts_triangle_edge_opposite(t, GTS_VERTEX(v))); return all_candidates_on_edge(op_e, routedata); } GList * triangle_all_candidate_points_from_edge(toporouter_t *r, GtsTriangle *t, toporouter_edge_t *e, toporouter_route_t *routedata, toporouter_vertex_t **dest, toporouter_vertex_t *curpoint) { toporouter_vertex_t *op_v; toporouter_edge_t *e1, *e2; GList *i, *rval = NULL, *rval2 = NULL; toporouter_vertex_t *boxpoint = NULL; guint e1intcap, e2intcap; op_v = TOPOROUTER_VERTEX(gts_triangle_vertex_opposite(t, GTS_EDGE(e))); if(vertex_bbox(op_v)) boxpoint = TOPOROUTER_VERTEX(vertex_bbox(op_v)->point); if(g_list_find(routedata->destvertices, op_v)) { rval = g_list_prepend(rval, op_v); *dest = op_v; return rval; }else if(g_list_find(routedata->destvertices, boxpoint)) { *dest = boxpoint; }else if(g_list_find(routedata->srcvertices, op_v)) { rval = g_list_prepend(rval, op_v); } e1 = TOPOROUTER_EDGE(gts_vertices_are_connected(GTS_VERTEX(op_v), edge_v1(e))); e2 = TOPOROUTER_EDGE(gts_vertices_are_connected(GTS_VERTEX(op_v), edge_v2(e))); rval = g_list_concat(rval, all_candidates_on_edge(e1, routedata)); rval = g_list_concat(rval, all_candidates_on_edge(e2, routedata)); e1intcap = check_triangle_interior_capacity(t, tedge_v1(e), curpoint, e2, e, e1); e2intcap = check_triangle_interior_capacity(t, tedge_v2(e), curpoint, e1, e, e2); i = rval; while(i) { toporouter_vertex_t *v = TOPOROUTER_VERTEX(i->data); if(!v->routingedge) rval2 = g_list_prepend(rval2, v); else if(v->routingedge == e1 && !(!TOPOROUTER_IS_CONSTRAINT(e1) && !e1intcap)) rval2 = g_list_prepend(rval2, v); else if(v->routingedge == e2 && !(!TOPOROUTER_IS_CONSTRAINT(e2) && !e2intcap)) rval2 = g_list_prepend(rval2, v); i = i->next; } g_list_free(rval); return rval2; } GList * triangle_candidate_points_from_edge(toporouter_t *r, GtsTriangle *t, toporouter_edge_t *e, toporouter_vertex_t *v, toporouter_vertex_t **dest, toporouter_route_t *routedata) { toporouter_vertex_t *v1, *v2, *op_v, *vv = NULL, *e1constraintv = NULL, *e2constraintv = NULL; toporouter_edge_t *e1, *e2; GList *e1cands = NULL, *e2cands = NULL, *rval = NULL; guint noe1 = 0, noe2 = 0; op_v = TOPOROUTER_VERTEX(gts_triangle_vertex_opposite(t, GTS_EDGE(e))); e1 = TOPOROUTER_EDGE(gts_vertices_are_connected(GTS_VERTEX(op_v), edge_v1(e))); e2 = TOPOROUTER_EDGE(gts_vertices_are_connected(GTS_VERTEX(op_v), edge_v2(e))); g_assert(*dest); // v1 is prev dir, v2 is next dir edge_adjacent_vertices(e, v, &v1, &v2); if(TOPOROUTER_IS_CONSTRAINT(e1)) { GList *i = edge_routing(e1); if(TOPOROUTER_CONSTRAINT(e1)->box->type == BOARD) { noe1 = 1; }else if(!constraint_route_test(TOPOROUTER_CONSTRAINT(e1), routedata)) { noe1 = 1; #ifdef DEBUG_ROUTE printf("noe1 netlist\n"); #endif }else if(v1 == tedge_v1(e) || (v1->parent->routingedge && v1->parent->routingedge == e1) || (v1->child->routingedge && v1->child->routingedge == e1)) { e1constraintv = new_temp_toporoutervertex_in_segment(e1, tedge_v1(e1), gts_point_distance(GTS_POINT(edge_v1(e1)), GTS_POINT(edge_v2(e1))) / 2., tedge_v2(e1)); } while(i) { toporouter_vertex_t *temp = TOPOROUTER_VERTEX(i->data); if((temp->child == tedge_v2(e) || temp->parent == tedge_v2(e)) && !(temp->flags & VERTEX_FLAG_TEMP)) noe2 = 1; i = i->next; } goto triangle_candidate_points_e2; } if(edge_is_blocked(e1)) { noe1 = 1; goto triangle_candidate_points_e2; } if(v1 == tedge_v1(e)) { // continue up e1 toporouter_vertex_t *vv1, *vv2; edge_adjacent_vertices(e1, v1, &vv1, &vv2); #ifdef DEBUG_ROUTE printf("v1 == e->v1\n"); #endif if(vv1) { // candidates from v1 until vv1 vv = vv1; }else{ // candidates from v1 until vv2 vv = vv2; } if(!e1constraintv) e1cands = candidate_vertices(v1, vv, *dest, e1); if(vv != op_v) { if(vv->parent == tedge_v2(e) || vv->child == tedge_v2(e)) { #ifdef DEBUG_ROUTE printf("noe2 0\n"); #endif noe2 = 1; } } }else if(v1->parent != op_v && v1->child != op_v) { toporouter_vertex_t *vv1 = NULL, *vv2 = NULL; #ifdef DEBUG_ROUTE printf("v1 != e->v1\n"); #endif if(v1->parent->routingedge == e1) { vv1 = v1->parent; #ifdef DEBUG_ROUTE printf("v1 parent = e1\n"); #endif if(op_v == tedge_v1(e1)) { // candidates from v1->parent until prev vertex vv2 = edge_routing_prev_not_temp(e1, g_list_find(edge_routing(e1), v1->parent)->prev); }else{ // candidates from v1->parent until next vertex vv2 = edge_routing_next_not_temp(e1, g_list_find(edge_routing(e1), v1->parent)->next); } }else if(v1->child->routingedge == e1) { vv1 = v1->child; #ifdef DEBUG_ROUTE printf("v1 child = e1\n"); #endif if(op_v == tedge_v1(e1)) { // candidates from v1->child until prev vertex vv2 = edge_routing_prev_not_temp(e1, g_list_find(edge_routing(e1), v1->child)->prev); }else{ // candidates from v1->child until next vertex vv2 = edge_routing_next_not_temp(e1, g_list_find(edge_routing(e1), v1->child)->next); } }else{ #ifdef DEBUG_ROUTE printf("v1 ? \n"); #endif goto triangle_candidate_points_e2; } if(vv1 && vv2) { if(vv2->parent == tedge_v2(e) || vv2->child == tedge_v2(e)) { #ifdef DEBUG_ROUTE printf("noe2 1\n"); #endif noe2 = 1; } if(!e1constraintv) e1cands = candidate_vertices(vv1, vv2, *dest, e1); vv = vv2; } } if(vv && vv == op_v) { toporouter_vertex_t *boxpoint = NULL; if(vertex_bbox(op_v)) boxpoint = TOPOROUTER_VERTEX(vertex_bbox(op_v)->point); if(g_list_find(routedata->destvertices, op_v)) { rval = g_list_prepend(rval, op_v); *dest = op_v; }else if(g_list_find(routedata->destvertices, boxpoint)) { *dest = boxpoint; }else if(g_list_find(routedata->srcvertices, op_v)) { rval = g_list_prepend(rval, op_v); } } triangle_candidate_points_e2: if(noe2) { // printf("noe2\n"); goto triangle_candidate_points_finish; } if(TOPOROUTER_IS_CONSTRAINT(e2)) { GList *i = edge_routing(e2); if(TOPOROUTER_CONSTRAINT(e2)->box->type == BOARD) { noe2 = 1; // goto triangle_candidate_points_finish; }else if(!constraint_route_test(TOPOROUTER_CONSTRAINT(e2), routedata)) { #ifdef DEBUG_ROUTE printf("noe2 netlist\n"); #endif noe2 = 1; // goto triangle_candidate_points_finish; }else if(v2 == tedge_v2(e) || (v2->parent->routingedge && v2->parent->routingedge == e2) || (v2->child->routingedge && v2->child->routingedge == e2)) { e2constraintv = new_temp_toporoutervertex_in_segment(e2, tedge_v1(e2), gts_point_distance(GTS_POINT(edge_v1(e2)), GTS_POINT(edge_v2(e2))) / 2., tedge_v2(e2)); } while(i) { toporouter_vertex_t *temp = TOPOROUTER_VERTEX(i->data); if((temp->child == tedge_v1(e) || temp->parent == tedge_v1(e)) && !(temp->flags & VERTEX_FLAG_TEMP)) noe1 = 1; i = i->next; } goto triangle_candidate_points_finish; } if(edge_is_blocked(e2)) { noe2 = 1; goto triangle_candidate_points_finish; } if(v2 == tedge_v2(e)) { // continue up e2 toporouter_vertex_t *vv1 = NULL, *vv2 = NULL; edge_adjacent_vertices(e2, v2, &vv1, &vv2); #ifdef DEBUG_ROUTE printf("v2 == e->v2\n"); #endif if(vv1) { // candidates from v2 until vv1 vv = vv1; }else{ // candidates from v2 until vv2 vv = vv2; } if(!e2constraintv) e2cands = candidate_vertices(v2, vv, *dest, e2); if(vv != op_v) { if(vv->parent == tedge_v1(e) || vv->child == tedge_v1(e)) { #ifdef DEBUG_ROUTE printf("noe1 0\n"); #endif noe1 = 1; } } }else if(v2->parent != op_v && v2->child != op_v) { toporouter_vertex_t *vv1 = NULL, *vv2 = NULL; #ifdef DEBUG_ROUTE printf("v2 == e->v2\n"); #endif if(v2->parent->routingedge == e2) { vv1 = v2->parent; if(op_v == tedge_v1(e2)) { // candidates from v2->parent until prev vertex vv2 = edge_routing_prev_not_temp(e2, g_list_find(edge_routing(e2), vv1)->prev); }else{ // candidates from v2->parent until next vertex vv2 = edge_routing_next_not_temp(e2, g_list_find(edge_routing(e2), vv1)->next); } }else if(v2->child->routingedge == e2) { vv1 = v2->child; if(op_v == tedge_v1(e2)) { // candidates from v2->child until prev vertex vv2 = edge_routing_prev_not_temp(e2, g_list_find(edge_routing(e2), vv1)->prev); }else{ // candidates from v2->child until next vertex vv2 = edge_routing_next_not_temp(e2, g_list_find(edge_routing(e2), vv1)->next); } }else{ goto triangle_candidate_points_finish; } if(vv1 && vv2) { if(vv2->parent == tedge_v1(e) || vv2->child == tedge_v1(e)) { #ifdef DEBUG_ROUTE printf("noe1 1\n"); #endif noe1 = 1; } if(!e2constraintv) e2cands = candidate_vertices(vv1, vv2, *dest, e2); } } triangle_candidate_points_finish: v1 = segment_common_vertex(GTS_SEGMENT(e), GTS_SEGMENT(e1)); v2 = segment_common_vertex(GTS_SEGMENT(e), GTS_SEGMENT(e2)); if(noe1 || !check_triangle_interior_capacity(t, v1, v, e2, e, e1)) { #ifdef DEBUG_ROUTE printf("freeing e1cands\n"); #endif routedata_insert_temppoints(routedata, e1cands); g_list_free(e1cands); e1cands = NULL; } if(noe2 || !check_triangle_interior_capacity(t, v2, v, e1, e, e2)) { #ifdef DEBUG_ROUTE printf("freeing e2cands\n"); #endif routedata_insert_temppoints(routedata, e2cands); g_list_free(e2cands); e2cands = NULL; } if(!noe1 && e1constraintv) { e1cands = g_list_prepend(e1cands, e1constraintv); }else if(e1constraintv) { g_hash_table_insert(routedata->alltemppoints, e1constraintv, e1constraintv); // delete_vertex(e1constraintv); } if(!noe2 && e2constraintv) { e2cands = g_list_prepend(e2cands, e2constraintv); }else if(e2constraintv) { g_hash_table_insert(routedata->alltemppoints, e2constraintv, e2constraintv); // delete_vertex(e2constraintv); } if(!noe1 && !noe2) return g_list_concat(rval, g_list_concat(e1cands, e2cands)); return g_list_concat(e1cands, e2cands); } GList * compute_candidate_points(toporouter_t *tr, toporouter_layer_t *l, toporouter_vertex_t *curpoint, toporouter_route_t *data, toporouter_vertex_t **closestdest) { GList *r = NULL, *j; toporouter_edge_t *edge = curpoint->routingedge, *tempedge; if(vertex_keepout_test(tr, curpoint)) goto compute_candidate_points_finish; /* direct connection */ // if(curpoint == TOPOROUTER_VERTEX(data->src->point)) if((tempedge = TOPOROUTER_EDGE(gts_vertices_are_connected(GTS_VERTEX(curpoint), GTS_VERTEX(*closestdest))))) { if(TOPOROUTER_IS_CONSTRAINT(tempedge)) { goto compute_candidate_points_finish; }else{ if(!tempedge->routing) { r = g_list_prepend(NULL, *closestdest); tempedge->flags |= EDGE_FLAG_DIRECTCONNECTION; goto compute_candidate_points_finish; }else{ #ifdef DEBUG_ROUTE printf("Direct connection, but has routing\n"); #endif } } /* if we get to here, there is routing blocking the direct connection, * continue as per normal */ } /* a real point origin */ if(!(curpoint->flags & VERTEX_FLAG_TEMP)) { GSList *triangles, *i; i = triangles = gts_vertex_triangles(GTS_VERTEX(curpoint), NULL); #ifdef DEBUG_ROUTE printf("triangle count = %d\n", g_slist_length(triangles)); #endif while(i) { GtsTriangle *t = GTS_TRIANGLE(i->data); GList *temppoints; if(tr->flags & TOPOROUTER_FLAG_LEASTINVALID) temppoints = triangle_all_candidate_points_from_vertex(t, curpoint, data); else temppoints = triangle_candidate_points_from_vertex(t, curpoint, *closestdest, data); #ifdef DEBUG_ROUTE printf("\treturned %d points\n", g_list_length(temppoints)); #endif routedata_insert_temppoints(data, temppoints); r = g_list_concat(r, temppoints); i = i->next; } g_slist_free(triangles); }else /* a temp point */ { int prevwind = vertex_wind(GTS_SEGMENT(edge)->v1, GTS_SEGMENT(edge)->v2, GTS_VERTEX(curpoint->parent)); // printf("tempoint\n"); GSList *i = GTS_EDGE(edge)->triangles; while(i) { GtsVertex *oppv = gts_triangle_vertex_opposite(GTS_TRIANGLE(i->data), GTS_EDGE(edge)); if(prevwind != vertex_wind(GTS_SEGMENT(edge)->v1, GTS_SEGMENT(edge)->v2, oppv)) { GList *temppoints; if(tr->flags & TOPOROUTER_FLAG_LEASTINVALID) temppoints = triangle_all_candidate_points_from_edge(tr, GTS_TRIANGLE(i->data), edge, data, closestdest, curpoint); else temppoints = triangle_candidate_points_from_edge(tr, GTS_TRIANGLE(i->data), edge, curpoint, closestdest, data); j = temppoints; while(j) { toporouter_vertex_t *tempj = TOPOROUTER_VERTEX(j->data); if(tempj->flags & VERTEX_FLAG_TEMP) g_hash_table_insert(data->alltemppoints, j->data, j->data); #ifdef DEBUG_ROUTE else printf("got cand not a temp\n"); #endif j = j->next; } r = g_list_concat(r, temppoints); break; } i = i->next; } } compute_candidate_points_finish: if(vertex_bbox(curpoint) && vertex_bbox(curpoint)->cluster) { if(vertex_bbox(curpoint)->cluster->c == data->src->c) { r = g_list_concat(r, g_list_copy(data->srcvertices)); } } return r; } gboolean temp_point_clean(gpointer key, gpointer value, gpointer user_data) { toporouter_vertex_t *tv = TOPOROUTER_VERTEX(value); if(tv->flags & VERTEX_FLAG_TEMP) { if(TOPOROUTER_IS_CONSTRAINT(tv->routingedge)) TOPOROUTER_CONSTRAINT(tv->routingedge)->routing = g_list_remove(TOPOROUTER_CONSTRAINT(tv->routingedge)->routing, tv); else tv->routingedge->routing = g_list_remove(tv->routingedge->routing, tv); gts_object_destroy ( GTS_OBJECT(tv) ); } return TRUE; } void clean_routing_edges(toporouter_t *r, toporouter_route_t *data) { g_hash_table_foreach_remove(data->alltemppoints, temp_point_clean, NULL); g_hash_table_destroy(data->alltemppoints); data->alltemppoints = NULL; } gdouble path_score(toporouter_t *r, GList *path) { gdouble score = 0.; toporouter_vertex_t *pv = NULL; toporouter_vertex_t *v0 = NULL; if(!path) return INFINITY; v0 = TOPOROUTER_VERTEX(path->data); while(path) { toporouter_vertex_t *v = TOPOROUTER_VERTEX(path->data); if(pv) { score += gts_point_distance(GTS_POINT(pv), GTS_POINT(v)); if(pv != v0 && vz(pv) != vz(v)) if(path->next) score += r->viacost; } pv = v; path = path->next; } return score; } void print_vertices(GList *vertices) { while(vertices) { toporouter_vertex_t *v = TOPOROUTER_VERTEX(vertices->data); print_vertex(v); print_bbox(vertex_bbox(v)); if(vertex_bbox(v)) { printf("has bbox\n"); if(vertex_bbox(v)->cluster) printf("has cluster\n"); else printf("no cluster\n"); }else printf("no bbox\n"); vertices = vertices->next; } } gint space_edge(gpointer item, gpointer data) { toporouter_edge_t *e = TOPOROUTER_EDGE(item); GList *i; gdouble *forces; if(TOPOROUTER_IS_CONSTRAINT(e)) return 0; if(!edge_routing(e) || !g_list_length(edge_routing(e))) return 0; forces = (gdouble *)malloc(sizeof(double) * g_list_length(edge_routing(e))); for(guint j=0;j<100;j++) { guint k=0; guint equilibrium = 1; i = edge_routing(e); while(i) { toporouter_vertex_t *v = TOPOROUTER_VERTEX(i->data); gdouble ms, d; if(i->prev) { // ms = min_net_net_spacing(TOPOROUTER_VERTEX(i->prev->data), v); ms = min_spacing(TOPOROUTER_VERTEX(i->prev->data), v); d = gts_point_distance(GTS_POINT(i->prev->data), GTS_POINT(v)); }else{ // ms = min_vertex_net_spacing(v, tedge_v1(e)); ms = min_spacing(v, tedge_v1(e)); d = gts_point_distance(GTS_POINT(edge_v1(e)), GTS_POINT(v)); } if(d < ms) forces[k] = ms - d; else forces[k] = 0.; if(i->next) { // ms = min_net_net_spacing(TOPOROUTER_VERTEX(i->next->data), v); ms = min_spacing(TOPOROUTER_VERTEX(i->next->data), v); d = gts_point_distance(GTS_POINT(i->next->data), GTS_POINT(v)); }else{ // ms = min_vertex_net_spacing(v, tedge_v2(e)); ms = min_spacing(v, tedge_v2(e)); d = gts_point_distance(GTS_POINT(edge_v2(e)), GTS_POINT(v)); } if(d < ms) forces[k] += d - ms; k++; i = i->next; } k = 0; i = edge_routing(e); while(i) { toporouter_vertex_t *v = TOPOROUTER_VERTEX(i->data); if(forces[k] > EPSILON || forces[k] < -EPSILON) equilibrium = 0; vertex_move_towards_vertex_values(GTS_VERTEX(v), edge_v2(e), forces[k] * 0.1, &(GTS_POINT(v)->x), &(GTS_POINT(v)->y)); k++; i = i->next; } if(equilibrium) { // printf("reached equilibriium at %d\n", j); break; } } free(forces); return 0; } void swap_vertices(toporouter_vertex_t **v1, toporouter_vertex_t **v2) { toporouter_vertex_t *tempv = *v1; *v1 = *v2; *v2 = tempv; } void split_edge_routing(toporouter_vertex_t *v, GList **l1, GList **l2) { GList *base, *i; g_assert(v); g_assert(v->routingedge); base = g_list_find(vrouting(v), v); *l1 = g_list_prepend(*l1, tedge_v1(v->routingedge)); *l2 = g_list_prepend(*l2, tedge_v2(v->routingedge)); g_assert(base); i = base->next; while(i) { if(!(TOPOROUTER_VERTEX(i->data)->flags & VERTEX_FLAG_TEMP)) *l2 = g_list_prepend(*l2, i->data); i = i->next; } i = base->prev; while(i) { if(!(TOPOROUTER_VERTEX(i->data)->flags & VERTEX_FLAG_TEMP)) *l1 = g_list_prepend(*l1, i->data); i = i->prev; } } GList * vertices_routing_conflicts(toporouter_vertex_t *v, toporouter_vertex_t *pv) { toporouter_edge_t *e; GList *rval = NULL, *l1 = NULL, *l2 = NULL, *i; if(vz(v) != vz(pv)) return NULL; g_assert(v != pv); if(!v->routingedge && !pv->routingedge) { e = TOPOROUTER_EDGE(gts_vertices_are_connected(GTS_VERTEX(v), GTS_VERTEX(pv))); if(!e) return NULL; i = edge_routing(e); while(i) { rval = g_list_prepend(rval, TOPOROUTER_VERTEX(i->data)->route); i = i->next; } return rval; } if(TOPOROUTER_IS_CONSTRAINT(v->routingedge) && TOPOROUTER_IS_CONSTRAINT(pv->routingedge)) return NULL; if(TOPOROUTER_IS_CONSTRAINT(pv->routingedge)) swap_vertices(&pv, &v); if(!v->routingedge) swap_vertices(&pv, &v); e = v->routingedge; split_edge_routing(v, &l1, &l2); g_assert(l2); g_assert(l1); if(!pv->routingedge) { toporouter_edge_t *e1, *e2; e1 = TOPOROUTER_EDGE(gts_vertices_are_connected(GTS_VERTEX(pv), edge_v1(e))); e2 = TOPOROUTER_EDGE(gts_vertices_are_connected(GTS_VERTEX(pv), edge_v2(e))); l1 = g_list_concat(l1, g_list_copy(edge_routing(e1))); l2 = g_list_concat(l2, g_list_copy(edge_routing(e2))); }else{ GList *pvlist1 = NULL, *pvlist2 = NULL; toporouter_vertex_t *commonv = route_vertices_common_vertex(v, pv); g_assert(commonv); split_edge_routing(pv, &pvlist1, &pvlist2); if(commonv == tedge_v1(e)) { toporouter_edge_t *ope; if(commonv == tedge_v1(pv->routingedge)) { l1 = g_list_concat(l1, pvlist1); l2 = g_list_concat(l2, pvlist2); ope = TOPOROUTER_EDGE(gts_vertices_are_connected(edge_v2(e), edge_v2(pv->routingedge))); }else{ l1 = g_list_concat(l1, pvlist2); l2 = g_list_concat(l2, pvlist1); ope = TOPOROUTER_EDGE(gts_vertices_are_connected(edge_v2(e), edge_v1(pv->routingedge))); } g_assert(ope); l2 = g_list_concat(l2, g_list_copy(edge_routing(ope))); }else{ toporouter_edge_t *ope; if(commonv == tedge_v1(pv->routingedge)) { l1 = g_list_concat(l1, pvlist2); l2 = g_list_concat(l2, pvlist1); ope = TOPOROUTER_EDGE(gts_vertices_are_connected(edge_v1(e), edge_v2(pv->routingedge))); }else{ l1 = g_list_concat(l1, pvlist1); l2 = g_list_concat(l2, pvlist2); ope = TOPOROUTER_EDGE(gts_vertices_are_connected(edge_v1(e), edge_v1(pv->routingedge))); } g_assert(ope); l1 = g_list_concat(l1, g_list_copy(edge_routing(ope))); } } i = l1; while(i) { toporouter_vertex_t *curv = TOPOROUTER_VERTEX(i->data); if(curv->flags & VERTEX_FLAG_ROUTE && (g_list_find(l2, curv->parent) || g_list_find(l2, curv->child))) { if(!g_list_find(rval, curv->route)) rval = g_list_prepend(rval, curv->route); } i = i->next; } i = l2; while(i) { toporouter_vertex_t *curv = TOPOROUTER_VERTEX(i->data); if(curv->flags & VERTEX_FLAG_ROUTE && (g_list_find(l1, curv->parent) || g_list_find(l1, curv->child))) { if(!g_list_find(rval, curv->route)) rval = g_list_prepend(rval, curv->route); } i = i->next; } g_list_free(l1); g_list_free(l2); return rval; } gdouble vertices_routing_conflict_cost(toporouter_t *r, toporouter_vertex_t *v, toporouter_vertex_t *pv, guint *n) { GList *conflicts = vertices_routing_conflicts(v, pv), *i; gdouble penalty = 0.; i = conflicts; while(i) { (*n) += 1; penalty += TOPOROUTER_ROUTE(i->data)->score; i = i->next; } g_list_free(conflicts); // if(penalty > 0.) printf("conflict penalty of %f with %f,%f %f,%f\n", penalty, vx(v), vy(v), vx(pv), vy(pv)); return penalty; } gdouble gcost(toporouter_t *r, toporouter_route_t *data, toporouter_vertex_t *srcv, toporouter_vertex_t *v, toporouter_vertex_t *pv, guint *n, toporouter_netlist_t *pair) { gdouble cost = 0., segcost; *n = pv->gn; if(g_list_find(data->srcvertices, v)) return 0.; segcost = tvdistance(pv, v); if(pair && !TOPOROUTER_IS_CONSTRAINT(v->routingedge) && v->routingedge) { GList *list = g_list_find(v->routingedge->routing, v); toporouter_vertex_t *pv = edge_routing_prev_not_temp(v->routingedge, list); toporouter_vertex_t *nv = edge_routing_next_not_temp(v->routingedge, list); if(pv->route && pv->route->netlist == pair) { }else if(nv->route && nv->route->netlist == pair) { }else{ segcost *= 10.; } } cost = pv->gcost + segcost; if(r->flags & TOPOROUTER_FLAG_LEASTINVALID) { gdouble conflictcost = 0.; if(pv && v != pv && vz(v) == vz(pv)) conflictcost = vertices_routing_conflict_cost(r, v, pv, n); if(!(r->flags & TOPOROUTER_FLAG_DETOUR && *n == 1)) { cost += conflictcost * (pow(*n,2)); } } return cost; } #define vlayer(x) (&r->layers[(int)vz(x)]) guint candidate_is_available(toporouter_vertex_t *pv, toporouter_vertex_t *v) { // TODO: still needed? while(pv) { if(pv == v) return 0; pv = pv->parent; } return 1; } GList * route(toporouter_t *r, toporouter_route_t *data, guint debug) { GtsEHeap *openlist = gts_eheap_new(route_heap_cmp, NULL); GList *closelist = NULL; GList *i, *rval = NULL; toporouter_netlist_t *pair = NULL; gint count = 0; toporouter_vertex_t *srcv = NULL, *destv = NULL, *curpoint = NULL; toporouter_layer_t *cur_layer; //, *dest_layer; g_assert(data->src->c != data->dest->c); if(data->destvertices) g_list_free(data->destvertices); if(data->srcvertices) g_list_free(data->srcvertices); data->destvertices = cluster_vertices(r, data->dest); data->srcvertices = cluster_vertices(r, data->src); closest_cluster_pair(r, data->srcvertices, data->destvertices, &curpoint, &destv); if(!curpoint || !destv) goto routing_return; srcv = curpoint; cur_layer = vlayer(curpoint); //dest_layer = vlayer(destv); data->path = NULL; data->alltemppoints = g_hash_table_new(g_direct_hash, g_direct_equal); curpoint->parent = NULL; curpoint->child = NULL; curpoint->gcost = 0.; curpoint->gn = 0; curpoint->hcost = simple_h_cost(r, curpoint, destv); if(data->netlist && data->netlist->pair) { GList *i = r->routednets; while(i) { toporouter_route_t *curroute = TOPOROUTER_ROUTE(i->data); if(curroute->netlist == data->netlist->pair) { pair = data->netlist->pair; break; } i = i->next; } } gts_eheap_insert(openlist, curpoint); while(gts_eheap_size(openlist) > 0) { GList *candidatepoints; data->curpoint = curpoint; //draw_route_status(r, closelist, openlist, curpoint, data, count++); curpoint = TOPOROUTER_VERTEX( gts_eheap_remove_top(openlist, NULL) ); if(curpoint->parent && !(curpoint->flags & VERTEX_FLAG_TEMP)) { if(vz(curpoint) != vz(destv)) { toporouter_vertex_t *tempv; cur_layer = vlayer(curpoint);//&r->layers[(int)vz(curpoint)]; tempv = closest_dest_vertex(r, curpoint, data); if(tempv) { destv = tempv; //dest_layer = vlayer(destv);//&r->layers[(int)vz(destv)]; } } } // destpoint = closest_dest_vertex(r, curpoint, data); // dest_layer = &r->layers[(int)vz(destpoint)]; if(g_list_find(data->destvertices, curpoint)) { toporouter_vertex_t *temppoint = curpoint; srcv = NULL; destv = curpoint; data->path = NULL; while(temppoint) { data->path = g_list_prepend(data->path, temppoint); if(g_list_find(data->srcvertices, temppoint)) { srcv = temppoint; if(r->flags & TOPOROUTER_FLAG_AFTERORDER) break; } temppoint = temppoint->parent; } rval = data->path; data->score = path_score(r, data->path); #ifdef DEBUG_ROUTE printf("ROUTE: path score = %f computation cost = %d\n", data->score, count); #endif if(srcv->bbox->cluster != data->src) { data->src = srcv->bbox->cluster; } if(destv->bbox->cluster != data->dest) { data->dest = destv->bbox->cluster; } goto route_finish; } closelist_insert(curpoint); #ifdef DEBUG_ROUTE printf("\n\n\n*** ROUTE COUNT = %d\n", count); #endif candidatepoints = compute_candidate_points(r, cur_layer, curpoint, data, &destv); //#ifdef DEBUG_ROUTE /********************* if(debug && !strcmp(data->dest->netlist, " unnamed_net2")) { unsigned int mask = ~(VERTEX_FLAG_RED | VERTEX_FLAG_GREEN | VERTEX_FLAG_BLUE); char buffer[256]; int j; for(j=0;jlayers[j].vertices; while(i) { TOPOROUTER_VERTEX(i->data)->flags &= mask; i = i->next; } } i = candidatepoints; while(i) { TOPOROUTER_VERTEX(i->data)->flags |= VERTEX_FLAG_GREEN; // printf("flagged a candpoint @ %f,%f\n", // vx(i->data), vy(i->data)); i = i->next; } curpoint->flags |= VERTEX_FLAG_BLUE; if(curpoint->parent) curpoint->parent->flags |= VERTEX_FLAG_RED; for(j=0;jlayers[j].surface, buffer, 1024, 1024, 2, datas, j, candidatepoints); g_list_free(datas); } } //#endif *********************/ count++; // if(count > 100) exit(0); i = candidatepoints; while(i) { toporouter_vertex_t *temppoint = TOPOROUTER_VERTEX(i->data); if(!g_list_find(closelist, temppoint) && candidate_is_available(curpoint, temppoint)) { //&& temppoint != curpoint) { toporouter_heap_search_data_t heap_search_data = { temppoint, NULL }; guint temp_gn; gdouble temp_g_cost = gcost(r, data, srcv, temppoint, curpoint, &temp_gn, pair); gts_eheap_foreach(openlist,toporouter_heap_search, &heap_search_data); if(heap_search_data.result) { if(temp_g_cost < temppoint->gcost) { temppoint->gcost = temp_g_cost; temppoint->gn = temp_gn; temppoint->parent = curpoint; curpoint->child = temppoint; gts_eheap_update(openlist); } }else{ temppoint->parent = curpoint; curpoint->child = temppoint; temppoint->gcost = temp_g_cost; temppoint->gn = temp_gn; temppoint->hcost = simple_h_cost(r, temppoint, destv); // if(cur_layer != dest_layer) temppoint->hcost += r->viacost; gts_eheap_insert(openlist, temppoint); } } i = i->next; } g_list_free(candidatepoints); } #ifdef DEBUG_ROUTE printf("ROUTE: could not find path!\n"); #endif data->score = INFINITY; clean_routing_edges(r, data); data->path = NULL; //TOPOROUTER_VERTEX(data->src->point)->parent = NULL; //TOPOROUTER_VERTEX(data->src->point)->child = NULL; goto routing_return; /* { int i; for(i=0;iroutecount, i); toporouter_draw_surface(r, r->layers[i].surface, buffer, 1280, 1280, 2, data, i, NULL); } r->routecount++; } // exit(0); */ route_finish: // printf(" * finished a*\n"); /* { int i; for(i=0;iroutecount); toporouter_draw_surface(r, r->layers[i].surface, buffer, 1024, 1024, 2, data, i, NULL); } r->routecount++; } */ /* { i = data->path; while(i) { toporouter_vertex_t *tv = TOPOROUTER_VERTEX(i->data); if(tv->routingedge) { GList *list = g_list_find(edge_routing(tv->routingedge), tv); toporouter_vertex_t *restartv = NULL, *boxpoint; g_assert(list); if(!list->next) { if(vertex_bbox(tedge_v2(tv->routingedge))) boxpoint = TOPOROUTER_VERTEX(vertex_bbox(tedge_v2(tv->routingedge))->point); else boxpoint = NULL; if(tedge_v2(tv->routingedge) != srcv && g_list_find(data->srcvertices, tedge_v2(tv->routingedge))) restartv = tedge_v2(tv->routingedge); else if(boxpoint != srcv && g_list_find(data->srcvertices, boxpoint)) restartv = boxpoint; } if(!list->prev) { if(vertex_bbox(tedge_v1(tv->routingedge))) boxpoint = TOPOROUTER_VERTEX(vertex_bbox(tedge_v1(tv->routingedge))->point); else boxpoint = NULL; if(tedge_v1(tv->routingedge) != srcv && g_list_find(data->srcvertices, tedge_v1(tv->routingedge))) restartv = tedge_v1(tv->routingedge); else if(boxpoint != srcv && g_list_find(data->srcvertices, boxpoint)) restartv = boxpoint; } if(restartv) { clean_routing_edges(r, data); gts_eheap_destroy(openlist); g_list_free(closelist); openlist = gts_eheap_new(route_heap_cmp, NULL); closelist = NULL; g_list_free(data->path); printf("ROUTING RESTARTING with new src %f,%f,%f\n", vx(restartv), vy(restartv), vz(restartv)); curpoint = restartv; goto route_begin; } } i = i->next; } }*/ ///* { toporouter_vertex_t *pv = NULL; GList *i = data->path; while(i) { toporouter_vertex_t *tv = TOPOROUTER_VERTEX(i->data); if(pv && g_list_find(data->srcvertices, tv)) { GList *temp = g_list_copy(i); g_list_free(data->path); data->path = temp; i = data->path; } pv = tv; i = i->next; } } //*/ { toporouter_vertex_t *pv = NULL; GList *i = data->path; while(i) { toporouter_vertex_t *tv = TOPOROUTER_VERTEX(i->data); if(tv->flags & VERTEX_FLAG_TEMP) { tv->flags ^= VERTEX_FLAG_TEMP; tv->flags |= VERTEX_FLAG_ROUTE; } if(pv) pv->child = tv; if(tv->routingedge) tv->route = data; // if(tv->routingedge && !TOPOROUTER_IS_CONSTRAINT(tv->routingedge)) space_edge(tv->routingedge, NULL); pv = tv; i = i->next; } } { toporouter_vertex_t *pv = NULL, *v = NULL; GList *i = data->path; while(i) { v = TOPOROUTER_VERTEX(i->data); if(pv) { v->parent = pv; pv->child = v; }else{ v->parent = NULL; } pv = v; i = i->next; } if(v) v->child = NULL; } clean_routing_edges(r, data); // /* { GList *i = data->path; while(i) { toporouter_vertex_t *v = TOPOROUTER_VERTEX(i->data); if(v->routingedge && !TOPOROUTER_IS_CONSTRAINT(v->routingedge)) space_edge(v->routingedge, NULL); i = i->next; } } // */ routing_return: g_list_free(data->destvertices); g_list_free(data->srcvertices); data->destvertices = NULL; data->srcvertices = NULL; gts_eheap_destroy(openlist); g_list_free(closelist); data->alltemppoints = NULL; return rval; } /* moves vertex v d units in the direction of vertex p */ void vertex_move_towards_vertex (GtsVertex *v, GtsVertex *p, double d) { double theta = atan2 (GTS_POINT(p)->y - GTS_POINT(v)->y, GTS_POINT(p)->x - GTS_POINT(v)->x); GTS_POINT(v)->x += d * cos (theta); GTS_POINT(v)->y += d * sin (theta); } gdouble pathvertex_arcing_through_constraint(toporouter_vertex_t *pathv, toporouter_vertex_t *arcv) { toporouter_vertex_t *v = pathv->child; if(!v || !v->routingedge) return 0.; while(v->flags & VERTEX_FLAG_ROUTE && (tedge_v1(v->routingedge) == arcv || tedge_v2(v->routingedge) == arcv)) { if(TOPOROUTER_IS_CONSTRAINT(v->routingedge)) return gts_point_distance(GTS_POINT(tedge_v1(v->routingedge)), GTS_POINT(tedge_v2(v->routingedge))); v = v->child; } v = pathv->parent; while(v->flags & VERTEX_FLAG_ROUTE && (tedge_v1(v->routingedge) == arcv || tedge_v2(v->routingedge) == arcv)) { if(TOPOROUTER_IS_CONSTRAINT(v->routingedge)) return gts_point_distance(GTS_POINT(tedge_v1(v->routingedge)), GTS_POINT(tedge_v2(v->routingedge))); v = v->parent; } return 0.; } gint vertices_connected(toporouter_vertex_t *a, toporouter_vertex_t *b) { return ((a->route->netlist == b->route->netlist && a->route->src->c == b->route->src->c) ? 1 : 0); } gdouble edge_min_spacing(GList *list, toporouter_edge_t *e, toporouter_vertex_t *v, guint debug) { toporouter_vertex_t *origin; GList *i = list; gdouble space = 0.; toporouter_vertex_t *nextv, *prevv; //toporouter_vertex_t *edgev; //gdouble constraint_spacing; if(!list) return INFINITY; // printf("\t CMS %f,%f - %f,%f\n", vx(tedge_v1(e)), vy(tedge_v1(e)), vx(tedge_v2(e)), vy(tedge_v2(e))); prevv = origin = TOPOROUTER_VERTEX(list->data); // print_edge(e); i = list; if(gts_point_distance2(GTS_POINT(origin), GTS_POINT(edge_v1(e))) < gts_point_distance2(GTS_POINT(v), GTS_POINT(edge_v1(e)))) { /* towards v2 */ while(i) { nextv = edge_routing_next(e, i); if(nextv->route && vertices_connected(nextv, prevv)) { i = i->next; continue; } if(!(nextv->flags & VERTEX_FLAG_TEMP)) { gdouble ms = min_spacing(prevv, nextv); if(nextv == tedge_v2(e)) { gdouble cms = pathvertex_arcing_through_constraint(TOPOROUTER_VERTEX(i->data), tedge_v2(e)); // printf("\t CMS to %f,%f = %f \t ms = %f\n", vx(tedge_v2(e)), vy(tedge_v2(e)), cms, ms); // if(vx(tedge_v2(e)) > -EPSILON && vx(tedge_v2(e)) < EPSILON) { // printf("\t\tPROB: "); // print_vertex(tedge_v2(e)); // } if(cms > EPSILON) space += MIN(ms, cms / 2.); else space += ms; } else space += ms; prevv = nextv; } // printf("%f ", space); i = i->next; } }else{ /* towards v1 */ while(i) { nextv = edge_routing_prev(e, i); if(nextv->route && vertices_connected(nextv, prevv)) { i = i->prev; continue; } if(!(nextv->flags & VERTEX_FLAG_TEMP)) { gdouble ms = min_spacing(prevv, nextv); if(nextv == tedge_v1(e)) { gdouble cms = pathvertex_arcing_through_constraint(TOPOROUTER_VERTEX(i->data), tedge_v1(e)); // printf("\t CMS to %f,%f = %f \t ms = %f\n", vx(tedge_v1(e)), vy(tedge_v1(e)), cms, ms); // if(vx(tedge_v1(e)) > -EPSILON && vx(tedge_v1(e)) < EPSILON) { // printf("\t\tPROB: "); // print_vertex(tedge_v1(e)); // } if(cms > EPSILON) space += MIN(ms, cms / 2.); else space += ms; } else space += ms; prevv = nextv; } // printf("%f ", space); i = i->prev; } } if(TOPOROUTER_IS_CONSTRAINT(e) && space > gts_point_distance(GTS_POINT(edge_v1(e)), GTS_POINT(edge_v2(e))) / 2.) space = gts_point_distance(GTS_POINT(edge_v1(e)), GTS_POINT(edge_v2(e))) / 2.; // if(debug) printf("\tedge_min_spacing: %f\n", space); return space; } /* line segment is 1 & 2, point is 3 returns 0 if v3 is outside seg */ guint vertex_line_normal_intersection(gdouble x1, gdouble y1, gdouble x2, gdouble y2, gdouble x3, gdouble y3, gdouble *x, gdouble *y) { gdouble m1 = cartesian_gradient(x1,y1,x2,y2); gdouble m2 = perpendicular_gradient(m1); gdouble c2 = (isinf(m2)) ? x3 : y3 - (m2 * x3); gdouble c1 = (isinf(m1)) ? x1 : y1 - (m1 * x1); if(isinf(m2)) *x = x3; else if(isinf(m1)) *x = x1; else *x = (c2 - c1) / (m1 - m2); *y = (isinf(m2)) ? y1 : (m2 * (*x)) + c2; if(*x >= MIN(x1,x2) - EPSILON && *x <= MAX(x1,x2) + EPSILON && *y >= MIN(y1,y2) - EPSILON && *y <= MAX(y1,y2) + EPSILON) return 1; return 0; } void print_toporouter_arc(toporouter_arc_t *arc) { // GList *i = arc->vs; printf("ARC CENTRE: %f,%f ", vx(arc->centre), vy(arc->centre));// print_vertex(arc->centre); printf("RADIUS: %f", arc->r); if(arc->dir>0) printf(" COUNTERCLOCKWISE "); else if(arc->dir<0) printf(" CLOCKWISE "); else printf(" COLINEAR(ERROR) "); /* printf("\n\tVS: "); while(i) { toporouter_vertex_t *v = TOPOROUTER_VERTEX(i->data); printf("%f,%f ", vx(v), vy(v)); i = i->next; } */ } void toporouter_arc_remove(toporouter_oproute_t *oproute, toporouter_arc_t *arc) { oproute->arcs = g_list_remove(oproute->arcs, arc); if(arc->v) arc->v->arc = NULL; } toporouter_arc_t * toporouter_arc_new(toporouter_oproute_t *oproute, toporouter_vertex_t *v1, toporouter_vertex_t *v2, toporouter_vertex_t *centre, gdouble r, gint dir) { toporouter_arc_t *arc = TOPOROUTER_ARC(gts_object_new(GTS_OBJECT_CLASS(toporouter_arc_class()))); arc->centre = centre; arc->v = v1; arc->v1 = v1; arc->v2 = v2; arc->r = r; arc->dir = dir; if(v1) v1->arc = arc; arc->oproute = oproute; arc->clearance = NULL; return arc; } void path_set_oproute(GList *path, toporouter_oproute_t *oproute) { while(path) { toporouter_vertex_t *v = TOPOROUTER_VERTEX(path->data); if(v->flags & VERTEX_FLAG_ROUTE) v->oproute = oproute; path = path->next; } } void print_oproute(toporouter_oproute_t *oproute) { GList *i = oproute->arcs; printf("Optimized Route:\n"); printf("\tNetlist:\t\t%s\n\tStyle:\t\t%s\n", oproute->netlist, oproute->style); // printf("%s\n", oproute->netlist); /* i = oproute->term1->zlink; while(i) { toporouter_vertex_t *thisv = TOPOROUTER_VERTEX(i->data); printf("\tNetlist:\t\t%s\n\tStyle:\t\t%s\n", vertex_bbox(thisv)->netlist, vertex_bbox(thisv)->style); i = i->next; } */ printf("\t"); print_vertex(oproute->term1); printf("\n"); i = oproute->arcs; while(i) { toporouter_arc_t *arc = (toporouter_arc_t *)i->data; printf("\t"); print_toporouter_arc(arc); printf("\n"); i = i->next; } printf("\t"); print_vertex(oproute->term2); printf("\n"); } gdouble export_pcb_drawline(guint layer, guint x0, guint y0, guint x1, guint y1, guint thickness, guint keepaway) { gdouble d = 0.; LineType *line; line = CreateDrawnLineOnLayer( LAYER_PTR(layer), x0, y0, x1, y1, thickness, keepaway, MakeFlags (AUTOFLAG | (TEST_FLAG (CLEARNEWFLAG, PCB) ? CLEARLINEFLAG : 0))); if(line) { AddObjectToCreateUndoList (LINE_TYPE, LAYER_PTR(layer), line, line); d = hypot(x0 - x1, y0 - y1); } return d; } gdouble arc_angle(toporouter_arc_t *arc) { gdouble x0, x1, y0, y1; x0 = arc->x0 - vx(arc->centre); x1 = arc->x1 - vx(arc->centre); y0 = arc->y0 - vy(arc->centre); y1 = arc->y1 - vy(arc->centre); return fabs(acos(((x0*x1)+(y0*y1))/(hypot(x0,y0)*hypot(x1,y1)))); } gdouble export_pcb_drawarc(guint layer, toporouter_arc_t *a, guint thickness, guint keepaway) { gdouble sa, da, theta; gdouble d = 0.; ArcType *arc; gint wind; wind = coord_wind(a->x0, a->y0, a->x1, a->y1, vx(a->centre), vy(a->centre)); /* NB: PCB's arcs have a funny coorindate system, with 0 degrees as the -ve X axis (left), * continuing clockwise, with +90 degrees being along the +ve Y axis (bottom). Because * Y+ points down, our internal angles increase clockwise from the +ve X axis. */ sa = (M_PI - coord_angle (vx (a->centre), vy (a->centre), a->x0, a->y0)) * 180. / M_PI; theta = arc_angle(a); if(!a->dir || !wind) return 0.; if(a->dir != wind) theta = 2. * M_PI - theta; da = -a->dir * theta * 180. / M_PI; if(da < 1. && da > -1.) return 0.; if(da > 359. || da < -359.) return 0.; arc = CreateNewArcOnLayer(LAYER_PTR(layer), vx(a->centre), vy(a->centre), a->r, a->r, sa, da, thickness, keepaway, MakeFlags( AUTOFLAG | (TEST_FLAG (CLEARNEWFLAG, PCB) ? CLEARLINEFLAG : 0))); if(arc) { AddObjectToCreateUndoList( ARC_TYPE, LAYER_PTR(layer), arc, arc); d = a->r * theta; } return d; } void calculate_term_to_arc(toporouter_vertex_t *v, toporouter_arc_t *arc, guint dir) { gdouble theta, a, b, bx, by, a0x, a0y, a1x, a1y; gint winddir; theta = acos(arc->r / gts_point_distance(GTS_POINT(v), GTS_POINT(arc->centre))); a = arc->r * sin(theta); b = arc->r * cos(theta); #ifdef DEBUG_EXPORT printf("drawing arc with r %f theta %f d %f centre = %f,%f\n", arc->r, theta, gts_point_distance(GTS_POINT(v), GTS_POINT(arc->centre)), vx(arc->centre), vy(arc->centre)); #endif point_from_point_to_point(arc->centre, v, b, &bx, &by); coords_on_line(bx, by, perpendicular_gradient(point_gradient(GTS_POINT(v), GTS_POINT(arc->centre))), a, &a0x, &a0y, &a1x, &a1y); winddir = coord_wind(vx(v), vy(v), a0x, a0y, vx(arc->centre), vy(arc->centre)); if(!winddir) { printf("!winddir @ v %f,%f arc->centre %f,%f\n", vx(v), vy(v), vx(arc->centre), vy(arc->centre)); //TODO: fix hack: this shouldn't happen arc->x0 = vx(v); arc->y0 = vy(v); arc->x1 = vx(v); arc->y1 = vy(v); return; } g_assert(winddir); if(dir) winddir = -winddir; if(winddir == arc->dir) { if(!dir) { arc->x0 = a0x; arc->y0 = a0y; } else{ arc->x1 = a0x; arc->y1 = a0y; } }else{ if(!dir) { arc->x0 = a1x; arc->y0 = a1y; } else{ arc->x1 = a1x; arc->y1 = a1y; } } } /*! * \brief . * * b1 is the projection in the direction of narc, while b2 is the * perpendicular projection. */ void arc_ortho_projections(toporouter_arc_t *arc, toporouter_arc_t *narc, gdouble *b1, gdouble *b2) { gdouble nax, nay, ax, ay, alen, c; gdouble b1x, b1y, b2x, b2y; #ifdef DEBUG_EXPORT printf("arc c = %f,%f narc c = %f,%f arc->0 = %f,%f\n", vx(arc->centre), vy(arc->centre), vx(narc->centre), vy(narc->centre), arc->x0, arc->y0); #endif nax = vx(narc->centre) - vx(arc->centre); nay = vy(narc->centre) - vy(arc->centre); alen = hypot(nax, nay); ax = arc->x0 - vx(arc->centre); ay = arc->y0 - vy(arc->centre); #ifdef DEBUG_EXPORT printf("norm narc = %f,%f - %f\tA=%f,%f\n", nax, nay, alen, ax, ay); #endif c = ((ax*nax)+(ay*nay)) / (alen*alen); b1x = c * nax; b1y = c * nay; b2x = ax - b1x; b2y = ay - b1y; #ifdef DEBUG_EXPORT printf("proj = %f,%f perp proj = %f,%f\n", b1x, b1y, b2x, b2y); #endif *b1 = hypot(b1x,b1y); *b2 = hypot(b2x,b2y); } guint calculate_arc_to_arc(toporouter_t *ar, toporouter_arc_t *parc, toporouter_arc_t *arc) { gdouble theta, a, b, bx, by, a0x, a0y, a1x, a1y, m, preva, prevb; gint winddir; toporouter_arc_t *bigr, *smallr; if(parc->r > arc->r) { bigr = parc; smallr = arc; }else{ bigr = arc; smallr = parc; } #ifdef DEBUG_EXPORT printf("bigr centre = %f,%f smallr centre = %f,%f\n", vx(bigr->centre), vy(bigr->centre), vx(smallr->centre), vy(smallr->centre)); #endif m = perpendicular_gradient(point_gradient(GTS_POINT(bigr->centre), GTS_POINT(smallr->centre))); if(bigr->centre == smallr->centre) { printf("bigr->centre == smallr->centre @ %f,%f\n", vx(smallr->centre), vy(smallr->centre)); } g_assert(bigr->centre != smallr->centre); if(parc->dir == arc->dir) { //export_arc_straight: theta = acos((bigr->r - smallr->r) / gts_point_distance(GTS_POINT(bigr->centre), GTS_POINT(smallr->centre))); a = bigr->r * sin(theta); b = bigr->r * cos(theta); point_from_point_to_point(bigr->centre, smallr->centre, b, &bx, &by); coords_on_line(bx, by, m, a, &a0x, &a0y, &a1x, &a1y); winddir = coord_wind(vx(smallr->centre), vy(smallr->centre), a0x, a0y, vx(bigr->centre), vy(bigr->centre)); arc_ortho_projections(parc, arc, &prevb, &preva); //#ifdef DEBUG_EXPORT if(!winddir) { printf("STRAIGHT:\n"); printf("bigr centre = %f,%f smallr centre = %f,%f\n", vx(bigr->centre), vy(bigr->centre), vx(smallr->centre), vy(smallr->centre)); printf("theta = %f a = %f b = %f bigrr = %f d = %f po = %f\n", theta, a, b, bigr->r, gts_point_distance(GTS_POINT(bigr->centre), GTS_POINT(smallr->centre)), bigr->r / gts_point_distance(GTS_POINT(bigr->centre), GTS_POINT(smallr->centre))); printf("bigr-r = %f smallr-r = %f ratio = %f\n", bigr->r, smallr->r, (bigr->r - smallr->r) / gts_point_distance(GTS_POINT(bigr->centre), GTS_POINT(smallr->centre))); printf("preva = %f prevb = %f\n\n", preva, prevb); } //#endif g_assert(winddir); if(bigr==parc) winddir = -winddir; if(winddir == bigr->dir) { if(bigr==arc) { bigr->x0 = a0x; bigr->y0 = a0y; }else{ bigr->x1 = a0x; bigr->y1 = a0y; } }else{ if(bigr==arc) { bigr->x0 = a1x; bigr->y0 = a1y; }else{ bigr->x1 = a1x; bigr->y1 = a1y; } } a = smallr->r * sin(theta); b = smallr->r * cos(theta); #ifdef DEBUG_EXPORT printf("a = %f b = %f\n", a, b); #endif point_from_point_to_point(smallr->centre, bigr->centre, -b, &bx, &by); coords_on_line(bx, by, m, a, &a0x, &a0y, &a1x, &a1y); if(winddir == bigr->dir) { if(bigr==arc) { smallr->x1 = a0x; smallr->y1 = a0y; }else{ smallr->x0 = a0x; smallr->y0 = a0y; } }else{ if(bigr==arc) { smallr->x1 = a1x; smallr->y1 = a1y; }else{ smallr->x0 = a1x; smallr->y0 = a1y; } } }else{ //export_arc_twist: theta = acos((bigr->r + smallr->r) / gts_point_distance(GTS_POINT(bigr->centre), GTS_POINT(smallr->centre))); a = bigr->r * sin(theta); b = bigr->r * cos(theta); point_from_point_to_point(bigr->centre, smallr->centre, b, &bx, &by); coords_on_line(bx, by, m, a, &a0x, &a0y, &a1x, &a1y); winddir = coord_wind(vx(smallr->centre), vy(smallr->centre), a0x, a0y, vx(bigr->centre), vy(bigr->centre)); //#ifdef DEBUG_EXPORT if(!winddir) { printf("TWIST:\n"); printf("theta = %f a = %f b = %f r = %f d = %f po = %f\n", theta, a, b, bigr->r + smallr->r, gts_point_distance(GTS_POINT(bigr->centre), GTS_POINT(smallr->centre)), (bigr->r+smallr->r) / gts_point_distance(GTS_POINT(bigr->centre), GTS_POINT(smallr->centre))); printf("bigr centre = %f,%f smallr centre = %f,%f\n\n", vx(bigr->centre), vy(bigr->centre), vx(smallr->centre), vy(smallr->centre)); printf("big wind = %d small wind = %d\n", bigr->dir, smallr->dir); return 1; } //#endif /* if(!winddir) { smallr->centre->flags |= VERTEX_FLAG_RED; bigr->centre->flags |= VERTEX_FLAG_GREEN; //bigr->centre->flags |= VERTEX_FLAG_RED; { int i; for(i=0;ilayers[i].surface, buffer, 2096, 2096, 2, NULL, i, NULL); } } return; } */ g_assert(winddir); if(bigr==parc) winddir = -winddir; if(winddir == bigr->dir) { if(bigr==arc) { bigr->x0 = a0x; bigr->y0 = a0y; }else{ bigr->x1 = a0x; bigr->y1 = a0y; } }else{ if(bigr==arc) { bigr->x0 = a1x; bigr->y0 = a1y; }else{ bigr->x1 = a1x; bigr->y1 = a1y; } } a = smallr->r * sin(theta); b = smallr->r * cos(theta); point_from_point_to_point(smallr->centre, bigr->centre, b, &bx, &by); coords_on_line(bx, by, m, a, &a0x, &a0y, &a1x, &a1y); winddir = coord_wind(vx(smallr->centre), vy(smallr->centre), a0x, a0y, vx(bigr->centre), vy(bigr->centre)); g_assert(winddir); if(bigr==parc) winddir = -winddir; if(winddir == smallr->dir) { if(bigr==arc) { smallr->x1 = a0x; smallr->y1 = a0y; }else{ smallr->x0 = a0x; smallr->y0 = a0y; } }else{ if(bigr==arc) { smallr->x1 = a1x; smallr->y1 = a1y; }else{ smallr->x0 = a1x; smallr->y0 = a1y; } } } return 0; } void export_oproutes(toporouter_t *ar, toporouter_oproute_t *oproute) { guint layer = PCB->LayerGroups.Entries[oproute->layergroup][0]; guint thickness = lookup_thickness(oproute->style); guint keepaway = lookup_keepaway(oproute->style); GList *arcs = oproute->arcs; toporouter_arc_t *arc, *parc = NULL; if(!arcs) { ar->wiring_score += export_pcb_drawline(layer, vx(oproute->term1), vy(oproute->term1), vx(oproute->term2), vy(oproute->term2), thickness, keepaway); return; } // calculate_term_to_arc(oproute->term1, TOPOROUTER_ARC(arcs->data), 0, layer); while(arcs) { arc = TOPOROUTER_ARC(arcs->data); if(parc && arc) { ar->wiring_score += export_pcb_drawarc(layer, parc, thickness, keepaway); ar->wiring_score += export_pcb_drawline(layer, parc->x1, parc->y1, arc->x0, arc->y0, thickness, keepaway); }else if(!parc) { ar->wiring_score += export_pcb_drawline(layer, vx(oproute->term1), vy(oproute->term1), arc->x0, arc->y0, thickness, keepaway); } parc = arc; arcs = arcs->next; } ar->wiring_score += export_pcb_drawarc(layer, arc, thickness, keepaway); ar->wiring_score += export_pcb_drawline(layer, arc->x1, arc->y1, vx(oproute->term2), vy(oproute->term2), thickness, keepaway); } void oproute_free(toporouter_oproute_t *oproute) { GList *i = oproute->arcs; while(i) { toporouter_arc_t *arc = (toporouter_arc_t *) i->data; if(arc->centre->flags & VERTEX_FLAG_TEMP) gts_object_destroy(GTS_OBJECT(arc->centre)); i = i->next; } g_list_free(oproute->arcs); free(oproute); } void oproute_calculate_tof(toporouter_oproute_t *oproute) { GList *arcs = oproute->arcs; toporouter_arc_t *parc = NULL, *arc; oproute->tof = 0.; if(!arcs) { oproute->tof = gts_point_distance(GTS_POINT(oproute->term1), GTS_POINT(oproute->term2)); return; } while(arcs) { arc = TOPOROUTER_ARC(arcs->data); if(parc && arc) { oproute->tof += arc_angle(parc) * parc->r; oproute->tof += hypot(parc->x1-arc->x0,parc->y1-arc->y0); }else if(!parc) { oproute->tof += hypot(arc->x0-vx(oproute->term1), arc->y0-vy(oproute->term1)); } parc = arc; arcs = arcs->next; } oproute->tof += arc_angle(parc) * parc->r; oproute->tof += hypot(arc->x1-vx(oproute->term2), arc->y1-vy(oproute->term2)); } gdouble line_line_distance_at_normal( gdouble line1_x1, gdouble line1_y1, gdouble line1_x2, gdouble line1_y2, gdouble line2_x1, gdouble line2_y1, gdouble line2_x2, gdouble line2_y2, gdouble x, gdouble y) { gdouble m1 = perpendicular_gradient(cartesian_gradient(line1_x1, line1_y1, line1_x2, line1_y2)); gdouble m2 = cartesian_gradient(line2_x1, line2_y1, line2_x2, line2_y2); gdouble c1 = (isinf(m1)) ? x : y - (m1 * x); gdouble c2 = (isinf(m2)) ? line2_x1 : line2_y1 - (m2 * line2_x1); gdouble intx, inty; if(isinf(m2)) intx = line2_x1; else if(isinf(m1)) intx = x; else intx = (c2 - c1) / (m1 - m2); inty = (isinf(m2)) ? (m1 * intx) + c1 : (m2 * intx) + c2; return hypot(x-intx,y-inty); } void calculate_serpintine(gdouble delta, gdouble r, gdouble initiala, gdouble *a, guint *nhalfcycles) { gdouble lhalfcycle = 2.*(initiala-r)+(M_PI*r); guint n; printf("lhalfcycle = %f r = %f\n", lhalfcycle, r); n = (delta - M_PI*r) / (lhalfcycle - 2.*r) + 1; *a = (delta + 4.*n*r - n*M_PI*r + 4.*r - M_PI*r)/(2.*n); *nhalfcycles = n; } gdouble oproute_min_spacing(toporouter_oproute_t *a, toporouter_oproute_t *b) { return lookup_thickness(a->style) / 2. + lookup_thickness(b->style) / 2. + MAX(lookup_keepaway(a->style), lookup_keepaway(b->style)); } gdouble vector_angle(gdouble ox, gdouble oy, gdouble ax, gdouble ay, gdouble bx, gdouble by) { gdouble alen = hypot(ax-ox,ay-oy); gdouble blen = hypot(bx-ox,by-oy); return acos( ((ax-ox)*(bx-ox)+(ay-oy)*(by-oy)) / (alen * blen) ); } toporouter_serpintine_t * toporouter_serpintine_new(gdouble x, gdouble y, gdouble x0, gdouble y0, gdouble x1, gdouble y1, gpointer start, gdouble halfa, gdouble radius, guint nhalfcycles) { toporouter_serpintine_t *serp = (toporouter_serpintine_t *)malloc(sizeof(toporouter_serpintine_t)); serp->x = x; serp->y = y; serp->x0 = x0; serp->y0 = y0; serp->x1 = x1; serp->y1 = y1; serp->start = start; serp->halfa = halfa; serp->radius = radius; serp->nhalfcycles = nhalfcycles; serp->arcs = NULL; return serp; } //#define DEBUG_RUBBERBAND 1 gdouble check_non_intersect_vertex(gdouble x0, gdouble y0, gdouble x1, gdouble y1, toporouter_vertex_t *pathv, toporouter_vertex_t *arcv, toporouter_vertex_t *opv, gint wind, gint *arcwind, gdouble *arcr, guint debug) { gdouble ms, line_int_x, line_int_y, x, y, d = 0., m; gdouble tx0, ty0, tx1, ty1; gint wind1, wind2; g_assert(pathv->routingedge); if(TOPOROUTER_IS_CONSTRAINT(pathv->routingedge)) { gdouble d = tvdistance(tedge_v1(pathv->routingedge), tedge_v2(pathv->routingedge)) / 2.; ms = min_spacing(pathv, arcv); if(ms > d) ms = d; }else{ ms = edge_min_spacing(g_list_find(edge_routing(pathv->routingedge), pathv), pathv->routingedge, arcv, debug); } if(!vertex_line_normal_intersection(x0, y0, x1, y1, vx(arcv), vy(arcv), &line_int_x, &line_int_y)) { if(hypot(x0 - line_int_x, y0 - line_int_y) < hypot(x1 - line_int_x, y1 - line_int_y)) { line_int_x = x0; line_int_y = y0; }else{ line_int_x = x1; line_int_y = y1; } m = perpendicular_gradient(cartesian_gradient(vx(arcv), vy(arcv), line_int_x, line_int_y)); }else{ m = cartesian_gradient(x0, y0, x1, y1); } coords_on_line(vx(arcv), vy(arcv), m, MIL_TO_COORD (1.), &tx0, &ty0, &tx1, &ty1); wind1 = coord_wind(tx0, ty0, tx1, ty1, line_int_x, line_int_y); wind2 = coord_wind(tx0, ty0, tx1, ty1, vx(opv), vy(opv)); if(!wind2 || wind1 == wind2) return -1.; if(!wind) { coords_on_line(line_int_x, line_int_y, perpendicular_gradient(m), ms, &tx0, &ty0, &tx1, &ty1); if(hypot(tx0 - vx(opv), ty0 - vy(opv)) < hypot(tx1 - vx(opv), ty1 - vy(opv))) { x = tx0; y = ty0; }else{ x = tx1; y = ty1; } }else{ toporouter_vertex_t *parent = pathv->parent, *child = pathv->child; guint windtests = 0; d = hypot(vx(arcv) - line_int_x, vy(arcv) - line_int_y); coord_move_towards_coord_values(line_int_x, line_int_y, vx(arcv), vy(arcv), ms + d, &x, &y); rewind_test: wind1 = coord_wind(line_int_x, line_int_y, x, y, vx(parent), vy(parent)); wind2 = coord_wind(line_int_x, line_int_y, x, y, vx(child), vy(child)); if(wind1 && wind2 && wind1 == wind2) { // return -1.; if(windtests++ == 2) return -1.; if(parent->flags & VERTEX_FLAG_ROUTE) parent = parent->parent; if(child->flags & VERTEX_FLAG_ROUTE) child = child->child; goto rewind_test; } } *arcr = ms; *arcwind = tvertex_wind(pathv->parent, pathv, arcv); #ifdef DEBUG_RUBBERBAND //if(debug) // printf("non-int check %f,%f ms %f d %f arcv %f,%f opv %f,%f\n", vx(arcv), vy(arcv), ms, d + ms, // vx(arcv), vy(arcv), vx(opv), vy(opv)); #endif return d + ms; } gdouble check_intersect_vertex(gdouble x0, gdouble y0, gdouble x1, gdouble y1, toporouter_vertex_t *pathv, toporouter_vertex_t *arcv, toporouter_vertex_t *opv, gint wind, gint *arcwind, gdouble *arcr, guint debug) { gdouble ms, line_int_x, line_int_y, x, y, d = 0.; if(TOPOROUTER_IS_CONSTRAINT(pathv->routingedge)) { gdouble d = tvdistance(tedge_v1(pathv->routingedge), tedge_v2(pathv->routingedge)) / 2.; ms = min_spacing(pathv, arcv); if(ms > d) ms = d; }else { ms = edge_min_spacing(g_list_find(edge_routing(pathv->routingedge), pathv), pathv->routingedge, arcv, debug); } if(!vertex_line_normal_intersection(x0, y0, x1, y1, vx(arcv), vy(arcv), &line_int_x, &line_int_y)) return -1.; d = hypot(line_int_x - vx(arcv), line_int_y - vy(arcv)); if(d > ms - EPSILON) return -1.; coord_move_towards_coord_values(vx(arcv), vy(arcv), line_int_x, line_int_y, ms, &x, &y); *arcr = ms; *arcwind = tvertex_wind(pathv->parent, pathv, arcv); // *arcwind = coord_wind(x0, y0, x, y, x1, y1); #ifdef DEBUG_RUBBERBAND //if(debug) // printf("int check %f,%f ms %f d %f arcv %f,%f opv %f,%f\n", vx(arcv), vy(arcv), ms, ms - d, // vx(arcv), vy(arcv), vx(opv), vy(opv)); #endif return ms - d; } /*! * \brief Returns non-zero if arc has loops. */ guint check_arc_for_loops(gpointer t1, toporouter_arc_t *arc, gpointer t2) { gdouble x0, y0, x1, y1; if(TOPOROUTER_IS_VERTEX(t1)) { x0 = vx(TOPOROUTER_VERTEX(t1)); y0 = vy(TOPOROUTER_VERTEX(t1)); } else { x0 = TOPOROUTER_ARC(t1)->x1; y0 = TOPOROUTER_ARC(t1)->y1; } if(TOPOROUTER_IS_VERTEX(t2)) { x1 = vx(TOPOROUTER_VERTEX(t2)); y1 = vy(TOPOROUTER_VERTEX(t2)); } else { x1 = TOPOROUTER_ARC(t2)->x0; y1 = TOPOROUTER_ARC(t2)->y0; } if(coord_intersect_prop(x0, y0, arc->x0, arc->y0, arc->x1, arc->y1, x1, y1) ) { // || // (arc->x0 > arc->x1 - EPSILON && arc->x0 < arc->x1 + EPSILON && // arc->y0 > arc->y1 - EPSILON && arc->y0 < arc->y1 + EPSILON) // ) { #ifdef DEBUG_RUBBERBAND printf("LOOPS %f %f -> %f %f & %f %f -> %f %f\n", x0, y0, arc->x0, arc->y0, arc->x1, arc->y1, x1, y1); #endif return 1; } return 0; } toporouter_rubberband_arc_t * new_rubberband_arc(toporouter_vertex_t *pathv, toporouter_vertex_t *arcv, gdouble r, gdouble d, gint wind, GList *list) { toporouter_rubberband_arc_t *rba = (toporouter_rubberband_arc_t *)malloc(sizeof(toporouter_rubberband_arc_t)); rba->pathv = pathv; rba->arcv = arcv; rba->r = r; rba->d = d; rba->wind = wind; rba->list = list; return rba; } gint compare_rubberband_arcs(toporouter_rubberband_arc_t *a, toporouter_rubberband_arc_t *b) { return b->d - a->d; } void free_list_elements(gpointer data, gpointer user_data) { free(data); } /* returns the edge opposite v from the triangle facing (x,y), or NULL if v is colinear with an edge between v and a neighbor */ /* GtsEdge * vertex_edge_facing_vertex(GtsVertex *v, gdouble x, gdouble y) { GSList *ts = gts_vertex_triangles(GTS_VERTEX(n), NULL); GSList *i = ts; while(i) { GtsTriangle *t = GTS_TRIANGLE(i->data); GtsEdge *e = gts_triangle_edge_opposite(t, v); if(coord_wind(vx(edge_v1(e)), vy(edge_v1(e)), vx(v), vy(v), x, y) == vertex_wind(edge_v1(e), v, edge_v2(e)) && coord_wind(vx(edge_v2(e)), vy(edge_v2(e)), vx(v), vy(v), x, y) == vertex_wind(edge_v2(e), v, edge_v1(e)) ) { g_slist_free(ts); return e; } i = i->next; } g_slist_free(ts); return NULL; } */ gdouble check_adj_pushing_vertex(toporouter_oproute_t *oproute, gdouble x0, gdouble y0, gdouble x1, gdouble y1, toporouter_vertex_t *v, gdouble *arcr, gint *arcwind, toporouter_vertex_t **arc) { GSList *ns = gts_vertex_neighbors(GTS_VERTEX(v), NULL, NULL); GSList *i = ns; gdouble maxd = 0.; while(i) { toporouter_vertex_t *n = TOPOROUTER_VERTEX(i->data); gdouble segintx, seginty; if(vertex_line_normal_intersection(x0, y0, x1, y1, vx(n), vy(n), &segintx, &seginty)) { toporouter_edge_t *e = tedge(n, v); gdouble ms = 0., d = hypot(segintx - vx(n), seginty - vy(n)); //toporouter_vertex_t *a; toporouter_vertex_t *b; GList *closestnet = NULL; g_assert(e); if(v == tedge_v1(e)) { //a = tedge_v1(e); b = tedge_v2(e); closestnet = edge_routing(e); }else{ //a = tedge_v2(e); b = tedge_v1(e); closestnet = g_list_last(edge_routing(e)); } if(closestnet) { ms = edge_min_spacing(closestnet, e, b, 0); ms += min_oproute_net_spacing(oproute, TOPOROUTER_VERTEX(closestnet->data)); }else{ ms = min_oproute_vertex_spacing(oproute, b); } if(ms - d > maxd) { *arcr = ms; *arc = n; maxd = ms - d; if(vx(v) == x0 && vy(v) == y0) { *arcwind = coord_wind(x0, y0, vx(n), vy(n), x1, y1); }else if(vx(v) == x1 && vy(v) == y1) { *arcwind = coord_wind(x1, y1, vx(n), vy(n), x0, y0); }else{ fprintf(stderr, "ERROR: check_adj_pushing_vertex encountered bad vertex v (coordinates don't match)\n"); } } } i = i->next; } g_slist_free(ns); return maxd; } /*! * \brief . * * path is t1 path. */ GList * oproute_rubberband_segment(toporouter_t *r, toporouter_oproute_t *oproute, GList *path, gpointer t1, gpointer t2, guint debug) { gdouble x0, y0, x1, y1; toporouter_vertex_t *v1, *v2, *av1, *av2; /* v{1,2} are the vertex terminals of the segment, or arc terminal centres */ toporouter_arc_t *arc1 = NULL, *arc2 = NULL, *newarc = NULL; /* arc{1,2} are the arc terminals of the segment, if they exist */ GList *i = path; GList *list1, *list2; GList *arcs = NULL; toporouter_rubberband_arc_t *max = NULL; gdouble d, arcr; gint v1wind, v2wind, arcwind; if(TOPOROUTER_IS_VERTEX(t1)) { v1 = TOPOROUTER_VERTEX(t1); x0 = vx(v1); y0 = vy(v1); }else{ g_assert(TOPOROUTER_IS_ARC(t1)); arc1 = TOPOROUTER_ARC(t1); v1 = TOPOROUTER_VERTEX(arc1->v1); x0 = arc1->x1; y0 = arc1->y1; } if(TOPOROUTER_IS_VERTEX(t2)) { v2 = TOPOROUTER_VERTEX(t2); x1 = vx(v2); y1 = vy(v2); }else{ g_assert(TOPOROUTER_IS_ARC(t2)); arc2 = TOPOROUTER_ARC(t2); v2 = TOPOROUTER_VERTEX(arc2->v2); x1 = arc2->x0; y1 = arc2->y0; } #define TEST_AND_INSERT(z) if(d > EPSILON) arcs = g_list_prepend(arcs, new_rubberband_arc(v, z, arcr, d, arcwind, i)); #define ARC_CHECKS(z) (!(arc1 && arc1->centre == z) && !(arc2 && arc2->centre == z) && \ !(TOPOROUTER_IS_VERTEX(t1) && z == v1) && !(TOPOROUTER_IS_VERTEX(t2) && z == v2)) if(v1 == v2 || !i->next || TOPOROUTER_VERTEX(i->data) == v2) return NULL; //#ifdef DEBUG_RUBBERBAND if(debug) { printf("\nRB: line %f,%f %f,%f v1 = %f,%f v2 = %f,%f \n ", x0, y0, x1, y1, vx(v1), vy(v1), vx(v2), vy(v2)); // if(v1->routingedge) print_edge(v1->routingedge); // if(v2->routingedge) print_edge(v2->routingedge); } //#endif /* check the vectices adjacent to the terminal vectices for push against the segment */ //if(TOPOROUTER_IS_VERTEX(t1)) { // toporouter_vertex_t *arcc = NULL; // d = check_adj_pushing_vertex(oproute, x0, y0, x1, y1, v1, &arcr, &arcwind, &arcc); // g_assert(arcc != v1); // if(ARC_CHECKS(arcc) && d > EPSILON) arcs = g_list_prepend(arcs, new_rubberband_arc(v1, arcc, arcr, d, arcwind, path->next)); //} // //if(TOPOROUTER_IS_VERTEX(t2)) { // toporouter_vertex_t *arcc = NULL; // d = check_adj_pushing_vertex(oproute, x0, y0, x1, y1, v2, &arcr, &arcwind, &arcc); // g_assert(arcc != v2); // if(ARC_CHECKS(arcc) && d > EPSILON) arcs = g_list_prepend(arcs, new_rubberband_arc(v2, arcc, arcr, d, arcwind, g_list_last(path)->prev)); //} i = i->next; while(i) { toporouter_vertex_t *v = TOPOROUTER_VERTEX(i->data); if(v == v2 || v == v1 || !v->routingedge) break; #ifdef DEBUG_RUBBERBAND // if(debug) // printf("current v %f,%f - edge %f,%f %f,%f\n", vx(v), vy(v), // vx(tedge_v1(v->routingedge)), vy(tedge_v1(v->routingedge)), // vx(tedge_v2(v->routingedge)), vy(tedge_v2(v->routingedge)) // ); #endif g_assert(v->routingedge); v1wind = coord_wind(x0, y0, x1, y1, vx(tedge_v1(v->routingedge)), vy(tedge_v1(v->routingedge))); v2wind = coord_wind(x0, y0, x1, y1, vx(tedge_v2(v->routingedge)), vy(tedge_v2(v->routingedge))); // if(debug) printf("\twinds: %d %d\n", v1wind, v2wind); if(!v1wind && !v2wind) { i = i->next; continue; } if(v1wind && v2wind && v1wind != v2wind) { /* edge is cutting through the current segment */ if(ARC_CHECKS(tedge_v1(v->routingedge)) ){ /* edge v1 is not the centre of an arc terminal */ d = check_intersect_vertex(x0, y0, x1, y1, v, tedge_v1(v->routingedge), tedge_v2(v->routingedge), v1wind, &arcwind, &arcr, debug); TEST_AND_INSERT(tedge_v1(v->routingedge)); } if(ARC_CHECKS(tedge_v2(v->routingedge)) ){ /* edge v2 is not the centre of an arc terminal */ d = check_intersect_vertex(x0, y0, x1, y1, v, tedge_v2(v->routingedge), tedge_v1(v->routingedge), v2wind, &arcwind, &arcr, debug); TEST_AND_INSERT(tedge_v2(v->routingedge)); } }else{ /* edge is on one side of the segment */ if(ARC_CHECKS(tedge_v1(v->routingedge)) ){ /* edge v1 is not the centre of an arc terminal */ d = check_non_intersect_vertex(x0, y0, x1, y1, v, tedge_v1(v->routingedge), tedge_v2(v->routingedge), v1wind, &arcwind, &arcr, debug); TEST_AND_INSERT(tedge_v1(v->routingedge)); } if(ARC_CHECKS(tedge_v2(v->routingedge)) ){ /* edge v2 is not the centre of an arc terminal */ d = check_non_intersect_vertex(x0, y0, x1, y1, v, tedge_v2(v->routingedge), tedge_v1(v->routingedge), v2wind, &arcwind, &arcr, debug); TEST_AND_INSERT(tedge_v2(v->routingedge)); } } i = i->next; } arcs = g_list_sort(arcs, (GCompareFunc) compare_rubberband_arcs); //rubberband_insert_maxarc: if(!arcs) return NULL; max = TOPOROUTER_RUBBERBAND_ARC(arcs->data); av2 = max->pathv; i = max->list->next; while(i) { toporouter_vertex_t *v = TOPOROUTER_VERTEX(i->data); if(v->routingedge && (tedge_v1(v->routingedge) == max->arcv || tedge_v2(v->routingedge) == max->arcv)) { av2 = v; i = i->next; continue; } break; } av1 = max->pathv; i = max->list->prev; while(i) { toporouter_vertex_t *v = TOPOROUTER_VERTEX(i->data); if(v->routingedge && (tedge_v1(v->routingedge) == max->arcv || tedge_v2(v->routingedge) == max->arcv)) { av1 = v; i = i->prev; continue; } break; } //#ifdef DEBUG_RUBBERBAND if(debug) printf("newarc @ %f,%f \t v1 = %f,%f v2 = %f,%f r = %f\n", vx(max->arcv), vy(max->arcv), vx(av1), vy(av1), vx(av2), vy(av2), max->r); //#endif newarc = toporouter_arc_new(oproute, av1, av2, max->arcv, max->r, max->wind); if(TOPOROUTER_IS_VERTEX(t1)) calculate_term_to_arc(TOPOROUTER_VERTEX(t1), newarc, 0); else if(calculate_arc_to_arc(r, TOPOROUTER_ARC(t1), newarc)) { printf("\tERROR: best: r = %f d = %f\n", max->r, max->d); printf("\tOPROUTE: %s\n", oproute->netlist); print_vertex(oproute->term1); print_vertex(oproute->term2); return NULL; } if(TOPOROUTER_IS_VERTEX(t2)) calculate_term_to_arc(TOPOROUTER_VERTEX(t2), newarc, 1); else if(calculate_arc_to_arc(r, newarc, TOPOROUTER_ARC(t2))) { printf("\tERROR: best: r = %f d = %f\n", max->r, max->d); printf("\tOPROUTE: %s\n", oproute->netlist); print_vertex(oproute->term1); print_vertex(oproute->term2); return NULL; } //if(check_arc_for_loops(t1, newarc, t2)) { // if(arc1 && arc2) calculate_arc_to_arc(r, arc1, arc2); // else if(arc1) calculate_term_to_arc(TOPOROUTER_VERTEX(t2), arc1, 1); // else if(arc2) calculate_term_to_arc(TOPOROUTER_VERTEX(t1), arc2, 0); //#ifdef DEBUG_RUBBERBAND // printf("REMOVING NEW ARC @ %f,%f\n", vx(newarc->centre), vy(newarc->centre)); // //TODO: properly remove newarc //#endif // arcs = g_list_remove(arcs, max); // free(max); // goto rubberband_insert_maxarc; //} list1 = oproute_rubberband_segment(r, oproute, path, t1, newarc, debug); list2 = oproute_rubberband_segment(r, oproute, i->next, newarc, t2, debug); if(list1) { GList *list = g_list_last(list1); toporouter_arc_t *testarc = TOPOROUTER_ARC(list->data); toporouter_arc_t *parc = list->prev ? TOPOROUTER_ARC(list->prev->data) : arc1; gdouble px = parc ? parc->x1 : vx(TOPOROUTER_VERTEX(t1)), py = parc ? parc->y1 : vy(TOPOROUTER_VERTEX(t1)); if(coord_intersect_prop(px, py, testarc->x0, testarc->y0, testarc->x1, testarc->y1, newarc->x0, newarc->y0)) { list1 = g_list_remove(list1, testarc); if(parc) calculate_arc_to_arc(r, parc, newarc); else calculate_term_to_arc(TOPOROUTER_VERTEX(t1), newarc, 0); //#ifdef DEBUG_RUBBERBAND if(debug) printf("REMOVING ARC @ %f,%f\n", vx(testarc->centre), vy(testarc->centre)); //#endif } } if(list2) { toporouter_arc_t *testarc = TOPOROUTER_ARC(list2->data); toporouter_arc_t *narc = list2->next ? TOPOROUTER_ARC(list2->next->data) : arc2; gdouble nx = narc ? narc->x0 : vx(TOPOROUTER_VERTEX(t2)), ny = narc ? narc->y0 : vy(TOPOROUTER_VERTEX(t2)); if(coord_intersect_prop(newarc->x1, newarc->y1, testarc->x0, testarc->y0, testarc->x1, testarc->y1, nx, ny)) { list2 = g_list_remove(list2, testarc); if(narc) calculate_arc_to_arc(r, newarc, narc); else calculate_term_to_arc(TOPOROUTER_VERTEX(t2), newarc, 1); //#ifdef DEBUG_RUBBERBAND if(debug) printf("REMOVING ARC @ %f,%f\n", vx(testarc->centre), vy(testarc->centre)); //#endif } } g_list_foreach(arcs, free_list_elements, NULL); g_list_free(arcs); return g_list_concat(list1, g_list_prepend(list2, newarc)); } void oproute_check_all_loops(toporouter_t *r, toporouter_oproute_t *oproute) { GList *i; gpointer t1; loopcheck_restart: t1 = oproute->term1; i = oproute->arcs; while(i) { toporouter_arc_t *arc = TOPOROUTER_ARC(i->data); gpointer t2 = i->next ? i->next->data : oproute->term2; if(check_arc_for_loops(t1, arc, t2)) { if(TOPOROUTER_IS_ARC(t1) && TOPOROUTER_IS_ARC(t2)) calculate_arc_to_arc(r, TOPOROUTER_ARC(t1), TOPOROUTER_ARC(t2)); else if(TOPOROUTER_IS_ARC(t1)) calculate_term_to_arc(TOPOROUTER_VERTEX(t2), TOPOROUTER_ARC(t1), 1); else if(TOPOROUTER_IS_ARC(t2)) calculate_term_to_arc(TOPOROUTER_VERTEX(t1), TOPOROUTER_ARC(t2), 0); oproute->arcs = g_list_remove(oproute->arcs, arc); goto loopcheck_restart; } t1 = arc; i = i->next; } } GtsTriangle * opposite_triangle(GtsTriangle *t, toporouter_edge_t *e) { GSList *i = GTS_EDGE(e)->triangles; g_assert(e && t); while(i) { if(GTS_TRIANGLE(i->data) != t) return GTS_TRIANGLE(i->data); i = i->next; } return NULL; } void speccut_edge_routing_from_edge(GList *i, toporouter_edge_t *e) { g_assert(TOPOROUTER_IS_EDGE(e)); while(i) { toporouter_vertex_t *curv = TOPOROUTER_VERTEX(i->data); if(!(curv->flags & VERTEX_FLAG_TEMP)) { toporouter_vertex_t *newv = tvertex_intersect(curv, curv->parent, tedge_v1(e), tedge_v2(e)); // printf("\nCURV:\n"); // print_vertex(curv); // // printf("CURV child:\n"); // if(curv->child) // print_vertex(curv->child); // else // printf("NULL\n"); // // printf("CURV parent:\n"); // if(curv->parent) // print_vertex(curv->parent); // else // printf("NULL\n"); if(newv) { gint index; newv->flags |= VERTEX_FLAG_ROUTE; newv->flags |= VERTEX_FLAG_SPECCUT; e->routing = g_list_insert_sorted_with_data(e->routing, newv, routing_edge_insert, e); newv->route = curv->route; newv->oproute = curv->oproute; newv->routingedge = e; GTS_POINT(newv)->z = vz(curv); newv->parent = curv->parent; newv->child = curv; // curv->parent = newv; index = g_list_index(newv->route->path, curv); newv->route->path = g_list_insert(newv->route->path, newv, index); if(newv->oproute) newv->oproute->path = newv->route->path; } if(!(curv->child->routingedge)) { newv = tvertex_intersect(curv, curv->child, tedge_v1(e), tedge_v2(e)); if(newv) { gint index; newv->flags |= VERTEX_FLAG_ROUTE; newv->flags |= VERTEX_FLAG_SPECCUT; e->routing = g_list_insert_sorted_with_data(e->routing, newv, routing_edge_insert, e); newv->route = curv->route; newv->oproute = curv->oproute; newv->routingedge = e; GTS_POINT(newv)->z = vz(curv); newv->parent = curv; newv->child = curv->child; // curv->child = newv; index = g_list_index(newv->route->path, curv); newv->route->path = g_list_insert(newv->route->path, newv, index+1); if(newv->oproute) newv->oproute->path = newv->route->path; } } } i = i->next; } } void speccut_edge_patch_links(toporouter_edge_t *e) { GList *i = e->routing; g_assert(TOPOROUTER_IS_EDGE(e)); while(i) { toporouter_vertex_t *v = TOPOROUTER_VERTEX(i->data); v->parent->child = v; v->child->parent = v; i = i->next; } } gint check_speccut(toporouter_oproute_t *oproute, toporouter_vertex_t *v1, toporouter_vertex_t *v2, toporouter_edge_t *e, toporouter_edge_t *e1, toporouter_edge_t *e2) { GtsTriangle *t, *opt; toporouter_vertex_t *opv, *opv2; toporouter_edge_t *ope1, *ope2; gdouble cap, flow, line_int_x, line_int_y; if(TOPOROUTER_IS_CONSTRAINT(e)) return 0; if(!(t = gts_triangle_use_edges(GTS_EDGE(e), GTS_EDGE(e1), GTS_EDGE(e2)))) { printf("check_speccut: NULL t\n"); return 0; } if(!(opt = opposite_triangle(t, e))) { // printf("check_speccut: NULL opt\n"); return 0; } if(!(opv = segment_common_vertex(GTS_SEGMENT(e1), GTS_SEGMENT(e2)))) { printf("check_speccut: NULL opv\n"); return 0; } if(!(opv2 = TOPOROUTER_VERTEX(gts_triangle_vertex_opposite(opt, GTS_EDGE(e))))) { printf("check_speccut: NULL opv2\n"); return 0; } //TODO: shifting it out of the way would be better if(e->routing) { GList *i = e->routing; while(i) { toporouter_vertex_t *ev = TOPOROUTER_VERTEX(i->data); if(!tvertex_wind(opv, ev, opv2)) return 0; i = i->next; } } ope1 = tedge(opv2, tedge_v1(e)); ope2 = tedge(opv2, tedge_v2(e)); //this fixes the weird pad exits in r8c board // if(TOPOROUTER_IS_CONSTRAINT(ope1)) return 0; if(TOPOROUTER_IS_CONSTRAINT(ope2)) return 0; if(!tvertex_wind(opv2, tedge_v1(e), opv)) return 0; if(!tvertex_wind(opv2, tedge_v2(e), opv)) return 0; if(!vertex_line_normal_intersection( vx(tedge_v1(e)), vy(tedge_v1(e)), vx(tedge_v2(e)), vy(tedge_v2(e)), vx(opv2), vy(opv2), &line_int_x, &line_int_y)) return 0; // return 0; //if(vertex_line_normal_intersection(tev1x(e), tev1y(e), tev2x(e), tev2y(e), vx(opv), vy(opv), &line_int_x, &line_int_y)) // return 0; g_assert(opt && opv2); /* this is just temp, for the purposes of determining flow */ if(tedge_v1(ope1) == opv2) { if(TOPOROUTER_IS_CONSTRAINT(ope1)) TOPOROUTER_CONSTRAINT(ope1)->routing = g_list_append(TOPOROUTER_CONSTRAINT(ope1)->routing, v1); else ope1->routing = g_list_append(ope1->routing, v1); }else{ if(TOPOROUTER_IS_CONSTRAINT(ope1)) TOPOROUTER_CONSTRAINT(ope1)->routing = g_list_prepend(TOPOROUTER_CONSTRAINT(ope1)->routing, v1); else ope1->routing = g_list_prepend(ope1->routing, v1); } cap = triangle_interior_capacity(opt, opv2); flow = flow_from_edge_to_edge(opt, tedge(opv2, tedge_v1(e)), tedge(opv2, tedge_v2(e)), opv2, v1); /* temp v1 removed */ if(TOPOROUTER_IS_CONSTRAINT(ope1)) TOPOROUTER_CONSTRAINT(ope1)->routing = g_list_remove(TOPOROUTER_CONSTRAINT(ope1)->routing, v1); else ope1->routing = g_list_remove(ope1->routing, v1); if(flow >= cap) { toporouter_edge_t *newe = TOPOROUTER_EDGE(gts_edge_new(GTS_EDGE_CLASS(toporouter_edge_class()), GTS_VERTEX(opv), GTS_VERTEX(opv2))); speccut_edge_routing_from_edge(edge_routing(e1), newe); speccut_edge_routing_from_edge(edge_routing(e2), newe); speccut_edge_routing_from_edge(edge_routing(ope1), newe); speccut_edge_routing_from_edge(edge_routing(ope2), newe); speccut_edge_patch_links(newe); /* printf("SPECCUT WITH v %f,%f for seg %f,%f %f,%f detected\n", vx(opv2), vy(opv2), vx(v1), vy(v1), vx(v2), vy(v2)); printf("\tflow %f cap %f\n", flow, cap); print_edge(newe); */ if(newe->routing) return 1; } return 0; } gint oproute_path_speccut(toporouter_oproute_t *oproute) { GList *i; toporouter_vertex_t *pv; path_speccut_restart: i = oproute->path; pv = NULL; while(i) { toporouter_vertex_t *v = TOPOROUTER_VERTEX(i->data); if(pv && (v->routingedge || pv->routingedge) && !(pv->flags & VERTEX_FLAG_SPECCUT) && !(v->flags & VERTEX_FLAG_SPECCUT)) { if(!v->routingedge) { if(check_speccut(oproute, pv, v, tedge(tedge_v1(pv->routingedge), v), pv->routingedge, tedge(tedge_v2(pv->routingedge), v))) goto path_speccut_restart; if(check_speccut(oproute, pv, v, tedge(tedge_v2(pv->routingedge), v), pv->routingedge, tedge(tedge_v1(pv->routingedge), v))) goto path_speccut_restart; }else if(!pv->routingedge) { if(check_speccut(oproute, v, pv, tedge(tedge_v1(v->routingedge), pv), v->routingedge, tedge(tedge_v2(v->routingedge), pv))) goto path_speccut_restart; if(check_speccut(oproute, v, pv, tedge(tedge_v2(v->routingedge), pv), v->routingedge, tedge(tedge_v1(v->routingedge), pv))) goto path_speccut_restart; }else{ toporouter_vertex_t *v1 = NULL, *v2 = NULL; edges_third_edge(GTS_SEGMENT(v->routingedge), GTS_SEGMENT(pv->routingedge), &v1, &v2); if(check_speccut(oproute, v, pv, tedge(v1, v2), v->routingedge, pv->routingedge)) goto path_speccut_restart; } } pv = v; i = i->next; } return 0; } toporouter_oproute_t * oproute_rubberband(toporouter_t *r, GList *path) { toporouter_oproute_t *oproute = (toporouter_oproute_t *)malloc(sizeof(toporouter_oproute_t)); g_assert(path); oproute->term1 = TOPOROUTER_VERTEX(path->data); oproute->term2 = TOPOROUTER_VERTEX(g_list_last(path)->data); oproute->arcs = NULL; oproute->style = vertex_bbox(oproute->term1)->cluster->netlist->style; oproute->netlist = vertex_bbox(oproute->term1)->cluster->netlist->netlist; oproute->layergroup = vz(oproute->term1); oproute->path = path; oproute->serp = NULL; oproute->term1->parent = NULL; oproute->term2->child = NULL; path_set_oproute(path, oproute); // if(!strcmp(oproute->netlist, " unnamed_net1")) oproute_path_speccut(oproute); #ifdef DEBUG_RUBBERBAND if(strcmp(oproute->netlist, " VCC3V3" == 0) && vx(oproute->term1) == MIL_TO_COORD (957.) && vy(oproute->term1) == MIL_TO_COORD (708.) && vx(oproute->term2) == MIL_TO_COORD (1967.) && vy(oproute->term2) == MIL_TO_COORD (673.)) { // printf("OPROUTE %s - %f,%f %f,%f\n", oproute->netlist, vx(oproute->term1), vy(oproute->term1), vx(oproute->term2), vy(oproute->term2)); // print_path(path); oproute->arcs = oproute_rubberband_segment(r, oproute, path, oproute->term1, oproute->term2, 1); }else #endif oproute->arcs = oproute_rubberband_segment(r, oproute, path, oproute->term1, oproute->term2, 0); oproute_check_all_loops(r, oproute); return oproute; } void toporouter_export(toporouter_t *r) { GList *i = r->routednets; GList *oproutes = NULL; while(i) { toporouter_route_t *routedata = TOPOROUTER_ROUTE(i->data); toporouter_oproute_t *oproute = oproute_rubberband(r, routedata->path); oproutes = g_list_prepend(oproutes, oproute); i = i->next; } i = oproutes; while(i) { toporouter_oproute_t *oproute = (toporouter_oproute_t *) i->data; export_oproutes(r, oproute); oproute_free(oproute); i = i->next; } Message (_("Reticulating splines... successful\n\n")); /* NB: We could use the %$mS specifier to print these distances, but we would * have to cast to Coord, which might overflow for complex routing when * PCB is built with Coord as a 32-bit integer. */ Message (_("Wiring cost: %f inches\n"), COORD_TO_INCH (r->wiring_score)); printf (_("Wiring cost: %f inches\n"), COORD_TO_INCH (r->wiring_score)); g_list_free(oproutes); } toporouter_route_t * routedata_create(void) { toporouter_route_t *routedata = (toporouter_route_t *)malloc(sizeof(toporouter_route_t)); routedata->netlist = NULL; routedata->alltemppoints = NULL; routedata->path = NULL; routedata->curpoint = NULL; routedata->pscore = routedata->score = 0.; routedata->flags = 0; routedata->src = routedata->dest = NULL; routedata->psrc = routedata->pdest = NULL; routedata->ppath = routedata->topopath = NULL; routedata->ppathindices = NULL; routedata->destvertices = routedata->srcvertices = NULL; return routedata; } /* void print_routedata(toporouter_route_t *routedata) { GList *srcvertices = cluster_vertices(routedata->src); GList *destvertices = cluster_vertices(routedata->dest); printf("ROUTEDATA:\n"); printf("SRCVERTICES:\n"); print_vertices(srcvertices); printf("DESTVERTICES:\n"); print_vertices(destvertices); g_list_free(srcvertices); g_list_free(destvertices); }*/ toporouter_route_t * import_route(toporouter_t *r, RatType *line) { toporouter_route_t *routedata = routedata_create(); routedata->src = cluster_find(r, line->Point1.X, line->Point1.Y, line->group1); routedata->dest = cluster_find(r, line->Point2.X, line->Point2.Y, line->group2); if(!routedata->src) printf("couldn't locate src\n"); if(!routedata->dest) printf("couldn't locate dest\n"); if(!routedata->src || !routedata->dest) { pcb_printf("PROBLEM: couldn't locate rat src or dest for rat %#mD, %d -> %#mD, %d\n", line->Point1.X, line->Point1.Y, line->group1, line->Point2.X, line->Point2.Y, line->group2); free(routedata); return NULL; } routedata->netlist = routedata->src->netlist; g_assert(routedata->src->netlist == routedata->dest->netlist); g_ptr_array_add(r->routes, routedata); g_ptr_array_add(routedata->netlist->routes, routedata); r->failednets = g_list_prepend(r->failednets, routedata); return routedata; } void delete_route(toporouter_route_t *routedata, guint destroy) { GList *i = routedata->path; toporouter_vertex_t *pv = NULL; while(i) { toporouter_vertex_t *tv = TOPOROUTER_VERTEX(i->data); g_assert(tv); if(tv && pv && !(tv->flags & VERTEX_FLAG_ROUTE) && !(pv->flags & VERTEX_FLAG_ROUTE)) { toporouter_edge_t *e = TOPOROUTER_EDGE(gts_vertices_are_connected(GTS_VERTEX(tv), GTS_VERTEX(pv))); if(e && (e->flags & EDGE_FLAG_DIRECTCONNECTION)) { e->flags ^= EDGE_FLAG_DIRECTCONNECTION; } } pv = tv; i = i->next; } i = routedata->path; while(i) { toporouter_vertex_t *tv = TOPOROUTER_VERTEX(i->data); tv->parent = NULL; tv->child = NULL; if(tv->routingedge) { if(TOPOROUTER_IS_CONSTRAINT(tv->routingedge)) TOPOROUTER_CONSTRAINT(tv->routingedge)->routing = g_list_remove(TOPOROUTER_CONSTRAINT(tv->routingedge)->routing, tv); else tv->routingedge->routing = g_list_remove(tv->routingedge->routing, tv); if(destroy) gts_object_destroy ( GTS_OBJECT(tv) ); } i = i->next; } if(routedata->path) g_list_free(routedata->path); routedata->path = NULL; routedata->curpoint = NULL; routedata->score = INFINITY; routedata->alltemppoints = NULL; } /*! * \brief Remove route can be later reapplied. */ void remove_route(GList *path) { GList *i = path; while(i) { toporouter_vertex_t *tv = TOPOROUTER_VERTEX(i->data); tv->parent = NULL; tv->child = NULL; // if(tv->flags & VERTEX_FLAG_ROUTE) g_assert(tv->route == routedata); if(tv->routingedge) { if(TOPOROUTER_IS_CONSTRAINT(tv->routingedge)) TOPOROUTER_CONSTRAINT(tv->routingedge)->routing = g_list_remove(TOPOROUTER_CONSTRAINT(tv->routingedge)->routing, tv); else tv->routingedge->routing = g_list_remove(tv->routingedge->routing, tv); } i = i->next; } } gint apply_route(GList *path, toporouter_route_t *routedata) { GList *i = path; toporouter_vertex_t *pv = NULL; gint count = 0; if(!path) return 0; // g_assert(path); while(i) { toporouter_vertex_t *tv = TOPOROUTER_VERTEX(i->data); if(tv->routingedge) { if(TOPOROUTER_IS_CONSTRAINT(tv->routingedge)) TOPOROUTER_CONSTRAINT(tv->routingedge)->routing = g_list_insert_sorted_with_data( TOPOROUTER_CONSTRAINT(tv->routingedge)->routing, tv, routing_edge_insert, tv->routingedge); else tv->routingedge->routing = g_list_insert_sorted_with_data( tv->routingedge->routing, tv, routing_edge_insert, tv->routingedge); count++; } if(pv) { pv->child = tv; tv->parent = pv; } if(tv->flags & VERTEX_FLAG_ROUTE) g_assert(tv->route == routedata); pv = tv; i = i->next; } TOPOROUTER_VERTEX(path->data)->parent = NULL; pv->child = NULL; return count; } gint compare_routedata_ascending(gconstpointer a, gconstpointer b) { toporouter_route_t *ra = (toporouter_route_t *)a; toporouter_route_t *rb = (toporouter_route_t *)b; return ra->score - rb->score; } void print_costmatrix(gdouble *m, guint n) { printf("COST MATRIX:\n"); for(guint i = 0;iid = id; netscore->routedata = routedata; routedata->detourscore = netscore->score = routedata->score; if(!isfinite(routedata->detourscore)) { printf("WARNING: !isfinite(detourscore)\n"); print_cluster(routedata->src); print_cluster(routedata->dest); return NULL; } netscore->pairwise_nodetour = (guint *)malloc(n * sizeof(guint)); for(guint i=0;ipairwise_nodetour[i] = 0; } netscore->pairwise_detour_sum = 0.; netscore->pairwise_fails = 0; netscore->r = r; if(path) { routedata->topopath = g_list_copy(routedata->path); delete_route(routedata, 0); } return netscore; } static inline void netscore_destroy(toporouter_netscore_t *netscore) { free(netscore->pairwise_nodetour); free(netscore); } void print_netscores(GPtrArray* netscores) { printf("NETSCORES: \n\n"); printf(" %15s %15s %15s\n----------------------------------------------------\n", "Score", "Detour Sum", "Pairwise Fails"); for(toporouter_netscore_t **i = (toporouter_netscore_t **) netscores->pdata; i < (toporouter_netscore_t **) netscores->pdata + netscores->len; i++) { #ifdef DEBUG_NETSCORES printf("%4d %15f %15f %15d %15x\n", (*i)->id, (*i)->score, (*i)->pairwise_detour_sum, (*i)->pairwise_fails, (guint)*i); #endif } printf("\n"); } void netscore_pairwise_calculation(toporouter_netscore_t *netscore, GPtrArray *netscores) { toporouter_netscore_t **netscores_base = (toporouter_netscore_t **) (netscores->pdata); toporouter_route_t *temproutedata = routedata_create(); //route(netscore->r, netscore->routedata, 0); apply_route(netscore->routedata->topopath, netscore->routedata); for(toporouter_netscore_t **i = netscores_base; i < netscores_base + netscores->len; i++) { if(!netscore->pairwise_nodetour[i-netscores_base] && *i != netscore && (*i)->routedata->netlist != netscore->routedata->netlist) { temproutedata->src = (*i)->routedata->src; temproutedata->dest = (*i)->routedata->dest; route(netscore->r, temproutedata, 0); if(temproutedata->score == (*i)->score) { netscore->pairwise_nodetour[i-netscores_base] = 1; (*i)->pairwise_nodetour[netscore->id] = 1; }else if(!isfinite(temproutedata->score)) { netscore->pairwise_fails += 1; }else{ netscore->pairwise_detour_sum += temproutedata->score - (*i)->score; } delete_route(temproutedata, 1); } } // delete_route(netscore->routedata, 1); remove_route(netscore->routedata->topopath); free(temproutedata); } gint netscore_pairwise_size_compare(toporouter_netscore_t **a, toporouter_netscore_t **b) { // infinite scores are last if(!isfinite((*a)->score) && !isfinite((*b)->score)) return 0; if(isfinite((*a)->score) && !isfinite((*b)->score)) return -1; if(isfinite((*b)->score) && !isfinite((*a)->score)) return 1; // order by pairwise fails if((*a)->pairwise_fails < (*b)->pairwise_fails) return -1; if((*b)->pairwise_fails < (*a)->pairwise_fails) return 1; // order by pairwise detour if((*a)->pairwise_detour_sum < (*b)->pairwise_detour_sum) return -1; if((*b)->pairwise_detour_sum < (*a)->pairwise_detour_sum) return 1; // order by score if((*a)->score < (*b)->score) return -1; if((*b)->score < (*a)->score) return 1; return 0; } gint netscore_pairwise_compare(toporouter_netscore_t **a, toporouter_netscore_t **b) { // infinite scores are last if(!isfinite((*a)->score) && !isfinite((*b)->score)) return 0; if(isfinite((*a)->score) && !isfinite((*b)->score)) return -1; if(isfinite((*b)->score) && !isfinite((*a)->score)) return 1; // order by pairwise fails if((*a)->pairwise_fails < (*b)->pairwise_fails) return -1; if((*b)->pairwise_fails < (*a)->pairwise_fails) return 1; // order by pairwise detour if((*a)->pairwise_detour_sum < (*b)->pairwise_detour_sum) return -1; if((*b)->pairwise_detour_sum < (*a)->pairwise_detour_sum) return 1; return 0; } guint order_nets_preroute_greedy(toporouter_t *r, GList *nets, GList **rnets) { gint len = g_list_length(nets); GPtrArray* netscores = g_ptr_array_sized_new(len); guint failcount = 0; while(nets) { toporouter_netscore_t *ns = netscore_create(r, TOPOROUTER_ROUTE(nets->data), len, failcount++); if(ns) g_ptr_array_add(netscores, ns); nets = nets->next; } failcount = 0; g_ptr_array_foreach(netscores, (GFunc) netscore_pairwise_calculation, netscores); g_ptr_array_sort(netscores, (GCompareFunc) r->netsort); #ifdef DEBUG_ORDERING print_netscores(netscores); #endif *rnets = NULL; FOREACH_NETSCORE(netscores) { *rnets = g_list_prepend(*rnets, netscore->routedata); if(!isfinite(netscore->score)) failcount++; netscore_destroy(netscore); } FOREACH_END; g_ptr_array_free(netscores, TRUE); return failcount; } toporouter_vertex_t * edge_closest_vertex(toporouter_edge_t *e, toporouter_vertex_t *v) { GList *i = v->routingedge ? edge_routing(v->routingedge) : NULL; gdouble closestd = 0.; toporouter_vertex_t *closestv = NULL; while(i) { toporouter_vertex_t *ev = TOPOROUTER_VERTEX(i->data); gdouble tempd = gts_point_distance2(GTS_POINT(ev), GTS_POINT(v)); if(!closestv || (tempd < closestd)) { closestd = tempd; closestv = ev; } i = i->next; } return closestv; } void snapshot(toporouter_t *r, char *name, GList *datas) { ///* { int i; for(i=0;ilayers[i].surface, buffer, 2048, 2048, 2, datas, i, NULL); } } //*/ } /* gdouble route_conflict(toporouter_t *r, toporouter_route_t *route, guint *n) { GList *i = route->path; toporouter_vertex_t *pv = NULL; gdouble cost = 0.; while(i) { toporouter_vertex_t *v = TOPOROUTER_VERTEX(i->data); if(pv && vz(v) == vz(pv)) cost += vertices_routing_conflict_cost(r, v, pv, n); pv = v; i = i->next; } return cost; } */ GList * route_conflicts(toporouter_route_t *route) { GList *conflicts = NULL, *i = route->path; toporouter_vertex_t *pv = NULL; while(i) { toporouter_vertex_t *v = TOPOROUTER_VERTEX(i->data); if(pv && vz(pv) == vz(v)) { GList *temp = vertices_routing_conflicts(pv, v), *j; j = temp; while(j) { toporouter_route_t *conroute = TOPOROUTER_ROUTE(j->data); if(!g_list_find(conflicts, conroute)) conflicts = g_list_prepend(conflicts, conroute); j = j->next; } if(temp) g_list_free(temp); } pv = v; i = i->next; } return conflicts; } gint spread_edge(gpointer item, gpointer data) { toporouter_edge_t *e = TOPOROUTER_EDGE(item); toporouter_vertex_t *v; gdouble spacing, s; GList *i; if(TOPOROUTER_IS_CONSTRAINT(e)) return 0; i = edge_routing(e); if(!g_list_length(i)) return 0; if(g_list_length(i) == 1) { v = TOPOROUTER_VERTEX(i->data); GTS_POINT(v)->x = (vx(edge_v1(e)) + vx(edge_v2(e))) / 2.; GTS_POINT(v)->y = (vy(edge_v1(e)) + vy(edge_v2(e))) / 2.; return 0; } s = spacing = (gts_point_distance(GTS_POINT(edge_v1(e)), GTS_POINT(edge_v2(e))) ) / (g_list_length(i) + 1); while(i) { v = TOPOROUTER_VERTEX(i->data); vertex_move_towards_vertex_values(edge_v1(e), edge_v2(e), s, &(GTS_POINT(v)->x), &(GTS_POINT(v)->y)); s += spacing; i = i->next; } return 0; } void route_checkpoint(toporouter_route_t *route, toporouter_route_t *temproute) { GList *i = g_list_last(route->path); gint n = g_list_length(route->path); if(route->ppathindices) free(route->ppathindices); route->ppathindices = (gint *)malloc(sizeof(gint)*n); // n = 0; while(i) { toporouter_vertex_t *v = TOPOROUTER_VERTEX(i->data); n--; if(v->routingedge) { GList *j = g_list_find(edge_routing(v->routingedge), v)->prev; gint tempindex = g_list_index(edge_routing(v->routingedge), v); while(j) { if(TOPOROUTER_VERTEX(j->data)->route == temproute) tempindex--; j = j->prev; } route->ppathindices[n] = tempindex; if(TOPOROUTER_IS_CONSTRAINT(v->routingedge)) TOPOROUTER_CONSTRAINT(v->routingedge)->routing = g_list_remove(TOPOROUTER_CONSTRAINT(v->routingedge)->routing, v); else v->routingedge->routing = g_list_remove(v->routingedge->routing, v); } i = i->prev; } route->pscore = route->score; route->ppath = route->path; remove_route(route->path); route->path = NULL; route->psrc = route->src; route->pdest = route->dest; //route->src->pc = route->src->c; //route->dest->pc = route->dest->c; } void route_restore(toporouter_route_t *route) { GList *i; toporouter_vertex_t *pv = NULL; gint n = 0; g_assert(route->ppath); g_assert(route->ppathindices); route->path = route->ppath; i = route->ppath; while(i) { toporouter_vertex_t *v = TOPOROUTER_VERTEX(i->data); if(v->routingedge) { if(TOPOROUTER_IS_CONSTRAINT(v->routingedge)) TOPOROUTER_CONSTRAINT(v->routingedge)->routing = g_list_insert(TOPOROUTER_CONSTRAINT(v->routingedge)->routing, v, route->ppathindices[n]); else v->routingedge->routing = g_list_insert(v->routingedge->routing, v, route->ppathindices[n]); // space_edge(v->routingedge, NULL); } if(pv) { pv->child = v; v->parent = pv; } n++; pv = v; i = i->next; } route->score = route->pscore; route->src = route->psrc; route->dest = route->pdest; //route->src->c = route->src->pc; //route->dest->c = route->dest->pc; } void cluster_merge(toporouter_route_t *routedata) { gint oldc = routedata->dest->c, newc = routedata->src->c; FOREACH_CLUSTER(routedata->netlist->clusters) { if(cluster->c == oldc) cluster->c = newc; } FOREACH_END; } void netlist_recalculate(toporouter_netlist_t *netlist, GList *ignore) { GList *i = g_list_last(netlist->routed); gint n = netlist->clusters->len-1; FOREACH_CLUSTER(netlist->clusters) { cluster->c = n--; } FOREACH_END; while(i) { if(!ignore || !g_list_find(ignore, i->data)) cluster_merge(TOPOROUTER_ROUTE(i->data)); i = i->prev; } } void netlists_recalculate(GList *netlists, GList *ignore) { GList *i = netlists; while(i) { netlist_recalculate(TOPOROUTER_NETLIST(i->data), ignore); i = i->next; } } void netlists_rollback(GList *netlists) { // netlists_recalculate(netlists, NULL); while(netlists) { toporouter_netlist_t *netlist = TOPOROUTER_NETLIST(netlists->data); FOREACH_CLUSTER(netlist->clusters) { cluster->c = cluster->pc; } FOREACH_END; netlists = netlists->next; } } void print_netlist(toporouter_netlist_t *netlist) { printf("NETLIST %s: ", netlist->netlist); FOREACH_CLUSTER(netlist->clusters) { printf("%d ", cluster->c); } FOREACH_END; printf("\n"); } #define REMOVE_ROUTING(x) x->netlist->routed = g_list_remove(x->netlist->routed, x); \ r->routednets = g_list_remove(r->routednets, x); \ r->failednets = g_list_prepend(r->failednets, x) #define INSERT_ROUTING(x) x->netlist->routed = g_list_prepend(x->netlist->routed, x); \ r->routednets = g_list_prepend(r->routednets, x); \ r->failednets = g_list_remove(r->failednets, x) gint roar_route(toporouter_t *r, toporouter_route_t *routedata, gint threshold) { gint intfails = 0; GList *netlists = NULL, *routed = NULL; g_assert(!routedata->path); if(routedata->src->c == routedata->dest->c) { printf("ERROR: attempt to route already complete route\n"); g_assert(routedata->src->c != routedata->dest->c); } routedata->src->pc = routedata->src->c; routedata->dest->pc = routedata->dest->c; routedata->psrc = routedata->src; routedata->pdest = routedata->dest; r->flags |= TOPOROUTER_FLAG_LEASTINVALID; if(route(r, routedata, 0)) { GList *conflicts, *j; INSERT_ROUTING(routedata); conflicts = route_conflicts(routedata); cluster_merge(routedata); r->flags &= ~TOPOROUTER_FLAG_LEASTINVALID; j = conflicts; while(j) { toporouter_route_t *conflict = TOPOROUTER_ROUTE(j->data); if(!g_list_find(netlists, conflict->netlist)) netlists = g_list_prepend(netlists, conflict->netlist); route_checkpoint(conflict, routedata); REMOVE_ROUTING(conflict); j = j->next; } netlists = g_list_prepend(netlists, routedata->netlist); netlists_recalculate(netlists, NULL); j = conflicts; while(j) { toporouter_route_t *conflict = TOPOROUTER_ROUTE(j->data); g_assert(conflict->src->c != conflict->dest->c); if(route(r, conflict, 0)) { cluster_merge(conflict); routed = g_list_prepend(routed, conflict); INSERT_ROUTING(conflict); netlist_recalculate(conflict->netlist, NULL); }else{ if(++intfails >= threshold) { GList *i = routed; while(i) { toporouter_route_t *intconflict = TOPOROUTER_ROUTE(i->data); REMOVE_ROUTING(intconflict); delete_route(intconflict, 1); i = i->next; } delete_route(routedata, 1); i = g_list_last(conflicts); while(i) { toporouter_route_t *intconflict = TOPOROUTER_ROUTE(i->data); route_restore(intconflict); INSERT_ROUTING(intconflict); i = i->prev; } REMOVE_ROUTING(routedata); intfails = 0; netlists_recalculate(netlists, NULL); goto roar_route_end; } } j = j->next; } netlists_recalculate(netlists, NULL); intfails--; roar_route_end: g_list_free(conflicts); g_list_free(netlists); }else{ r->flags &= ~TOPOROUTER_FLAG_LEASTINVALID; } g_list_free(routed); return intfails; } gint roar_router(toporouter_t *r, gint failcount, gint threshold) { gint pfailcount = failcount +1; Message(_("ROAR router: ")); for(guint j=0;j<6;j++) { GList *failed = g_list_copy(r->failednets), *k = failed; k = failed; while(k) { failcount += roar_route(r, TOPOROUTER_ROUTE(k->data), threshold); k = k->next; } g_list_free(failed); printf("\tROAR pass %d - %d routed - %d failed\n", j, g_list_length(r->routednets), g_list_length(r->failednets)); if(!failcount || failcount >= pfailcount) { Message(_("%d nets remaining\n"), failcount); break; } Message(_("%d -> "), failcount); pfailcount = failcount; } return failcount; } gint route_detour_compare(toporouter_route_t **a, toporouter_route_t **b) { return ((*b)->score - (*b)->detourscore) - ((*a)->score - (*a)->detourscore); } void roar_detour_route(toporouter_t *r, toporouter_route_t *data) { gdouble pscore = data->score, nscore = 0.; GList *netlists = NULL; route_checkpoint(data, NULL); REMOVE_ROUTING(data); netlists = g_list_prepend(NULL, data->netlist); netlists_recalculate(netlists, NULL); r->flags |= TOPOROUTER_FLAG_LEASTINVALID; if(route(r, data, 0)) { GList *conflicts, *j; nscore = data->score; conflicts = route_conflicts(data); INSERT_ROUTING(data); r->flags &= ~TOPOROUTER_FLAG_LEASTINVALID; j = conflicts; while(j) { toporouter_route_t *conflict = TOPOROUTER_ROUTE(j->data); if(!g_list_find(netlists, conflict->netlist)) netlists = g_list_prepend(netlists, conflict->netlist); pscore += conflict->score; route_checkpoint(conflict, NULL); REMOVE_ROUTING(conflict); j = j->next; } netlists_recalculate(netlists, NULL); j = conflicts; while(j) { toporouter_route_t *conflict = TOPOROUTER_ROUTE(j->data); if(route(r, conflict, 0)) { cluster_merge(conflict); INSERT_ROUTING(conflict); nscore += conflict->score; }else{ j = j->prev; goto roar_detour_route_rollback_int; } j = j->next; } if(nscore > pscore) { j = g_list_last(conflicts); roar_detour_route_rollback_int: REMOVE_ROUTING(data); while(j) { toporouter_route_t *conflict = TOPOROUTER_ROUTE(j->data); REMOVE_ROUTING(conflict); delete_route(conflict, 1); j = j->prev; } j = g_list_last(conflicts); while(j) { toporouter_route_t *conflict = TOPOROUTER_ROUTE(j->data); route_restore(conflict); INSERT_ROUTING(conflict); j = j->prev; } delete_route(data, 1); goto roar_detour_route_rollback_exit; } g_list_free(conflicts); }else{ r->flags &= ~TOPOROUTER_FLAG_LEASTINVALID; roar_detour_route_rollback_exit: route_restore(data); INSERT_ROUTING(data); } netlists_recalculate(netlists, NULL); g_list_free(netlists); } void detour_router(toporouter_t *r) { GList *i = r->routednets; guint n = g_list_length(r->routednets); GPtrArray* scores = g_ptr_array_sized_new(n); while(i) { toporouter_route_t *curroute = TOPOROUTER_ROUTE(i->data); curroute->score = path_score(r, curroute->path); g_ptr_array_add(scores, i->data); i = i->next; } g_ptr_array_sort(scores, (GCompareFunc) route_detour_compare); r->flags |= TOPOROUTER_FLAG_DETOUR; for(toporouter_route_t **i = (toporouter_route_t **) scores->pdata; i < (toporouter_route_t **) scores->pdata + scores->len; i++) { toporouter_route_t *curroute = (*i); if(isfinite(curroute->score) && isfinite(curroute->detourscore)) { // printf("%15s %15f \t %8f,%8f - %8f,%8f\n", (*i)->src->netlist + 2, (*i)->score - (*i)->detourscore, // vx(curroute->mergebox1->point), vy(curroute->mergebox1->point), // vx(curroute->mergebox2->point), vy(curroute->mergebox2->point)); if(curroute->score - curroute->detourscore > ROAR_DETOUR_THRESHOLD) { roar_detour_route(r, curroute); }else break; } } printf("\n"); r->flags ^= TOPOROUTER_FLAG_DETOUR; g_ptr_array_free(scores, TRUE); } gint rubix_router(toporouter_t *r, gint failcount) { GList *i, *ordering; order_nets_preroute_greedy(r, r->failednets, &ordering); i = ordering; while(i) { toporouter_route_t *data = TOPOROUTER_ROUTE(i->data); if(route(r, data, 0)) { INSERT_ROUTING(data); cluster_merge(data); failcount--; } i = i->next; } g_list_free(ordering); return failcount; } guint hybrid_router(toporouter_t *r) { gint failcount = g_list_length(r->failednets); r->flags |= TOPOROUTER_FLAG_AFTERORDER; r->flags |= TOPOROUTER_FLAG_AFTERRUBIX; failcount = rubix_router(r, failcount); Message(_("RUBIX router: %d nets remaining\n"), failcount); printf(_("RUBIX router: %d nets remaining\n"), failcount); r->flags |= TOPOROUTER_FLAG_GOFAR; for(guint i=0;i<6 && failcount;i++) { if(i % 2 == 1) { failcount = roar_router(r, failcount, 5); // printf("THRESH 5\n"); }else{ failcount = roar_router(r, failcount, 2); // printf("THRESH 2\n"); } detour_router(r); } failcount = roar_router(r, failcount, 2); detour_router(r); return failcount; } void parse_arguments(toporouter_t *r, int argc, char **argv) { int i, tempint; for(i=0;iviacost = (double)tempint; }else if(sscanf(argv[i], "l%d", &tempint)) { gdouble *layer = (gdouble *)malloc(sizeof(gdouble)); *layer = (double)tempint; r->keepoutlayers = g_list_prepend(r->keepoutlayers, layer); } } for (guint group = 0; group < max_group; group++) for (i = 0; i < PCB->LayerGroups.Number[group]; i++) if ((PCB->LayerGroups.Entries[group][i] < max_copper_layer) && !(PCB->Data->Layer[PCB->LayerGroups.Entries[group][i]].On)) { gdouble *layer = (gdouble *)malloc(sizeof(gdouble)); *layer = (double)group; r->keepoutlayers = g_list_prepend(r->keepoutlayers, layer); } } toporouter_t * toporouter_new(void) { toporouter_t *r = (toporouter_t *)calloc(1, sizeof(toporouter_t)); time_t ltime; gettimeofday(&r->starttime, NULL); r->netsort = netscore_pairwise_compare; r->destboxes = NULL; r->consumeddestboxes = NULL; r->paths = NULL; r->layers = NULL; r->flags = 0; r->viacost = VIA_COST_AS_DISTANCE; r->wiring_score = 0.; r->bboxes = NULL; r->bboxtree = NULL; r->netlists = g_ptr_array_new(); r->routes = g_ptr_array_new(); r->keepoutlayers = NULL; r->routednets = NULL; r->failednets = NULL; ltime=time(NULL); gts_predicates_init(); Message(_("Topological Autorouter\n")); Message(_("Started %s"),asctime(localtime(<ime))); Message(_("-------------------------------------\n")); return r; } void acquire_twonets(toporouter_t *r) { RAT_LOOP(PCB->Data); if( TEST_FLAG(SELECTEDFLAG, line) ) import_route(r, line); END_LOOP; // /* if(!r->routes->len) { RAT_LOOP(PCB->Data); import_route(r, line); END_LOOP; } // */ } toporouter_netlist_t * find_netlist_by_name(toporouter_t *r, char *name) { FOREACH_NETLIST(r->netlists) { if(!strcmp(netlist->netlist, name)) return netlist; } FOREACH_END; return NULL; } gint toporouter_set_pair(toporouter_t *r, toporouter_netlist_t *n1, toporouter_netlist_t *n2) { if(!n1 || !n2) return 0; n1->pair = n2; n2->pair = n1; return 1; } static int toporouter (int argc, char **argv, Coord x, Coord y) { toporouter_t *r = toporouter_new(); parse_arguments(r, argc, argv); import_geometry(r); acquire_twonets(r); //if(!toporouter_set_pair(r, find_netlist_by_name(r, " DRAM_DQS_N"), find_netlist_by_name(r, " DRAM_DQS"))) { // printf("Couldn't associate pair\n"); //} hybrid_router(r); /* for(gint i=0;ilayers[i].surface, space_edge, NULL); } { int i; for(i=0;ilayers[i].surface, buffer, 1024, 1024, 2, NULL, i, NULL); } } */ toporouter_export(r); toporouter_free(r); SaveUndoSerialNumber (); DeleteRats (false); RestoreUndoSerialNumber (); AddAllRats (false, NULL); RestoreUndoSerialNumber (); IncrementUndoSerialNumber (); Redraw (); return 0; } static int escape (int argc, char **argv, Coord x, Coord y) { guint dir, viax, viay; gdouble pitch, dx, dy; if(argc != 1) return 0; dir = atoi(argv[0]); ALLPAD_LOOP(PCB->Data); { if( TEST_FLAG(SELECTEDFLAG, pad) ) { PinType *via; LineType *line; PadType *pad0 = element->Pad->data; PadType *pad1 = g_list_next (element->Pad)->data; pitch = hypot (pad0->Point1.X - pad1->Point1.X, pad0->Point1.Y - pad1->Point1.Y); dx = pitch / 2; dy = pitch / 2; switch(dir) { case 1: viax = pad->Point1.X - dx; viay = pad->Point1.Y + dy; break; case 3: viax = pad->Point1.X + dx; viay = pad->Point1.Y + dy; break; case 9: viax = pad->Point1.X + dx; viay = pad->Point1.Y - dy; break; case 7: viax = pad->Point1.X - dx; viay = pad->Point1.Y - dy; break; case 2: viax = pad->Point1.X; viay = pad->Point1.Y + dy; break; case 8: viax = pad->Point1.X; viay = pad->Point1.Y - dy; break; case 4: viax = pad->Point1.X - dx; viay = pad->Point1.Y; break; case 6: viax = pad->Point1.X + dx; viay = pad->Point1.Y; break; default: printf("ERROR: escape() with bad direction (%d)\n", dir); return 1; } if ((via = CreateNewVia (PCB->Data, viax, viay, Settings.ViaThickness, 2 * Settings.Keepaway, 0, Settings.ViaDrillingHole, NULL, NoFlags ())) != NULL) { AddObjectToCreateUndoList (VIA_TYPE, via, via, via); // if (gui->shift_is_pressed ()) // ChangeObjectThermal (VIA_TYPE, via, via, via, PCB->ThermStyle); DrawVia (via); if((line = CreateDrawnLineOnLayer (CURRENT, pad->Point1.X + 1., pad->Point1.Y + 1., viax + 1., viay + 1., Settings.LineThickness, 2 * Settings.Keepaway, NoFlags()))) { AddObjectToCreateUndoList (LINE_TYPE, CURRENT, line, line); DrawLine (CURRENT, line); } } } } END_LOOP; END_LOOP; IncrementUndoSerialNumber (); Draw (); return 0; } static HID_Action toporouter_action_list[] = { {"Escape", N_("Select a set of pads"), escape, N_("Pad escape"), N_("Escape()")}, {"Toporouter", N_("Select net(s)"), toporouter, N_("Topological autorouter"), N_("Toporouter()")} }; REGISTER_ACTIONS (toporouter_action_list) void hid_toporouter_init() { register_toporouter_action_list(); } pcb-4.3.0/src/dolists.h0000664000175000017500000000054213773431044011635 00000000000000#undef REGISTER_ACTIONS #undef REGISTER_ATTRIBUTES #undef REGISTER_FLAGS #define REGISTER_ACTIONS(a) {extern void HIDCONCAT(register_,a)();HIDCONCAT(register_,a)();} #define REGISTER_ATTRIBUTES(a) {extern void HIDCONCAT(register_,a)();HIDCONCAT(register_,a)();} #define REGISTER_FLAGS(a) {extern void HIDCONCAT(register_,a)();HIDCONCAT(register_,a)();} pcb-4.3.0/src/puller.c0000664000175000017500000020306713773431044011461 00000000000000/*! * \file src/puller.c * * \brief . * * \todo Things that need to be fixed before this is "perfect".\n * Add to this list as we find things. * - respect the outline layer. * - don't consider points that are perpendicular to our start_arc. * I.e. when we have busses going around corners, we have a *lot* of * arcs and endpoints that are all in the same direction and all * equally "good", but rounding the arc angles to integers causes * all sorts of tiny differences that result in bumps, reversals, * and other messes. * - Store the X,Y values in our shadow struct so we don't fill up the * undo buffer with all our line reversals. * - at least check the other layers in our layer group. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 2006 DJ Delorie * * Copyright (C) 2011 PCB Contributers (See ChangeLog for details) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * DJ Delorie, 334 North Road, Deerfield NH 03037-1110, USA * dj@delorie.com */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "global.h" #include #include #include #include #include "create.h" #include "data.h" #include "draw.h" #include "misc.h" #include "move.h" #include "pcb-printf.h" #include "remove.h" #include "rtree.h" #include "strflags.h" #include "undo.h" #include "error.h" #ifdef HAVE_LIBDMALLOC #include #endif #define abort1() fprintf(stderr, "abort at line %d\n", __LINE__), abort() #define TRACE0 0 #define TRACE1 0 /*! Sine of one degree. */ #define SIN1D 0.0174524064372835 static jmp_buf abort_buf; static int multi, line_exact, arc_exact; static LineType *the_line; static ArcType *the_arc; static double arc_dist; /* We canonicalize the arc and line such that the point to be moved is always Point2 for the line, and at start+delta for the arc. */ static Coord x, y; /* the point we're moving */ static Coord cx, cy; /* centerpoint of the arc */ static Coord ex, ey; /* fixed end of the line */ /* 0 is left (-x), 90 is down (+y), 180 is right (+x), 270 is up (-y) */ static Coord within (Coord x1, Coord y1, Coord x2, Coord y2, Coord r) { return Distance (x1, y1, x2, y2) <= r / 2; } static int arc_endpoint_is (ArcType *a, int angle, Coord x, Coord y) { Coord ax = a->X, ay = a->Y; if (angle % 90 == 0) { int ai = (int) (angle / 90) & 3; switch (ai) { case 0: ax -= a->Width; break; case 1: ay += a->Height; break; case 2: ax += a->Width; break; case 3: ay -= a->Height; break; } } else { double rad = angle * M_PI / 180; ax -= a->Width * cos (rad); ay += a->Width * sin (rad); } #if TRACE1 pcb_printf (" - arc endpoint %#mD\n", ax, ay); #endif arc_dist = Distance (ax, ay, x, y); if (arc_exact) return arc_dist < 2; return arc_dist < a->Thickness / 2; } /*! * brief Cross c->u and c->v, return the magnitude. */ static double cross2d (Coord cx, Coord cy, Coord ux, Coord uy, Coord vx, Coord vy) { ux -= cx; uy -= cy; vx -= cx; vy -= cy; return (double)ux * vy - (double)uy * vx; } /*! * \brief Likewise, for dot product. */ static double dot2d (Coord cx, Coord cy, Coord ux, Coord uy, Coord vx, Coord vy) { ux -= cx; uy -= cy; vx -= cx; vy -= cy; return (double)ux * vx + (double)uy * vy; } #if 0 /*! * \brief . * * angle of c->v, relative to c->u, in radians. * Range is -pi..pi. */ static double angle2d (Coord cx, Coord cy, Coord ux, Coord uy, Coord vx, Coord vy) { double cross; double magu, magv, sintheta; #if TRACE1 pcb_printf("angle2d %mD %mD %mD\n", cx, cy, ux, uy, vx, vy); #endif ux -= cx; uy -= cy; vx -= cx; vy -= cy; #if TRACE1 pcb_printf(" = %mD %mD\n", ux, uy, vx, vy); #endif cross = (double)ux * vy - (double)uy * vx; magu = hypot(ux, uy); magv = hypot(vx, vy); sintheta = cross / (magu * magv); #if TRACE1 printf(" = %f / (%f * %f) = %f\n", cross, magu, magv, sintheta); #endif return asin (sintheta); } #endif static int same_sign (double a, double b) { return (a * b >= 0); } static double r2d (double r) { return 180.0 * r / M_PI; } static double d2r (double d) { return M_PI * d / 180.0; } /*! * \brief . * * | a b | * * | c d | */ static double det (double a, double b, double c, double d) { return a * d - b * c; } /*! * \brief . * * The lines are \f$ x_1y_1-x_2y_2 \f$ and \f$ x_3y_3-x_4y_4 \f$. * * \return True if they intersect. */ static int intersection_of_lines (Coord x1, Coord y1, Coord x2, Coord y2, Coord x3, Coord y3, Coord x4, Coord y4, Coord *xr, Coord *yr) { double x, y, d; d = det (x1 - x2, y1 - y2, x3 - x4, y3 - y4); if (!d) return 0; x = (det (det (x1, y1, x2, y2), x1 - x2, det (x3, y3, x4, y4), x3 - x4) / d); y = (det (det (x1, y1, x2, y2), y1 - y2, det (x3, y3, x4, y4), y3 - y4) / d); *xr = (Coord) (x + 0.5); *yr = (Coord) (y + 0.5); return 1; } /*! * \brief Same, for line segments. * * \return True if they intersect. * * For this function, \c xr and \c yr may be \c NULL if you don't need * the values. */ static int intersection_of_linesegs (Coord x1, Coord y1, Coord x2, Coord y2, Coord x3, Coord y3, Coord x4, Coord y4, Coord *xr, Coord *yr) { double x, y, d; d = det (x1 - x2, y1 - y2, x3 - x4, y3 - y4); if (!d) return 0; x = (det (det (x1, y1, x2, y2), x1 - x2, det (x3, y3, x4, y4), x3 - x4) / d); y = (det (det (x1, y1, x2, y2), y1 - y2, det (x3, y3, x4, y4), y3 - y4) / d); if (MIN (x1, x2) > x || x > MAX (x1, x2) || MIN (y1, y2) > y || y > MAX (y1, y2)) return 0; if (MIN (x3, x4) > x || x > MAX (x3, x4) || MIN (y3, y4) > y || y > MAX (y3, y4)) return 0; if (xr) *xr = (Coord) (x + 0.5); if (yr) *yr = (Coord) (y + 0.5); return 1; } /*! * \brief Distance between a line and a point. */ static double dist_lp (Coord x1, Coord y1, Coord x2, Coord y2, Coord px, Coord py) { double den = Distance (x1, y1, x2, y2); double rv = (fabs (((double)x2 - x1) * ((double)y1 - py) - ((double)x1 - px) * ((double)y2 - y1)) / den); #if TRACE1 pcb_printf("dist %#mD-%#mD to %#mD is %f\n", x1, y1, x2, y2, px, py, rv); #endif return rv; } /*! * \brief Distance between a line segment and a point. */ static double dist_lsp (Coord x1, Coord y1, Coord x2, Coord y2, Coord px, Coord py) { double d; if (dot2d (x1, y1, x2, y2, px, py) < 0) return Distance (x1, y1, px, py); if (dot2d (x2, y2, x1, y1, px, py) < 0) return Distance (x2, y2, px, py); d = (fabs (((double)x2 - x1) * ((double)y1 - py) - ((double)x1 - px) * ((double)y2 - y1)) / Distance (x1, y1, x2, y2)); return d; } /* Single Point Puller */ static int line_callback (const BoxType * b, void *cl) { /* LayerType *layer = (LayerType *)cl; */ LineType *l = (LineType *) b; double d1, d2, t; #if TRACE1 pcb_printf ("line %#mD .. %#mD\n", l->Point1.X, l->Point1.Y, l->Point2.X, l->Point2.Y); #endif d1 = Distance (l->Point1.X, l->Point1.Y, x, y); d2 = Distance (l->Point2.X, l->Point2.Y, x, y); if ((d1 < 2 || d2 < 2) && !line_exact) { line_exact = 1; the_line = 0; } t = line_exact ? 2 : l->Thickness / 2; if (d1 < t || d2 < t) { if (the_line) multi = 1; the_line = l; #if TRACE1 printf ("picked, exact %d\n", line_exact); #endif } return 1; } static int arc_callback (const BoxType * b, void *cl) { /* LayerType *layer = (LayerType *) cl; */ ArcType *a = (ArcType *) b; #if TRACE1 pcb_printf ("arc a %#mD r %#mS sa %ld d %ld\n", a->X, a->Y, a->Width, a->StartAngle, a->Delta); #endif if (!arc_endpoint_is (a, a->StartAngle, x, y) && !arc_endpoint_is (a, a->StartAngle + a->Delta, x, y)) return 1; if (arc_dist < 2) { if (!arc_exact) { arc_exact = 1; the_arc = 0; } if (the_arc) multi = 1; the_arc = a; #if TRACE1 printf ("picked, exact %d\n", arc_exact); #endif } else if (!arc_exact) { if (the_arc) multi = 1; the_arc = a; #if TRACE1 printf ("picked, exact %d\n", arc_exact); #endif } return 1; } static int find_pair (Coord Px, Coord Py) { BoxType spot; #if TRACE1 pcb_printf ("\nPuller find_pair at %#mD\n", Px, Py); #endif x = Px; y = Py; multi = 0; line_exact = arc_exact = 0; the_line = 0; the_arc = 0; spot.X1 = x - 1; spot.Y1 = y - 1; spot.X2 = x + 1; spot.Y2 = y + 1; r_search (CURRENT->line_tree, &spot, NULL, line_callback, CURRENT); r_search (CURRENT->arc_tree, &spot, NULL, arc_callback, CURRENT); if (the_line && the_arc && !multi) return 1; x = Px; y = Py; return 0; } static const char puller_syntax[] = "Puller()"; static const char puller_help[] = "Pull an arc-line junction tight."; /* %start-doc actions Puller The @code{Puller()} action is a special-purpose optimization. When invoked while the crosshair is over the junction of an arc and a line, it will adjust the arc's angle and the connecting line's endpoint such that the line intersects the arc at a tangent. In the example below, the left side is ``before'' with the black target marking where to put the crosshair: @center @image{puller,,,Example of how puller works,png} The right side is ``after'' with the black target marking where the arc-line intersection was moved to. %end-doc */ static int Puller (int argc, char **argv, Coord Ux, Coord Uy) { double arc_angle, base_angle; #if TRACE1 double line_angle, rel_angle; #endif double tangent; int new_delta_angle; if (!find_pair (Crosshair.X, Crosshair.Y)) if (!find_pair (Ux, Uy)) return 0; if (within (the_line->Point1.X, the_line->Point1.Y, x, y, the_line->Thickness)) { ex = the_line->Point2.X; ey = the_line->Point2.Y; the_line->Point2.X = the_line->Point1.X; the_line->Point2.Y = the_line->Point1.Y; the_line->Point1.X = ex; the_line->Point1.Y = ey; } else if (!within (the_line->Point2.X, the_line->Point2.Y, x, y, the_line->Thickness)) { #if TRACE1 printf ("Line endpoint not at cursor\n"); #endif return 1; } ex = the_line->Point1.X; ey = the_line->Point1.Y; cx = the_arc->X; cy = the_arc->Y; if (arc_endpoint_is (the_arc, the_arc->StartAngle, x, y)) { ChangeArcAngles (CURRENT, the_arc, the_arc->StartAngle + the_arc->Delta, -the_arc->Delta); } else if (!arc_endpoint_is (the_arc, the_arc->StartAngle + the_arc->Delta, x, y)) { #if TRACE1 printf ("arc not endpoints\n"); #endif return 1; } if (within (cx, cy, ex, ey, the_arc->Width * 2)) { #if TRACE1 printf ("line ends inside arc\n"); #endif return 1; } if (the_arc->Delta > 0) arc_angle = the_arc->StartAngle + the_arc->Delta + 90; else arc_angle = the_arc->StartAngle + the_arc->Delta - 90; base_angle = r2d (atan2 (ey - cy, cx - ex)); tangent = r2d (acos (the_arc->Width / Distance (cx, cy, ex, ey))); #if TRACE1 line_angle = r2d (atan2 (ey - y, x - ex)); rel_angle = line_angle - arc_angle; printf ("arc %g line %g rel %g base %g\n", arc_angle, line_angle, rel_angle, base_angle); printf ("tangent %g\n", tangent); printf ("arc was start %ld end %ld\n", the_arc->StartAngle, the_arc->StartAngle + the_arc->Delta); #endif if (the_arc->Delta > 0) arc_angle = base_angle - tangent; else arc_angle = base_angle + tangent; #if TRACE1 printf ("new end angle %g\n", arc_angle); #endif new_delta_angle = arc_angle - the_arc->StartAngle; if (new_delta_angle > 180) new_delta_angle -= 360; if (new_delta_angle < -180) new_delta_angle += 360; ChangeArcAngles (CURRENT, the_arc, the_arc->StartAngle, new_delta_angle); #if TRACE1 printf ("arc now start %ld end %ld\n", the_arc->StartAngle, the_arc->StartAngle + new_delta_angle); #endif arc_angle = the_arc->StartAngle + the_arc->Delta; x = the_arc->X - the_arc->Width * cos (d2r (arc_angle)) + 0.5; y = the_arc->Y + the_arc->Height * sin (d2r (arc_angle)) + 0.5; MoveObject (LINEPOINT_TYPE, CURRENT, the_line, &(the_line->Point2), x - the_line->Point2.X, y - the_line->Point2.Y); gui->invalidate_all (); IncrementUndoSerialNumber (); return 1; } /* Global Puller */ static const char globalpuller_syntax[] = "GlobalPuller()"; static const char globalpuller_help[] = "Pull all traces tight."; /* %start-doc actions GlobalPuller %end-doc */ /* Ok, here's the deal. We look for the intersection of two traces. The triangle formed by those traces is searched for things we need to avoid. From the other two corners of the triangle, we compute the angle to each obstacle, and remember the ones closest to the start angles. If the two traces hit the same obstacle, we put in the arc and we're done. Else, we bring the traces up to the obstacles and start again. Note that we assume each start point is a tangent to an arc. We start with a radius of zero, but future steps use the arcs we create as we go. For obstacles, we list each round pin, pad, via, and line/arc endpoints as points with a given radius. For each square pin, pad, via, and polygon points, we list each corner with a zero radius. We also list arcs from their centerpoint. We don't currently do anything to move vias, or intersections of three or more traces. In the future, three-way intersections will be handles similarly to two-way - calculate the range of angles valid from each of the three other endpoints, choose the angle closest to making 120 degree angles at the center. For four-way or more intersections, we break them up into multiple three-way intersections. For simplicity, we only do the current layer at this time. We will also edit the lines and arcs in place so that the intersection is always on the second point, and the other ends are always at start+delta for arcs. We also defer intersections which are blocked by other intersections yet to be moved; the idea is to wait until those have been moved so we don't end up with arcs that no longer wrap around things. At a later point, we may choose to pull arced corners in also. You'll see lots of variables of the form "foo_sign" which keep track of which way things are pointing. This is because everything is relative to corners and arcs, not absolute directions. */ static int nloops, npulled; static void status () { Message ("%6d loops, %d pulled \r", nloops, npulled); } /*! * \brief Extra data we need to temporarily attach to all lines and * arcs. */ typedef struct End { /* These point to "multi_next" if there are more than one. */ struct Extra *next; void *pin; unsigned char in_pin:1; unsigned char at_pin:1; unsigned char is_pad:1; unsigned char pending:1; /* set if this may be moved later */ Coord x, y; /* arc endpoint */ /* If not NULL, points to End with pending==1 we're blocked on. */ struct End *waiting_for; } End; typedef struct Extra { End start; End end; unsigned char found:1; unsigned char deleted:1; int type; union { LineType *line; ArcType *arc; } parent; } Extra; static Extra multi_next; static GHashTable *lines; static GHashTable *arcs; static int did_something; static int current_is_top, current_is_bottom; /* If set, these are the pins/pads/vias that this path ends on. */ /* static void *start_pin_pad, *end_pin_pad; */ #if TRACE1 static void trace_paths (); #endif static void mark_line_for_deletion (LineType *); #define LINE2EXTRA(l) ((Extra *)g_hash_table_lookup (lines, l)) #define ARC2EXTRA(a) ((Extra *)g_hash_table_lookup (arcs, a)) #define EXTRA2LINE(e) (e->parent.line) #define EXTRA2ARC(e) (e->parent.arc) #define EXTRA_IS_LINE(e) (e->type == LINE_TYPE) #define EXTRA_IS_ARC(e) (e->type == ARC_TYPE) static void unlink_end (Extra *x, Extra **e) { if (*e) { if ((*e)->start.next == x) { #if TRACE1 printf("%d: unlink_end, was %p\n", __LINE__, (*e)->start.next); #endif (*e)->start.next = &multi_next; } if ((*e)->end.next == x) { #if TRACE1 printf("%d: unlink_end, was %p\n", __LINE__, (*e)->start.next); #endif (*e)->end.next = &multi_next; } } #if TRACE1 printf("%d: unlink_end, was %p\n", __LINE__, (*e)); #endif (*e) = &multi_next; } #if TRACE1 static void clear_found_cb (AnyObjectType *ptr, Extra *extra, void *userdata) { extra->found = 0; } static void clear_found () { g_hash_table_foreach (lines, (GHFunc)clear_found_cb, NULL); g_hash_table_foreach (arcs, (GHFunc)clear_found_cb, NULL); } #endif static void fix_arc_extra (ArcType *a, Extra *e) { #if TRACE1 printf("new arc angles %ld %ld\n", a->StartAngle, a->Delta); #endif e->start.x = a->X - (a->Width * cos (d2r (a->StartAngle)) + 0.5); e->start.y = a->Y + (a->Height * sin (d2r (a->StartAngle)) + 0.5); e->end.x = a->X - (a->Width * cos (d2r (a->StartAngle+a->Delta)) + 0.5); e->end.y = a->Y + (a->Height * sin (d2r (a->StartAngle+a->Delta)) + 0.5); #if TRACE1 pcb_printf("new X,Y is %#mD to %#mD\n", e->start.x, e->start.y, e->end.x, e->end.y); #endif } typedef struct { void *me; Coord x, y; int is_arc; Extra **extra_ptr; } FindPairCallbackStruct; #define NEAR(a,b) ((a) <= (b) + 2 && (a) >= (b) - 2) static int find_pair_line_callback (const BoxType * b, void *cl) { LineType *line = (LineType *) b; #if TRACE1 Extra *e = LINE2EXTRA (line); #endif FindPairCallbackStruct *fpcs = (FindPairCallbackStruct *) cl; if (line == fpcs->me) return 0; #ifdef CHECK_LINE_PT_NEG if (line->Point1.X < 0) abort1(); #endif #if TRACE1 pcb_printf(" - %p line %#mD or %#mD\n", e, line->Point1.X, line->Point1.Y, line->Point2.X, line->Point2.Y); #endif if ((NEAR (line->Point1.X, fpcs->x) && NEAR (line->Point1.Y, fpcs->y)) || (NEAR (line->Point2.X, fpcs->x) && NEAR (line->Point2.Y, fpcs->y))) { if (* fpcs->extra_ptr) { #if TRACE1 printf("multiple, was %p\n", *fpcs->extra_ptr); #endif *fpcs->extra_ptr = & multi_next; } else { *fpcs->extra_ptr = LINE2EXTRA (line); #if TRACE1 printf(" - next now %p\n", *fpcs->extra_ptr); #endif } } return 0; } static int find_pair_arc_callback (const BoxType * b, void *cl) { ArcType *arc = (ArcType *) b; Extra *e = ARC2EXTRA (arc); FindPairCallbackStruct *fpcs = (FindPairCallbackStruct *) cl; if (arc == fpcs->me) return 0; #if TRACE1 pcb_printf(" - %p arc %#mD or %#mD\n", e, e->start.x, e->start.y, e->end.x, e->end.y); #endif if ((NEAR (e->start.x, fpcs->x) && NEAR (e->start.y, fpcs->y)) || (NEAR (e->end.x, fpcs->x) && NEAR (e->end.y, fpcs->y))) { if (* fpcs->extra_ptr) { #if TRACE1 printf("multiple, was %p\n", *fpcs->extra_ptr); #endif *fpcs->extra_ptr = & multi_next; } else *fpcs->extra_ptr = e; } return 0; } static void find_pairs_1 (void *me, Extra **e, Coord x, Coord y) { FindPairCallbackStruct fpcs; BoxType b; if (*e) return; fpcs.me = me; fpcs.extra_ptr = e; fpcs.x = x; fpcs.y = y; #if TRACE1 pcb_printf("looking for %#mD\n", x, y); #endif b.X1 = x - 10; b.X2 = x + 10; b.Y1 = y - 10; b.Y2 = y + 10; r_search(CURRENT->line_tree, &b, NULL, find_pair_line_callback, &fpcs); r_search(CURRENT->arc_tree, &b, NULL, find_pair_arc_callback, &fpcs); } static int check_point_in_pin (PinType *pin, Coord x, Coord y, End *e) { int inside_p; Coord t = (PIN_SIZE(pin)+1)/2; if (TEST_FLAG (SQUAREFLAG, pin)) inside_p = (x >= pin->X - t && x <= pin->X + t && y >= pin->Y - t && y <= pin->Y + t); else inside_p = (Distance (pin->X, pin->Y, x, y) <= t); if (inside_p) { e->in_pin = 1; if (pin->X == x && pin->Y == y) e->at_pin = 1; e->pin = pin; return 1; } return 0; } static int find_pair_pinline_callback (const BoxType * b, void *cl) { LineType *line = (LineType *) b; PinType *pin = (PinType *) cl; Extra *e = LINE2EXTRA (line); int hits; #ifdef CHECK_LINE_PT_NEG if (line->Point1.X < 0) abort1(); #endif hits = check_point_in_pin (pin, line->Point1.X, line->Point1.Y, &(e->start)); hits += check_point_in_pin (pin, line->Point2.X, line->Point2.Y, &(e->end)); if (hits) return 0; /* See if the line passes through this pin. */ /*! \todo This assumes round pads, but it's good enough for square * ones for now. */ if (dist_lsp (line->Point1.X, line->Point1.Y, line->Point2.X, line->Point2.Y, pin->X, pin->Y) <= PIN_SIZE(pin)/2) { #if TRACE1 pcb_printf("splitting line %#mD-%#mD because it passes through pin %#mD r%d\n", line->Point1.X, line->Point1.Y, line->Point2.X, line->Point2.Y, pin->X, pin->Y, PIN_SIZE(pin)/2); #endif unlink_end (e, &e->start.next); unlink_end (e, &e->end.next); } return 0; } static int find_pair_pinarc_callback (const BoxType * b, void *cl) { ArcType *arc = (ArcType *) b; PinType *pin = (PinType *) cl; Extra *e = ARC2EXTRA (arc); int hits; hits = check_point_in_pin (pin, e->start.x, e->start.y, &(e->start)); hits += check_point_in_pin (pin, e->end.x, e->end.y, &(e->end)); return 0; } static int check_point_in_pad (PadType *pad, Coord x, Coord y, End *e) { int inside_p; Coord t; pcb_printf("pad %#mD - %#mD t %#mS vs %#mD\n", pad->Point1.X, pad->Point1.Y, pad->Point2.X, pad->Point2.Y, pad->Thickness, x, y); t = (pad->Thickness+1)/2; if (TEST_FLAG (SQUAREFLAG, pad)) { inside_p = (x >= MIN (pad->Point1.X - t, pad->Point2.X - t) && x <= MAX (pad->Point1.X + t, pad->Point2.X + t) && y >= MIN (pad->Point1.Y - t, pad->Point2.Y - t) && y <= MAX (pad->Point1.Y + t, pad->Point2.Y + t)); printf(" - inside_p = %d\n", inside_p); } else { if (pad->Point1.X == pad->Point2.X) { inside_p = (x >= pad->Point1.X - t && x <= pad->Point1.X + t && y >= MIN (pad->Point1.Y, pad->Point2.Y) && y <= MAX (pad->Point1.Y, pad->Point2.Y)); } else { inside_p = (x >= MIN (pad->Point1.X, pad->Point2.X) && x <= MAX (pad->Point1.X, pad->Point2.X) && y >= pad->Point1.Y - t && y <= pad->Point1.Y + t); } if (!inside_p) { if (Distance (pad->Point1.X, pad->Point1.Y, x, y) <= t || Distance (pad->Point2.X, pad->Point2.Y, x, y) <= t) inside_p = 1; } } if (inside_p) { e->in_pin = 1; if (pad->Point1.X == x && pad->Point1.Y == y) e->at_pin = 1; if (pad->Point2.X == x && pad->Point2.Y == y) e->at_pin = 1; e->pin = pad; e->is_pad = 1; return 1; } return 0; } static int find_pair_padline_callback (const BoxType * b, void *cl) { LineType *line = (LineType *) b; PadType *pad = (PadType *) cl; Extra *e = LINE2EXTRA (line); int hits; double t; int intersect; double p1_d, p2_d; if (TEST_FLAG (ONSOLDERFLAG, pad)) { if (!current_is_bottom) return 0; } else { if (!current_is_top) return 0; } #ifdef CHECK_LINE_PT_NEG if (line->Point1.X < 0) abort1(); #endif hits = check_point_in_pad (pad, line->Point1.X, line->Point1.Y, &(e->start)); hits += check_point_in_pad (pad, line->Point2.X, line->Point2.Y, &(e->end)); if (hits) return 0; /* Ok, something strange. The line intersects our space, but doesn't end in our space. See if it just passes through us, and mark it anyway. */ t = (pad->Thickness + 1)/2; /*! \todo This is for round pads. Good enough for now, but add * square pad support later. */ intersect = intersection_of_linesegs (pad->Point1.X, pad->Point1.Y, pad->Point2.X, pad->Point2.Y, line->Point1.X, line->Point1.Y, line->Point2.X, line->Point2.Y, NULL, NULL); p1_d = dist_lsp(line->Point1.X, line->Point1.Y, line->Point2.X, line->Point2.Y, pad->Point1.X, pad->Point1.Y); p2_d = dist_lsp(line->Point1.X, line->Point1.Y, line->Point2.X, line->Point2.Y, pad->Point2.X, pad->Point2.Y); if (intersect || p1_d < t || p2_d < t) { /* It does. */ /*! \todo We should split the line. */ #if TRACE1 pcb_printf("splitting line %#mD-%#mD because it passes through pad %#mD-%#mD r %#mS\n", line->Point1.X, line->Point1.Y, line->Point2.X, line->Point2.Y, pad->Point1.X, pad->Point1.Y, pad->Point2.X, pad->Point2.Y, pad->Thickness/2); #endif unlink_end (e, &e->start.next); unlink_end (e, &e->end.next); } return 0; } static int find_pair_padarc_callback (const BoxType * b, void *cl) { ArcType *arc = (ArcType *) b; PadType *pad = (PadType *) cl; Extra *e = ARC2EXTRA (arc); int hits; if (TEST_FLAG (ONSOLDERFLAG, pad)) { if (!current_is_bottom) return 0; } else { if (!current_is_top) return 0; } hits = check_point_in_pad (pad, e->start.x, e->start.y, &(e->start)); hits += check_point_in_pad (pad, e->end.x, e->end.y, &(e->end)); return 0; } static void null_multi_next_ends (AnyObjectType *ptr, Extra *extra, void *userdata) { if (extra->start.next == &multi_next) extra->start.next = NULL; if (extra->end.next == &multi_next) extra->end.next = NULL; } static Extra * new_line_extra (LineType *line) { Extra *extra = g_slice_new0 (Extra); g_hash_table_insert (lines, line, extra); extra->parent.line = line; extra->type = LINE_TYPE; return extra; } static Extra * new_arc_extra (ArcType *arc) { Extra *extra = g_slice_new0 (Extra); g_hash_table_insert (arcs, arc, extra); extra->parent.arc = arc; extra->type = ARC_TYPE; return extra; } static void find_pairs () { ARC_LOOP (CURRENT); { Extra *e = new_arc_extra (arc); fix_arc_extra (arc, e); } END_LOOP; LINE_LOOP (CURRENT); { new_line_extra (line); } END_LOOP; LINE_LOOP (CURRENT); { Extra *e = LINE2EXTRA (line); if (line->Point1.X >= 0) { find_pairs_1 (line, & e->start.next, line->Point1.X, line->Point1.Y); find_pairs_1 (line, & e->end.next, line->Point2.X, line->Point2.Y); } } END_LOOP; ARC_LOOP (CURRENT); { Extra *e = ARC2EXTRA (arc); if (!e->deleted) { find_pairs_1 (arc, & e->start.next, e->start.x, e->start.y); find_pairs_1 (arc, & e->end.next, e->end.x, e->end.y); } } END_LOOP; ALLPIN_LOOP (PCB->Data); { BoxType box; box.X1 = pin->X - PIN_SIZE(pin)/2; box.Y1 = pin->Y - PIN_SIZE(pin)/2; box.X2 = pin->X + PIN_SIZE(pin)/2; box.Y2 = pin->Y + PIN_SIZE(pin)/2; r_search (CURRENT->line_tree, &box, NULL, find_pair_pinline_callback, pin); r_search (CURRENT->arc_tree, &box, NULL, find_pair_pinarc_callback, pin); } ENDALL_LOOP; VIA_LOOP (PCB->Data); { BoxType box; box.X1 = via->X - PIN_SIZE(via)/2; box.Y1 = via->Y - PIN_SIZE(via)/2; box.X2 = via->X + PIN_SIZE(via)/2; box.Y2 = via->Y + PIN_SIZE(via)/2; r_search (CURRENT->line_tree, &box, NULL, find_pair_pinline_callback, via); r_search (CURRENT->arc_tree, &box, NULL, find_pair_pinarc_callback, via); } END_LOOP; ALLPAD_LOOP (PCB->Data); { BoxType box; box.X1 = MIN(pad->Point1.X, pad->Point2.X) - pad->Thickness/2; box.Y1 = MIN(pad->Point1.Y, pad->Point2.Y) - pad->Thickness/2; box.X2 = MAX(pad->Point1.X, pad->Point2.X) + pad->Thickness/2; box.Y2 = MAX(pad->Point1.Y, pad->Point2.Y) + pad->Thickness/2; r_search (CURRENT->line_tree, &box, NULL, find_pair_padline_callback, pad); r_search (CURRENT->arc_tree, &box, NULL, find_pair_padarc_callback, pad); } ENDALL_LOOP; g_hash_table_foreach (lines, (GHFunc)null_multi_next_ends, NULL); g_hash_table_foreach (arcs, (GHFunc)null_multi_next_ends, NULL); } #define PROP_NEXT(e,n,f) \ if (f->next->start.next == e) { \ e = f->next; \ n = & e->start; \ f = & e->end; \ } else { \ e = f->next; \ n = & e->end; \ f = & e->start; } static void propogate_ends_at (Extra *e, End *near, End *far) { while (far->in_pin && far->pin == near->pin) { far->in_pin = 0; if (!far->next) return; PROP_NEXT (e, near, far); near->in_pin = 0; } } static void propogate_end_pin (Extra *e, End *near, End *far) { void *pinpad = near->pin; int ispad = near->is_pad; while (far->next) { PROP_NEXT (e, near, far); if (near->pin == pinpad) break; near->pin = pinpad; near->is_pad = ispad; } } static void propogate_end_step1_cb (AnyObjectType *ptr, Extra *extra, void *userdata) { if (extra->start.next != NULL && extra->start.next == extra->end.next) { extra->end.next = NULL; mark_line_for_deletion ((LineType *)ptr); } if (extra->start.at_pin) propogate_ends_at (extra, &extra->start, &extra->end); if (extra->end.at_pin) propogate_ends_at (extra, &extra->end, &extra->start); } static void propogate_end_step2_cb (AnyObjectType *ptr, Extra *extra, void *userdata) { if (extra->start.in_pin) { #if TRACE1 printf("MULTI at %d: was %p\n", __LINE__, extra->start.next); #endif extra->start.next = NULL; } if (extra->end.in_pin) { #if TRACE1 printf("MULTI at %d: was %p\n", __LINE__, extra->end.next); #endif extra->end.next = NULL; } } static void propogate_end_step3_cb (AnyObjectType *ptr, Extra *extra, void *userdata) { if (extra->start.next) propogate_end_pin (extra, &extra->end, &extra->start); if (extra->end.next) propogate_end_pin (extra, &extra->start, &extra->end); } static void propogate_ends () { /* First, shut of "in pin" when we have an "at pin". We also clean up zero-length lines. */ g_hash_table_foreach (lines, (GHFunc)propogate_end_step1_cb, NULL); /* Now end all paths at pins/pads. */ g_hash_table_foreach (lines, (GHFunc)propogate_end_step2_cb, NULL); /* Now, propogate the pin/pad/vias along paths. */ g_hash_table_foreach (lines, (GHFunc)propogate_end_step3_cb, NULL); } static Extra *last_pextra = 0; static void print_extra (Extra *e, Extra *prev) { int which = 0; if (e->start.next == last_pextra) which = 1; else if (e->end.next == last_pextra) which = 2; switch (which) { case 0: printf("%10p %10p %10p :", e, e->start.next, e->end.next); break; case 1: printf("%10p \033[33m%10p\033[0m %10p :", e, e->start.next, e->end.next); break; case 2: printf("%10p %10p \033[33m%10p\033[0m :", e, e->start.next, e->end.next); break; } last_pextra = e; printf(" %c%c", e->deleted ? 'd' : '-', e->found ? 'f' : '-'); printf(" s:%s%s%s%s", e->start.in_pin ? "I" : "-", e->start.at_pin ? "A" : "-", e->start.is_pad ? "P" : "-", e->start.pending ? "p" : "-"); printf(" e:%s%s%s%s ", e->end.in_pin ? "I" : "-", e->end.at_pin ? "A" : "-", e->end.is_pad ? "P" : "-", e->end.pending ? "p" : "-"); if (EXTRA_IS_LINE (e)) { LineType *line = EXTRA2LINE (e); pcb_printf(" %p L %#mD-%#mD", line, line->Point1.X, line->Point1.Y, line->Point2.X, line->Point2.Y); printf(" %s %p %s %p\n", e->start.is_pad ? "pad" : "pin", e->start.pin, e->end.is_pad ? "pad" : "pin", e->end.pin); } else if (EXTRA_IS_ARC (e)) { ArcType *arc = EXTRA2ARC (e); pcb_printf(" %p A %#mD-%#mD", arc, e->start.x, e->start.y, e->end.x, e->end.y); pcb_printf(" at %#mD ang %ld,%ld\n", arc->X, arc->Y, arc->StartAngle, arc->Delta); } else if (e == &multi_next) { printf("-- Multi-next\n"); } else { printf("-- Unknown extra: %p\n", e); } } #if TRACE1 static void trace_path (Extra *e) { Extra *prev = 0; if ((e->start.next && e->end.next) || (!e->start.next && !e->end.next)) return; if (e->found) return; printf("- path -\n"); last_pextra = 0; while (e) { e->found = 1; print_extra (e, prev); if (e->start.next == prev) { prev = e; e = e->end.next; } else { prev = e; e = e->start.next; } } } static void trace_paths () { Extra *e; clear_found (); LINE_LOOP (CURRENT); { e = LINE2EXTRA (line); trace_path (e); } END_LOOP; ARC_LOOP (CURRENT); { e = ARC2EXTRA (arc); trace_path (e); } END_LOOP; } #endif static void reverse_line (LineType *line) { Extra *e = LINE2EXTRA (line); Coord x, y; End etmp; x = line->Point1.X; y = line->Point1.Y; #if 1 MoveObject (LINEPOINT_TYPE, CURRENT, line, &(line->Point1), line->Point2.X - line->Point1.X, line->Point2.Y - line->Point1.Y); MoveObject (LINEPOINT_TYPE, CURRENT, line, &(line->Point2), x - line->Point2.X, y - line->Point2.Y); #else /* In theory, we should be using the above so that undo works. */ line->Point1.X = line->Point2.X; line->Point1.Y = line->Point2.Y; line->Point2.X = x; line->Point2.Y = y; #endif memcpy (&etmp, &e->start, sizeof (End)); memcpy (&e->start, &e->end, sizeof (End)); memcpy (&e->end, &etmp, sizeof (End)); } static void reverse_arc (ArcType *arc) { Extra *e = ARC2EXTRA (arc); End etmp; #if 1 ChangeArcAngles (CURRENT, arc, arc->StartAngle + arc->Delta, -arc->Delta); #else /* Likewise, see above. */ arc->StartAngle += arc->Delta; arc->Delta *= -1; #endif memcpy (&etmp, &e->start, sizeof (End)); memcpy (&e->start, &e->end, sizeof (End)); memcpy (&e->end, &etmp, sizeof (End)); } static void expand_box (BoxType *b, Coord x, Coord y, Coord t) { b->X1 = MIN (b->X1, x-t); b->X2 = MAX (b->X2, x+t); b->Y1 = MIN (b->Y1, y-t); b->Y2 = MAX (b->Y2, y+t); } /* ---------------------------------------------------------------------- */ /* These are the state variables for the intersection we're currently working on. */ /* what we're working with */ static ArcType *start_arc; static LineType *start_line; static LineType *end_line; static ArcType *end_arc; static Extra *start_extra, *end_extra; static Extra *sarc_extra, *earc_extra; static void *start_pinpad, *end_pinpad; static Coord thickness; /* Pre-computed values. Note that all values are computed according to CARTESIAN coordinates, not PCB coordinates. Do an up-down board flip before wrapping your brain around the math. */ /* se_sign is positive when you make a right turn going from start to end. */ /* sa_sign is positive when start's arc is on the same side of start as end. */ /* ea_sign is positive when end's arc is on the same side of end as start. */ /* sa_sign and ea_sign may be zero if there's no arc. */ static double se_sign, sa_sign, ea_sign; static double best_angle, start_angle, end_dist; /* arc radii are positive when they're on the same side as the things we're interested in. */ static Coord sa_r, ea_r; static Coord sa_x, sa_y; /* start "arc" point */ /* what we've found so far */ static Coord fx, fy, fr; static int fp; static End *fp_end; static double fa; /* relative angle */ #define gp_point(x,y,t,e) gp_point_2(x,y,t,e,0,0,__FUNCTION__) static int gp_point_force (Coord x, Coord y, Coord t, End *e, int esa, int eda, int force, const char *name) { double r, a, d; Coord scx, scy, sr; double base_angle, rel_angle, point_angle; #if TRACE1 pcb_printf("\033[34mgp_point_force %#mD %#mS via %s\033[0m\n", x, y, t, name); #endif if (start_arc) { scx = start_arc->X; scy = start_arc->Y; sr = start_arc->Width; } else { scx = start_line->Point1.X; scy = start_line->Point1.Y; sr = 0; } r = t + thickness; /* See if the point is inside our start arc. */ d = Distance (scx, scy, x, y); #if TRACE1 pcb_printf("%f = dist #mD to %#mD\n", d, scx, scy, x, y); pcb_printf("sr %#mS r %f d %f\n", sr, r, d); #endif if (d < sr - r) { #if TRACE1 printf("inside start arc, %f < %f\n", d, sr-r); #endif return 0; } if (sr == 0 && d < r) { #if TRACE1 printf("start is inside arc, %f < %f\n", d, r); #endif return 0; } /* Now for the same tricky math we needed for the single puller. sr and r are the radii for the two points scx,scy and x,y. */ /* angle between points (NOT pcb arc angles) */ base_angle = atan2 (y - scy, x - scx); #if TRACE1 pcb_printf("%.1f = atan2 (%#mS-%#mS = %#mS, %#mS-%#mS = %#mS)\n", r2d(base_angle), y, scy, y-scy, x, scx, x-scx); #endif if ((sa_sign * sr - r) / d > 1 || (sa_sign * sr - r) / d < -1) return 0; /* Angle of tangent, relative to the angle between point centers. */ rel_angle = se_sign * asin ((sa_sign * sr - r) / d); #if TRACE1 printf("%.1f = %d * asin ((%d * %d - %f) / %f)\n", r2d(rel_angle), (int)se_sign, (int)sa_sign, sr, r, d); #endif /* Absolute angle of tangent. */ point_angle = base_angle + rel_angle; #if TRACE1 printf("base angle %.1f rel_angle %.1f point_angle %.1f\n", r2d(base_angle), r2d(rel_angle), r2d(point_angle)); #endif if (eda) { /* Check arc angles */ double pa = point_angle; double sa = d2r(180-esa); double da = d2r(-eda); if (da < 0) { sa = sa + da; da = -da; } pa -= se_sign * M_PI/2; while (sa+da < pa) sa += M_PI*2; while (sa > pa) sa -= M_PI*2; if (sa+da < pa) { #if TRACE1 printf("arc doesn't apply: sa %.1f da %.1f pa %.1f\n", r2d(sa), r2d(da), r2d(pa)); #endif return 0; } } a = point_angle - start_angle; while (a > M_PI) a -= M_PI*2; while (a < -M_PI) a += M_PI*2; #if TRACE1 printf(" - angle relative to S-E baseline is %.1f\n", r2d(a)); #endif if (!force && a * se_sign < -0.007) { double new_r; #if TRACE1 printf("skipping, would increase angle (%f * %f)\n", a, se_sign); #endif new_r = dist_lp (start_line->Point1.X, start_line->Point1.Y, start_line->Point2.X, start_line->Point2.Y, x, y); #if TRACE1 pcb_printf("point %#mD dist %#mS vs thickness %#mS\n", x, y, new_r, thickness); #endif new_r -= thickness; new_r = (int)new_r - 1; #if TRACE1 pcb_printf(" - new thickness %f old %#mS\n", new_r, t); #endif if (new_r < t) gp_point_force (x, y, new_r, e, esa, eda, 1, __FUNCTION__); return 0; } #if TRACE1 printf("%f * %f < %f * %f ?\n", a, se_sign, best_angle, se_sign); #endif if (a * se_sign == best_angle * se_sign) { double old_d = Distance (start_line->Point1.X, start_line->Point1.Y, fx, fy); double new_d = Distance (start_line->Point1.X, start_line->Point1.Y, x, y); if (new_d > old_d) { best_angle = a; fx = x; fy = y; fr = r; fa = a; fp = e ? e->pending : 0; fp_end = e; } } else if (a * se_sign < best_angle * se_sign) { best_angle = a; fx = x; fy = y; fr = r; fa = a; fp = e ? e->pending : 0; fp_end = e; } return 1; } static int gp_point_2 (Coord x, Coord y, Coord t, End *e, int esa, int eda, const char *func) { double sc, ec; double sd, ed; if (x == sa_x && y ==sa_y) return 0; #if TRACE1 pcb_printf("\033[34mgp_point %#mD %#mS via %s\033[0m\n", x, y, t, func); #endif /* There are two regions we care about. For points inside our triangle, we check the crosses against start_line and end_line to make sure the point is "inside" the triangle. For points on the other side of the s-e line of the triangle, we check the dots to make sure it's between our endpoints. */ /* See what side of the s-e line we're on */ sc = cross2d (start_line->Point1.X, start_line->Point1.Y, end_line->Point2.X, end_line->Point2.Y, x, y); #if TRACE1 printf("s-e cross = %f\n", sc); #endif if (t >= 0) { if (same_sign (sc, se_sign)) { /* Outside, check dots. */ /* Ok, is it "in front of" our vectors? */ sd = dot2d (start_line->Point1.X, start_line->Point1.Y, end_line->Point2.X, end_line->Point2.Y, x, y); #if TRACE1 printf("sd = %f\n", sd); #endif if (sd <= 0) return 0; ed = dot2d (end_line->Point2.X, end_line->Point2.Y, start_line->Point1.X, start_line->Point1.Y, x, y); #if TRACE1 printf("ed = %f\n", ed); #endif if (ed <= 0) return 0; sd = dist_lp (start_line->Point1.X, start_line->Point1.Y, end_line->Point2.X, end_line->Point2.Y, x, y); if (sd > t + thickness) return 0; } else { /* Inside, check crosses. */ /* First off, is it on the correct side of the start line? */ sc = cross2d (start_line->Point1.X, start_line->Point1.Y, start_line->Point2.X, start_line->Point2.Y, x, y); #if TRACE1 printf("sc = %f\n", sc); #endif if (! same_sign (sc, se_sign)) return 0; /* Ok, is it on the correct side of the end line? */ ec = cross2d (end_line->Point1.X, end_line->Point1.Y, end_line->Point2.X, end_line->Point2.Y, x, y); #if TRACE1 printf("ec = %f\n", ec); #endif if (! same_sign (ec, se_sign)) return 0; } } #if TRACE1 printf("in range!\n"); #endif return gp_point_force (x, y, t, e, esa, eda, 0, func); } static int gp_line_cb (const BoxType *b, void *cb) { const LineType *l = (LineType *) b; Extra *e = LINE2EXTRA(l); if (l == start_line || l == end_line) return 0; if (e->deleted) return 0; #ifdef CHECK_LINE_PT_NEG if (l->Point1.X < 0) abort1(); #endif if (! e->start.next || ! EXTRA_IS_ARC (e->start.next)) gp_point (l->Point1.X, l->Point1.Y, l->Thickness/2, &e->start); if (! e->end.next || ! EXTRA_IS_ARC (e->end.next)) gp_point (l->Point2.X, l->Point2.Y, l->Thickness/2, &e->end); return 0; } static int gp_arc_cb (const BoxType *b, void *cb) { const ArcType *a = (ArcType *) b; Extra *e = ARC2EXTRA(a); if (a == start_arc || a == end_arc) return 0; if (e->deleted) return 0; gp_point_2 (a->X, a->Y, a->Width + a->Thickness/2, 0, a->StartAngle, a->Delta, __FUNCTION__); if (start_arc && a->X == start_arc->X && a->Y == start_arc->Y) return 0; if (end_arc && a->X != end_arc->X && a->Y != end_arc->Y) return 0; if (e->start.next || e->end.next) return 0; gp_point (e->start.x, e->start.y, a->Thickness/2, 0); gp_point (e->end.x, e->end.y, a->Thickness/2, 0); return 0; } static int gp_text_cb (const BoxType *b, void *cb) { const TextType *t = (TextType *) b; /* FIXME: drop in the actual text-line endpoints later. */ gp_point (t->BoundingBox.X1, t->BoundingBox.Y1, 0, 0); gp_point (t->BoundingBox.X1, t->BoundingBox.Y2, 0, 0); gp_point (t->BoundingBox.X2, t->BoundingBox.Y2, 0, 0); gp_point (t->BoundingBox.X2, t->BoundingBox.Y1, 0, 0); return 0; } static int gp_poly_cb (const BoxType *b, void *cb) { int i; const PolygonType *p = (PolygonType *) b; for (i=0; iPointN; i++) gp_point (p->Points[i].X, p->Points[i].Y, 0, 0); return 0; } static int gp_pin_cb (const BoxType *b, void *cb) { const PinType *p = (PinType *) b; Coord t2 = (PIN_SIZE(p)+1)/2; if (p == start_pinpad || p == end_pinpad) return 0; /*! \todo We lump octagonal pins in with square; safe, but not * optimal. */ if (TEST_FLAG (SQUAREFLAG, p) || TEST_FLAG (OCTAGONFLAG, p)) { gp_point (p->X - t2, p->Y - t2, 0, 0); gp_point (p->X - t2, p->Y + t2, 0, 0); gp_point (p->X + t2, p->Y + t2, 0, 0); gp_point (p->X + t2, p->Y - t2, 0, 0); } else { gp_point (p->X, p->Y, t2, 0); } return 0; } static int gp_pad_cb (const BoxType *b, void *cb) { const PadType *p = (PadType *) b; Coord t2 = (p->Thickness+1)/2; if (p == start_pinpad || p == end_pinpad) return 0; if (TEST_FLAG (ONSOLDERFLAG, p)) { if (!current_is_bottom) return 0; } else { if (!current_is_top) return 0; } /*! \todo We lump octagonal pads in with square; safe, but not optimal. I don't think we even support octagonal pads. */ if (TEST_FLAG (SQUAREFLAG, p) || TEST_FLAG (OCTAGONFLAG, p)) { if (p->Point1.X == p->Point2.X) { Coord y1 = MIN (p->Point1.Y, p->Point2.Y) - t2; Coord y2 = MAX (p->Point1.Y, p->Point2.Y) + t2; gp_point (p->Point1.X - t2, y1, 0, 0); gp_point (p->Point1.X - t2, y2, 0, 0); gp_point (p->Point1.X + t2, y1, 0, 0); gp_point (p->Point1.X + t2, y2, 0, 0); } else { Coord x1 = MIN (p->Point1.X, p->Point2.X) - t2; Coord x2 = MAX (p->Point1.X, p->Point2.X) + t2; gp_point (x1, p->Point1.Y - t2, 0, 0); gp_point (x2, p->Point1.Y - t2, 0, 0); gp_point (x1, p->Point1.Y + t2, 0, 0); gp_point (x2, p->Point1.Y + t2, 0, 0); } } else { gp_point (p->Point1.X, p->Point1.Y, t2, 0); gp_point (p->Point2.X, p->Point2.Y, t2, 0); } return 0; } static LineType * create_line (LineType *sample, Coord x1, Coord y1, Coord x2, Coord y2) { #if TRACE1 Extra *e; pcb_printf("create_line from %#mD to %#mD\n", x1, y1, x2, y2); #endif LineType *line = CreateNewLineOnLayer (CURRENT, x1, y1, x2, y2, sample->Thickness, sample->Clearance, sample->Flags); AddObjectToCreateUndoList (LINE_TYPE, CURRENT, line, line); #if TRACE1 e = #endif new_line_extra (line); #if TRACE1 printf(" - line extra is %p\n", e); #endif return line; } static ArcType * create_arc (LineType *sample, Coord x, Coord y, Coord r, Coord sa, Coord da) { Extra *e; ArcType *arc; if (r % 100 == 1) r--; if (r % 100 == 99) r++; #if TRACE1 pcb_printf("create_arc at %#mD r %#mS sa %d delta %d\n", x, y, r, sa, da); #endif arc = CreateNewArcOnLayer (CURRENT, x, y, r, r, sa, da, sample->Thickness, sample->Clearance, sample->Flags); if (arc == 0) { arc = CreateNewArcOnLayer (CURRENT, x, y, r, r, sa, da*2, sample->Thickness, sample->Clearance, sample->Flags); } AddObjectToCreateUndoList (ARC_TYPE, CURRENT, arc, arc); if (!arc) longjmp (abort_buf, 1); e = new_arc_extra (arc); #if TRACE1 printf(" - arc extra is %p\n", e); #endif fix_arc_extra (arc, e); return arc; } static void unlink_extras (Extra *e) { #if TRACE1 fprintf(stderr, "unlink %p\n", e); print_extra(e,0); #endif if (e->start.next) { #if TRACE1 print_extra(e->start.next, 0); #endif if (e->start.next->start.next == e) { #if TRACE1 fprintf(stderr, " - %p->start points to me\n", e->start.next); #endif e->start.next->start.next = e->end.next; } else if (e->start.next->end.next == e) { #if TRACE1 fprintf(stderr, " - %p->end points to me\n", e->start.next); #endif e->start.next->end.next = e->end.next; } else { fprintf(stderr, " - %p doesn't point to me!\n", e->start.next); abort(); } } if (e->end.next) { #if TRACE1 print_extra(e->end.next, 0); #endif if (e->end.next->start.next == e) { #if TRACE1 fprintf(stderr, " - %p->end points to me\n", e->end.next); #endif e->end.next->start.next = e->start.next; } else if (e->end.next->end.next == e) { #if TRACE1 fprintf(stderr, " - %p->end points to me\n", e->end.next); #endif e->end.next->end.next = e->start.next; } else { fprintf(stderr, " - %p doesn't point to me!\n", e->end.next); abort(); } } e->start.next = e->end.next = 0; } static void mark_line_for_deletion (LineType *l) { Extra *e = LINE2EXTRA(l); if (e->deleted) { fprintf(stderr, "double delete?\n"); abort(); } e->deleted = 1; unlink_extras (e); #if TRACE1 pcb_printf("Marked line %p for deletion %#mD to %#mD\n", e, l->Point1.X, l->Point1.Y, l->Point2.X, l->Point2.Y); #endif #if 0 if (l->Point1.X < 0) { fprintf(stderr, "double neg move?\n"); abort(); } MoveObject (LINEPOINT_TYPE, CURRENT, l, &(l->Point1), -1 - l->Point1.X, -1 - l->Point1.Y); MoveObject (LINEPOINT_TYPE, CURRENT, l, &(l->Point2), -1 - l->Point2.X, -1 - l->Point2.Y); #endif } static void mark_arc_for_deletion (ArcType *a) { Extra *e = ARC2EXTRA(a); e->deleted = 1; unlink_extras (e); #if TRACE1 printf("Marked arc %p for deletion %ld < %ld\n", e, a->StartAngle, a->Delta); #endif } /*! * \brief . * * Given a starting line, which may be attached to an arc, and which * intersects with an ending line, which also may be attached to an * arc, maybe pull them.\n * We assume start_line is attached to the arc via Point1, and attached * to the end line via Point2.\n * Likewise, we make end_line attach to the start_line via Point1 and * the arc via Point 2.\n * We also make the arcs attach on the Delta end, not the Start end.\n * Here's a picture: *
     S            S+D  P1            P2   P1          P2  S+D          S
   *--- start_arc ---*--- start_line ---*--- end_line ---*--- end_arc ---*
     S             E   S              E   S            E   E           S
 * 
*/ static void maybe_pull_1 (LineType *line) { BoxType box; /* Line half-thicknesses, including line space */ Coord ex, ey; LineType *new_line; Extra *new_lextra; ArcType *new_arc; Extra *new_aextra; double abs_angle; start_line = line; start_extra = LINE2EXTRA (start_line); end_extra = start_extra->end.next; end_line = EXTRA2LINE (end_extra); if (end_extra->deleted) { start_extra->end.pending = 0; return; } if (end_extra->end.next == start_extra) reverse_line (end_line); if (start_extra->start.next && EXTRA_IS_ARC (start_extra->start.next)) { sarc_extra = start_extra->start.next; start_arc = EXTRA2ARC (sarc_extra); if (sarc_extra->start.next == start_extra) reverse_arc (start_arc); } else { start_arc = 0; sarc_extra = 0; } if (end_extra->end.next && EXTRA_IS_ARC (end_extra->end.next)) { earc_extra = end_extra->end.next; end_arc = EXTRA2ARC (earc_extra); if (earc_extra->start.next == end_extra) reverse_arc (end_arc); } else { end_arc = 0; earc_extra = 0; } #if TRACE1 printf("maybe_pull_1 %p %p %p %p\n", sarc_extra, start_extra, end_extra, earc_extra); if (sarc_extra) print_extra(sarc_extra,0); print_extra(start_extra,0); print_extra(end_extra,0); if (earc_extra) print_extra(earc_extra,0); if (start_extra->deleted || end_extra->deleted || (sarc_extra && sarc_extra->deleted) || (earc_extra && earc_extra->deleted)) { printf(" one is deleted?\n"); fflush(stdout); abort(); } #endif if (!start_extra->end.pending) return; #if 0 if (start_extra->end.waiting_for && start_extra->end.waiting_for->pending) return; #endif if (start_line->Thickness != end_line->Thickness) return; thickness = (start_line->Thickness + 1)/2 + PCB->Bloat; /* At this point, our expectations are all met. */ box.X1 = start_line->Point1.X - thickness; box.X2 = start_line->Point1.X + thickness; box.Y1 = start_line->Point1.Y - thickness; box.Y2 = start_line->Point1.Y + thickness; expand_box (&box, start_line->Point2.X, start_line->Point2.Y, thickness); expand_box (&box, end_line->Point2.X, end_line->Point2.Y, thickness); if (start_arc) expand_box (&box, sarc_extra->start.x, sarc_extra->start.y, start_arc->Thickness/2); if (end_arc) expand_box (&box, earc_extra->start.x, earc_extra->start.y, end_arc->Thickness/2); se_sign = copysign (1, cross2d (start_line->Point1.X, start_line->Point1.Y, start_line->Point2.X, start_line->Point2.Y, end_line->Point2.X, end_line->Point2.Y)); best_angle = se_sign * M_PI; if (start_arc) { sa_sign = copysign (1, -start_arc->Delta); sa_sign *= se_sign; } else sa_sign = 0; if (end_arc) { ea_sign = copysign (1, -end_arc->Delta); ea_sign *= -se_sign; } else ea_sign = 0; start_angle = atan2 (start_line->Point2.Y - start_line->Point1.Y, start_line->Point2.X - start_line->Point1.X); #if TRACE1 printf("se_sign %f sa_sign %f ea_sign %f best_angle %f start_angle %f\n", se_sign, sa_sign, ea_sign, r2d (best_angle), r2d(start_angle)); #endif if (start_arc) { sa_x = start_arc->X; sa_y = start_arc->Y; if (same_sign (start_arc->Delta, se_sign)) sa_r = - start_arc->Width; else sa_r = start_arc->Width; } else { sa_x = start_line->Point1.X; sa_y = start_line->Point1.Y; sa_r = 0; } if (end_arc) { if (ea_sign < 0) ea_r = end_arc->Width; else ea_r = - end_arc->Width; } else ea_r = 0; #if TRACE1 trace_path (sarc_extra ? sarc_extra : start_extra); #endif if (end_arc) { gp_point_force (end_arc->X, end_arc->Y, -ea_r-thickness, 0, 0, 0, 1, "end arc"); ex = end_arc->X; ey = end_arc->Y; } else { gp_point_force (end_line->Point2.X, end_line->Point2.Y, -thickness, 0, 0, 0, 1, "end arc"); ex = end_line->Point2.X; ey = end_line->Point2.Y; } fx = ex; fy = ey; if (fx < 0) { pcb_fprintf(stderr, "end line corrupt? f is %#mD\n", fx, fy); print_extra (end_extra, 0); if (earc_extra) print_extra(earc_extra, 0); abort(); } end_dist = Distance (end_line->Point1.X, end_line->Point1.Y, end_line->Point2.X, end_line->Point2.Y); start_pinpad = start_extra->start.pin; end_pinpad = start_extra->end.pin; fp = 0; r_search(CURRENT->line_tree, &box, NULL, gp_line_cb, 0); r_search(CURRENT->arc_tree, &box, NULL, gp_arc_cb, 0); r_search(CURRENT->text_tree, &box, NULL, gp_text_cb, 0); r_search(CURRENT->polygon_tree, &box, NULL, gp_poly_cb, 0); r_search(PCB->Data->pin_tree, &box, NULL, gp_pin_cb, 0); r_search(PCB->Data->via_tree, &box, NULL, gp_pin_cb, 0); r_search(PCB->Data->pad_tree, &box, NULL, gp_pad_cb, 0); /* radians, absolute angle of (at the moment) the start_line */ abs_angle = fa + start_angle; #if TRACE1 pcb_printf("\033[43;30mBest: at %#mD r %#mS, angle %.1f fp %d\033[0m\n", fx, fy, fr, r2d(fa), fp); #endif #if 0 if (fa > M_PI/2 || fa < -M_PI/2) { SET_FLAG (FOUNDFLAG, line); longjmp (abort_buf, 1); } #endif if (fp) { start_extra->end.waiting_for = fp_end; return; } start_extra->end.pending = 0; /* Step 0: check for merged arcs (special case). */ if (fx == ex && fy == ey && start_arc && end_arc && start_arc->X == end_arc->X && start_arc->Y == end_arc->Y) { /* Merge arcs */ int new_delta; new_delta = end_arc->StartAngle - start_arc->StartAngle; if (start_arc->Delta > 0) { while (new_delta > 360) new_delta -= 360; while (new_delta < 0) new_delta += 360; } else { while (new_delta < -360) new_delta += 360; while (new_delta > 0) new_delta -= 360; } #if TRACE1 pcb_printf("merging arcs at %#mS nd %d\n", start_arc->X, start_arc->Y, new_delta); print_extra(sarc_extra, 0); print_extra(earc_extra, 0); #endif mark_arc_for_deletion (end_arc); mark_line_for_deletion (start_line); mark_line_for_deletion (end_line); ChangeArcAngles (CURRENT, start_arc, start_arc->StartAngle, new_delta); fix_arc_extra (start_arc, sarc_extra); did_something ++; return; } /* Step 1: adjust start_arc's angles and move start_line's Point1 to match it. */ if (start_arc) { double new_delta; int del_arc = 0; /* We must always round towards "larger arcs", whichever way that is. */ new_delta = 180 - r2d(abs_angle); #if TRACE1 printf("new_delta starts at %d vs %d < %d\n", (int)new_delta, (int)start_arc->StartAngle, (int)start_arc->Delta); #endif if (start_arc->Delta < 0) new_delta = (int)(new_delta) + 90; else new_delta = (int)new_delta - 90; new_delta = new_delta - start_arc->StartAngle; while (new_delta > start_arc->Delta+180) new_delta -= 360; while (new_delta < start_arc->Delta-180) new_delta += 360; #if TRACE1 printf("new_delta adjusts to %d\n", (int)new_delta); printf("fa = %f, new_delta ends at %.1f vs start %d\n", fa, new_delta, (int)start_arc->StartAngle); #endif if (new_delta * start_arc->Delta <= 0) del_arc = 1; ChangeArcAngles (CURRENT, start_arc, start_arc->StartAngle, new_delta); fix_arc_extra (start_arc, sarc_extra); MoveObject (LINEPOINT_TYPE, CURRENT, start_line, &(start_line->Point1), sarc_extra->end.x - start_line->Point1.X, sarc_extra->end.y - start_line->Point1.Y); if (del_arc) { MoveObject (LINEPOINT_TYPE, CURRENT, start_line, &(start_line->Point1), sarc_extra->start.x - start_line->Point1.X, sarc_extra->start.y - start_line->Point1.Y); mark_arc_for_deletion (start_arc); } } /* Step 1.5: If the "obstacle" is right at the end, ignore it. */ { double oa = start_angle+fa - M_PI/2*se_sign; double ox = fx + fr * cos(oa); double oy = fy + fr * sin(oa); #if TRACE1 pcb_printf("obstacle at %#mD angle %d = arc starts at %#mD\n", fx, fy, (int)r2d(oa), (Coord)ox, (Coord)oy); #endif if (Distance (ox, oy, end_line->Point2.X, end_line->Point2.Y) < fr * SIN1D) { /* Pretend it doesn't exist. */ fx = ex; fy = ey; } } /* Step 2: If we have no obstacles, connect start and end. */ #if TRACE1 pcb_printf("fx %#mS ex %#mS fy %#mS ey %#mS\n", fx, ex, fy, ey); #endif if (fx == ex && fy == ey) { /* No obstacles. */ #if TRACE1 printf("\033[32mno obstacles\033[0m\n"); #endif if (end_arc) { int del_arc = 0; int new_delta, end_angle, pcb_fa, end_change; end_angle = end_arc->StartAngle + end_arc->Delta; if (end_arc->Delta < 0) end_angle -= 90; else end_angle += 90; /* We must round so as to make the larger arc. */ if (end_arc->Delta < 0) pcb_fa = - r2d(start_angle + fa); else pcb_fa = 1 - r2d(start_angle + fa); end_change = pcb_fa - end_angle; while (end_change > 180) end_change -= 360; while (end_change < -180) end_change += 360; new_delta = end_arc->Delta + end_change; if (new_delta * end_arc->Delta <= 0) del_arc = 1; ChangeArcAngles (CURRENT, end_arc, end_arc->StartAngle, new_delta); fix_arc_extra (end_arc, earc_extra); MoveObject (LINEPOINT_TYPE, CURRENT, start_line, &(start_line->Point2), earc_extra->end.x - start_line->Point2.X, earc_extra->end.y - start_line->Point2.Y); if (del_arc) { MoveObject (LINEPOINT_TYPE, CURRENT, start_line, &(start_line->Point2), earc_extra->start.x - start_line->Point2.X, earc_extra->start.y - start_line->Point2.Y); mark_arc_for_deletion (end_arc); } } else { MoveObject (LINEPOINT_TYPE, CURRENT, start_line, &(start_line->Point2), end_line->Point2.X - start_line->Point2.X, end_line->Point2.Y - start_line->Point2.Y); } mark_line_for_deletion (end_line); start_extra->end.pending = 1; #if TRACE1 printf("\033[35mdid_something: no obstacles\033[0m\n"); #endif did_something ++; npulled ++; status(); return; } /* Step 3: Compute the new intersection of start_line and end_line. */ ex = start_line->Point1.X + cos(start_angle + fa) * 10000.0; ey = start_line->Point1.Y + sin(start_angle + fa) * 10000.0; #if TRACE1 pcb_printf("temp point %#mS\n", ex, ey); pcb_printf("intersect %#mS-%#mS with %#mS-%#mS\n", start_line->Point1.X, start_line->Point1.Y, ex, ey, end_line->Point1.X, end_line->Point1.Y, end_line->Point2.X, end_line->Point2.Y); #endif if (! intersection_of_lines (start_line->Point1.X, start_line->Point1.Y, ex, ey, end_line->Point1.X, end_line->Point1.Y, end_line->Point2.X, end_line->Point2.Y, &ex, &ey)) { ex = end_line->Point2.X; ey = end_line->Point2.Y; } #if TRACE1 pcb_printf("new point %#mS\n", ex, ey); #endif MoveObject (LINEPOINT_TYPE, CURRENT, end_line, &(end_line->Point1), ex - end_line->Point1.X, ey - end_line->Point1.Y); /* Step 4: Split start_line at the obstacle and insert a zero-delta arc at it. */ new_arc = create_arc (start_line, fx, fy, fr, 90-(int)(r2d(start_angle+fa)+0.5) + 90 + 90*se_sign, -se_sign); new_aextra = ARC2EXTRA (new_arc); if (start_arc) sarc_extra = ARC2EXTRA (start_arc); if (end_arc) earc_extra = ARC2EXTRA (end_arc); MoveObject (LINEPOINT_TYPE, CURRENT, start_line, &(start_line->Point2), new_aextra->start.x - start_line->Point2.X, new_aextra->start.y - start_line->Point2.Y); new_line = create_line (start_line, new_aextra->end.x, new_aextra->end.y, ex, ey); start_extra = LINE2EXTRA (start_line); new_lextra = LINE2EXTRA (new_line); end_extra = LINE2EXTRA (end_line); new_lextra->start.pin = start_extra->start.pin; new_lextra->end.pin = start_extra->end.pin; new_lextra->start.pending = 1; new_lextra->end.pending = 1; start_extra->end.next = new_aextra; new_aextra->start.next = start_extra; new_aextra->end.next = new_lextra; new_lextra->start.next = new_aextra; new_lextra->end.next = end_extra; end_extra->start.next = new_lextra; /* Step 5: Recurse. */ did_something ++; npulled ++; status(); #if TRACE0 printf("\033[35mdid_something: recursing\033[0m\n"); { int i = gui->confirm_dialog("recurse?", 0); printf("confirm = %d\n", i); if (i == 0) return; } printf("\n\033[33mRECURSING\033[0m\n\n"); IncrementUndoSerialNumber(); #endif maybe_pull_1 (new_line); } /*! * \brief Given a line with a end_next, attempt to pull both ends. */ static void maybe_pull (LineType *line, Extra *e) { #if TRACE0 printf("maybe_pull: "); print_extra (e, 0); #endif if (e->end.next && EXTRA_IS_LINE (e->end.next)) { maybe_pull_1 (line); } else { e->end.pending = 0; if (e->start.next && EXTRA_IS_LINE (e->start.next)) { reverse_line (line); maybe_pull_1 (line); } else e->start.pending = 0; } } static void validate_pair (Extra *e, End *end) { if (!end->next) return; if (end->next->start.next == e) return; if (end->next->end.next == e) return; fprintf(stderr, "no backlink!\n"); print_extra (e, 0); print_extra (end->next, 0); abort(); } static void validate_pair_cb (AnyObjectType *ptr, Extra *extra, void *userdata) { validate_pair (extra, &extra->start); validate_pair (extra, &extra->end); } static void validate_pairs () { g_hash_table_foreach (lines, (GHFunc)validate_pair_cb, NULL); #if TRACE1 printf("\narcs\n"); #endif g_hash_table_foreach (arcs, (GHFunc)validate_pair_cb, NULL); } static void FreeExtra (Extra *extra) { g_slice_free (Extra, extra); } static void mark_ends_pending (LineType *line, Extra *extra, void *userdata) { int *select_flags = userdata; if (TEST_FLAGS (*select_flags, line)) { extra->start.pending = 1; extra->end.pending = 1; } } #if TRACE1 static void trace_print_extra (AnyObjectType *ptr, Extra *extra, void *userdata) { last_pextra = (Extra *)1; print_extra(extra, 0); } static void trace_print_lines_arcs (void) { printf("\nlines\n"); g_hash_table_foreach (lines, (GHFunc)trace_print_extra, NULL); printf("\narcs\n"); g_hash_table_foreach (arcs, (GHFunc)trace_print_extra, NULL); printf("\n"); } #endif static int GlobalPuller(int argc, char **argv, Coord x, Coord y) { int select_flags = 0; setbuf(stdout, 0); nloops = 0; npulled = 0; Message ("puller! %s\n", argc > 0 ? argv[0] : ""); if (argc > 0 && strcasecmp (argv[0], "selected") == 0) select_flags = SELECTEDFLAG; if (argc > 0 && strcasecmp (argv[0], "found") == 0) select_flags = FOUNDFLAG; Message ("optimizing...\n"); /* This canonicalizes all the lines, and cleans up near-misses. */ /* hid_actionl ("djopt", "puller", 0); */ current_is_bottom = (GetLayerGroupNumberByPointer(CURRENT) == GetLayerGroupNumberBySide (BOTTOM_SIDE)); current_is_top = (GetLayerGroupNumberByPointer(CURRENT) == GetLayerGroupNumberBySide (TOP_SIDE)); lines = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify)FreeExtra); arcs = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify)FreeExtra); Message ("pairing...\n"); find_pairs (); validate_pairs (); g_hash_table_foreach (lines, (GHFunc)mark_ends_pending, &select_flags); #if TRACE1 trace_print_lines_arcs (); #endif propogate_ends (); #if TRACE1 trace_print_lines_arcs (); trace_paths (); #endif Message ("pulling...\n"); if (setjmp(abort_buf) == 0) { #if TRACE0 int old_did_something = -1; #endif did_something = 1; while (did_something) { nloops ++; status(); did_something = 0; LINE_LOOP (CURRENT); { Extra *e = LINE2EXTRA (line); if (e->deleted) continue; #ifdef CHECK_LINE_PT_NEG if (line->Point1.X < 0) abort1(); #endif if (e->start.next || e->end.next) maybe_pull (line, e); #if TRACE0 if (did_something != old_did_something) { IncrementUndoSerialNumber(); old_did_something = did_something; if (gui->confirm_dialog("more?", 0) == 0) { did_something = 0; break; } } #endif /*gui->progress(0,0,0);*/ } END_LOOP; } } #if TRACE0 printf("\nlines\n"); g_hash_table_foreach (lines, (GHFunc)trace_print_extra, NULL); printf("\narcs\n"); g_hash_table_foreach (arcs, (GHFunc)trace_print_extra, NULL); printf("\n"); printf("\nlines\n"); #endif LINE_LOOP (CURRENT); { if (LINE2EXTRA (line)->deleted) RemoveLine (CURRENT, line); } END_LOOP; ARC_LOOP (CURRENT); { if (ARC2EXTRA (arc)->deleted) RemoveArc (CURRENT, arc); } END_LOOP; g_hash_table_unref (lines); g_hash_table_unref (arcs); IncrementUndoSerialNumber(); return 0; } /* Actions */ HID_Action puller_action_list[] = { {"Puller", "Click on a line-arc intersection or line segment", Puller, puller_help, puller_syntax}, {"GlobalPuller", 0, GlobalPuller, globalpuller_help, globalpuller_syntax} }; REGISTER_ACTIONS (puller_action_list) pcb-4.3.0/src/res_parse.y0000664000175000017500000000772113773431044012166 00000000000000%{ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #ifdef HAVE_STRING_H #include #endif #define YYDEBUG 0 #define YYERROR_VERBOSE 1 /* #define YYSTYPE void * */ #include "global.h" #include "resource.h" #include "res_parse.h" #ifdef HAVE_LIBDMALLOC #include #endif static Resource *parsed_res; static Resource *current_res; int reserror(const char *); int reslex(); #define f(x) current_res->flags |= x %} %name-prefix "res" %start top_res %union { int ival; char *sval; Resource *rval; }; %token STRING INCLUDE %type res %% top_res : { current_res = parsed_res = resource_create(NULL); } res_item_zm ; res : { current_res = resource_create(current_res); } '{' res_item_zm '}' { $$ = current_res; current_res = current_res->parent; } ; res_item_zm : res_item res_item_zm | ; res_item : STRING { resource_add_val(current_res, 0, $1, 0); f(FLAG_V); } | STRING '=' STRING { resource_add_val(current_res, $1, $3, 0); f(FLAG_NV); } | INCLUDE { resource_add_val(current_res, 0, $1, 0); f(FLAG_S); } | res { resource_add_val(current_res, 0, 0, $1); f(FLAG_S); } | STRING '=' res { resource_add_val(current_res, $1, 0, $3); f(FLAG_NS); } | error ; %% static const char *res_filename = NULL; static FILE *res_file = NULL; static const char **res_strings = NULL; static int res_string_idx = 0; int res_lineno; int res_parse_getchars(char *buf, int max_size) { if (res_file) { int i = fgetc(res_file); buf[0] = i; if (i == EOF) return 0; } else { if (res_strings[0] == 0) return 0; buf[0] = res_strings[0][res_string_idx]; res_string_idx ++; if (buf[0] == 0) { res_strings ++; res_string_idx = 0; buf[0] = '\n'; return 1; } } return 1; } Resource * resource_parse(const char *filename, const char **strings) { res_lineno = 1; if (filename) { res_file = fopen (filename, "r"); if (res_file == NULL) { perror(filename); return NULL; } res_filename = filename; } else if (strings) { res_strings = strings; res_string_idx = 0; } else return NULL; #if YYDEBUG yydebug = 1; #endif if (resparse()) parsed_res = NULL; if (filename) { fclose (res_file); res_filename = NULL; res_file = NULL; } else res_strings = NULL; return parsed_res; } Resource * resource_create(Resource *parent) { Resource *rv = (Resource *)malloc(sizeof(Resource)); rv->parent = parent; rv->flags = 0; rv->c = 0; rv->v = (ResourceVal *)malloc(sizeof(ResourceVal)); return rv; } void resource_add_val(Resource *n, char *name, char *value, Resource *subres) { n->v = (ResourceVal *)realloc(n->v, sizeof(ResourceVal)*(n->c+1)); n->v[n->c].name = name; n->v[n->c].value = value; n->v[n->c].subres = subres; n->c++; } char * resource_value(const Resource *res, char *name) { int i; if (res == 0 || name == 0) return 0; for (i=0; ic; i++) if (res->v[i].name && res->v[i].value && NSTRCMP(res->v[i].name, name) == 0) return res->v[i].value; return 0; } Resource * resource_subres(const Resource *res, const char *name) { int i; if (res == 0 || name == 0) return 0; for (i=0; ic; i++) if (res->v[i].name && res->v[i].subres && NSTRCMP(res->v[i].name, name) == 0) return res->v[i].subres; return 0; } int reserror(const char *str) { fprintf(stderr, "Error: %s around line %d: %s\n", res_file ? res_filename : "internal strings", res_lineno, str); return 0; } static void dump_res(Resource *n, int l) { int i; for (i=0; ic; i++) { if (n->v[i].subres) { printf("%*cn[%s] = {\n", l, ' ', n->v[i].name? n->v[i].name :""); dump_res(n->v[i].subres, l+3); printf("%*c}\n", l, ' '); } else printf("%*cn[%s] = v[%s]\n", l, ' ', n->v[i].name? n->v[i].name :"", n->v[i].value? n->v[i].value :""); } } void resource_dump (Resource *r) { dump_res (r, 0); } pcb-4.3.0/src/main-test.c0000664000175000017500000000250413773431044012050 00000000000000/*! * \file src/main-test.c * * \brief . * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 2015 Andrew Poelstra * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * Andrew Poelstra, 16966 60A Ave, V3S 8X5 Surrey, BC, Canada * asp11@sfu.ca */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "global.h" #include "pcb-printf.h" #include "object_list.h" int main (int argc, char *argv[]) { initialize_units (); pcb_printf_register_tests (); object_list_register_tests (); g_test_init (&argc, &argv, NULL); g_test_run (); return 0; } pcb-4.3.0/src/action.c0000664000175000017500000063267413773431044011445 00000000000000/*! * \file src/action.c * * \brief Action routines for output window. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA * haceaton@aplcomm.jhuapl.edu */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "global.h" #include "action.h" #include "autoplace.h" #include "autoroute.h" #include "buffer.h" #include "change.h" #include "copy.h" #include "create.h" #include "crosshair.h" #include "data.h" #include "draw.h" #include "error.h" #include "file.h" #include "find.h" #include "flags.h" #include "hid.h" #include "insert.h" #include "line.h" #include "mymem.h" #include "misc.h" #include "mirror.h" #include "move.h" #include "polygon.h" /*#include "print.h"*/ #include "rats.h" #include "remove.h" #include "report.h" #include "rotate.h" #include "rubberband.h" #include "search.h" #include "select.h" #include "set.h" #include "thermal.h" #include "undo.h" #include "rtree.h" #include "macro.h" #include "pcb-printf.h" #include #include /* rand() */ #ifdef HAVE_LIBDMALLOC #include #endif /* for fork() and friends */ #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_WAIT_H #include #endif /* --------------------------------------------------------------------------- * some local types */ typedef enum { F_AddSelected, F_All, F_AllConnections, F_AllRats, F_AllUnusedPins, F_Arc, F_Arrow, F_Block, F_Description, F_Cancel, F_Center, F_Clear, F_ClearAndRedraw, F_ClearList, F_Close, F_Found, F_Connection, F_Convert, F_Copy, F_CycleClip, F_CycleCrosshair, F_DeleteRats, F_Drag, F_DrillReport, F_Element, F_ElementByName, F_ElementConnections, F_ElementToBuffer, F_Escape, F_Find, F_FlipElement, F_FoundPins, F_Grid, F_InsertPoint, F_Layer, F_Layout, F_LayoutAs, F_LayoutToBuffer, F_Line, F_LineSize, F_Lock, F_Mirror, F_Move, F_NameOnPCB, F_Netlist, F_NetByName, F_None, F_Notify, F_Object, F_ObjectByName, F_PasteBuffer, F_PadByName, F_PinByName, F_PinOrPadName, F_Pinout, F_Polygon, F_PolygonHole, F_PreviousPoint, F_RatsNest, F_Rectangle, F_Redraw, F_Release, F_Revert, F_Remove, F_RemoveSelected, F_Report, F_Reset, F_ResetLinesAndPolygons, F_ResetPinsViasAndPads, F_Restore, F_Rotate, F_Save, F_Selected, F_SelectedArcs, F_SelectedElements, F_SelectedLines, F_SelectedNames, F_SelectedObjects, F_SelectedPads, F_SelectedPins, F_SelectedTexts, F_SelectedVias, F_SelectedRats, F_Stroke, F_Text, F_TextByName, F_TextScale, F_Thermal, F_ToLayout, F_ToggleAllDirections, F_ToggleAutoDRC, F_ToggleClearLine, F_ToggleFullPoly, F_ToggleGrid, F_ToggleHideNames, F_ToggleMask, F_ToggleName, F_ToggleObject, F_ToggleShowDRC, F_ToggleLiveRoute, F_ToggleRubberBandMode, F_ToggleStartDirection, F_ToggleSnapPin, F_ToggleThindraw, F_ToggleLockNames, F_ToggleOnlyNames, F_ToggleThindrawPoly, F_ToggleOrthoMove, F_ToggleLocalRef, F_ToggleCheckPlanes, F_ToggleUniqueNames, F_Via, F_ViaByName, F_Value, F_ViaDrillingHole, F_ViaSize, F_Zoom, F_ThroughHole, F_BuriedVias, F_ToggleAutoBuriedVias } FunctionID; typedef struct /* used to identify subfunctions */ { char *Identifier; FunctionID ID; } FunctionType; /* --------------------------------------------------------------------------- */ /* %start-doc actions 00delta Many actions take a @code{delta} parameter as the last parameter, which is an amount to change something. That @code{delta} may include units, as an additional parameter, such as @code{Action(Object,5,mm)}. If no units are specified, the default is PCB's native units (currently 1/100 mil). Also, if the delta is prefixed by @code{+} or @code{-}, the size is increased or decreased by that amount. Otherwise, the size size is set to the given amount. @example Action(Object,5,mil) Action(Object,+0.5,mm) Action(Object,-1) @end example Actions which take a @code{delta} parameter which do not accept all these options will specify what they do take. %end-doc */ /* %start-doc actions 00objects Many actions act on indicated objects on the board. They will have parameters like @code{ToggleObject} or @code{SelectedVias} to indicate what group of objects they act on. Unless otherwise specified, these parameters are defined as follows: @table @code @item Object @itemx ToggleObject Affects the object under the mouse pointer. If this action is invoked from a menu or script, the user will be prompted to click on an object, which is then the object affected. @item Selected @itemx SelectedObjects Affects all objects which are currently selected. At least, all selected objects for which the given action makes sense. @item SelectedPins @itemx SelectedVias @itemx Selected@var{Type} @itemx @i{etc} Affects all objects which are both selected and of the @var{Type} specified. @end table %end-doc */ /* %start-doc actions 00macros @macro pinshapes Pins, pads, and vias can have various shapes. All may be round. Pins and pads may be square (obviously "square" pads are usually rectangular). Pins and vias may be octagonal. When you change a shape flag of an element, you actually change all of its pins and pads. Note that the square flag takes precedence over the octagon flag, thus, if both the square and octagon flags are set, the object is square. When the square flag is cleared, the pins and pads will be either round or, if the octagon flag is set, octagonal. @end macro %end-doc */ /* --------------------------------------------------------------------------- * some local identifiers */ static PointType InsertedPoint; static LayerType *lastLayer; static struct { PolygonType *poly; LineType line; } fake; static struct { Coord X, Y; Cardinal Buffer; bool Click; bool Moving; /* selected type clicked on */ int Hit; /* move type clicked on */ void *ptr1; void *ptr2; void *ptr3; } Note; static bool netlist_loaded; static int defer_updates = 0; static int defer_needs_update = 0; static Cardinal polyIndex = 0; static bool saved_mode = false; #ifdef HAVE_LIBSTROKE static bool mid_stroke = false; static BoxType StrokeBox; #endif static FunctionType Functions[] = { {"AddSelected", F_AddSelected}, {"All", F_All}, {"AllConnections", F_AllConnections}, {"AllRats", F_AllRats}, {"AllUnusedPins", F_AllUnusedPins}, {"Arc", F_Arc}, {"Arrow", F_Arrow}, {"Block", F_Block}, {"Description", F_Description}, {"Cancel", F_Cancel}, {"Center", F_Center}, {"Clear", F_Clear}, {"ClearAndRedraw", F_ClearAndRedraw}, {"ClearList", F_ClearList}, {"Close", F_Close}, {"Found", F_Found}, {"Connection", F_Connection}, {"Convert", F_Convert}, {"Copy", F_Copy}, {"CycleClip", F_CycleClip}, {"CycleCrosshair", F_CycleCrosshair}, {"DeleteRats", F_DeleteRats}, {"Drag", F_Drag}, {"DrillReport", F_DrillReport}, {"Element", F_Element}, {"ElementByName", F_ElementByName}, {"ElementConnections", F_ElementConnections}, {"ElementToBuffer", F_ElementToBuffer}, {"Escape", F_Escape}, {"Find", F_Find}, {"FlipElement", F_FlipElement}, {"FoundPins", F_FoundPins}, {"Grid", F_Grid}, {"InsertPoint", F_InsertPoint}, {"Layer", F_Layer}, {"Layout", F_Layout}, {"LayoutAs", F_LayoutAs}, {"LayoutToBuffer", F_LayoutToBuffer}, {"Line", F_Line}, {"LineSize", F_LineSize}, {"Lock", F_Lock}, {"Mirror", F_Mirror}, {"Move", F_Move}, {"NameOnPCB", F_NameOnPCB}, {"Netlist", F_Netlist}, {"NetByName", F_NetByName}, {"None", F_None}, {"Notify", F_Notify}, {"Object", F_Object}, {"ObjectByName", F_ObjectByName}, {"PasteBuffer", F_PasteBuffer}, {"PadByName", F_PadByName}, {"PinByName", F_PinByName}, {"PinOrPadName", F_PinOrPadName}, {"Pinout", F_Pinout}, {"Polygon", F_Polygon}, {"PolygonHole", F_PolygonHole}, {"PreviousPoint", F_PreviousPoint}, {"RatsNest", F_RatsNest}, {"Rectangle", F_Rectangle}, {"Redraw", F_Redraw}, {"Release", F_Release}, {"Remove", F_Remove}, {"RemoveSelected", F_RemoveSelected}, {"Report", F_Report}, {"Reset", F_Reset}, {"ResetLinesAndPolygons", F_ResetLinesAndPolygons}, {"ResetPinsViasAndPads", F_ResetPinsViasAndPads}, {"Restore", F_Restore}, {"Revert", F_Revert}, {"Rotate", F_Rotate}, {"Save", F_Save}, {"Selected", F_Selected}, {"SelectedArcs", F_SelectedArcs}, {"SelectedElements", F_SelectedElements}, {"SelectedLines", F_SelectedLines}, {"SelectedNames", F_SelectedNames}, {"SelectedObjects", F_SelectedObjects}, {"SelectedPins", F_SelectedPins}, {"SelectedPads", F_SelectedPads}, {"SelectedRats", F_SelectedRats}, {"SelectedTexts", F_SelectedTexts}, {"SelectedVias", F_SelectedVias}, {"Stroke", F_Stroke}, {"Text", F_Text}, {"TextByName", F_TextByName}, {"TextScale", F_TextScale}, {"Thermal", F_Thermal}, {"ToLayout", F_ToLayout}, {"Toggle45Degree", F_ToggleAllDirections}, {"ToggleClearLine", F_ToggleClearLine}, {"ToggleFullPoly", F_ToggleFullPoly}, {"ToggleGrid", F_ToggleGrid}, {"ToggleMask", F_ToggleMask}, {"ToggleName", F_ToggleName}, {"ToggleObject", F_ToggleObject}, {"ToggleRubberBandMode", F_ToggleRubberBandMode}, {"ToggleStartDirection", F_ToggleStartDirection}, {"ToggleSnapPin", F_ToggleSnapPin}, {"ToggleThindraw", F_ToggleThindraw}, {"ToggleThindrawPoly", F_ToggleThindrawPoly}, {"ToggleLockNames", F_ToggleLockNames}, {"ToggleOnlyNames", F_ToggleOnlyNames}, {"ToggleHideNames", F_ToggleHideNames}, {"ToggleCheckPlanes", F_ToggleCheckPlanes}, {"ToggleLocalRef", F_ToggleLocalRef}, {"ToggleOrthoMove", F_ToggleOrthoMove}, {"ToggleShowDRC", F_ToggleShowDRC}, {"ToggleLiveRoute", F_ToggleLiveRoute}, {"ToggleAutoDRC", F_ToggleAutoDRC}, {"ToggleUniqueNames", F_ToggleUniqueNames}, {"Value", F_Value}, {"Via", F_Via}, {"ViaByName", F_ViaByName}, {"ViaSize", F_ViaSize}, {"ViaDrillingHole", F_ViaDrillingHole}, {"Zoom", F_Zoom}, {"ThroughHole", F_ThroughHole}, {"TH", F_ThroughHole}, {"BuriedVias", F_BuriedVias}, {"ToggleAutoBuriedVias", F_ToggleAutoBuriedVias} }; /* --------------------------------------------------------------------------- * some local routines */ static int GetFunctionID (String); static void AdjustAttachedBox (void); static void NotifyLine (void); static void NotifyBlock (void); static void NotifyMode (void); static void ClearWarnings (void); #ifdef HAVE_LIBSTROKE static void FinishStroke (void); extern void stroke_init (void); extern void stroke_record (int x, int y); extern int stroke_trans (char *s); #endif static void ChangeFlag (char *, char *, int, char *); #ifdef HAVE_LIBSTROKE /*! * \brief Try to recognize the stroke sent. */ void FinishStroke (void) { char msg[255]; int type; unsigned long num; void *ptr1, *ptr2, *ptr3; mid_stroke = false; if (stroke_trans (msg)) { num = atoi (msg); switch (num) { case 456: if (Settings.Mode == LINE_MODE) { SetMode (LINE_MODE); } break; case 9874123: case 74123: case 987412: case 8741236: case 874123: RotateScreenObject (StrokeBox.X1, StrokeBox.Y1, SWAP_IDENT ? 1 : 3); break; case 7896321: case 786321: case 789632: case 896321: RotateScreenObject (StrokeBox.X1, StrokeBox.Y1, SWAP_IDENT ? 3 : 1); break; case 258: SetMode (LINE_MODE); break; case 852: SetMode (ARROW_MODE); break; case 1478963: ActionUndo (""); break; case 147423: case 147523: case 1474123: Redo (true); break; case 148963: case 147863: case 147853: case 145863: SetMode (VIA_MODE); break; case 951: case 9651: case 9521: case 9621: case 9851: case 9541: case 96521: case 96541: case 98541: /* XXX: FIXME: Call a zoom-extents action */ break; case 159: case 1269: case 1259: case 1459: case 1569: case 1589: case 12569: case 12589: case 14589: /* XXX: FIXME: Zoom to fit the box StrokeBox.[X1,Y1] - StrokeBox.[X2,Y2] */ break; default: Message (_("Unknown stroke %s\n"), msg); break; } } else gui->beep (); } #endif /*! * \brief Clear warning color from pins/pads. */ static void ClearWarnings () { Settings.RatWarn = false; ALLPIN_LOOP (PCB->Data); { if (TEST_FLAG (WARNFLAG, pin)) { CLEAR_FLAG (WARNFLAG, pin); DrawPin (pin); } } ENDALL_LOOP; ALLPAD_LOOP (PCB->Data); { if (TEST_FLAG (WARNFLAG, pad)) { CLEAR_FLAG (WARNFLAG, pad); DrawPad (pad); } } ENDALL_LOOP; Draw (); } /*! * \brief Click callback. * * This is called a clicktime after a mouse down, to we can distinguish * between short clicks (typically: select or create something) and long * clicks. Long clicks typically drag something. */ static void click_cb (hidval hv) { if (Note.Click) { notify_crosshair_change (false); Note.Click = false; if (Note.Moving && !gui->shift_is_pressed ()) { Note.Buffer = Settings.BufferNumber; SetBufferNumber (MAX_BUFFER - 1); ClearBuffer (PASTEBUFFER); AddSelectedToBuffer (PASTEBUFFER, Note.X, Note.Y, true); SaveUndoSerialNumber (); RemoveSelected (); SaveMode (); saved_mode = true; SetMode (PASTEBUFFER_MODE); } else if (Note.Hit && !gui->shift_is_pressed ()) { SaveMode (); saved_mode = true; SetMode (gui->control_is_pressed ()? COPY_MODE : MOVE_MODE); Crosshair.AttachedObject.Ptr1 = Note.ptr1; Crosshair.AttachedObject.Ptr2 = Note.ptr2; Crosshair.AttachedObject.Ptr3 = Note.ptr3; Crosshair.AttachedObject.Type = Note.Hit; AttachForCopy (Note.X, Note.Y); } else { BoxType box; Note.Hit = 0; Note.Moving = false; SaveUndoSerialNumber (); box.X1 = -MAX_COORD; box.Y1 = -MAX_COORD; box.X2 = MAX_COORD; box.Y2 = MAX_COORD; /* unselect first if shift key not down */ if (!gui->shift_is_pressed () && SelectBlock (&box, false)) SetChangedFlag (true); NotifyBlock (); Crosshair.AttachedBox.Point1.X = Note.X; Crosshair.AttachedBox.Point1.Y = Note.Y; } notify_crosshair_change (true); } } /*! * \brief This is typically called when the mouse has moved or the mouse * button was released. */ static void ReleaseMode (void) { BoxType box; if (Note.Click) { BoxType box; box.X1 = -MAX_COORD; box.Y1 = -MAX_COORD; box.X2 = MAX_COORD; box.Y2 = MAX_COORD; Note.Click = false; /* inhibit timer action */ SaveUndoSerialNumber (); /* unselect first if shift key not down */ if (!gui->shift_is_pressed ()) { if (SelectBlock (&box, false)) SetChangedFlag (true); if (Note.Moving) { Note.Moving = 0; Note.Hit = 0; return; } } /* Restore the SN so that if we select something the deselect/select combo gets the same SN. */ RestoreUndoSerialNumber(); if (SelectObject ()) SetChangedFlag (true); else /* We didn't select anything new, so, the deselection should get its own SN. */ IncrementUndoSerialNumber(); Note.Hit = 0; Note.Moving = 0; } else if (Note.Moving) { RestoreUndoSerialNumber (); NotifyMode (); ClearBuffer (PASTEBUFFER); SetBufferNumber (Note.Buffer); Note.Moving = false; Note.Hit = 0; } else if (Note.Hit) { NotifyMode (); Note.Hit = 0; } else if (Settings.Mode == ARROW_MODE) { box.X1 = MIN (Crosshair.AttachedBox.Point1.X, Crosshair.AttachedBox.Point2.X); box.Y1 = MIN (Crosshair.AttachedBox.Point1.Y, Crosshair.AttachedBox.Point2.Y); box.X2 = MAX (Crosshair.AttachedBox.Point1.X, Crosshair.AttachedBox.Point2.X); box.Y2 = MAX (Crosshair.AttachedBox.Point1.Y, Crosshair.AttachedBox.Point2.Y); RestoreUndoSerialNumber (); if (SelectBlock (&box, true)) SetChangedFlag (true); else if (Bumped) IncrementUndoSerialNumber (); Crosshair.AttachedBox.State = STATE_FIRST; } if (saved_mode) RestoreMode (); saved_mode = false; } #define HSIZE 257 static char function_hash[HSIZE]; static int hash_initted = 0; static int hashfunc(String s) { int i = 0; while (*s) { i ^= i >> 16; i = (i * 13) ^ (unsigned char)tolower((int) *s); s ++; } i = (unsigned int)i % HSIZE; return i; } /*! * \brief Get function ID of passed string. */ static int GetFunctionID (String Ident) { int i, h; if (Ident == 0) return -1; if (!hash_initted) { hash_initted = 1; if (HSIZE < ENTRIES (Functions) * 2) { fprintf(stderr, _("Error: function hash size too small (%d vs %lu at %s:%d)\n"), HSIZE, (unsigned long) ENTRIES (Functions)*2, __FILE__, __LINE__); exit(1); } if (ENTRIES (Functions) > 254) { /* Change 'char' to 'int' and remove this when we get to 256 strings to hash. */ fprintf(stderr, _("Error: function hash type too small (%d vs %lu at %s:%d)\n"), 256, (unsigned long) ENTRIES (Functions), __FILE__, __LINE__); exit(1); } for (i=ENTRIES (Functions)-1; i>=0; i--) { h = hashfunc (Functions[i].Identifier); while (function_hash[h]) h = (h + 1) % HSIZE; function_hash[h] = i + 1; } } i = hashfunc (Ident); while (1) { /* We enforce the "hash table bigger than function table" rule, so we know there will be at least one zero entry to find. */ if (!function_hash[i]) return (-1); if (!strcasecmp (Ident, Functions[function_hash[i]-1].Identifier)) return ((int) Functions[function_hash[i]-1].ID); i = (i + 1) % HSIZE; } } /*! * \brief Set new coordinates if in 'RECTANGLE' mode. * * The cursor shape is also adjusted. */ static void AdjustAttachedBox (void) { if (Settings.Mode == ARC_MODE) { Crosshair.AttachedBox.otherway = gui->shift_is_pressed (); return; } switch (Crosshair.AttachedBox.State) { case STATE_SECOND: /* one corner is selected */ { /* update coordinates */ Crosshair.AttachedBox.Point2.X = Crosshair.X; Crosshair.AttachedBox.Point2.Y = Crosshair.Y; break; } } } /*! * \brief Adjusts the objects which are to be created like attached * lines. */ void AdjustAttachedObjects (void) { PointType *pnt; switch (Settings.Mode) { /* update at least an attached block (selection) */ case NO_MODE: case ARROW_MODE: if (Crosshair.AttachedBox.State) { Crosshair.AttachedBox.Point2.X = Crosshair.X; Crosshair.AttachedBox.Point2.Y = Crosshair.Y; } break; /* rectangle creation mode */ case RECTANGLE_MODE: case ARC_MODE: AdjustAttachedBox (); break; /* polygon creation mode */ case POLYGON_MODE: case POLYGONHOLE_MODE: AdjustAttachedLine (); break; /* line creation mode */ case LINE_MODE: if (PCB->RatDraw || PCB->Clipping == 0) AdjustAttachedLine (); else AdjustTwoLine (PCB->Clipping - 1); break; /* point insertion mode */ case INSERTPOINT_MODE: pnt = AdjustInsertPoint (); if (pnt) InsertedPoint = *pnt; break; case ROTATE_MODE: break; } } /*! * \brief Creates points of a line. */ static void NotifyLine (void) { int type = NO_TYPE; void *ptr1, *ptr2, *ptr3; if (!Marked.status || TEST_FLAG (LOCALREFFLAG, PCB)) SetLocalRef (Crosshair.X, Crosshair.Y, true); switch (Crosshair.AttachedLine.State) { case STATE_FIRST: /* first point */ if (PCB->RatDraw && SearchScreen (Crosshair.X, Crosshair.Y, PAD_TYPE | PIN_TYPE, &ptr1, &ptr1, &ptr1) == NO_TYPE) { gui->beep (); break; } if (TEST_FLAG (AUTODRCFLAG, PCB) && Settings.Mode == LINE_MODE) { type = SearchScreen (Crosshair.X, Crosshair.Y, PIN_TYPE | PAD_TYPE | VIA_TYPE, &ptr1, &ptr2, &ptr3); LookupConnection (Crosshair.X, Crosshair.Y, true, 1, CONNECTEDFLAG, false); LookupConnection (Crosshair.X, Crosshair.Y, true, 1, FOUNDFLAG, true); } if (type == PIN_TYPE || type == VIA_TYPE) { Crosshair.AttachedLine.Point1.X = Crosshair.AttachedLine.Point2.X = ((PinType *) ptr2)->X; Crosshair.AttachedLine.Point1.Y = Crosshair.AttachedLine.Point2.Y = ((PinType *) ptr2)->Y; } else if (type == PAD_TYPE) { PadType *pad = (PadType *) ptr2; double d1 = Distance (Crosshair.X, Crosshair.Y, pad->Point1.X, pad->Point1.Y); double d2 = Distance (Crosshair.X, Crosshair.Y, pad->Point2.X, pad->Point2.Y); if (d2 < d1) { Crosshair.AttachedLine.Point1 = Crosshair.AttachedLine.Point2 = pad->Point2; } else { Crosshair.AttachedLine.Point1 = Crosshair.AttachedLine.Point2 = pad->Point1; } } else { Crosshair.AttachedLine.Point1.X = Crosshair.AttachedLine.Point2.X = Crosshair.X; Crosshair.AttachedLine.Point1.Y = Crosshair.AttachedLine.Point2.Y = Crosshair.Y; } Crosshair.AttachedLine.State = STATE_SECOND; break; case STATE_SECOND: /* fall through to third state too */ lastLayer = CURRENT; default: /* all following points */ Crosshair.AttachedLine.State = STATE_THIRD; break; } } /*! * \brief Create first or second corner of a marked block. */ static void NotifyBlock (void) { notify_crosshair_change (false); switch (Crosshair.AttachedBox.State) { case STATE_FIRST: /* setup first point */ Crosshair.AttachedBox.Point1.X = Crosshair.AttachedBox.Point2.X = Crosshair.X; Crosshair.AttachedBox.Point1.Y = Crosshair.AttachedBox.Point2.Y = Crosshair.Y; Crosshair.AttachedBox.State = STATE_SECOND; break; case STATE_SECOND: /* setup second point */ Crosshair.AttachedBox.State = STATE_THIRD; break; } notify_crosshair_change (true); } /*! * \brief This is called after every mode change, like mouse button pressed, * mouse button released, dragging something started or a different tool * selected. * * It does what's appropriate for the current mode setting. * This can also mean creation of an object at the current crosshair location. * * New created objects are added to the create undo list of course. */ static void NotifyMode (void) { void *ptr1, *ptr2, *ptr3; int type; if (Settings.RatWarn) ClearWarnings (); switch (Settings.Mode) { case ARROW_MODE: { int test; hidval hv; Note.Click = true; /* do something after click time */ gui->add_timer (click_cb, CLICK_TIME, hv); /* see if we clicked on something already selected * (Note.Moving) or clicked on a MOVE_TYPE * (Note.Hit) */ for (test = (SELECT_TYPES | MOVE_TYPES) & ~RATLINE_TYPE; test; test &= ~type) { type = SearchScreen (Note.X, Note.Y, test, &ptr1, &ptr2, &ptr3); if (!Note.Hit && (type & MOVE_TYPES) && !TEST_FLAG (LOCKFLAG, (PinType *) ptr2)) { Note.Hit = type; Note.ptr1 = ptr1; Note.ptr2 = ptr2; Note.ptr3 = ptr3; } if (!Note.Moving && (type & SELECT_TYPES) && TEST_FLAG (SELECTEDFLAG, (PinType *) ptr2)) Note.Moving = true; if ((Note.Hit && Note.Moving) || type == NO_TYPE) break; } break; } case VIA_MODE: { PinType *via; if (!PCB->ViaOn) { Message (_("You must turn via visibility on before\n" "you can place vias\n")); break; } if ((via = CreateNewVia (PCB->Data, Note.X, Note.Y, Settings.ViaThickness, 2 * Settings.Keepaway, Settings.ViaMaskAperture, Settings.ViaDrillingHole, NULL, NoFlags ())) != NULL) { AddObjectToCreateUndoList (VIA_TYPE, via, via, via); if (gui->shift_is_pressed ()) ChangeObjectThermal (VIA_TYPE, via, via, via, PCB->ThermStyle); IncrementUndoSerialNumber (); DrawVia (via); Draw (); } break; } case ARC_MODE: { switch (Crosshair.AttachedBox.State) { case STATE_FIRST: Crosshair.AttachedBox.Point1.X = Crosshair.AttachedBox.Point2.X = Note.X; Crosshair.AttachedBox.Point1.Y = Crosshair.AttachedBox.Point2.Y = Note.Y; Crosshair.AttachedBox.State = STATE_SECOND; break; case STATE_SECOND: case STATE_THIRD: { ArcType *arc; Coord wx, wy; Angle sa, dir; wx = Note.X - Crosshair.AttachedBox.Point1.X; wy = Note.Y - Crosshair.AttachedBox.Point1.Y; if (XOR (Crosshair.AttachedBox.otherway, abs (wy) > abs (wx))) { Crosshair.AttachedBox.Point2.X = Crosshair.AttachedBox.Point1.X + abs (wy) * SGNZ (wx); sa = (wx >= 0) ? 0 : 180; #ifdef ARC45 if (abs (wy) / 2 >= abs (wx)) dir = (SGNZ (wx) == SGNZ (wy)) ? 45 : -45; else #endif dir = (SGNZ (wx) == SGNZ (wy)) ? 90 : -90; } else { Crosshair.AttachedBox.Point2.Y = Crosshair.AttachedBox.Point1.Y + abs (wx) * SGNZ (wy); sa = (wy >= 0) ? -90 : 90; #ifdef ARC45 if (abs (wx) / 2 >= abs (wy)) dir = (SGNZ (wx) == SGNZ (wy)) ? -45 : 45; else #endif dir = (SGNZ (wx) == SGNZ (wy)) ? -90 : 90; wy = wx; } if (abs (wy) > 0 && (arc = CreateNewArcOnLayer (CURRENT, Crosshair. AttachedBox. Point2.X, Crosshair. AttachedBox. Point2.Y, abs (wy), abs (wy), sa, dir, Settings. LineThickness, 2 * Settings. Keepaway, MakeFlags (TEST_FLAG (CLEARNEWFLAG, PCB) ? CLEARLINEFLAG : 0)))) { BoxType *bx; bx = GetArcEnds (arc); Crosshair.AttachedBox.Point1.X = Crosshair.AttachedBox.Point2.X = bx->X2; Crosshair.AttachedBox.Point1.Y = Crosshair.AttachedBox.Point2.Y = bx->Y2; AddObjectToCreateUndoList (ARC_TYPE, CURRENT, arc, arc); IncrementUndoSerialNumber (); addedLines++; DrawArc (CURRENT, arc); Draw (); Crosshair.AttachedBox.State = STATE_THIRD; } break; } } break; } case LOCK_MODE: { type = SearchScreen (Note.X, Note.Y, LOCK_TYPES, &ptr1, &ptr2, &ptr3); if (type == ELEMENT_TYPE) { ElementType *element = (ElementType *) ptr2; TOGGLE_FLAG (LOCKFLAG, element); PIN_LOOP (element); { TOGGLE_FLAG (LOCKFLAG, pin); CLEAR_FLAG (SELECTEDFLAG, pin); } END_LOOP; PAD_LOOP (element); { TOGGLE_FLAG (LOCKFLAG, pad); CLEAR_FLAG (SELECTEDFLAG, pad); } END_LOOP; CLEAR_FLAG (SELECTEDFLAG, element); /* always re-draw it since I'm too lazy * to tell if a selected flag changed */ DrawElement (element); Draw (); SetChangedFlag (true); hid_actionl ("Report", "Object", NULL); } else if (type != NO_TYPE) { TextType *thing = (TextType *) ptr3; TOGGLE_FLAG (LOCKFLAG, thing); if (TEST_FLAG (LOCKFLAG, thing) && TEST_FLAG (SELECTEDFLAG, thing)) { /* this is not un-doable since LOCK isn't */ CLEAR_FLAG (SELECTEDFLAG, thing); DrawObject (type, ptr1, ptr2); Draw (); } SetChangedFlag (true); hid_actionl ("Report", "Object", NULL); } break; } case THERMAL_MODE: { if (((type = SearchScreen (Note.X, Note.Y, PIN_TYPES, &ptr1, &ptr2, &ptr3)) != NO_TYPE) && !TEST_FLAG (HOLEFLAG, (PinType *) ptr3)) { if (gui->shift_is_pressed ()) { int tstyle = GET_THERM (INDEXOFCURRENT, (PinType *) ptr3); tstyle++; if (tstyle > 5) tstyle = 1; ChangeObjectThermal (type, ptr1, ptr2, ptr3, tstyle); } else if (GET_THERM (INDEXOFCURRENT, (PinType *) ptr3)) ChangeObjectThermal (type, ptr1, ptr2, ptr3, 0); else ChangeObjectThermal (type, ptr1, ptr2, ptr3, PCB->ThermStyle); } break; } case LINE_MODE: /* do update of position */ NotifyLine (); if (Crosshair.AttachedLine.State != STATE_THIRD) break; /* Remove anchor if clicking on start point; * this means we can't paint 0 length lines * which could be used for square SMD pads. * Instead use a very small delta, or change * the file after saving. */ if (Crosshair.X == Crosshair.AttachedLine.Point1.X && Crosshair.Y == Crosshair.AttachedLine.Point1.Y) { SetMode (LINE_MODE); break; } if (PCB->RatDraw) { RatType *line; if ((line = AddNet ())) { addedLines++; AddObjectToCreateUndoList (RATLINE_TYPE, line, line, line); IncrementUndoSerialNumber (); DrawRat (line); Crosshair.AttachedLine.Point1.X = Crosshair.AttachedLine.Point2.X; Crosshair.AttachedLine.Point1.Y = Crosshair.AttachedLine.Point2.Y; Draw (); } break; } else /* create line if both ends are determined && length != 0 */ { LineType *line; int line_flags = 0; if (TEST_FLAG (AUTODRCFLAG, PCB) && !TEST_SILK_LAYER (CURRENT)) line_flags |= CONNECTEDFLAG | FOUNDFLAG; if (TEST_FLAG (CLEARNEWFLAG, PCB)) line_flags |= CLEARLINEFLAG; if (PCB->Clipping && Crosshair.AttachedLine.Point1.X == Crosshair.AttachedLine.Point2.X && Crosshair.AttachedLine.Point1.Y == Crosshair.AttachedLine.Point2.Y && (Crosshair.AttachedLine.Point2.X != Note.X || Crosshair.AttachedLine.Point2.Y != Note.Y)) { /* We will only need to paint the second line segment. Since we only check for vias on the first segment, swap them so the non-empty segment is the first segment. */ Crosshair.AttachedLine.Point2.X = Note.X; Crosshair.AttachedLine.Point2.Y = Note.Y; } if ((Crosshair.AttachedLine.Point1.X != Crosshair.AttachedLine.Point2.X || Crosshair.AttachedLine.Point1.Y != Crosshair.AttachedLine.Point2.Y)) { PinType *via; Cardinal layer_from, layer_to; if ((line = CreateDrawnLineOnLayer (CURRENT, Crosshair.AttachedLine.Point1.X, Crosshair.AttachedLine.Point1.Y, Crosshair.AttachedLine.Point2.X, Crosshair.AttachedLine.Point2.Y, Settings.LineThickness, 2 * Settings.Keepaway, MakeFlags (line_flags))) != NULL) { addedLines++; AddObjectToCreateUndoList (LINE_TYPE, CURRENT, line, line); DrawLine (CURRENT, line); } /* place a via if vias are visible, the layer is in a new group since the last line and there isn't a pin already here */ if (TEST_FLAG (AUTOBURIEDVIASFLAG, PCB)) { layer_from = GetLayerNumber (PCB->Data, lastLayer); layer_to = GetLayerNumber (PCB->Data, CURRENT); } else { layer_from = 0; layer_to = 0; } if (PCB->ViaOn && GetLayerGroupNumberByPointer (CURRENT) != GetLayerGroupNumberByPointer (lastLayer) && SearchObjectByLocation (PIN_TYPES, &ptr1, &ptr2, &ptr3, Crosshair.AttachedLine.Point1.X, Crosshair.AttachedLine.Point1.Y, Settings.ViaThickness / 2) == NO_TYPE && (via = CreateNewViaEx (PCB->Data, Crosshair.AttachedLine.Point1.X, Crosshair.AttachedLine.Point1.Y, Settings.ViaThickness, 2 * Settings.Keepaway, Settings.ViaMaskAperture, Settings.ViaDrillingHole, NULL, NoFlags (), layer_from, layer_to)) != NULL) { AddObjectToCreateUndoList (VIA_TYPE, via, via, via); DrawVia (via); } /* copy the coordinates */ Crosshair.AttachedLine.Point1.X = Crosshair.AttachedLine.Point2.X; Crosshair.AttachedLine.Point1.Y = Crosshair.AttachedLine.Point2.Y; IncrementUndoSerialNumber (); lastLayer = CURRENT; } if (PCB->Clipping && (Note.X != Crosshair.AttachedLine.Point2.X || Note.Y != Crosshair.AttachedLine.Point2.Y)) { if ((line = CreateDrawnLineOnLayer (CURRENT, Crosshair.AttachedLine.Point2.X, Crosshair.AttachedLine.Point2.Y, Note.X, Note.Y, Settings.LineThickness, 2 * Settings.Keepaway, MakeFlags (line_flags))) != NULL) { addedLines++; AddObjectToCreateUndoList (LINE_TYPE, CURRENT, line, line); IncrementUndoSerialNumber (); DrawLine (CURRENT, line); } /* move to new start point */ Crosshair.AttachedLine.Point1.X = Note.X; Crosshair.AttachedLine.Point1.Y = Note.Y; Crosshair.AttachedLine.Point2.X = Note.X; Crosshair.AttachedLine.Point2.Y = Note.Y; if (TEST_FLAG (SWAPSTARTDIRFLAG, PCB)) { PCB->Clipping ^= 3; } } if (TEST_FLAG (AUTODRCFLAG, PCB) && !TEST_SILK_LAYER (CURRENT)) LookupConnection (Note.X, Note.Y, true, 1, CONNECTEDFLAG, false); Draw (); } break; case RECTANGLE_MODE: /* do update of position */ NotifyBlock (); /* create rectangle if both corners are determined * and width, height are != 0 */ if (Crosshair.AttachedBox.State == STATE_THIRD && Crosshair.AttachedBox.Point1.X != Crosshair.AttachedBox.Point2.X && Crosshair.AttachedBox.Point1.Y != Crosshair.AttachedBox.Point2.Y) { PolygonType *polygon; int flags = CLEARPOLYFLAG; if (TEST_FLAG (NEWFULLPOLYFLAG, PCB)) flags |= FULLPOLYFLAG; if ((polygon = CreateNewPolygonFromRectangle (CURRENT, Crosshair. AttachedBox.Point1.X, Crosshair. AttachedBox.Point1.Y, Crosshair. AttachedBox.Point2.X, Crosshair. AttachedBox.Point2.Y, MakeFlags (flags))) != NULL) { AddObjectToCreateUndoList (POLYGON_TYPE, CURRENT, polygon, polygon); IncrementUndoSerialNumber (); DrawPolygon (CURRENT, polygon); Draw (); } /* reset state to 'first corner' */ Crosshair.AttachedBox.State = STATE_FIRST; } break; case TEXT_MODE: { char *string; if ((string = gui->prompt_for (_("Enter text:"), "")) != NULL) { if (strlen(string) > 0) { TextType *text; int flag = CLEARLINEFLAG; if (GetLayerGroupNumberByNumber (INDEXOFCURRENT) == GetLayerGroupNumberBySide (BOTTOM_SIDE)) flag |= ONSOLDERFLAG; if ((text = CreateNewText (CURRENT, &PCB->Font, Note.X, Note.Y, 0, Settings.TextScale, string, MakeFlags (flag))) != NULL) { AddObjectToCreateUndoList (TEXT_TYPE, CURRENT, text, text); IncrementUndoSerialNumber (); DrawText (CURRENT, text); Draw (); } } free (string); } break; } case POLYGON_MODE: { PointType *points = Crosshair.AttachedPolygon.Points; Cardinal n = Crosshair.AttachedPolygon.PointN; /* do update of position; use the 'LINE_MODE' mechanism */ NotifyLine (); /* check if this is the last point of a polygon */ if (n >= 3 && points->X == Crosshair.AttachedLine.Point2.X && points->Y == Crosshair.AttachedLine.Point2.Y) { CopyAttachedPolygonToLayer (); Draw (); break; } /* create new point if it's the first one or if it's * different to the last one */ if (!n || points[n - 1].X != Crosshair.AttachedLine.Point2.X || points[n - 1].Y != Crosshair.AttachedLine.Point2.Y) { CreateNewPointInPolygon (&Crosshair.AttachedPolygon, Crosshair.AttachedLine.Point2.X, Crosshair.AttachedLine.Point2.Y); /* copy the coordinates */ Crosshair.AttachedLine.Point1.X = Crosshair.AttachedLine.Point2.X; Crosshair.AttachedLine.Point1.Y = Crosshair.AttachedLine.Point2.Y; } break; } case POLYGONHOLE_MODE: { switch (Crosshair.AttachedObject.State) { /* first notify, lookup object */ case STATE_FIRST: Crosshair.AttachedObject.Type = SearchScreen (Note.X, Note.Y, POLYGON_TYPE, &Crosshair.AttachedObject.Ptr1, &Crosshair.AttachedObject.Ptr2, &Crosshair.AttachedObject.Ptr3); if (Crosshair.AttachedObject.Type == NO_TYPE) { Message (_("The first point of a polygon hole must be on a polygon.\n")); break; /* don't start doing anything if clicked outside of polys */ } if (TEST_FLAG(LOCKFLAG, (PolygonType *) Crosshair.AttachedObject.Ptr2)) { Message (_("Sorry, the object is locked\n")); Crosshair.AttachedObject.Type = NO_TYPE; break; } else Crosshair.AttachedObject.State = STATE_SECOND; /* Fall thru: first click is also the first point of the * poly hole. */ /* second notify, insert new point into object */ case STATE_SECOND: { PointType *points = Crosshair.AttachedPolygon.Points; Cardinal n = Crosshair.AttachedPolygon.PointN; POLYAREA *original, *new_hole, *result; FlagType Flags; /* do update of position; use the 'LINE_MODE' mechanism */ NotifyLine (); /* check if this is the last point of a polygon */ if (n >= 3 && points->X == Crosshair.AttachedLine.Point2.X && points->Y == Crosshair.AttachedLine.Point2.Y) { /* Create POLYAREAs from the original polygon * and the new hole polygon */ original = PolygonToPoly ((PolygonType *)Crosshair.AttachedObject.Ptr2); new_hole = PolygonToPoly (&Crosshair.AttachedPolygon); /* Subtract the hole from the original polygon shape */ poly_Boolean_free (original, new_hole, &result, PBO_SUB); /* Convert the resulting polygon(s) into a new set of nodes * and place them on the page. Delete the original polygon. */ SaveUndoSerialNumber (); Flags = ((PolygonType *)Crosshair.AttachedObject.Ptr2)->Flags; PolyToPolygonsOnLayer (PCB->Data, (LayerType *)Crosshair.AttachedObject.Ptr1, result, Flags); RemoveObject (POLYGON_TYPE, Crosshair.AttachedObject.Ptr1, Crosshair.AttachedObject.Ptr2, Crosshair.AttachedObject.Ptr3); RestoreUndoSerialNumber (); IncrementUndoSerialNumber (); Draw (); /* reset state of attached line */ memset (&Crosshair.AttachedPolygon, 0, sizeof (PolygonType)); Crosshair.AttachedObject.State = STATE_FIRST; addedLines = 0; break; } /* create new point if it's the first one or if it's * different to the last one */ if (!n || points[n - 1].X != Crosshair.AttachedLine.Point2.X || points[n - 1].Y != Crosshair.AttachedLine.Point2.Y) { CreateNewPointInPolygon (&Crosshair.AttachedPolygon, Crosshair.AttachedLine.Point2.X, Crosshair.AttachedLine.Point2.Y); /* copy the coordinates */ Crosshair.AttachedLine.Point1.X = Crosshair.AttachedLine.Point2.X; Crosshair.AttachedLine.Point1.Y = Crosshair.AttachedLine.Point2.Y; } break; } } break; } case PASTEBUFFER_MODE: { TextType estr[MAX_ELEMENTNAMES]; ElementType *e = 0; if (gui->shift_is_pressed ()) { int type = SearchScreen (Note.X, Note.Y, ELEMENT_TYPE, &ptr1, &ptr2, &ptr3); if (type == ELEMENT_TYPE) { e = (ElementType *) ptr1; if (e) { int i; memcpy (estr, e->Name, MAX_ELEMENTNAMES * sizeof (TextType)); for (i = 0; i < MAX_ELEMENTNAMES; ++i) estr[i].TextString = estr[i].TextString ? strdup(estr[i].TextString) : NULL; RemoveElement (e); } } } if (CopyPastebufferToLayout (Note.X, Note.Y)) SetChangedFlag (true); if (e) { int type = SearchScreen (Note.X, Note.Y, ELEMENT_TYPE, &ptr1, &ptr2, &ptr3); if (type == ELEMENT_TYPE && ptr1) { int i, save_n; e = (ElementType *) ptr1; save_n = NAME_INDEX (PCB); for (i = 0; i < MAX_ELEMENTNAMES; i++) { if (i == save_n) EraseElementName (e); r_delete_entry (PCB->Data->name_tree[i], (BoxType *) & (e->Name[i])); memcpy (&(e->Name[i]), &(estr[i]), sizeof (TextType)); e->Name[i].Element = e; SetTextBoundingBox (&PCB->Font, &(e->Name[i])); r_insert_entry (PCB->Data->name_tree[i], (BoxType *) & (e->Name[i]), 0); if (i == save_n) DrawElementName (e); } } } break; } case REMOVE_MODE: if ((type = SearchScreen (Note.X, Note.Y, REMOVE_TYPES, &ptr1, &ptr2, &ptr3)) != NO_TYPE) { if (TEST_FLAG (LOCKFLAG, (LineType *) ptr2)) { Message (_("Sorry, the object is locked\n")); break; } if (type == ELEMENT_TYPE) { RubberbandType *ptr; int i; Crosshair.AttachedObject.RubberbandN = 0; LookupRatLines (type, ptr1, ptr2, ptr3); ptr = Crosshair.AttachedObject.Rubberband; for (i = 0; i < Crosshair.AttachedObject.RubberbandN; i++) { if (PCB->RatOn) EraseRat ((RatType *) ptr->Line); if (TEST_FLAG (RUBBERENDFLAG, ptr->Line)) MoveObjectToRemoveUndoList (RATLINE_TYPE, ptr->Line, ptr->Line, ptr->Line); else TOGGLE_FLAG (RUBBERENDFLAG, ptr->Line); /* only remove line once */ ptr++; } } RemoveObject (type, ptr1, ptr2, ptr3); IncrementUndoSerialNumber (); SetChangedFlag (true); } break; case ROTATE_MODE: RotateScreenObject (Note.X, Note.Y, gui->shift_is_pressed ()? (SWAP_IDENT ? 1 : 3) : (SWAP_IDENT ? 3 : 1)); break; /* both are almost the same */ case COPY_MODE: case MOVE_MODE: switch (Crosshair.AttachedObject.State) { /* first notify, lookup object */ case STATE_FIRST: { int types = (Settings.Mode == COPY_MODE) ? COPY_TYPES : MOVE_TYPES; Crosshair.AttachedObject.Type = SearchScreen (Note.X, Note.Y, types, &Crosshair.AttachedObject.Ptr1, &Crosshair.AttachedObject.Ptr2, &Crosshair.AttachedObject.Ptr3); if (Crosshair.AttachedObject.Type != NO_TYPE) { if (Settings.Mode == MOVE_MODE && TEST_FLAG (LOCKFLAG, (PinType *) Crosshair.AttachedObject.Ptr2)) { Message (_("Sorry, the object is locked\n")); Crosshair.AttachedObject.Type = NO_TYPE; } else AttachForCopy (Note.X, Note.Y); } break; } /* second notify, move or copy object */ case STATE_SECOND: if (Settings.Mode == COPY_MODE) CopyObject (Crosshair.AttachedObject.Type, Crosshair.AttachedObject.Ptr1, Crosshair.AttachedObject.Ptr2, Crosshair.AttachedObject.Ptr3, Note.X - Crosshair.AttachedObject.X, Note.Y - Crosshair.AttachedObject.Y); else { MoveObjectAndRubberband (Crosshair.AttachedObject.Type, Crosshair.AttachedObject.Ptr1, Crosshair.AttachedObject.Ptr2, Crosshair.AttachedObject.Ptr3, Note.X - Crosshair.AttachedObject.X, Note.Y - Crosshair.AttachedObject.Y); SetLocalRef (0, 0, false); } SetChangedFlag (true); /* reset identifiers */ Crosshair.AttachedObject.Type = NO_TYPE; Crosshair.AttachedObject.State = STATE_FIRST; break; } break; /* insert a point into a polygon/line/... */ case INSERTPOINT_MODE: switch (Crosshair.AttachedObject.State) { /* first notify, lookup object */ case STATE_FIRST: Crosshair.AttachedObject.Type = SearchScreen (Note.X, Note.Y, INSERT_TYPES, &Crosshair.AttachedObject.Ptr1, &Crosshair.AttachedObject.Ptr2, &Crosshair.AttachedObject.Ptr3); if (Crosshair.AttachedObject.Type != NO_TYPE) { if (TEST_FLAG (LOCKFLAG, (PolygonType *) Crosshair.AttachedObject.Ptr2)) { Message (_("Sorry, the object is locked\n")); Crosshair.AttachedObject.Type = NO_TYPE; break; } else { /* get starting point of nearest segment */ if (Crosshair.AttachedObject.Type == POLYGON_TYPE) { fake.poly = (PolygonType *) Crosshair.AttachedObject.Ptr2; polyIndex = GetLowestDistancePolygonPoint (fake.poly, Note.X, Note.Y); fake.line.Point1 = fake.poly->Points[polyIndex]; fake.line.Point2 = fake.poly->Points[ prev_contour_point (fake.poly, polyIndex)]; Crosshair.AttachedObject.Ptr2 = &fake.line; } Crosshair.AttachedObject.State = STATE_SECOND; InsertedPoint = *AdjustInsertPoint (); } } break; /* second notify, insert new point into object */ case STATE_SECOND: if (Crosshair.AttachedObject.Type == POLYGON_TYPE) InsertPointIntoObject (POLYGON_TYPE, Crosshair.AttachedObject.Ptr1, fake.poly, &polyIndex, InsertedPoint.X, InsertedPoint.Y, false, false); else InsertPointIntoObject (Crosshair.AttachedObject.Type, Crosshair.AttachedObject.Ptr1, Crosshair.AttachedObject.Ptr2, &polyIndex, InsertedPoint.X, InsertedPoint.Y, false, false); SetChangedFlag (true); /* reset identifiers */ Crosshair.AttachedObject.Type = NO_TYPE; Crosshair.AttachedObject.State = STATE_FIRST; break; } break; } } /* --------------------------------------------------------------------------- */ static const char atomic_syntax[] = N_("Atomic(Save|Restore|Close|Block)"); static const char atomic_help[] = N_("Save or restore the undo serial number."); /* %start-doc actions Atomic This action allows making multiple-action bindings into an atomic operation that will be undone by a single Undo command. For example, to optimize rat lines, you'd delete the rats and re-add them. To group these into a single undo, you'd want the deletions and the additions to have the same undo serial number. So, you @code{Save}, delete the rats, @code{Restore}, add the rats - using the same serial number as the deletes, then @code{Block}, which checks to see if the deletions or additions actually did anything. If not, the serial number is set to the saved number, as there's nothing to undo. If something did happen, the serial number is incremented so that these actions are counted as a single undo step. @table @code @item Save Saves the undo serial number. @item Restore Returns it to the last saved number. @item Close Sets it to 1 greater than the last save. @item Block Does a Restore if there was nothing to undo, else does a Close. @end table %end-doc */ static int ActionAtomic (int argc, char **argv, Coord x, Coord y) { if (argc != 1) AFAIL (atomic); switch (GetFunctionID (argv[0])) { case F_Save: SaveUndoSerialNumber (); break; case F_Restore: RestoreUndoSerialNumber (); break; case F_Close: RestoreUndoSerialNumber (); IncrementUndoSerialNumber (); break; case F_Block: RestoreUndoSerialNumber (); if (Bumped) IncrementUndoSerialNumber (); break; } return 0; } /* -------------------------------------------------------------------------- */ static const char dumplibrary_syntax[] = N_("DumpLibrary()"); static const char dumplibrary_help[] = N_("Display the entire contents of the libraries."); /* %start-doc actions DumpLibrary %end-doc */ static int ActionDumpLibrary (int argc, char **argv, Coord x, Coord y) { int i, j; printf ("**** Do not count on this format. It will change ****\n\n"); printf ("MenuN = %d\n", (int) Library.MenuN); printf ("MenuMax = %d\n", (int) Library.MenuMax); for (i = 0; i < Library.MenuN; i++) { printf ("Library #%d:\n", i); printf (" EntryN = %d\n", (int) Library.Menu[i].EntryN); printf (" EntryMax = %d\n", (int) Library.Menu[i].EntryMax); printf (" Name = \"%s\"\n", UNKNOWN (Library.Menu[i].Name)); printf (" directory = \"%s\"\n", UNKNOWN (Library.Menu[i].directory)); printf (" Style = \"%s\"\n", UNKNOWN (Library.Menu[i].Style)); printf (" flag = %d\n", Library.Menu[i].flag); for (j = 0; j < Library.Menu[i].EntryN; j++) { printf (" #%4d: ", j); if (Library.Menu[i].Entry[j].Template == (char *) -1) { printf ("newlib: \"%s\"\n", UNKNOWN (Library.Menu[i].Entry[j].ListEntry)); } else { printf ("\"%s\", \"%s\", \"%s\", \"%s\", \"%s\"\n", UNKNOWN (Library.Menu[i].Entry[j].ListEntry), UNKNOWN (Library.Menu[i].Entry[j].Template), UNKNOWN (Library.Menu[i].Entry[j].Package), UNKNOWN (Library.Menu[i].Entry[j].Value), UNKNOWN (Library.Menu[i].Entry[j].Description)); } } } return 0; } /* -------------------------------------------------------------------------- */ static const char flip_syntax[] = N_("Flip(Object|Selected|SelectedElements)"); static const char flip_help[] = N_("Flip an element to the opposite side of the board."); /* %start-doc actions Flip Note that the location of the element will be symmetric about the cursor location; i.e. if the part you are pointing at will still be at the same spot once the element is on the other side. When flipping multiple elements, this retains their positions relative to each other, not their absolute positions on the board. %end-doc */ static int ActionFlip (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); ElementType *element; void *ptrtmp; int err = 0; if (function) { switch (GetFunctionID (function)) { case F_Object: if ((SearchScreen (x, y, ELEMENT_TYPE, &ptrtmp, &ptrtmp, &ptrtmp)) != NO_TYPE) { element = (ElementType *) ptrtmp; ChangeElementSide (element, 2 * Crosshair.Y - PCB->MaxHeight); IncrementUndoSerialNumber (); Draw (); } break; case F_Selected: case F_SelectedElements: ChangeSelectedElementSide (); break; default: err = 1; break; } if (!err) return 0; } AFAIL (flip); } /* -------------------------------------------------------------------------- */ static const char message_syntax[] = N_("Message(message)"); static const char message_help[] = N_("Writes a message to the log window."); /* %start-doc actions Message This action displays a message to the log window. This action is primarily provided for use by other programs which may interface with PCB. If multiple arguments are given, each one is sent to the log window followed by a newline. %end-doc */ static int ActionMessage (int argc, char **argv, Coord x, Coord y) { int i; if (argc < 1) AFAIL (message); for (i = 0; i < argc; i++) { Message (argv[i]); Message ("\n"); } return 0; } /* -------------------------------------------------------------------------- */ static const char setthermal_syntax[] = "SetThermal(Object|SelectedPins|SelectedVias|Selected, Style)"; static const char setthermal_help[] = N_("Set the thermal (on the current layer) of pins or vias to the given style.\n" "Style = 0 means no thermal.\n" "Style = 1 has diagonal fingers with sharp edges.\n" "Style = 2 has horizontal and vertical fingers with sharp edges.\n" "Style = 3 is a solid connection to the plane.\n" "Style = 4 has diagonal fingers with rounded edges.\n" "Style = 5 has horizontal and vertical fingers with rounded edges.\n"); /* %start-doc actions SetThermal This changes how/whether pins or vias connect to any rectangle or polygon on the current layer. The first argument can specify one object, or all selected pins, or all selected vias, or all selected pins and vias. The second argument specifies the style of connection. There are 5 possibilities: 0 - no connection, 1 - 45 degree fingers with sharp edges, 2 - horizontal & vertical fingers with sharp edges, 3 - solid connection, 4 - 45 degree fingers with rounded corners, 5 - horizontal & vertical fingers with rounded corners. Pins and Vias may have thermals whether or not there is a polygon available to connect with. However, they will have no effect without the polygon. %end-doc */ static int ActionSetThermal (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); char *style = ARG (1); void *ptr1, *ptr2, *ptr3; int type, kind; int err = 0; if (function && *function) { bool absolute; if ( ! style || ! *style) { kind = PCB->ThermStyle; absolute = true; } else kind = GetUnitlessValue (style, &absolute); /* To allow relative values we could search for the first selected item and make 'kind' relative to that, but that's not too useful and requires quite some code. For example there's no GetFirstSelectedPin() function available. Let's postpone this functionality, there are more urgent things to do. */ if (absolute) switch (GetFunctionID (function)) { case F_Object: if ((type = SearchScreen (Crosshair.X, Crosshair.Y, CHANGETHERMAL_TYPES, &ptr1, &ptr2, &ptr3)) != NO_TYPE) { ChangeObjectThermal (type, ptr1, ptr2, ptr3, kind); IncrementUndoSerialNumber (); Draw (); } break; case F_SelectedPins: ChangeSelectedThermals (PIN_TYPE, kind); break; case F_SelectedVias: ChangeSelectedThermals (VIA_TYPE, kind); break; case F_Selected: case F_SelectedElements: ChangeSelectedThermals (CHANGETHERMAL_TYPES, kind); break; default: err = 1; break; } else err = 1; } else err = 1; if (err) AFAIL (setthermal); return 0; } /*! * \brief Event handler to set the cursor according to the X pointer * position called from inside main.c. * * \warning !!! no action routine !!! */ void EventMoveCrosshair (int ev_x, int ev_y) { #ifdef HAVE_LIBSTROKE if (mid_stroke) { StrokeBox.X2 = ev_x; StrokeBox.Y2 = ev_y; stroke_record (ev_x, ev_y); return; } #endif /* HAVE_LIBSTROKE */ if (MoveCrosshairAbsolute (ev_x, ev_y)) { /* update object position and cursor location */ AdjustAttachedObjects (); notify_crosshair_change (true); } } /* --------------------------------------------------------------------------- */ static const char setvalue_syntax[] = N_("SetValue(Grid|Line|LineSize|Text|TextScale|ViaDrillingHole|Via|ViaSize, " "delta)"); static const char setvalue_help[] = N_("Change various board-wide values and sizes."); /* %start-doc actions SetValue @table @code @item ViaDrillingHole Changes the diameter of the drill for new vias. @item Grid Sets the grid spacing. @item Line @item LineSize Changes the thickness of new lines. @item Via @item ViaSize Changes the diameter of new vias. @item Text @item TextScale Changes the size of new text. @end table %end-doc */ static int ActionSetValue (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); char *val = ARG (1); char *units = ARG (2); bool absolute; /* flag for 'absolute' value */ double value; int text_scale; int err = 0; if (function && val) { value = GetValue (val, units, &absolute); switch (GetFunctionID (function)) { case F_ViaDrillingHole: SetViaDrillingHole (absolute ? value : value + Settings.ViaDrillingHole, false); hid_action ("RouteStylesChanged"); break; case F_Grid: if (absolute) SetGrid (value, false); else { if (value == 0) value = val[0] == '-' ? -Settings.increments->grid : Settings.increments->grid; /* On the way down, short against the minimum * PCB drawing unit */ if ((value + PCB->Grid) < 1) SetGrid (1, false); else if (PCB->Grid == 1) SetGrid (value, false); else SetGrid (value + PCB->Grid, false); } break; case F_LineSize: case F_Line: if (!absolute && value == 0) value = val[0] == '-' ? -Settings.increments->line : Settings.increments->line; SetLineSize (absolute ? value : value + Settings.LineThickness); hid_action ("RouteStylesChanged"); break; case F_Via: case F_ViaSize: SetViaSize (absolute ? value : value + Settings.ViaThickness, false); hid_action ("RouteStylesChanged"); break; case F_Text: case F_TextScale: text_scale = value / (double)FONT_CAPHEIGHT * 100.; if (!absolute) text_scale += Settings.TextScale; SetTextScale (text_scale); break; default: err = 1; break; } if (!err) return 0; } AFAIL (setvalue); } /* --------------------------------------------------------------------------- */ static const char quit_syntax[] = N_("Quit()"); static const char quit_help[] = N_("Quits the application after confirming."); /* %start-doc actions Quit If you have unsaved changes, you will be prompted to confirm (or save) before quitting. %end-doc */ static int ActionQuit (int argc, char **argv, Coord x, Coord y) { char *force = ARG (0); if (force && strcasecmp (force, "force") == 0) { PCB->Changed = 0; exit (0); } if (!PCB->Changed || gui->close_confirm_dialog () == HID_CLOSE_CONFIRM_OK) QuitApplication (); return 1; } /* --------------------------------------------------------------------------- */ static const char connection_syntax[] = N_("Connection(Find|ResetLinesAndPolygons|ResetPinsAndVias|Reset)"); static const char connection_help[] = N_("Searches connections of the object at the cursor position."); /* %start-doc actions Connection Connections found with this action will be highlighted in the ``connected-color'' color and will have the ``found'' flag set. @table @code @item Find The net under the cursor is ``found''. @item ResetLinesAndPolygons Any ``found'' lines and polygons are marked ``not found''. @item ResetPinsAndVias Any ``found'' pins and vias are marked ``not found''. @item Reset All ``found'' objects are marked ``not found''. @end table %end-doc */ static int ActionConnection (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); if (function) { switch (GetFunctionID (function)) { case F_Find: { gui->get_coords (_("Click on a connection"), &x, &y); LookupConnection (x, y, true, 1, CONNECTEDFLAG, false); LookupConnection (x, y, true, 1, FOUNDFLAG, true); break; } case F_ResetLinesAndPolygons: if (ClearFlagOnLinesAndPolygons (CONNECTEDFLAG | FOUNDFLAG, true)) { IncrementUndoSerialNumber (); Draw (); } break; case F_ResetPinsViasAndPads: if (ClearFlagOnPinsViasAndPads (CONNECTEDFLAG | FOUNDFLAG, true)) { IncrementUndoSerialNumber (); Draw (); } break; case F_Reset: if (ClearFlagOnAllObjects (CONNECTEDFLAG | FOUNDFLAG, true)) { IncrementUndoSerialNumber (); Draw (); } break; } return 0; } AFAIL (connection); } /* --------------------------------------------------------------------------- */ static const char disperseelements_syntax[] = N_("DisperseElements(All|Selected)"); static const char disperseelements_help[] = N_("Disperses elements."); /* %start-doc actions DisperseElements Normally this is used when starting a board, by selecting all elements and then dispersing them. This scatters the elements around the board so that you can pick individual ones, rather than have all the elements at the same 0,0 coordinate and thus impossible to choose from. %end-doc */ #define GAP MIL_TO_COORD(100) static int ActionDisperseElements (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); Coord minx = GAP, miny = GAP, maxy = GAP, dx, dy; int all = 0, bad = 0; if (!function || !*function) { bad = 1; } else { switch (GetFunctionID (function)) { case F_All: all = 1; break; case F_Selected: all = 0; break; default: bad = 1; } } if (bad) { AFAIL (disperseelements); } ELEMENT_LOOP (PCB->Data); { /* * If we want to disperse selected elements, maybe we need smarter * code here to avoid putting components on top of others which * are not selected. For now, I'm assuming that this is typically * going to be used either with a brand new design or a scratch * design holding some new components */ if (!TEST_FLAG (LOCKFLAG, element) && (all || TEST_FLAG (SELECTEDFLAG, element))) { /* figure out how much to move the element */ dx = minx - element->BoundingBox.X1; /* snap to the grid */ dx -= (element->MarkX + dx) % PCB->Grid; /* * and add one grid size so we make sure we always space by GAP or * more */ dx += PCB->Grid; /* Figure out if this row has room. If not, start a new row */ if (GAP + element->BoundingBox.X2 + dx > PCB->MaxWidth) { miny = maxy + GAP; minx = GAP; } /* figure out how much to move the element */ dx = minx - element->BoundingBox.X1; dy = miny - element->BoundingBox.Y1; /* snap to the grid */ dx -= (element->MarkX + dx) % PCB->Grid; dx += PCB->Grid; dy -= (element->MarkY + dy) % PCB->Grid; dy += PCB->Grid; /* move the element */ MoveElementLowLevel (PCB->Data, element, dx, dy); /* and add to the undo list so we can undo this operation */ AddObjectToMoveUndoList (ELEMENT_TYPE, NULL, NULL, element, dx, dy); /* keep track of how tall this row is */ minx += element->BoundingBox.X2 - element->BoundingBox.X1 + GAP; if (maxy < element->BoundingBox.Y2) { maxy = element->BoundingBox.Y2; } } } END_LOOP; /* done with our action so increment the undo # */ IncrementUndoSerialNumber (); Redraw (); SetChangedFlag (true); return 0; } #undef GAP /* --------------------------------------------------------------------------- */ static const char display_syntax[] = N_("Display(NameOnPCB|Description|Value)\n" "Display(Grid|Redraw)\n" "Display(CycleClip|CycleCrosshair|Toggle45Degree|ToggleStartDirection)\n" "Display(ToggleGrid|ToggleRubberBandMode|ToggleUniqueNames)\n" "Display(ToggleMask|ToggleName|ToggleClearLine|ToggleFullPoly|ToggleSnapPin)\n" "Display(ToggleThindraw|ToggleThindrawPoly|ToggleOrthoMove|ToggleLocalRef)\n" "Display(ToggleCheckPlanes|ToggleShowDRC|ToggleAutoDRC)\n" "Display(ToggleLiveRoute|LockNames|OnlyNames)\n" "Display(Pinout|PinOrPadName)"); static const char display_help[] = N_("Several display-related actions."); /* %start-doc actions Display @table @code @item NameOnPCB @item Description @item Value Specify whether all elements show their name, description, or value. @item Redraw Redraw the whole board. @item Toggle45Degree When clear, lines can be drawn at any angle. When set, lines are restricted to multiples of 45 degrees and requested lines may be broken up according to the clip setting. @item CycleClip Changes the way lines are restricted to 45 degree increments. The various settings are: straight only, orthogonal then angled, and angled then orthogonal. If AllDirections is set, this action disables it. @item CycleCrosshair Changes crosshair drawing. Crosshair may accept form of 4-ray, 8-ray and 12-ray cross. @item ToggleRubberBandMode If set, moving an object moves all the lines attached to it too. @item ToggleStartDirection If set, each time you set a point in a line, the Clip toggles between orth-angle and angle-ortho. @item ToggleUniqueNames If set, you will not be permitted to change the name of an element to match that of another element. @item ToggleSnapPin If set, pin centers and pad end points are treated as additional grid points that the cursor can snap to. @item ToggleLocalRef If set, the mark is automatically set to the beginning of any move, so you can see the relative distance you've moved. @item ToggleThindraw If set, objects on the screen are drawn as outlines (lines are drawn as center-lines). This lets you see line endpoints hidden under pins, for example. @item ToggleThindrawPoly If set, polygons on the screen are drawn as outlines. @item ToggleShowDRC If set, pending objects (i.e. lines you're in the process of drawing) will be drawn with an outline showing how far away from other copper you need to be. @item ToggleLiveRoute If set, the progress of the autorouter will be visible on the screen. @item ToggleAutoDRC If set, you will not be permitted to make connections which violate the current DRC and netlist settings. @item ToggleCheckPlanes If set, lines and arcs aren't drawn, which usually leaves just the polygons. If you also disable all but the layer you're interested in, this allows you to check for isolated regions. @item ToggleOrthoMove If set, the crosshair is only allowed to move orthogonally from its previous position. I.e. you can move an element or line up, down, left, or right, but not up+left or down+right. @item ToggleName Selects whether the pinouts show the pin names or the pin numbers. @item ToggleLockNames If set, text will ignore left mouse clicks and actions that work on objects under the mouse. You can still select text with a lasso (left mouse drag) and perform actions on the selection. @item ToggleOnlyNames If set, only text will be sensitive for mouse clicks and actions that work on objects under the mouse. You can still select other objects with a lasso (left mouse drag) and perform actions on the selection. @item ToggleMask Turns the solder mask on or off. @item ToggleClearLine When set, the clear-line flag causes new lines and arcs to have their ``clear polygons'' flag set, so they won't be electrically connected to any polygons they overlap. @item ToggleFullPoly When set, the full-poly flag causes new polygons to have their ``full polygon'' flag set, so all parts of them will be displayed instead of only the biggest one. @item ToggleGrid Resets the origin of the current grid to be wherever the mouse pointer is (not where the crosshair currently is). If you provide two numbers after this, the origin is set to that coordinate. @item Grid Toggles whether the grid is displayed or not. @item Pinout Causes the pinout of the element indicated by the cursor to be displayed, usually in a separate window. @item PinOrPadName Toggles whether the names of pins, pads, or (yes) vias will be displayed. If the cursor is over an element, all of its pins and pads are affected. @item ToggleAutoBuriedVias If set, automatically created vias are buried vias. @end table %end-doc */ static enum crosshair_shape CrosshairShapeIncrement (enum crosshair_shape shape) { switch(shape) { case Basic_Crosshair_Shape: shape = Union_Jack_Crosshair_Shape; break; case Union_Jack_Crosshair_Shape: shape = Dozen_Crosshair_Shape; break; case Dozen_Crosshair_Shape: shape = Crosshair_Shapes_Number; break; case Crosshair_Shapes_Number: shape = Basic_Crosshair_Shape; break; } return shape; } static int ActionDisplay (int argc, char **argv, Coord childX, Coord childY) { char *function, *str_dir; int id; int err = 0; function = ARG (0); str_dir = ARG (1); if (function && (!str_dir || !*str_dir)) { switch (id = GetFunctionID (function)) { /* redraw layout */ case F_ClearAndRedraw: case F_Redraw: Redraw (); break; /* change the displayed name of elements */ case F_Value: case F_NameOnPCB: case F_Description: ELEMENT_LOOP (PCB->Data); { EraseElementName (element); } END_LOOP; CLEAR_FLAG (DESCRIPTIONFLAG | NAMEONPCBFLAG, PCB); switch (id) { case F_Value: break; case F_NameOnPCB: SET_FLAG (NAMEONPCBFLAG, PCB); break; case F_Description: SET_FLAG (DESCRIPTIONFLAG, PCB); break; } ELEMENT_LOOP (PCB->Data); { DrawElementName (element); } END_LOOP; Draw (); break; /* toggle line-adjust flag */ case F_ToggleAllDirections: TOGGLE_FLAG (ALLDIRECTIONFLAG, PCB); AdjustAttachedObjects (); break; case F_CycleClip: notify_crosshair_change (false); if (TEST_FLAG (ALLDIRECTIONFLAG, PCB)) { TOGGLE_FLAG (ALLDIRECTIONFLAG, PCB); PCB->Clipping = 0; } else PCB->Clipping = (PCB->Clipping + 1) % 3; AdjustAttachedObjects (); notify_crosshair_change (true); break; case F_CycleCrosshair: notify_crosshair_change (false); Crosshair.shape = CrosshairShapeIncrement(Crosshair.shape); if (Crosshair_Shapes_Number == Crosshair.shape) Crosshair.shape = Basic_Crosshair_Shape; notify_crosshair_change (true); break; case F_ToggleRubberBandMode: notify_crosshair_change (false); TOGGLE_FLAG (RUBBERBANDFLAG, PCB); notify_crosshair_change (true); break; case F_ToggleAutoBuriedVias: notify_crosshair_change (false); TOGGLE_FLAG (AUTOBURIEDVIASFLAG, PCB); notify_crosshair_change (true); break; case F_ToggleStartDirection: notify_crosshair_change (false); TOGGLE_FLAG (SWAPSTARTDIRFLAG, PCB); notify_crosshair_change (true); break; case F_ToggleUniqueNames: TOGGLE_FLAG (UNIQUENAMEFLAG, PCB); break; case F_ToggleSnapPin: notify_crosshair_change (false); TOGGLE_FLAG (SNAPPINFLAG, PCB); notify_crosshair_change (true); break; case F_ToggleLocalRef: TOGGLE_FLAG (LOCALREFFLAG, PCB); break; case F_ToggleThindraw: TOGGLE_FLAG (THINDRAWFLAG, PCB); Redraw (); break; case F_ToggleThindrawPoly: TOGGLE_FLAG (THINDRAWPOLYFLAG, PCB); Redraw (); break; case F_ToggleLockNames: TOGGLE_FLAG (LOCKNAMESFLAG, PCB); CLEAR_FLAG (ONLYNAMESFLAG, PCB); break; case F_ToggleOnlyNames: TOGGLE_FLAG (ONLYNAMESFLAG, PCB); CLEAR_FLAG (LOCKNAMESFLAG, PCB); break; case F_ToggleHideNames: TOGGLE_FLAG (HIDENAMESFLAG, PCB); Redraw (); break; case F_ToggleShowDRC: TOGGLE_FLAG (SHOWDRCFLAG, PCB); break; case F_ToggleLiveRoute: TOGGLE_FLAG (LIVEROUTEFLAG, PCB); break; case F_ToggleAutoDRC: notify_crosshair_change (false); TOGGLE_FLAG (AUTODRCFLAG, PCB); if (TEST_FLAG (AUTODRCFLAG, PCB) && Settings.Mode == LINE_MODE) { if (ClearFlagOnAllObjects (CONNECTEDFLAG | FOUNDFLAG, true)) { IncrementUndoSerialNumber (); Draw (); } if (Crosshair.AttachedLine.State != STATE_FIRST) { LookupConnection (Crosshair.AttachedLine.Point1.X, Crosshair.AttachedLine.Point1.Y, true, 1, CONNECTEDFLAG, false); LookupConnection (Crosshair.AttachedLine.Point1.X, Crosshair.AttachedLine.Point1.Y, true, 1, FOUNDFLAG, true); } } notify_crosshair_change (true); break; case F_ToggleCheckPlanes: TOGGLE_FLAG (CHECKPLANESFLAG, PCB); Redraw (); break; case F_ToggleOrthoMove: TOGGLE_FLAG (ORTHOMOVEFLAG, PCB); break; case F_ToggleName: TOGGLE_FLAG (SHOWNUMBERFLAG, PCB); Redraw (); break; case F_ToggleMask: TOGGLE_FLAG (SHOWMASKFLAG, PCB); Redraw (); break; case F_ToggleClearLine: TOGGLE_FLAG (CLEARNEWFLAG, PCB); break; case F_ToggleFullPoly: TOGGLE_FLAG (NEWFULLPOLYFLAG, PCB); break; /* shift grid alignment */ case F_ToggleGrid: { Coord oldGrid = PCB->Grid; PCB->Grid = 1; if (MoveCrosshairAbsolute (Crosshair.X, Crosshair.Y)) notify_crosshair_change (true); /* first notify was in MoveCrosshairAbs */ SetGrid (oldGrid, true); } break; /* toggle displaying of the grid */ case F_Grid: Settings.DrawGrid = !Settings.DrawGrid; Redraw (); break; /* display the pinout of an element */ case F_Pinout: { ElementType *element; void *ptrtmp; Coord x, y; gui->get_coords (_("Click on an element"), &x, &y); if ((SearchScreen (x, y, ELEMENT_TYPE, &ptrtmp, &ptrtmp, &ptrtmp)) != NO_TYPE) { element = (ElementType *) ptrtmp; gui->show_item (element); } break; } /* toggle displaying of pin/pad/via names */ case F_PinOrPadName: { void *ptr1, *ptr2, *ptr3; Coord x, y; gui->get_coords(_("Click on an element"), &x, &y); switch (SearchScreen (x, y, ELEMENT_TYPE | PIN_TYPE | PAD_TYPE | VIA_TYPE, (void **) &ptr1, (void **) &ptr2, (void **) &ptr3)) { case ELEMENT_TYPE: PIN_LOOP ((ElementType *) ptr1); { if (TEST_FLAG (DISPLAYNAMEFLAG, pin)) ErasePinName (pin); else DrawPinName (pin); AddObjectToFlagUndoList (PIN_TYPE, ptr1, pin, pin); TOGGLE_FLAG (DISPLAYNAMEFLAG, pin); } END_LOOP; PAD_LOOP ((ElementType *) ptr1); { if (TEST_FLAG (DISPLAYNAMEFLAG, pad)) ErasePadName (pad); else DrawPadName (pad); AddObjectToFlagUndoList (PAD_TYPE, ptr1, pad, pad); TOGGLE_FLAG (DISPLAYNAMEFLAG, pad); } END_LOOP; SetChangedFlag (true); IncrementUndoSerialNumber (); Draw (); break; case PIN_TYPE: if (TEST_FLAG (DISPLAYNAMEFLAG, (PinType *) ptr2)) ErasePinName ((PinType *) ptr2); else DrawPinName ((PinType *) ptr2); AddObjectToFlagUndoList (PIN_TYPE, ptr1, ptr2, ptr3); TOGGLE_FLAG (DISPLAYNAMEFLAG, (PinType *) ptr2); SetChangedFlag (true); IncrementUndoSerialNumber (); Draw (); break; case PAD_TYPE: if (TEST_FLAG (DISPLAYNAMEFLAG, (PadType *) ptr2)) ErasePadName ((PadType *) ptr2); else DrawPadName ((PadType *) ptr2); AddObjectToFlagUndoList (PAD_TYPE, ptr1, ptr2, ptr3); TOGGLE_FLAG (DISPLAYNAMEFLAG, (PadType *) ptr2); SetChangedFlag (true); IncrementUndoSerialNumber (); Draw (); break; case VIA_TYPE: if (TEST_FLAG (DISPLAYNAMEFLAG, (PinType *) ptr2)) EraseViaName ((PinType *) ptr2); else DrawViaName ((PinType *) ptr2); AddObjectToFlagUndoList (VIA_TYPE, ptr1, ptr2, ptr3); TOGGLE_FLAG (DISPLAYNAMEFLAG, (PinType *) ptr2); SetChangedFlag (true); IncrementUndoSerialNumber (); Draw (); break; } break; } default: err = 1; } } else if (function && str_dir) { switch (GetFunctionID (function)) { case F_ToggleGrid: if (argc > 2) { PCB->GridOffsetX = GetValue (argv[1], NULL, NULL); PCB->GridOffsetY = GetValue (argv[2], NULL, NULL); if (Settings.DrawGrid) Redraw (); } break; default: err = 1; break; } } else err = 1; if (err) AFAIL (display); return 0; } /* --------------------------------------------------------------------------- */ static const char mode_syntax[] = N_("Mode(Arc|Arrow|Copy|InsertPoint|Line|Lock|Move|None|PasteBuffer)\n" "Mode(Polygon|Rectangle|Remove|Rotate|Text|Thermal|Via)\n" "Mode(Notify|Release|Cancel|Stroke)\n" "Mode(Save|Restore)"); static const char mode_help[] = N_("Change or use the tool mode."); /* %start-doc actions Mode @table @code @item Arc @itemx Arrow @itemx Copy @itemx InsertPoint @itemx Line @itemx Lock @itemx Move @itemx None @itemx PasteBuffer @itemx Polygon @itemx Rectangle @itemx Remove @itemx Rotate @itemx Text @itemx Thermal @itemx Via Select the indicated tool. @item Notify Called when you press the mouse button, or move the mouse. @item Release Called when you release the mouse button. @item Cancel Cancels any pending tool activity, allowing you to restart elsewhere. For example, this allows you to start a new line rather than attach a line to the previous line. @item Escape Similar to Cancel but calling this action a second time will return to the Arrow tool. @item Stroke If your @code{pcb} was built with libstroke, this invokes the stroke input method. If not, this will restart a drawing mode if you were drawing, else it will select objects. @item Save Remembers the current tool. @item Restore Restores the tool to the last saved tool. @end table %end-doc */ static int ActionMode (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); if (function) { Note.X = Crosshair.X; Note.Y = Crosshair.Y; notify_crosshair_change (false); switch (GetFunctionID (function)) { case F_Arc: SetMode (ARC_MODE); break; case F_Arrow: SetMode (ARROW_MODE); break; case F_Copy: SetMode (COPY_MODE); break; case F_InsertPoint: SetMode (INSERTPOINT_MODE); break; case F_Line: SetMode (LINE_MODE); break; case F_Lock: SetMode (LOCK_MODE); break; case F_Move: SetMode (MOVE_MODE); break; case F_None: SetMode (NO_MODE); break; case F_Cancel: { int saved_mode = Settings.Mode; SetMode (NO_MODE); SetMode (saved_mode); } break; case F_Escape: { switch (Settings.Mode) { case VIA_MODE: case PASTEBUFFER_MODE: case TEXT_MODE: case ROTATE_MODE: case REMOVE_MODE: case MOVE_MODE: case COPY_MODE: case INSERTPOINT_MODE: case RUBBERBANDMOVE_MODE: case THERMAL_MODE: case LOCK_MODE: SetMode (NO_MODE); SetMode (ARROW_MODE); break; case LINE_MODE: if (Crosshair.AttachedLine.State == STATE_FIRST) SetMode (ARROW_MODE); else { SetMode (NO_MODE); SetMode (LINE_MODE); } break; case RECTANGLE_MODE: if (Crosshair.AttachedBox.State == STATE_FIRST) SetMode (ARROW_MODE); else { SetMode (NO_MODE); SetMode (RECTANGLE_MODE); } break; case POLYGON_MODE: if (Crosshair.AttachedLine.State == STATE_FIRST) SetMode (ARROW_MODE); else { SetMode (NO_MODE); SetMode (POLYGON_MODE); } break; case POLYGONHOLE_MODE: if (Crosshair.AttachedLine.State == STATE_FIRST) SetMode (ARROW_MODE); else { SetMode (NO_MODE); SetMode (POLYGONHOLE_MODE); } break; case ARC_MODE: if (Crosshair.AttachedBox.State == STATE_FIRST) SetMode (ARROW_MODE); else { SetMode (NO_MODE); SetMode (ARC_MODE); } break; case ARROW_MODE: break; default: break; } } break; case F_Notify: NotifyMode (); break; case F_PasteBuffer: SetMode (PASTEBUFFER_MODE); break; case F_Polygon: SetMode (POLYGON_MODE); break; case F_PolygonHole: SetMode (POLYGONHOLE_MODE); break; #ifndef HAVE_LIBSTROKE case F_Release: ReleaseMode (); break; #else case F_Release: if (mid_stroke) FinishStroke (); else ReleaseMode (); break; #endif case F_Remove: SetMode (REMOVE_MODE); break; case F_Rectangle: SetMode (RECTANGLE_MODE); break; case F_Rotate: SetMode (ROTATE_MODE); break; case F_Stroke: #ifdef HAVE_LIBSTROKE mid_stroke = true; StrokeBox.X1 = Crosshair.X; StrokeBox.Y1 = Crosshair.Y; break; #else /* Handle middle mouse button restarts of drawing mode. If not in | a drawing mode, middle mouse button will select objects. */ if (Settings.Mode == LINE_MODE && Crosshair.AttachedLine.State != STATE_FIRST) { SetMode (LINE_MODE); } else if (Settings.Mode == ARC_MODE && Crosshair.AttachedBox.State != STATE_FIRST) SetMode (ARC_MODE); else if (Settings.Mode == RECTANGLE_MODE && Crosshair.AttachedBox.State != STATE_FIRST) SetMode (RECTANGLE_MODE); else if (Settings.Mode == POLYGON_MODE && Crosshair.AttachedLine.State != STATE_FIRST) SetMode (POLYGON_MODE); else { SaveMode (); saved_mode = true; SetMode (ARROW_MODE); NotifyMode (); } break; #endif case F_Text: SetMode (TEXT_MODE); break; case F_Thermal: SetMode (THERMAL_MODE); break; case F_Via: SetMode (VIA_MODE); break; case F_Restore: /* restore the last saved mode */ RestoreMode (); break; case F_Save: /* save currently selected mode */ SaveMode (); break; } notify_crosshair_change (true); return 0; } AFAIL (mode); } /* --------------------------------------------------------------------------- */ static const char removeselected_syntax[] = N_("RemoveSelected()"); static const char removeselected_help[] = N_("Removes any selected objects."); /* %start-doc actions RemoveSelected %end-doc */ static int ActionRemoveSelected (int argc, char **argv, Coord x, Coord y) { if (RemoveSelected ()) SetChangedFlag (true); return 0; } /* --------------------------------------------------------------------------- */ static const char renumber_syntax[] = N_("Renumber()\n" "Renumber(filename)"); static const char renumber_help[] = N_("Renumber all elements. The changes will be recorded to filename\n" "for use in backannotating these changes to the schematic."); /* %start-doc actions Renumber %end-doc */ static int ActionRenumber (int argc, char **argv, Coord x, Coord y) { bool changed = false; ElementType **element_list; ElementType **locked_element_list; unsigned int i, j, k, cnt, lock_cnt; unsigned int tmpi; size_t sz; char *tmps; char *name; FILE *out; static char * default_file = NULL; size_t cnt_list_sz = 100; struct _cnt_list { char *name; unsigned int cnt; } *cnt_list; char **was, **is, *pin; unsigned int c_cnt = 0; int unique, ok; int free_name = 0; if (argc < 1) { /* * We deal with the case where name already exists in this * function so the GUI doesn't need to deal with it */ name = gui->fileselect (_("Save Renumber Annotation File As ..."), _("Choose a file to record the renumbering to.\n" "This file may be used to back annotate the\n" "change to the schematics.\n"), default_file, ".eco", "eco", 0); free_name = 1; } else name = argv[0]; if (default_file) { free (default_file); default_file = NULL; } if (name && *name) { default_file = strdup (name); } if ((out = fopen (name, "r"))) { fclose (out); if (!gui->confirm_dialog (_("File exists! Ok to overwrite?"), 0)) { if (free_name && name) free (name); return 0; } } if ((out = fopen (name, "w")) == NULL) { Message (_("Could not open %s\n"), name); if (free_name && name) free (name); return 1; } if (free_name && name) free (name); fprintf (out, "*COMMENT* PCB Annotation File\n"); fprintf (out, "*FILEVERSION* 20061031\n"); /* * Make a first pass through all of the elements and sort them out * by location on the board. While here we also collect a list of * locked elements. * * We'll actually renumber things in the 2nd pass. */ element_list = (ElementType **)calloc (PCB->Data->ElementN, sizeof (ElementType *)); locked_element_list = (ElementType **)calloc (PCB->Data->ElementN, sizeof (ElementType *)); was = (char **)calloc (PCB->Data->ElementN, sizeof (char *)); is = (char **)calloc (PCB->Data->ElementN, sizeof (char *)); if (element_list == NULL || locked_element_list == NULL || was == NULL || is == NULL) { fprintf (stderr, "calloc() failed in %s\n", __FUNCTION__); exit (1); } cnt = 0; lock_cnt = 0; ELEMENT_LOOP (PCB->Data); { if (TEST_FLAG (LOCKFLAG, element->Name) || TEST_FLAG (LOCKFLAG, element)) { /* * add to the list of locked elements which we won't try to * renumber and whose reference designators are now reserved. */ pcb_fprintf (out, "*WARN* Element \"%s\" at %$md is locked and will not be renumbered.\n", UNKNOWN (NAMEONPCB_NAME (element)), element->MarkX, element->MarkY); locked_element_list[lock_cnt] = element; lock_cnt++; } else { /* count of devices which will be renumbered */ cnt++; /* search for correct position in the list */ i = 0; while (element_list[i] && element->MarkY > element_list[i]->MarkY) i++; /* * We have found the position where we have the first element that * has the same Y value or a lower Y value. Now move forward if * needed through the X values */ while (element_list[i] && element->MarkY == element_list[i]->MarkY && element->MarkX > element_list[i]->MarkX) i++; for (j = cnt - 1; j > i; j--) { element_list[j] = element_list[j - 1]; } element_list[i] = element; } } END_LOOP; /* * Now that the elements are sorted by board position, we go through * and renumber them. */ /* * turn off the flag which requires unique names so it doesn't get * in our way. When we're done with the renumber we will have unique * names. */ unique = TEST_FLAG (UNIQUENAMEFLAG, PCB); CLEAR_FLAG (UNIQUENAMEFLAG, PCB); cnt_list = (struct _cnt_list *)calloc (cnt_list_sz, sizeof (struct _cnt_list)); for (i = 0; i < cnt; i++) { /* If there is no refdes, maybe just spit out a warning */ if (NAMEONPCB_NAME (element_list[i])) { /* figure out the prefix */ tmps = strdup (NAMEONPCB_NAME (element_list[i])); j = 0; while (tmps[j] && (tmps[j] < '0' || tmps[j] > '9') && tmps[j] != '?') j++; tmps[j] = '\0'; /* check the counter for this prefix */ for (j = 0; cnt_list[j].name && (strcmp (cnt_list[j].name, tmps) != 0) && j < cnt_list_sz; j++); /* grow the list if needed */ if (j == cnt_list_sz) { cnt_list_sz += 100; cnt_list = (struct _cnt_list *)realloc (cnt_list, cnt_list_sz); if (cnt_list == NULL) { fprintf (stderr, _("realloc() failed in %s()\n"), __FUNCTION__); exit (1); } /* zero out the memory that we added */ for (tmpi = j; tmpi < cnt_list_sz; tmpi++) { cnt_list[tmpi].name = NULL; cnt_list[tmpi].cnt = 0; } } /* * start a new counter if we don't have a counter for this * prefix */ if (!cnt_list[j].name) { cnt_list[j].name = strdup (tmps); cnt_list[j].cnt = 0; } /* * check to see if the new refdes is already used by a * locked element */ do { ok = 1; cnt_list[j].cnt++; free (tmps); /* space for the prefix plus 1 digit plus the '\0' */ sz = strlen (cnt_list[j].name) + 2; /* and 1 more per extra digit needed to hold the number */ tmpi = cnt_list[j].cnt; while (tmpi > 10) { sz++; tmpi = tmpi / 10; } tmps = (char *)malloc (sz * sizeof (char)); sprintf (tmps, "%s%d", cnt_list[j].name, (int) cnt_list[j].cnt); /* * now compare to the list of reserved (by locked * elements) names */ for (k = 0; k < lock_cnt; k++) { if (strcmp (UNKNOWN (NAMEONPCB_NAME (locked_element_list[k])), tmps) == 0) { ok = 0; break; } } } while (!ok); if (strcmp (tmps, NAMEONPCB_NAME (element_list[i])) != 0) { fprintf (out, "*RENAME* \"%s\" \"%s\"\n", NAMEONPCB_NAME (element_list[i]), tmps); /* add this rename to our table of renames so we can update the netlist */ was[c_cnt] = strdup (NAMEONPCB_NAME (element_list[i])); is[c_cnt] = strdup (tmps); c_cnt++; AddObjectToChangeNameUndoList (ELEMENT_TYPE, NULL, NULL, element_list[i], NAMEONPCB_NAME (element_list [i])); ChangeObjectName (ELEMENT_TYPE, element_list[i], NULL, NULL, tmps); changed = true; /* we don't free tmps in this case because it is used */ } else free (tmps); } else { pcb_fprintf (out, "*WARN* Element at %$md has no name.\n", element_list[i]->MarkX, element_list[i]->MarkY); } } fclose (out); /* restore the unique flag setting */ if (unique) SET_FLAG (UNIQUENAMEFLAG, PCB); if (changed) { /* update the netlist */ AddNetlistLibToUndoList (&(PCB->NetlistLib)); /* iterate over each net */ for (i = 0; i < PCB->NetlistLib.MenuN; i++) { /* iterate over each pin on the net */ for (j = 0; j < PCB->NetlistLib.Menu[i].EntryN; j++) { /* figure out the pin number part from strings like U3-21 */ tmps = strdup (PCB->NetlistLib.Menu[i].Entry[j].ListEntry); for (k = 0; tmps[k] && tmps[k] != '-'; k++); tmps[k] = '\0'; pin = tmps + k + 1; /* iterate over the list of changed reference designators */ for (k = 0; k < c_cnt; k++) { /* * if the pin needs to change, change it and quit * searching in the list. */ if (strcmp (tmps, was[k]) == 0) { free (PCB->NetlistLib.Menu[i].Entry[j].ListEntry); PCB->NetlistLib.Menu[i].Entry[j].ListEntry = (char *)malloc ((strlen (is[k]) + strlen (pin) + 2) * sizeof (char)); sprintf (PCB->NetlistLib.Menu[i].Entry[j].ListEntry, "%s-%s", is[k], pin); k = c_cnt; } } free (tmps); } } for (k = 0; k < c_cnt; k++) { free (was[k]); free (is[k]); } NetlistChanged (0); IncrementUndoSerialNumber (); SetChangedFlag (true); } free (locked_element_list); free (element_list); free (cnt_list); free (is); free (was); return 0; } /* --------------------------------------------------------------------------- */ static const char ripup_syntax[] = N_("RipUp(All|Selected|Element)"); static const char ripup_help[] = N_("Ripup auto-routed tracks, or convert an element to parts."); /* %start-doc actions RipUp @table @code @item All Removes all lines and vias which were created by the autorouter. @item Selected Removes all selected lines and vias which were created by the autorouter. @item Element Converts the element under the cursor to parts (vias and lines). Note that this uses the highest numbered paste buffer. @end table %end-doc */ static int ActionRipUp (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); bool changed = false; if (function) { switch (GetFunctionID (function)) { case F_All: ALLLINE_LOOP (PCB->Data); { if (TEST_FLAG (AUTOFLAG, line) && !TEST_FLAG (LOCKFLAG, line)) { RemoveObject (LINE_TYPE, layer, line, line); changed = true; } } ENDALL_LOOP; ALLARC_LOOP (PCB->Data); { if (TEST_FLAG (AUTOFLAG, arc) && !TEST_FLAG (LOCKFLAG, arc)) { RemoveObject (ARC_TYPE, layer, arc, arc); changed = true; } } ENDALL_LOOP; VIA_LOOP (PCB->Data); { if (TEST_FLAG (AUTOFLAG, via) && !TEST_FLAG (LOCKFLAG, via)) { RemoveObject (VIA_TYPE, via, via, via); changed = true; } } END_LOOP; if (changed) { IncrementUndoSerialNumber (); SetChangedFlag (true); } break; case F_Selected: VISIBLELINE_LOOP (PCB->Data); { if (TEST_FLAGS (AUTOFLAG | SELECTEDFLAG, line) && !TEST_FLAG (LOCKFLAG, line)) { RemoveObject (LINE_TYPE, layer, line, line); changed = true; } } ENDALL_LOOP; if (PCB->ViaOn) VIA_LOOP (PCB->Data); { if (TEST_FLAGS (AUTOFLAG | SELECTEDFLAG, via) && !TEST_FLAG (LOCKFLAG, via)) { RemoveObject (VIA_TYPE, via, via, via); changed = true; } } END_LOOP; if (changed) { IncrementUndoSerialNumber (); SetChangedFlag (true); } break; case F_Element: { void *ptr1, *ptr2, *ptr3; if (SearchScreen (Crosshair.X, Crosshair.Y, ELEMENT_TYPE, &ptr1, &ptr2, &ptr3) != NO_TYPE) { Note.Buffer = Settings.BufferNumber; SetBufferNumber (MAX_BUFFER - 1); ClearBuffer (PASTEBUFFER); CopyObjectToBuffer (PASTEBUFFER->Data, PCB->Data, ELEMENT_TYPE, ptr1, ptr2, ptr3); SmashBufferElement (PASTEBUFFER); PASTEBUFFER->X = 0; PASTEBUFFER->Y = 0; SaveUndoSerialNumber (); EraseObject (ELEMENT_TYPE, ptr1, ptr1); MoveObjectToRemoveUndoList (ELEMENT_TYPE, ptr1, ptr2, ptr3); RestoreUndoSerialNumber (); CopyPastebufferToLayout (0, 0); SetBufferNumber (Note.Buffer); SetChangedFlag (true); } } break; } } return 0; } /* --------------------------------------------------------------------------- */ static const char addrats_syntax[] = N_("AddRats(AllRats|SelectedRats|Close)"); static const char addrats_help[] = N_("Add one or more rat lines to the board."); /* %start-doc actions AddRats @table @code @item AllRats Create rat lines for all loaded nets that aren't already connected on with copper. @item SelectedRats Similarly, but only add rat lines for nets connected to selected pins and pads. @item Close Selects the shortest unselected rat on the board. @end table %end-doc */ static int ActionAddRats (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); RatType *shorty; float len, small; if (function) { if (Settings.RatWarn) ClearWarnings (); switch (GetFunctionID (function)) { case F_AllRats: if (AddAllRats (false, NULL)) SetChangedFlag (true); break; case F_SelectedRats: case F_Selected: if (AddAllRats (true, NULL)) SetChangedFlag (true); break; case F_Close: small = SQUARE (MAX_COORD); shorty = NULL; RAT_LOOP (PCB->Data); { if (TEST_FLAG (SELECTEDFLAG, line)) continue; len = SQUARE (line->Point1.X - line->Point2.X) + SQUARE (line->Point1.Y - line->Point2.Y); if (len < small) { small = len; shorty = line; } } END_LOOP; if (shorty) { AddObjectToFlagUndoList (RATLINE_TYPE, shorty, shorty, shorty); SET_FLAG (SELECTEDFLAG, shorty); DrawRat (shorty); Draw (); CenterDisplay ((shorty->Point2.X + shorty->Point1.X) / 2, (shorty->Point2.Y + shorty->Point1.Y) / 2, false); } break; } } return 0; } /* --------------------------------------------------------------------------- */ static const char delete_syntax[] = N_("Delete(Object|Selected)\n" "Delete(AllRats|SelectedRats)"); static const char delete_help[] = N_("Delete stuff."); /* %start-doc actions Delete %end-doc */ static int ActionDelete (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); int id = GetFunctionID (function); Note.X = Crosshair.X; Note.Y = Crosshair.Y; if (id == -1) /* no arg */ { if (RemoveSelected() == false) id = F_Object; } switch (id) { case F_Object: SaveMode(); SetMode(REMOVE_MODE); NotifyMode(); RestoreMode(); break; case F_Selected: RemoveSelected(); break; case F_AllRats: if (DeleteRats (false)) SetChangedFlag (true); break; case F_SelectedRats: if (DeleteRats (true)) SetChangedFlag (true); break; } return 0; } /* --------------------------------------------------------------------------- */ static const char deleterats_syntax[] = N_("DeleteRats(AllRats|Selected|SelectedRats)"); static const char deleterats_help[] = N_("Delete rat lines."); /* %start-doc actions DeleteRats %end-doc */ static int ActionDeleteRats (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); if (function) { if (Settings.RatWarn) ClearWarnings (); switch (GetFunctionID (function)) { case F_AllRats: if (DeleteRats (false)) SetChangedFlag (true); break; case F_SelectedRats: case F_Selected: if (DeleteRats (true)) SetChangedFlag (true); break; } } return 0; } /* --------------------------------------------------------------------------- */ static const char autoplace_syntax[] = N_("AutoPlaceSelected()"); static const char autoplace_help[] = N_("Auto-place selected components."); /* %start-doc actions AutoPlaceSelected Attempts to re-arrange the selected components such that the nets connecting them are minimized. Note that you cannot undo this. %end-doc */ static int ActionAutoPlaceSelected (int argc, char **argv, Coord x, Coord y) { hid_action("Busy"); if (gui->confirm_dialog (_("Auto-placement can NOT be undone.\n" "Do you want to continue anyway?\n"), 0)) { if (AutoPlaceSelected ()) SetChangedFlag (true); } return 0; } /* --------------------------------------------------------------------------- */ static const char autoroute_syntax[] = N_("AutoRoute(AllRats|SelectedRats)"); static const char autoroute_help[] = N_("Auto-route some or all rat lines."); /* %start-doc actions AutoRoute @table @code @item AllRats Attempt to autoroute all rats. @item SelectedRats Attempt to autoroute the selected rats. @end table Before autorouting, it's important to set up a few things. First, make sure any layers you aren't using are disabled, else the autorouter may use them. Next, make sure the current line and via styles are set accordingly. Last, make sure "new lines clear polygons" is set, in case you eventually want to add a copper pour. Autorouting takes a while. During this time, the program may not be responsive. %end-doc */ static int ActionAutoRoute (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); hid_action("Busy"); if (function) /* one parameter */ { switch (GetFunctionID (function)) { case F_AllRats: if (AutoRoute (false)) SetChangedFlag (true); break; case F_SelectedRats: case F_Selected: if (AutoRoute (true)) SetChangedFlag (true); break; } } return 0; } /* --------------------------------------------------------------------------- */ static const char markcrosshair_syntax[] = N_("MarkCrosshair()\n" "MarkCrosshair(Center)"); static const char markcrosshair_help[] = N_("Set/Reset the Crosshair mark."); /* %start-doc actions MarkCrosshair The ``mark'' is a small X-shaped target on the display which is treated like a second origin (the normal origin is the upper let corner of the board). The GUI will display a second set of coordinates for this mark, which tells you how far you are from it. If no argument is given, the mark is toggled - disabled if it was enabled, or enabled at the current cursor position of disabled. If the @code{Center} argument is given, the mark is moved to the current cursor location. %end-doc */ static int ActionMarkCrosshair (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); if (!function || !*function) { if (Marked.status) { notify_mark_change (false); Marked.status = false; notify_mark_change (true); } else { notify_mark_change (false); Marked.status = false; Marked.status = true; Marked.X = Crosshair.X; Marked.Y = Crosshair.Y; notify_mark_change (true); } } else if (GetFunctionID (function) == F_Center) { notify_mark_change (false); Marked.status = true; Marked.X = Crosshair.X; Marked.Y = Crosshair.Y; notify_mark_change (true); } return 0; } /* --------------------------------------------------------------------------- */ static const char changesize_syntax[] = N_("ChangeSize(Object, delta)\n" "ChangeSize(SelectedObjects|Selected, delta)\n" "ChangeSize(SelectedLines|SelectedPins|SelectedVias, delta)\n" "ChangeSize(SelectedPads|SelectedTexts|SelectedNames, delta)\n" "ChangeSize(SelectedElements, delta)"); static const char changesize_help[] = N_("Changes the size of objects."); /* %start-doc actions ChangeSize For lines and arcs, this changes the width. For pins and vias, this changes the overall diameter of the copper annulus. For pads, this changes the width and, indirectly, the length. For texts and names, this changes the scaling factor. For elements, this changes the width of the silk layer lines and arcs for this element. %end-doc */ static int ActionChangeSize (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); char *delta = ARG (1); char *units = ARG (2); bool absolute; /* indicates if absolute size is given */ Coord value; if (function && delta) { value = GetValue (delta, units, &absolute); if (value == 0) value = delta[0] == '-' ? -Settings.increments->size : Settings.increments->size; switch (GetFunctionID (function)) { case F_Object: { int type; void *ptr1, *ptr2, *ptr3; if ((type = SearchScreen (Crosshair.X, Crosshair.Y, CHANGESIZE_TYPES, &ptr1, &ptr2, &ptr3)) != NO_TYPE) if (TEST_FLAG (LOCKFLAG, (PinType *) ptr2)) Message (_("Sorry, the object is locked\n")); if (ChangeObjectSize (type, ptr1, ptr2, ptr3, value, absolute)) SetChangedFlag (true); break; } case F_SelectedVias: if (ChangeSelectedSize (VIA_TYPE, value, absolute)) SetChangedFlag (true); break; case F_SelectedPins: if (ChangeSelectedSize (PIN_TYPE, value, absolute)) SetChangedFlag (true); break; case F_SelectedPads: if (ChangeSelectedSize (PAD_TYPE, value, absolute)) SetChangedFlag (true); break; case F_SelectedArcs: if (ChangeSelectedSize (ARC_TYPE, value, absolute)) SetChangedFlag (true); break; case F_SelectedLines: if (ChangeSelectedSize (LINE_TYPE, value, absolute)) SetChangedFlag (true); break; case F_SelectedTexts: if (ChangeSelectedSize (TEXT_TYPE, value, absolute)) SetChangedFlag (true); break; case F_SelectedNames: if (ChangeSelectedSize (ELEMENTNAME_TYPE, value, absolute)) SetChangedFlag (true); break; case F_SelectedElements: if (ChangeSelectedSize (ELEMENT_TYPE, value, absolute)) SetChangedFlag (true); break; case F_Selected: case F_SelectedObjects: if (ChangeSelectedSize (CHANGESIZE_TYPES, value, absolute)) SetChangedFlag (true); break; } } return 0; } /* --------------------------------------------------------------------------- */ static const char changedrillsize_syntax[] = N_("ChangeDrillSize(Object, delta)\n" "ChangeDrillSize(SelectedPins|SelectedVias|Selected|SelectedObjects, delta)"); static const char changedrillsize_help[] = N_("Changes the drilling hole size of objects."); /* %start-doc actions ChangeDrillSize %end-doc */ static int ActionChange2ndSize (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); char *delta = ARG (1); char *units = ARG (2); bool absolute; Coord value; if (function && delta) { value = GetValue (delta, units, &absolute); switch (GetFunctionID (function)) { case F_Object: { int type; void *ptr1, *ptr2, *ptr3; gui->get_coords (_("Select an Object"), &x, &y); if ((type = SearchScreen (x, y, CHANGE2NDSIZE_TYPES, &ptr1, &ptr2, &ptr3)) != NO_TYPE) if (ChangeObject2ndSize (type, ptr1, ptr2, ptr3, value, absolute, true)) SetChangedFlag (true); break; } case F_SelectedVias: if (ChangeSelected2ndSize (VIA_TYPE, value, absolute)) SetChangedFlag (true); break; case F_SelectedPins: if (ChangeSelected2ndSize (PIN_TYPE, value, absolute)) SetChangedFlag (true); break; case F_Selected: case F_SelectedObjects: if (ChangeSelected2ndSize (PIN_TYPES, value, absolute)) SetChangedFlag (true); break; } } return 0; } /* --------------------------------------------------------------------------- */ static const char changeclearsize_syntax[] = N_("ChangeClearSize(Object, delta)\n" "ChangeClearSize(SelectedPins|SelectedPads|SelectedVias, delta)\n" "ChangeClearSize(SelectedLines|SelectedArcs, delta\n" "ChangeClearSize(Selected|SelectedObjects, delta)"); static const char changeclearsize_help[] = N_("Changes the clearance size of objects."); /* %start-doc actions ChangeClearSize If the solder mask is currently showing, this action changes the solder mask clearance. If the mask is not showing, this action changes the polygon clearance. %end-doc */ static int ActionChangeClearSize (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); char *delta = ARG (1); char *units = ARG (2); bool absolute; Coord value; if (function && delta) { value = 2 * GetValue (delta, units, &absolute); if ((value == 0) && !absolute) value = delta[0] == '-' ? -Settings.increments->clear : Settings.increments->clear; switch (GetFunctionID (function)) { case F_Object: { int type; void *ptr1, *ptr2, *ptr3; gui->get_coords (_("Select an Object"), &x, &y); if ((type = SearchScreen (x, y, CHANGECLEARSIZE_TYPES, &ptr1, &ptr2, &ptr3)) != NO_TYPE) if (ChangeObjectClearSize (type, ptr1, ptr2, ptr3, value, absolute)) SetChangedFlag (true); break; } case F_SelectedVias: if (ChangeSelectedClearSize (VIA_TYPE, value, absolute)) SetChangedFlag (true); break; case F_SelectedPads: if (ChangeSelectedClearSize (PAD_TYPE, value, absolute)) SetChangedFlag (true); break; case F_SelectedPins: if (ChangeSelectedClearSize (PIN_TYPE, value, absolute)) SetChangedFlag (true); break; case F_SelectedLines: if (ChangeSelectedClearSize (LINE_TYPE, value, absolute)) SetChangedFlag (true); break; case F_SelectedArcs: if (ChangeSelectedClearSize (ARC_TYPE, value, absolute)) SetChangedFlag (true); break; case F_Selected: case F_SelectedObjects: if (ChangeSelectedClearSize (CHANGECLEARSIZE_TYPES, value, absolute)) SetChangedFlag (true); break; } } return 0; } /* --------------------------------------------------------------------------- */ static const char minmaskgap_syntax[] = N_("MinMaskGap(delta)\n" "MinMaskGap(Selected, delta)"); static const char minmaskgap_help[] = N_("Ensures the mask is a minimum distance from pins and pads."); /* %start-doc actions MinMaskGap Checks all specified pins and/or pads, and increases the mask if needed to ensure a minimum distance between the pin or pad edge and the mask edge. %end-doc */ static int ActionMinMaskGap (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); char *delta = ARG (1); char *units = ARG (2); bool absolute; Coord value; Coord thickness; int flags; if (!function) return 1; if (strcasecmp (function, "Selected") == 0) flags = SELECTEDFLAG; else { units = delta; delta = function; flags = 0; } value = 2 * GetValue (delta, units, &absolute); SaveUndoSerialNumber (); ELEMENT_LOOP (PCB->Data); { PIN_LOOP (element); { if (!TEST_FLAGS (flags, pin) || ! pin->Mask) continue; thickness = pin->DrillingHole; if (pin->Thickness > thickness) thickness = pin->Thickness; thickness += value; if (pin->Mask < thickness) { ChangeObjectMaskSize (PIN_TYPE, element, pin, 0, thickness, 1); RestoreUndoSerialNumber (); } } END_LOOP; PAD_LOOP (element); { if (!TEST_FLAGS (flags, pad) || ! pad->Mask) continue; if (pad->Mask < pad->Thickness + value) { ChangeObjectMaskSize (PAD_TYPE, element, pad, 0, pad->Thickness + value, 1); RestoreUndoSerialNumber (); } } END_LOOP; } END_LOOP; VIA_LOOP (PCB->Data); { if (!TEST_FLAGS (flags, via) || ! via->Mask) continue; thickness = via->DrillingHole; if (via->Thickness > thickness) thickness = via->Thickness; thickness += value; if (via->Mask < thickness) { ChangeObjectMaskSize (VIA_TYPE, via, 0, 0, thickness, 1); RestoreUndoSerialNumber (); } } END_LOOP; RestoreUndoSerialNumber (); IncrementUndoSerialNumber (); return 0; } /* --------------------------------------------------------------------------- */ static const char mincleargap_syntax[] = N_("MinClearGap(delta)\n" "MinClearGap(Selected, delta)"); static const char mincleargap_help[] = N_("Ensures that polygons are a minimum distance from objects."); /* %start-doc actions MinClearGap Checks all specified objects, and increases the polygon clearance if needed to ensure a minimum distance between their edges and the polygon edges. %end-doc */ static int ActionMinClearGap (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); char *delta = ARG (1); char *units = ARG (2); bool absolute; Coord value; int flags; if (!function) return 1; if (strcasecmp (function, "Selected") == 0) flags = SELECTEDFLAG; else { units = delta; delta = function; flags = 0; } value = 2 * GetValue (delta, units, &absolute); SaveUndoSerialNumber (); ELEMENT_LOOP (PCB->Data); { PIN_LOOP (element); { if (!TEST_FLAGS (flags, pin)) continue; if (pin->Clearance < value) { ChangeObjectClearSize (PIN_TYPE, element, pin, 0, value, 1); RestoreUndoSerialNumber (); } } END_LOOP; PAD_LOOP (element); { if (!TEST_FLAGS (flags, pad)) continue; if (pad->Clearance < value) { ChangeObjectClearSize (PAD_TYPE, element, pad, 0, value, 1); RestoreUndoSerialNumber (); } } END_LOOP; } END_LOOP; VIA_LOOP (PCB->Data); { if (!TEST_FLAGS (flags, via)) continue; if (via->Clearance < value) { ChangeObjectClearSize (VIA_TYPE, via, 0, 0, value, 1); RestoreUndoSerialNumber (); } } END_LOOP; ALLLINE_LOOP (PCB->Data); { if (!TEST_FLAGS (flags, line)) continue; if (line->Clearance < value) { ChangeObjectClearSize (LINE_TYPE, layer, line, 0, value, 1); RestoreUndoSerialNumber (); } } ENDALL_LOOP; ALLARC_LOOP (PCB->Data); { if (!TEST_FLAGS (flags, arc)) continue; if (arc->Clearance < value) { ChangeObjectClearSize (ARC_TYPE, layer, arc, 0, value, 1); RestoreUndoSerialNumber (); } } ENDALL_LOOP; RestoreUndoSerialNumber (); IncrementUndoSerialNumber (); return 0; } /* --------------------------------------------------------------------------- */ static const char changepinname_syntax[] = N_("ChangePinName(ElementName,PinNumber,PinName)"); static const char changepinname_help[] = N_("Sets the name of a specific pin on a specific element."); /* %start-doc actions ChangePinName This can be especially useful for annotating pin names from a schematic to the layout without requiring knowledge of the pcb file format. @example ChangePinName(U3, 7, VCC) @end example %end-doc */ static int ActionChangePinName (int argc, char **argv, Coord x, Coord y) { int changed = 0; char *refdes, *pinnum, *pinname; if (argc != 3) { AFAIL (changepinname); } refdes = argv[0]; pinnum = argv[1]; pinname = argv[2]; ELEMENT_LOOP (PCB->Data); { if (NSTRCMP (refdes, NAMEONPCB_NAME (element)) == 0) { PIN_LOOP (element); { if (NSTRCMP (pinnum, pin->Number) == 0) { AddObjectToChangeNameUndoList (PIN_TYPE, NULL, NULL, pin, pin->Name); /* * Note: we can't free() pin->Name first because * it is used in the undo list */ pin->Name = strdup (pinname); SetChangedFlag (true); changed = 1; } } END_LOOP; PAD_LOOP (element); { if (NSTRCMP (pinnum, pad->Number) == 0) { AddObjectToChangeNameUndoList (PAD_TYPE, NULL, NULL, pad, pad->Name); /* * Note: we can't free() pad->Name first because * it is used in the undo list */ pad->Name = strdup (pinname); SetChangedFlag (true); changed = 1; } } END_LOOP; } } END_LOOP; /* * done with our action so increment the undo # if we actually * changed anything */ if (changed) { if (defer_updates) defer_needs_update = 1; else { IncrementUndoSerialNumber (); gui->invalidate_all (); } } return 0; } /* --------------------------------------------------------------------------- */ static const char changename_syntax[] = N_("ChangeName(Object)\n" "ChangeName(Layout|Layer)"); static const char changename_help[] = N_("Sets the name of objects."); /* %start-doc actions ChangeName @table @code @item Object Changes the name of the element under the cursor. @item Layout Changes the name of the layout. This is printed on the fab drawings. @item Layer Changes the name of the currently active layer. @end table %end-doc */ int ActionChangeName (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); char *name; if (function) { switch (GetFunctionID (function)) { /* change the name of an object */ case F_Object: { int type; void *ptr1, *ptr2, *ptr3; gui->get_coords (_("Select an Object"), &x, &y); if ((type = SearchScreen (x, y, CHANGENAME_TYPES, &ptr1, &ptr2, &ptr3)) != NO_TYPE) { SaveUndoSerialNumber (); if (QueryInputAndChangeObjectName (type, ptr1, ptr2, ptr3)) { SetChangedFlag (true); if (type == ELEMENT_TYPE) { RubberbandType *ptr; int i; RestoreUndoSerialNumber (); Crosshair.AttachedObject.RubberbandN = 0; LookupRatLines (type, ptr1, ptr2, ptr3); ptr = Crosshair.AttachedObject.Rubberband; for (i = 0; i < Crosshair.AttachedObject.RubberbandN; i++, ptr++) { if (PCB->RatOn) EraseRat ((RatType *) ptr->Line); MoveObjectToRemoveUndoList (RATLINE_TYPE, ptr->Line, ptr->Line, ptr->Line); } IncrementUndoSerialNumber (); Draw (); } } } break; } /* change the layout's name */ case F_Layout: name = gui->prompt_for (_("Enter the layout name:"), EMPTY (PCB->Name)); /* NB: ChangeLayoutName takes ownership of the passed memory */ if (name && ChangeLayoutName (name)) SetChangedFlag (true); break; /* change the name of the active layer */ case F_Layer: name = gui->prompt_for (_("Enter the layer name:"), EMPTY (CURRENT->Name)); /* NB: ChangeLayerName takes ownership of the passed memory */ if (name && ChangeLayerName (CURRENT, name)) SetChangedFlag (true); break; } } return 0; } /* --------------------------------------------------------------------------- */ static const char morphpolygon_syntax[] = N_("MorphPolygon(Object|Selected)"); static const char morphpolygon_help[] = N_("Converts dead polygon islands into separate polygons."); /* %start-doc actions MorphPolygon If a polygon is divided into unconnected "islands", you can use this command to convert the otherwise disappeared islands into separate polygons. Be sure the cursor is over a portion of the polygon that remains visible. Very small islands that may flake off are automatically deleted. %end-doc */ static int ActionMorphPolygon (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); if (function) { switch (GetFunctionID (function)) { case F_Object: { int type; void *ptr1, *ptr2, *ptr3; gui->get_coords (_("Select an Object"), &x, &y); if ((type = SearchScreen (x, y, POLYGON_TYPE, &ptr1, &ptr2, &ptr3)) != NO_TYPE) { MorphPolygon ((LayerType *) ptr1, (PolygonType *) ptr3); Draw (); IncrementUndoSerialNumber (); } break; } case F_Selected: case F_SelectedObjects: ALLPOLYGON_LOOP (PCB->Data); { if (TEST_FLAG (SELECTEDFLAG, polygon)) MorphPolygon (layer, polygon); } ENDALL_LOOP; Draw (); IncrementUndoSerialNumber (); break; } } return 0; } /* --------------------------------------------------------------------------- */ static const char togglehidename_syntax[] = N_("ToggleHideName(Object|SelectedElements)"); static const char togglehidename_help[] = N_("Toggles the visibility of element names."); /* %start-doc actions ToggleHideName If names are hidden you won't see them on the screen and they will not appear on the silk layer when you print the layout. %end-doc */ static int ActionToggleHideName (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); if (function && PCB->ElementOn) { switch (GetFunctionID (function)) { case F_Object: { int type; void *ptr1, *ptr2, *ptr3; gui->get_coords (_("Select an Object"), &x, &y); if ((type = SearchScreen (x, y, ELEMENT_TYPE, &ptr1, &ptr2, &ptr3)) != NO_TYPE) { AddObjectToFlagUndoList (type, ptr1, ptr2, ptr3); EraseElementName ((ElementType *) ptr2); TOGGLE_FLAG (HIDENAMEFLAG, (ElementType *) ptr2); DrawElementName ((ElementType *) ptr2); Draw (); IncrementUndoSerialNumber (); } break; } case F_SelectedElements: case F_Selected: { bool changed = false; ELEMENT_LOOP (PCB->Data); { if ((TEST_FLAG (SELECTEDFLAG, element) || TEST_FLAG (SELECTEDFLAG, &NAMEONPCB_TEXT (element))) && (FRONT (element) || PCB->InvisibleObjectsOn)) { AddObjectToFlagUndoList (ELEMENT_TYPE, element, element, element); EraseElementName (element); TOGGLE_FLAG (HIDENAMEFLAG, element); DrawElementName (element); changed = true; } } END_LOOP; if (changed) { Draw (); IncrementUndoSerialNumber (); } } } } return 0; } /* --------------------------------------------------------------------------- */ static const char changejoin_syntax[] = N_("ChangeJoin(ToggleObject|SelectedLines|SelectedArcs|Selected)"); static const char changejoin_help[] = N_("Changes the join (clearance through polygons) of objects."); /* %start-doc actions ChangeJoin The join flag determines whether a line or arc, drawn to intersect a polygon, electrically connects to the polygon or not. When joined, the line/arc is simply drawn over the polygon, making an electrical connection. When not joined, a gap is drawn between the line and the polygon, insulating them from each other. %end-doc */ static int ActionChangeJoin (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); if (function) { switch (GetFunctionID (function)) { case F_ToggleObject: case F_Object: { int type; void *ptr1, *ptr2, *ptr3; gui->get_coords (_("Select an Object"), &x, &y); if ((type = SearchScreen (x, y, CHANGEJOIN_TYPES, &ptr1, &ptr2, &ptr3)) != NO_TYPE) if (ChangeObjectJoin (type, ptr1, ptr2, ptr3)) SetChangedFlag (true); break; } case F_SelectedLines: if (ChangeSelectedJoin (LINE_TYPE)) SetChangedFlag (true); break; case F_SelectedArcs: if (ChangeSelectedJoin (ARC_TYPE)) SetChangedFlag (true); break; case F_Selected: case F_SelectedObjects: if (ChangeSelectedJoin (CHANGEJOIN_TYPES)) SetChangedFlag (true); break; } } return 0; } /* --------------------------------------------------------------------------- */ static const char changesquare_syntax[] = N_("ChangeSquare(ToggleObject)\n" "ChangeSquare(SelectedElements|SelectedPins)\n" "ChangeSquare(Selected|SelectedObjects)"); static const char changesquare_help[] = N_("Changes the square flag of pins and pads."); /* %start-doc actions ChangeSquare Note that @code{Pins} means both pins and pads. @pinshapes %end-doc */ static int ActionChangeSquare (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); if (function) { switch (GetFunctionID (function)) { case F_ToggleObject: case F_Object: { int type; void *ptr1, *ptr2, *ptr3; gui->get_coords (_("Select an Object"), &x, &y); if ((type = SearchScreen (x, y, CHANGESQUARE_TYPES, &ptr1, &ptr2, &ptr3)) != NO_TYPE) if (ChangeObjectSquare (type, ptr1, ptr2, ptr3)) SetChangedFlag (true); break; } case F_SelectedElements: if (ChangeSelectedSquare (ELEMENT_TYPE)) SetChangedFlag (true); break; case F_SelectedPins: if (ChangeSelectedSquare (PIN_TYPE | PAD_TYPE)) SetChangedFlag (true); break; case F_Selected: case F_SelectedObjects: if (ChangeSelectedSquare (PIN_TYPE | PAD_TYPE)) SetChangedFlag (true); break; } } return 0; } /* --------------------------------------------------------------------------- */ static const char setsquare_syntax[] = N_("SetSquare(ToggleObject|SelectedElements|SelectedPins)"); static const char setsquare_help[] = N_("sets the square-flag of objects."); /* %start-doc actions SetSquare Note that @code{Pins} means pins and pads. @pinshapes %end-doc */ static int ActionSetSquare (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); if (function && *function) { switch (GetFunctionID (function)) { case F_ToggleObject: case F_Object: { int type; void *ptr1, *ptr2, *ptr3; gui->get_coords (_("Select an Object"), &x, &y); if ((type = SearchScreen (x, y, CHANGESQUARE_TYPES, &ptr1, &ptr2, &ptr3)) != NO_TYPE) if (SetObjectSquare (type, ptr1, ptr2, ptr3)) SetChangedFlag (true); break; } case F_SelectedElements: if (SetSelectedSquare (ELEMENT_TYPE)) SetChangedFlag (true); break; case F_SelectedPins: if (SetSelectedSquare (PIN_TYPE | PAD_TYPE)) SetChangedFlag (true); break; case F_Selected: case F_SelectedObjects: if (SetSelectedSquare (PIN_TYPE | PAD_TYPE)) SetChangedFlag (true); break; } } return 0; } /* --------------------------------------------------------------------------- */ static const char clearsquare_syntax[] = N_("ClearSquare(ToggleObject|SelectedElements|SelectedPins)"); static const char clearsquare_help[] = N_("Clears the square-flag of pins and pads."); /* %start-doc actions ClearSquare Note that @code{Pins} means pins and pads. @pinshapes %end-doc */ static int ActionClearSquare (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); if (function && *function) { switch (GetFunctionID (function)) { case F_ToggleObject: case F_Object: { int type; void *ptr1, *ptr2, *ptr3; gui->get_coords (_("Select an Object"), &x, &y); if ((type = SearchScreen (x, y, CHANGESQUARE_TYPES, &ptr1, &ptr2, &ptr3)) != NO_TYPE) if (ClrObjectSquare (type, ptr1, ptr2, ptr3)) SetChangedFlag (true); break; } case F_SelectedElements: if (ClrSelectedSquare (ELEMENT_TYPE)) SetChangedFlag (true); break; case F_SelectedPins: if (ClrSelectedSquare (PIN_TYPE | PAD_TYPE)) SetChangedFlag (true); break; case F_Selected: case F_SelectedObjects: if (ClrSelectedSquare (PIN_TYPE | PAD_TYPE)) SetChangedFlag (true); break; } } return 0; } /* --------------------------------------------------------------------------- */ static const char changeoctagon_syntax[] = N_("ChangeOctagon(Object|ToggleObject|SelectedObjects|Selected)\n" "ChangeOctagon(SelectedElements|SelectedPins|SelectedVias)"); static const char changeoctagon_help[] = N_("Changes the octagon-flag of pins and vias."); /* %start-doc actions ChangeOctagon @pinshapes %end-doc */ static int ActionChangeOctagon (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); if (function) { switch (GetFunctionID (function)) { case F_ToggleObject: case F_Object: { int type; void *ptr1, *ptr2, *ptr3; gui->get_coords (_("Select an Object"), &x, &y); if ((type = SearchScreen (x, y, CHANGEOCTAGON_TYPES, &ptr1, &ptr2, &ptr3)) != NO_TYPE) if (ChangeObjectOctagon (type, ptr1, ptr2, ptr3)) SetChangedFlag (true); break; } case F_SelectedElements: if (ChangeSelectedOctagon (ELEMENT_TYPE)) SetChangedFlag (true); break; case F_SelectedPins: if (ChangeSelectedOctagon (PIN_TYPE)) SetChangedFlag (true); break; case F_SelectedVias: if (ChangeSelectedOctagon (VIA_TYPE)) SetChangedFlag (true); break; case F_Selected: case F_SelectedObjects: if (ChangeSelectedOctagon (PIN_TYPES)) SetChangedFlag (true); break; } } return 0; } /* --------------------------------------------------------------------------- */ static const char setoctagon_syntax[] = N_("SetOctagon(Object|ToggleObject|SelectedElements|Selected)"); static const char setoctagon_help[] = N_("Sets the octagon-flag of objects."); /* %start-doc actions SetOctagon @pinshapes %end-doc */ static int ActionSetOctagon (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); if (function) { switch (GetFunctionID (function)) { case F_ToggleObject: case F_Object: { int type; void *ptr1, *ptr2, *ptr3; gui->get_coords (_("Select an Object"), &x, &y); if ((type = SearchScreen (x, y, CHANGEOCTAGON_TYPES, &ptr1, &ptr2, &ptr3)) != NO_TYPE) if (SetObjectOctagon (type, ptr1, ptr2, ptr3)) SetChangedFlag (true); break; } case F_SelectedElements: if (SetSelectedOctagon (ELEMENT_TYPE)) SetChangedFlag (true); break; case F_SelectedPins: if (SetSelectedOctagon (PIN_TYPE)) SetChangedFlag (true); break; case F_SelectedVias: if (SetSelectedOctagon (VIA_TYPE)) SetChangedFlag (true); break; case F_Selected: case F_SelectedObjects: if (SetSelectedOctagon (PIN_TYPES)) SetChangedFlag (true); break; } } return 0; } /* --------------------------------------------------------------------------- */ static const char clearoctagon_syntax[] = N_("ClearOctagon(ToggleObject|Object|SelectedObjects|Selected)\n" "ClearOctagon(SelectedElements|SelectedPins|SelectedVias)"); static const char clearoctagon_help[] = N_("Clears the octagon-flag of pins and vias."); /* %start-doc actions ClearOctagon @pinshapes %end-doc */ static int ActionClearOctagon (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); if (function) { switch (GetFunctionID (function)) { case F_ToggleObject: case F_Object: { int type; void *ptr1, *ptr2, *ptr3; gui->get_coords (_("Select an Object"), &x, &y); if ((type = SearchScreen (Crosshair.X, Crosshair.Y, CHANGEOCTAGON_TYPES, &ptr1, &ptr2, &ptr3)) != NO_TYPE) if (ClrObjectOctagon (type, ptr1, ptr2, ptr3)) SetChangedFlag (true); break; } case F_SelectedElements: if (ClrSelectedOctagon (ELEMENT_TYPE)) SetChangedFlag (true); break; case F_SelectedPins: if (ClrSelectedOctagon (PIN_TYPE)) SetChangedFlag (true); break; case F_SelectedVias: if (ClrSelectedOctagon (VIA_TYPE)) SetChangedFlag (true); break; case F_Selected: case F_SelectedObjects: if (ClrSelectedOctagon (PIN_TYPES)) SetChangedFlag (true); break; } } return 0; } /* --------------------------------------------------------------------------- */ static const char changehold_syntax[] = N_("ChangeHole(ToggleObject|Object|SelectedVias|Selected)"); static const char changehold_help[] = N_("Changes the hole flag of objects."); /* %start-doc actions ChangeHole The "hole flag" of a via determines whether the via is a plated-through hole (not set), or an unplated hole (set). %end-doc */ static int ActionChangeHole (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); if (function) { switch (GetFunctionID (function)) { case F_ToggleObject: case F_Object: { int type; void *ptr1, *ptr2, *ptr3; gui->get_coords (_("Select an Object"), &x, &y); if ((type = SearchScreen (x, y, VIA_TYPE, &ptr1, &ptr2, &ptr3)) != NO_TYPE && ChangeHole ((PinType *) ptr3)) IncrementUndoSerialNumber (); break; } case F_SelectedVias: case F_Selected: if (ChangeSelectedHole ()) SetChangedFlag (true); break; } } return 0; } /* --------------------------------------------------------------------------- */ static const char changepaste_syntax[] = N_("ChangePaste(ToggleObject|Object|SelectedPads|Selected)"); static const char changepaste_help[] = N_("Changes the no paste flag of objects."); /* %start-doc actions ChangePaste The "no paste flag" of a pad determines whether the solderpaste stencil will have an opening for the pad (no set) or if there wil be no solderpaste on the pad (set). This is used for things such as fiducial pads. %end-doc */ static int ActionChangePaste (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); if (function) { switch (GetFunctionID (function)) { case F_ToggleObject: case F_Object: { int type; void *ptr1, *ptr2, *ptr3; gui->get_coords (_("Select an Object"), &x, &y); if ((type = SearchScreen (x, y, PAD_TYPE, &ptr1, &ptr2, &ptr3)) != NO_TYPE && ChangePaste ((PadType *) ptr3)) IncrementUndoSerialNumber (); break; } case F_SelectedPads: case F_Selected: if (ChangeSelectedPaste ()) SetChangedFlag (true); break; } } return 0; } /* --------------------------------------------------------------------------- */ static const char select_syntax[] = N_("Select(Object|ToggleObject)\n" "Select(All|Block|Connection|BuriedVias)\n" "Select(ElementByName|ObjectByName|PadByName|PinByName)\n" "Select(ElementByName|ObjectByName|PadByName|PinByName, Name)\n" "Select(TextByName|ViaByName|NetByName)\n" "Select(TextByName|ViaByName|NetByName, Name)\n" "Select(Convert)"); static const char select_help[] = N_("Toggles or sets the selection."); /* %start-doc actions Select @table @code @item ElementByName @item ObjectByName @item PadByName @item PinByName @item TextByName @item ViaByName @item NetByName These all rely on having a regular expression parser built into @code{pcb}. If the name is not specified then the user is prompted for a pattern, and all objects that match the pattern and are of the type specified are selected. @item Object @item ToggleObject Selects the object under the cursor. @item Block Selects all objects in a rectangle indicated by the cursor. @item All Selects all objects on the board. @item Found Selects all connections with the ``found'' flag set. @item Connection Selects all connections with the ``connected'' flag set. @item Connection Selects all blind and buried vias. @item Convert Converts the selected objects to an element. This uses the highest numbered paste buffer. @end table %end-doc */ static int ActionSelect (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); if (function) { switch (GetFunctionID (function)) { #if defined(HAVE_REGCOMP) || defined(HAVE_RE_COMP) int type; /* select objects by their names */ case F_ElementByName: type = ELEMENT_TYPE; goto commonByName; case F_ObjectByName: type = ALL_TYPES; goto commonByName; case F_PadByName: type = PAD_TYPE; goto commonByName; case F_PinByName: type = PIN_TYPE; goto commonByName; case F_TextByName: type = TEXT_TYPE; goto commonByName; case F_ViaByName: type = VIA_TYPE; goto commonByName; case F_NetByName: type = NET_TYPE; goto commonByName; commonByName: { char *pattern = ARG (1); if (pattern || (pattern = gui->prompt_for (_("Enter pattern:"), "")) != NULL) { if (SelectObjectByName (type, pattern, true)) SetChangedFlag (true); if (ARG (1) == NULL) free (pattern); } break; } #endif /* defined(HAVE_REGCOMP) || defined(HAVE_RE_COMP) */ /* select a single object */ case F_ToggleObject: case F_Object: if (SelectObject ()) SetChangedFlag (true); break; /* all objects in block */ case F_Block: { BoxType box; box.X1 = MIN (Crosshair.AttachedBox.Point1.X, Crosshair.AttachedBox.Point2.X); box.Y1 = MIN (Crosshair.AttachedBox.Point1.Y, Crosshair.AttachedBox.Point2.Y); box.X2 = MAX (Crosshair.AttachedBox.Point1.X, Crosshair.AttachedBox.Point2.X); box.Y2 = MAX (Crosshair.AttachedBox.Point1.Y, Crosshair.AttachedBox.Point2.Y); notify_crosshair_change (false); NotifyBlock (); if (Crosshair.AttachedBox.State == STATE_THIRD && SelectBlock (&box, true)) { SetChangedFlag (true); Crosshair.AttachedBox.State = STATE_FIRST; } notify_crosshair_change (true); break; } /* select all visible objects */ case F_All: { BoxType box; box.X1 = -MAX_COORD; box.Y1 = -MAX_COORD; box.X2 = MAX_COORD; box.Y2 = MAX_COORD; if (SelectBlock (&box, true)) SetChangedFlag (true); break; } /* all logical connections */ case F_Found: if (SelectByFlag (FOUNDFLAG, true)) { Draw (); IncrementUndoSerialNumber (); SetChangedFlag (true); } break; /* all physical connections */ case F_Connection: if (SelectByFlag (CONNECTEDFLAG, true)) { Draw (); IncrementUndoSerialNumber (); SetChangedFlag (true); } break; case F_BuriedVias: if (SelectBuriedVias (true)) { Draw (); IncrementUndoSerialNumber (); SetChangedFlag (true); } break; case F_Convert: { Coord x, y; Note.Buffer = Settings.BufferNumber; SetBufferNumber (MAX_BUFFER - 1); ClearBuffer (PASTEBUFFER); gui->get_coords (_("Select the Element's Mark Location"), &x, &y); x = GridFit (x, PCB->Grid, PCB->GridOffsetX); y = GridFit (y, PCB->Grid, PCB->GridOffsetY); AddSelectedToBuffer (PASTEBUFFER, x, y, true); SaveUndoSerialNumber (); RemoveSelected (); ConvertBufferToElement (PASTEBUFFER); RestoreUndoSerialNumber (); CopyPastebufferToLayout (x, y); SetBufferNumber (Note.Buffer); } break; default: AFAIL (select); break; } } return 0; } /* FLAG(have_regex,FlagHaveRegex,0) */ int FlagHaveRegex (int parm) { #if defined(HAVE_REGCOMP) || defined(HAVE_RE_COMP) return 1; #else return 0; #endif } /* --------------------------------------------------------------------------- */ static const char unselect_syntax[] = N_("Unselect(All|Block|Connection)\n" "Unselect(ElementByName|ObjectByName|PadByName|PinByName)\n" "Unselect(ElementByName|ObjectByName|PadByName|PinByName, Name)\n" "Unselect(TextByName|ViaByName)\n" "Unselect(TextByName|ViaByName, Name)\n"); static const char unselect_help[] = N_("Unselects the object at the pointer location or the specified objects."); /* %start-doc actions Unselect @table @code @item All Unselect all objects. @item Block Unselect all objects in a rectangle given by the cursor. @item Connection Unselect all connections with the ``found'' flag set. @item ElementByName @item ObjectByName @item PadByName @item PinByName @item TextByName @item ViaByName These all rely on having a regular expression parser built into @code{pcb}. If the name is not specified then the user is prompted for a pattern, and all objects that match the pattern and are of the type specified are unselected. @end table %end-doc */ static int ActionUnselect (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); if (function) { switch (GetFunctionID (function)) { #if defined(HAVE_REGCOMP) || defined(HAVE_RE_COMP) int type; /* select objects by their names */ case F_ElementByName: type = ELEMENT_TYPE; goto commonByName; case F_ObjectByName: type = ALL_TYPES; goto commonByName; case F_PadByName: type = PAD_TYPE; goto commonByName; case F_PinByName: type = PIN_TYPE; goto commonByName; case F_TextByName: type = TEXT_TYPE; goto commonByName; case F_ViaByName: type = VIA_TYPE; goto commonByName; case F_NetByName: type = NET_TYPE; goto commonByName; commonByName: { char *pattern = ARG (1); if (pattern || (pattern = gui->prompt_for (_("Enter pattern:"), "")) != NULL) { if (SelectObjectByName (type, pattern, false)) SetChangedFlag (true); if (ARG (1) == NULL) free (pattern); } break; } #endif /* defined(HAVE_REGCOMP) || defined(HAVE_RE_COMP) */ /* all objects in block */ case F_Block: { BoxType box; box.X1 = MIN (Crosshair.AttachedBox.Point1.X, Crosshair.AttachedBox.Point2.X); box.Y1 = MIN (Crosshair.AttachedBox.Point1.Y, Crosshair.AttachedBox.Point2.Y); box.X2 = MAX (Crosshair.AttachedBox.Point1.X, Crosshair.AttachedBox.Point2.X); box.Y2 = MAX (Crosshair.AttachedBox.Point1.Y, Crosshair.AttachedBox.Point2.Y); notify_crosshair_change (false); NotifyBlock (); if (Crosshair.AttachedBox.State == STATE_THIRD && SelectBlock (&box, false)) { SetChangedFlag (true); Crosshair.AttachedBox.State = STATE_FIRST; } notify_crosshair_change (true); break; } /* unselect all visible objects */ case F_All: { BoxType box; box.X1 = -MAX_COORD; box.Y1 = -MAX_COORD; box.X2 = MAX_COORD; box.Y2 = MAX_COORD; if (SelectBlock (&box, false)) SetChangedFlag (true); break; } /* all logical connections */ case F_Found: if (SelectByFlag (FOUNDFLAG, false)) { Draw (); IncrementUndoSerialNumber (); SetChangedFlag (true); } break; /* all physical connections */ case F_Connection: if (SelectByFlag (CONNECTEDFLAG, false)) { Draw (); IncrementUndoSerialNumber (); SetChangedFlag (true); } break; default: AFAIL (unselect); break; } } return 0; } /* --------------------------------------------------------------------------- */ static const char saveto_syntax[] = N_("SaveTo(Layout|LayoutAs,filename)\n" "SaveTo(AllConnections|AllUnusedPins|ElementConnections,filename)\n" "SaveTo(PasteBuffer,filename)"); static const char saveto_help[] = N_("Saves data to a file."); /* %start-doc actions SaveTo @table @code @item Layout Saves the current layout. @item LayoutAs Saves the current layout, and remembers the filename used. @item AllConnections Save all connections to a file. @item AllUnusedPins List all unused pins to a file. @item ElementConnections Save connections to the element at the cursor to a file. @item PasteBuffer Save the content of the active Buffer to a file. This is the graphical way to create a footprint. @end table %end-doc */ static int ActionSaveTo (int argc, char **argv, Coord x, Coord y) { char *function; char *name; function = ARG (0); if ( ! function || strcasecmp (function, "Layout") == 0) { if (SavePCB (PCB->Filename) == 0) SetChangedFlag (false); return 0; } if (argc != 2) AFAIL (saveto); name = argv[1]; if (strcasecmp (function, "LayoutAs") == 0) { if (SavePCB (name) == 0) { SetChangedFlag (false); free (PCB->Filename); PCB->Filename = strdup (name); if (gui->notify_filename_changed != NULL) gui->notify_filename_changed (); } return 0; } if (strcasecmp (function, "AllConnections") == 0) { FILE *fp; bool result; if ((fp = CheckAndOpenFile (name, true, false, &result, NULL)) != NULL) { LookupConnectionsToAllElements (fp); fclose (fp); SetChangedFlag (true); } return 0; } if (strcasecmp (function, "AllUnusedPins") == 0) { FILE *fp; bool result; if ((fp = CheckAndOpenFile (name, true, false, &result, NULL)) != NULL) { LookupUnusedPins (fp); fclose (fp); SetChangedFlag (true); } return 0; } if (strcasecmp (function, "ElementConnections") == 0) { ElementType *element; void *ptrtmp; FILE *fp; bool result; if ((SearchScreen (Crosshair.X, Crosshair.Y, ELEMENT_TYPE, &ptrtmp, &ptrtmp, &ptrtmp)) != NO_TYPE) { element = (ElementType *) ptrtmp; if ((fp = CheckAndOpenFile (name, true, false, &result, NULL)) != NULL) { LookupElementConnections (element, fp); fclose (fp); SetChangedFlag (true); } } return 0; } if (strcasecmp (function, "PasteBuffer") == 0) { return SaveBufferElements (name); } AFAIL (saveto); } /* --------------------------------------------------------------------------- */ static const char savesettings_syntax[] = N_("SaveSettings()\n" "SaveSettings(local)"); static const char savesettings_help[] = N_("Saves settings."); /* %start-doc actions SaveSettings If you pass no arguments, the settings are stored in @code{$HOME/.pcb/settings}. If you pass the word @code{local} they're saved in @code{./pcb.settings}. %end-doc */ static int ActionSaveSettings (int argc, char **argv, Coord x, Coord y) { int locally = argc > 0 ? (strncasecmp (argv[0], "local", 5) == 0) : 0; hid_save_settings (locally); return 0; } /* --------------------------------------------------------------------------- */ static const char loadfrom_syntax[] = N_("LoadFrom(Layout|LayoutToBuffer|ElementToBuffer|Netlist|Revert,filename)"); static const char loadfrom_help[] = N_("Load layout data from a file."); /* %start-doc actions LoadFrom This action assumes you know what the filename is. The various GUIs should have a similar @code{Load} action where the filename is optional, and will provide their own file selection mechanism to let you choose the file name. @table @code @item Layout Loads an entire PCB layout, replacing the current one. @item LayoutToBuffer Loads an entire PCB layout to the paste buffer. @item ElementToBuffer Loads the given element file into the paste buffer. Element files contain only a single @code{Element} definition, such as the ``newlib'' library uses. @item Netlist Loads a new netlist, replacing any current netlist. @item Revert Re-loads the current layout from its disk file, reverting any changes you may have made. @end table %end-doc */ static int ActionLoadFrom (int argc, char **argv, Coord x, Coord y) { char *function; char *name; if (argc < 2) AFAIL (loadfrom); function = argv[0]; name = argv[1]; if (strcasecmp (function, "ElementToBuffer") == 0) { notify_crosshair_change (false); if (LoadElementToBuffer (PASTEBUFFER, name, true)) SetMode (PASTEBUFFER_MODE); notify_crosshair_change (true); } else if (strcasecmp (function, "LayoutToBuffer") == 0) { notify_crosshair_change (false); if (LoadLayoutToBuffer (PASTEBUFFER, name)) SetMode (PASTEBUFFER_MODE); notify_crosshair_change (true); } else if (strcasecmp (function, "Layout") == 0) { if (!PCB->Changed || gui->confirm_dialog (_("OK to override layout data?"), 0)) LoadPCB (name); } else if (strcasecmp (function, "Netlist") == 0) { if (PCB->Netlistname) free (PCB->Netlistname); PCB->Netlistname = StripWhiteSpaceAndDup (name); FreeLibraryMemory (&PCB->NetlistLib); ImportNetlist (PCB->Netlistname); NetlistChanged (1); netlist_loaded = true; } else if (strcasecmp (function, "Revert") == 0 && PCB->Filename && (!PCB->Changed || gui->confirm_dialog (_("OK to override changes?"), 0))) { RevertPCB (); } return 0; } /* --------------------------------------------------------------------------- */ static const char new_syntax[] = N_("New([name])"); static const char new_help[] = N_("Starts a new layout."); /* %start-doc actions New If a name is not given, one is prompted for. %end-doc */ static int ActionNew (int argc, char **argv, Coord x, Coord y) { char *name = ARG (0); if (!PCB->Changed || gui->confirm_dialog (_("OK to clear layout data?"), 0)) { if (name) name = strdup (name); else name = gui->prompt_for (_("Enter the layout name:"), ""); if (!name) return 1; notify_crosshair_change (false); /* do emergency saving * clear the old struct and allocate memory for the new one */ if (PCB->Changed && Settings.SaveInTMP) SaveInTMP (); RemovePCB (PCB); PCB = NULL; PCB = CreateNewPCB (); CreateNewPCBPost (PCB, 1); /* setup the new name and reset some values to default */ free (PCB->Name); PCB->Name = name; ResetStackAndVisibility (); CenterDisplay (PCB->MaxWidth / 2, PCB->MaxHeight / 2, false); Redraw (); hid_action ("PCBChanged"); notify_crosshair_change (true); return 0; } return 1; } /*! * \brief No operation, just for testing purposes. * syntax: Bell(volume) */ void ActionBell (char *volume) { gui->beep (); } /* --------------------------------------------------------------------------- */ static const char pastebuffer_syntax[] = N_("PasteBuffer(AddSelected|Clear|1..MAX_BUFFER)\n" "PasteBuffer(Rotate, 1..3)\n" "PasteBuffer(Convert|Save|Restore|Mirror)\n" "PasteBuffer(ToLayout, X, Y, units)"); static const char pastebuffer_help[] = N_("Various operations on the paste buffer."); /* %start-doc actions PasteBuffer There are a number of paste buffers; the actual limit is a compile-time constant @code{MAX_BUFFER} in @file{globalconst.h}. It is currently @code{5}. One of these is the ``current'' paste buffer, often referred to as ``the'' paste buffer. @table @code @item AddSelected Copies the selected objects to the current paste buffer. @item Clear Remove all objects from the current paste buffer. @item Convert Convert the current paste buffer to an element. Vias are converted to pins, lines are converted to pads. @item Restore Convert any elements in the paste buffer back to vias and lines. @item Mirror Flip all objects in the paste buffer vertically (up/down flip). To mirror horizontally, combine this with rotations. @item Rotate Rotates the current buffer. The number to pass is 1..3, where 1 means 90 degrees counter clockwise, 2 means 180 degrees, and 3 means 90 degrees clockwise (270 CCW). @item Save Saves any elements in the current buffer to the indicated file. @item ToLayout Pastes any elements in the current buffer to the indicated X, Y coordinates in the layout. The @code{X} and @code{Y} are treated like @code{delta} is for many other objects. For each, if it's prefixed by @code{+} or @code{-}, then that amount is relative to the last location. Otherwise, it's absolute. Units can be @code{mil} or @code{mm}; if unspecified, units are PCB's internal units, currently 1/100 mil. @item 1..MAX_BUFFER Selects the given buffer to be the current paste buffer. @end table %end-doc */ static int ActionPasteBuffer (int argc, char **argv, Coord x, Coord y) { char *function = argc ? argv[0] : (char *)""; char *sbufnum = argc > 1 ? argv[1] : (char *)""; char *name; static char *default_file = NULL; int free_name = 0; notify_crosshair_change (false); if (function) { switch (GetFunctionID (function)) { /* clear contents of paste buffer */ case F_Clear: ClearBuffer (PASTEBUFFER); break; /* copies objects to paste buffer */ case F_AddSelected: AddSelectedToBuffer (PASTEBUFFER, 0, 0, false); break; /* converts buffer contents into an element */ case F_Convert: ConvertBufferToElement (PASTEBUFFER); break; /* break up element for editing */ case F_Restore: SmashBufferElement (PASTEBUFFER); break; /* Mirror buffer */ case F_Mirror: MirrorBuffer (PASTEBUFFER); break; case F_Rotate: if (sbufnum) { RotateBuffer (PASTEBUFFER, (BYTE) atoi (sbufnum)); crosshair_update_range(); } break; case F_Save: if (PASTEBUFFER->Data->ElementN == 0) { Message (_("Buffer has no elements!\n")); break; } free_name = 0; if (argc <= 1) { name = gui->fileselect (_("Save Paste Buffer As ..."), _("Choose a file to save the contents of the\n" "paste buffer to.\n"), default_file, ".fp", "footprint", 0); if (default_file) { free (default_file); default_file = NULL; } if ( name && *name) { default_file = strdup (name); } free_name = 1; } else name = argv[1]; { FILE *exist; if ((exist = fopen (name, "r"))) { fclose (exist); if (gui-> confirm_dialog (_("File exists! Ok to overwrite?"), 0)) SaveBufferElements (name); } else SaveBufferElements (name); if (free_name && name) free (name); } break; case F_ToLayout: { static Coord oldx = 0, oldy = 0; Coord x, y; bool absolute; if (argc == 1) { x = y = 0; } else if (argc == 3 || argc == 4) { x = GetValue (ARG (1), ARG (3), &absolute); if (!absolute) x += oldx; y = GetValue (ARG (2), ARG (3), &absolute); if (!absolute) y += oldy; } else { notify_crosshair_change (true); AFAIL (pastebuffer); } oldx = x; oldy = y; if (CopyPastebufferToLayout (x, y)) SetChangedFlag (true); } break; /* set number */ default: { int number = atoi (function); /* correct number */ if (number) SetBufferNumber (number - 1); } } } notify_crosshair_change (true); return 0; } /* --------------------------------------------------------------------------- */ static const char undo_syntax[] = N_("Undo()\n" "Undo(ClearList)"); static const char undo_help[] = N_("Undo recent changes."); /* %start-doc actions Undo The unlimited undo feature of @code{Pcb} allows you to recover from most operations that materially affect you work. Calling @code{Undo()} without any parameter recovers from the last (non-undo) operation. @code{ClearList} is used to release the allocated memory. @code{ClearList} is called whenever a new layout is started or loaded. See also @code{Redo} and @code{Atomic}. Note that undo groups operations by serial number; changes with the same serial number will be undone (or redone) as a group. See @code{Atomic}. %end-doc */ static int ActionUndo (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); if (!function || !*function) { /* don't allow undo in the middle of an operation */ if (Settings.Mode != POLYGONHOLE_MODE && Crosshair.AttachedObject.State != STATE_FIRST) return 1; if (Crosshair.AttachedBox.State != STATE_FIRST && Settings.Mode != ARC_MODE) return 1; /* undo the last operation */ notify_crosshair_change (false); if ((Settings.Mode == POLYGON_MODE || Settings.Mode == POLYGONHOLE_MODE) && Crosshair.AttachedPolygon.PointN) { GoToPreviousPoint (); notify_crosshair_change (true); return 0; } /* move anchor point if undoing during line creation */ if (Settings.Mode == LINE_MODE) { if (Crosshair.AttachedLine.State == STATE_SECOND) { if (TEST_FLAG (AUTODRCFLAG, PCB)) Undo (true); /* undo the connection find */ Crosshair.AttachedLine.State = STATE_FIRST; SetLocalRef (0, 0, false); notify_crosshair_change (true); return 0; } if (Crosshair.AttachedLine.State == STATE_THIRD) { int type; void *ptr1, *ptr3, *ptrtmp; LineType *ptr2; /* this search is guaranteed to succeed */ SearchObjectByLocation (LINE_TYPE | RATLINE_TYPE, &ptr1, &ptrtmp, &ptr3, Crosshair.AttachedLine.Point1.X, Crosshair.AttachedLine.Point1.Y, 0); ptr2 = (LineType *) ptrtmp; /* save both ends of line */ Crosshair.AttachedLine.Point2.X = ptr2->Point1.X; Crosshair.AttachedLine.Point2.Y = ptr2->Point1.Y; if ((type = Undo (true))) SetChangedFlag (true); /* check that the undo was of the right type */ if ((type & UNDO_CREATE) == 0) { /* wrong undo type, restore anchor points */ Crosshair.AttachedLine.Point2.X = Crosshair.AttachedLine.Point1.X; Crosshair.AttachedLine.Point2.Y = Crosshair.AttachedLine.Point1.Y; notify_crosshair_change (true); return 0; } /* move to new anchor */ Crosshair.AttachedLine.Point1.X = Crosshair.AttachedLine.Point2.X; Crosshair.AttachedLine.Point1.Y = Crosshair.AttachedLine.Point2.Y; /* check if an intermediate point was removed */ if (type & UNDO_REMOVE) { /* this search should find the restored line */ SearchObjectByLocation (LINE_TYPE | RATLINE_TYPE, &ptr1, &ptrtmp, &ptr3, Crosshair.AttachedLine.Point2.X, Crosshair.AttachedLine.Point2.Y, 0); ptr2 = (LineType *) ptrtmp; if (TEST_FLAG (AUTODRCFLAG, PCB)) { /* undo loses CONNECTEDFLAG and FOUNDFLAG */ SET_FLAG(CONNECTEDFLAG, ptr2); SET_FLAG(FOUNDFLAG, ptr2); DrawLine (CURRENT, ptr2); } Crosshair.AttachedLine.Point1.X = Crosshair.AttachedLine.Point2.X = ptr2->Point2.X; Crosshair.AttachedLine.Point1.Y = Crosshair.AttachedLine.Point2.Y = ptr2->Point2.Y; } FitCrosshairIntoGrid (Crosshair.X, Crosshair.Y); AdjustAttachedObjects (); if (--addedLines == 0) { Crosshair.AttachedLine.State = STATE_SECOND; lastLayer = CURRENT; } else { /* this search is guaranteed to succeed too */ SearchObjectByLocation (LINE_TYPE | RATLINE_TYPE, &ptr1, &ptrtmp, &ptr3, Crosshair.AttachedLine.Point1.X, Crosshair.AttachedLine.Point1.Y, 0); ptr2 = (LineType *) ptrtmp; lastLayer = (LayerType *) ptr1; } notify_crosshair_change (true); return 0; } } if (Settings.Mode == ARC_MODE) { if (Crosshair.AttachedBox.State == STATE_SECOND) { Crosshair.AttachedBox.State = STATE_FIRST; notify_crosshair_change (true); return 0; } if (Crosshair.AttachedBox.State == STATE_THIRD) { void *ptr1, *ptr2, *ptr3; BoxType *bx; /* guaranteed to succeed */ SearchObjectByLocation (ARC_TYPE, &ptr1, &ptr2, &ptr3, Crosshair.AttachedBox.Point1.X, Crosshair.AttachedBox.Point1.Y, 0); bx = GetArcEnds ((ArcType *) ptr2); Crosshair.AttachedBox.Point1.X = Crosshair.AttachedBox.Point2.X = bx->X1; Crosshair.AttachedBox.Point1.Y = Crosshair.AttachedBox.Point2.Y = bx->Y1; AdjustAttachedObjects (); if (--addedLines == 0) Crosshair.AttachedBox.State = STATE_SECOND; } } /* undo the last destructive operation */ if (Undo (true)) SetChangedFlag (true); } else if (function) { switch (GetFunctionID (function)) { /* clear 'undo objects' list */ case F_ClearList: ClearUndoList (false); break; } } notify_crosshair_change (true); return 0; } /* --------------------------------------------------------------------------- */ static const char redo_syntax[] = N_("Redo()"); static const char redo_help[] = N_("Redo recent \"undo\" operations."); /* %start-doc actions Redo This routine allows you to recover from the last undo command. You might want to do this if you thought that undo was going to revert something other than what it actually did (in case you are confused about which operations are un-doable), or if you have been backing up through a long undo list and over-shoot your stopping point. Any change that is made since the undo in question will trim the redo list. For example if you add ten lines, then undo three of them you could use redo to put them back, but if you move a line on the board before performing the redo, you will lose the ability to "redo" the three "undone" lines. %end-doc */ static int ActionRedo (int argc, char **argv, Coord x, Coord y) { if (((Settings.Mode == POLYGON_MODE || Settings.Mode == POLYGONHOLE_MODE) && Crosshair.AttachedPolygon.PointN) || Crosshair.AttachedLine.State == STATE_SECOND) return 1; notify_crosshair_change (false); if (Redo (true)) { SetChangedFlag (true); if (Settings.Mode == LINE_MODE && Crosshair.AttachedLine.State != STATE_FIRST) { LineType *line = g_list_last (CURRENT->Line)->data; Crosshair.AttachedLine.Point1.X = Crosshair.AttachedLine.Point2.X = line->Point2.X; Crosshair.AttachedLine.Point1.Y = Crosshair.AttachedLine.Point2.Y = line->Point2.Y; addedLines++; } } notify_crosshair_change (true); return 0; } /* --------------------------------------------------------------------------- */ static const char polygon_syntax[] = N_("Polygon(Close|PreviousPoint)"); static const char polygon_help[] = N_("Some polygon related stuff."); /* %start-doc actions Polygon Polygons need a special action routine to make life easier. @table @code @item Close Creates the final segment of the polygon. This may fail if clipping to 45 degree lines is switched on, in which case a warning is issued. @item PreviousPoint Resets the newly entered corner to the previous one. The Undo action will call Polygon(PreviousPoint) when appropriate to do so. @end table %end-doc */ static int ActionPolygon (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); if (function && Settings.Mode == POLYGON_MODE) { notify_crosshair_change (false); switch (GetFunctionID (function)) { /* close open polygon if possible */ case F_Close: ClosePolygon (); break; /* go back to the previous point */ case F_PreviousPoint: GoToPreviousPoint (); break; } notify_crosshair_change (true); } return 0; } /* --------------------------------------------------------------------------- */ static const char routestyle_syntax[] = N_("RouteStyle(1|2|3|4)"); static const char routestyle_help[] = N_("Copies the indicated routing style into the current sizes."); /* %start-doc actions RouteStyle %end-doc */ static int ActionRouteStyle (int argc, char **argv, Coord x, Coord y) { char *str = ARG (0); RouteStyleType *rts; int number; if (str) { number = atoi (str); if (number > 0 && number <= NUM_STYLES) { rts = &PCB->RouteStyle[number - 1]; SetLineSize (rts->Thick); SetViaSize (rts->Diameter, true); SetViaDrillingHole (rts->Hole, true); SetKeepawayWidth (rts->Keepaway); SetViaMaskAperture(rts->ViaMask); hid_action("RouteStylesChanged"); } } return 0; } /* --------------------------------------------------------------------------- */ static const char moveobject_syntax[] = N_("MoveObject(X,Y,dim)"); static const char moveobject_help[] = N_("Moves the object under the crosshair."); /* %start-doc actions MoveObject The @code{X} and @code{Y} are treated like @code{delta} is for many other objects. For each, if it's prefixed by @code{+} or @code{-}, then that amount is relative. Otherwise, it's absolute. Units can be @code{mil} or @code{mm}; if unspecified, units are PCB's internal units, currently 1/100 mil. %end-doc */ static int ActionMoveObject (int argc, char **argv, Coord x, Coord y) { char *x_str = ARG (0); char *y_str = ARG (1); char *units = ARG (2); Coord nx, ny; bool absolute1, absolute2; void *ptr1, *ptr2, *ptr3; int type; ny = GetValue (y_str, units, &absolute1); nx = GetValue (x_str, units, &absolute2); type = SearchScreen (x, y, MOVE_TYPES, &ptr1, &ptr2, &ptr3); if (type == NO_TYPE) { Message (_("Nothing found under crosshair\n")); return 1; } if (absolute1) nx -= x; if (absolute2) ny -= y; Crosshair.AttachedObject.RubberbandN = 0; if (TEST_FLAG (RUBBERBANDFLAG, PCB)) LookupRubberbandLines (type, ptr1, ptr2, ptr3); if (type == ELEMENT_TYPE) LookupRatLines (type, ptr1, ptr2, ptr3); MoveObjectAndRubberband (type, ptr1, ptr2, ptr3, nx, ny); SetChangedFlag (true); return 0; } /* --------------------------------------------------------------------------- */ static const char movetocurrentlayer_syntax[] = N_("MoveToCurrentLayer(Object|SelectedObjects)"); static const char movetocurrentlayer_help[] = N_("Moves objects to the current layer."); /* %start-doc actions MoveToCurrentLayer Note that moving an element from a component layer to a solder layer, or from solder to component, won't automatically flip it. Use the @code{Flip()} action to do that. %end-doc */ static int ActionMoveToCurrentLayer (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); if (function) { switch (GetFunctionID (function)) { case F_Object: { int type; void *ptr1, *ptr2, *ptr3; gui->get_coords (_("Select an Object"), &x, &y); if ((type = SearchScreen (x, y, MOVETOLAYER_TYPES, &ptr1, &ptr2, &ptr3)) != NO_TYPE) if (MoveObjectToLayer (type, ptr1, ptr2, ptr3, CURRENT, false)) SetChangedFlag (true); break; } case F_SelectedObjects: case F_Selected: if (MoveSelectedObjectsToLayer (CURRENT)) SetChangedFlag (true); break; } } return 0; } static const char setsame_syntax[] = N_("SetSame()"); static const char setsame_help[] = N_("Sets current layer and sizes to match indicated item."); /* %start-doc actions SetSame When invoked over any line, arc, polygon, or via, this changes the current layer to be the layer that item is on, and changes the current sizes (thickness, keepaway, drill, etc) according to that item. %end-doc */ static int ActionSetSame (int argc, char **argv, Coord x, Coord y) { void *ptr1, *ptr2, *ptr3; int type; LayerType *layer = CURRENT; type = SearchScreen (x, y, CLONE_TYPES, &ptr1, &ptr2, &ptr3); /* set layer current and size from line or arc */ switch (type) { case LINE_TYPE: notify_crosshair_change (false); Settings.LineThickness = ((LineType *) ptr2)->Thickness; Settings.Keepaway = ((LineType *) ptr2)->Clearance / 2; layer = (LayerType *) ptr1; if (Settings.Mode != LINE_MODE) SetMode (LINE_MODE); notify_crosshair_change (true); hid_action ("RouteStylesChanged"); break; case ARC_TYPE: notify_crosshair_change (false); Settings.LineThickness = ((ArcType *) ptr2)->Thickness; Settings.Keepaway = ((ArcType *) ptr2)->Clearance / 2; layer = (LayerType *) ptr1; if (Settings.Mode != ARC_MODE) SetMode (ARC_MODE); notify_crosshair_change (true); hid_action ("RouteStylesChanged"); break; case POLYGON_TYPE: layer = (LayerType *) ptr1; break; case VIA_TYPE: notify_crosshair_change (false); Settings.ViaThickness = ((PinType *) ptr2)->Thickness; Settings.ViaDrillingHole = ((PinType *) ptr2)->DrillingHole; Settings.Keepaway = ((PinType *) ptr2)->Clearance / 2; if (Settings.Mode != VIA_MODE) SetMode (VIA_MODE); notify_crosshair_change (true); hid_action ("RouteStylesChanged"); break; default: return 1; } if (layer != CURRENT) { ChangeGroupVisibility (GetLayerNumber (PCB->Data, layer), true, true); Redraw (); } return 0; } /* --------------------------------------------------------------------------- */ static const char setflag_syntax[] = N_("SetFlag(Object|Selected|SelectedObjects, flag)\n" "SetFlag(SelectedLines|SelectedPins|SelectedVias, flag)\n" "SetFlag(SelectedPads|SelectedTexts|SelectedNames, flag)\n" "SetFlag(SelectedElements, flag)\n" "flag = square | octagon | thermal | join"); static const char setflag_help[] = N_("Sets flags on objects."); /* %start-doc actions SetFlag Turns the given flag on, regardless of its previous setting. See @code{ChangeFlag}. @example SetFlag(SelectedPins,thermal) @end example %end-doc */ static int ActionSetFlag (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); char *flag = ARG (1); ChangeFlag (function, flag, 1, "SetFlag"); return 0; } /* --------------------------------------------------------------------------- */ static const char clrflag_syntax[] = N_("ClrFlag(Object|Selected|SelectedObjects, flag)\n" "ClrFlag(SelectedLines|SelectedPins|SelectedVias, flag)\n" "ClrFlag(SelectedPads|SelectedTexts|SelectedNames, flag)\n" "ClrFlag(SelectedElements, flag)\n" "flag = square | octagon | thermal | join"); static const char clrflag_help[] = N_("Clears flags on objects."); /* %start-doc actions ClrFlag Turns the given flag off, regardless of its previous setting. See @code{ChangeFlag}. @example ClrFlag(SelectedLines,join) @end example %end-doc */ static int ActionClrFlag (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); char *flag = ARG (1); ChangeFlag (function, flag, 0, "ClrFlag"); return 0; } /* --------------------------------------------------------------------------- */ static const char changeflag_syntax[] = N_("ChangeFlag(Object|Selected|SelectedObjects, flag, value)\n" "ChangeFlag(SelectedLines|SelectedPins|SelectedVias, flag, value)\n" "ChangeFlag(SelectedPads|SelectedTexts|SelectedNames, flag, value)\n" "ChangeFlag(SelectedElements, flag, value)\n" "flag = square | octagon | thermal | join\n" "value = 0 | 1"); static const char changeflag_help[] = N_("Sets or clears flags on objects."); /* %start-doc actions ChangeFlag Toggles the given flag on the indicated object(s). The flag may be one of the flags listed above (square, octagon, thermal, join). The value may be the number 0 or 1. If the value is 0, the flag is cleared. If the value is 1, the flag is set. %end-doc */ static int ActionChangeFlag (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); char *flag = ARG (1); int value = argc > 2 ? atoi (argv[2]) : -1; if (value != 0 && value != 1) AFAIL (changeflag); ChangeFlag (function, flag, value, "ChangeFlag"); return 0; } static void ChangeFlag (char *what, char *flag_name, int value, char *cmd_name) { bool (*set_object) (int, void *, void *, void *); bool (*set_selected) (int); if (NSTRCMP (flag_name, "square") == 0) { set_object = value ? SetObjectSquare : ClrObjectSquare; set_selected = value ? SetSelectedSquare : ClrSelectedSquare; } else if (NSTRCMP (flag_name, "octagon") == 0) { set_object = value ? SetObjectOctagon : ClrObjectOctagon; set_selected = value ? SetSelectedOctagon : ClrSelectedOctagon; } else if (NSTRCMP (flag_name, "join") == 0) { /* Note: these are backwards, because the flag is "clear" but the command is "join". */ set_object = value ? ClrObjectJoin : SetObjectJoin; set_selected = value ? ClrSelectedJoin : SetSelectedJoin; } else { Message (_("%s(): Flag \"%s\" is not valid\n"), cmd_name, flag_name); return; } switch (GetFunctionID (what)) { case F_Object: { int type; void *ptr1, *ptr2, *ptr3; if ((type = SearchScreen (Crosshair.X, Crosshair.Y, CHANGESIZE_TYPES, &ptr1, &ptr2, &ptr3)) != NO_TYPE) if (TEST_FLAG (LOCKFLAG, (PinType *) ptr2)) Message (_("Sorry, the object is locked\n")); if (set_object (type, ptr1, ptr2, ptr3)) SetChangedFlag (true); break; } case F_SelectedVias: if (set_selected (VIA_TYPE)) SetChangedFlag (true); break; case F_SelectedPins: if (set_selected (PIN_TYPE)) SetChangedFlag (true); break; case F_SelectedPads: if (set_selected (PAD_TYPE)) SetChangedFlag (true); break; case F_SelectedLines: if (set_selected (LINE_TYPE)) SetChangedFlag (true); break; case F_SelectedTexts: if (set_selected (TEXT_TYPE)) SetChangedFlag (true); break; case F_SelectedNames: if (set_selected (ELEMENTNAME_TYPE)) SetChangedFlag (true); break; case F_SelectedElements: if (set_selected (ELEMENT_TYPE)) SetChangedFlag (true); break; case F_Selected: case F_SelectedObjects: if (set_selected (CHANGESIZE_TYPES)) SetChangedFlag (true); break; } } /* --------------------------------------------------------------------------- */ static const char executefile_syntax[] = N_("ExecuteFile(filename)"); static const char executefile_help[] = N_("Run actions from the given file."); /* %start-doc actions ExecuteFile Lines starting with @code{#} are ignored. %end-doc */ static int ActionExecuteFile (int argc, char **argv, Coord x, Coord y) { FILE *fp; char *fname; char line[256]; int n = 0; char *sp; if (argc != 1) AFAIL (executefile); fname = argv[0]; if ((fp = fopen (fname, "r")) == NULL) { fprintf (stderr, _("Could not open actions file \"%s\".\n"), fname); return 1; } defer_updates = 1; defer_needs_update = 0; while (fgets (line, sizeof (line), fp) != NULL) { n++; sp = line; /* eat the trailing newline */ while (*sp && *sp != '\r' && *sp != '\n') sp++; *sp = '\0'; /* eat leading spaces and tabs */ sp = line; while (*sp && (*sp == ' ' || *sp == '\t')) sp++; /* * if we have anything left and its not a comment line * then execute it */ if (*sp && *sp != '#') { /*Message ("%s : line %-3d : \"%s\"\n", fname, n, sp);*/ hid_parse_actions (sp); } } defer_updates = 0; if (defer_needs_update) { IncrementUndoSerialNumber (); gui->invalidate_all (); } fclose (fp); return 0; } /* --------------------------------------------------------------------------- */ static int ActionPSCalib (int argc, char **argv, Coord x, Coord y) { HID *ps = hid_find_exporter ("ps"); ps->calibrate (0.0,0.0); return 0; } /* --------------------------------------------------------------------------- */ static ElementType *element_cache = NULL; static ElementType * find_element_by_refdes (char *refdes) { if (element_cache && NAMEONPCB_NAME(element_cache) && strcmp (NAMEONPCB_NAME(element_cache), refdes) == 0) return element_cache; ELEMENT_LOOP (PCB->Data); { if (NAMEONPCB_NAME(element) && strcmp (NAMEONPCB_NAME(element), refdes) == 0) { element_cache = element; return element_cache; } } END_LOOP; return NULL; } static AttributeType * lookup_attr (AttributeListType *list, const char *name) { int i; for (i=0; iNumber; i++) if (strcmp (list->List[i].name, name) == 0) return & list->List[i]; return NULL; } static void delete_attr (AttributeListType *list, AttributeType *attr) { int idx = attr - list->List; if (idx < 0 || idx >= list->Number) return; if (list->Number - idx > 1) memmove (attr, attr+1, (list->Number - idx - 1) * sizeof(AttributeType)); list->Number --; } /* ---------------------------------------------------------------- */ static const char elementlist_syntax[] = N_("ElementList(Start|Done|Need,,,)"); static const char elementlist_help[] = N_("Adds the given element if it doesn't already exist."); /* %start-doc actions elementlist @table @code @item Start Indicates the start of an element list; call this before any Need actions. @item Need Searches the board for an element with a matching refdes. If found, the value and footprint are updated. If not found, a new element is created with the given footprint and value. @item Done Compares the list of elements needed since the most recent @code{start} with the list of elements actually on the board. Any elements that weren't listed are selected, so that the user may delete them. @end table %end-doc */ static int number_of_footprints_not_found; static int parse_layout_attribute_units (char *name, int def) { const char *as = AttributeGet (PCB, name); if (!as) return def; return GetValue (as, NULL, NULL); } static int ActionElementList (int argc, char **argv, Coord x, Coord y) { ElementType *e = NULL; char *refdes, *value, *footprint, *old; char *args[3]; char *function; if (argc < 1) AFAIL (elementlist); function = argv[0]; #ifdef DEBUG printf("Entered ActionElementList, executing function %s\n", function); #endif if (strcasecmp (function, "start") == 0) { ELEMENT_LOOP (PCB->Data); { CLEAR_FLAG (FOUNDFLAG, element); } END_LOOP; element_cache = NULL; number_of_footprints_not_found = 0; return 0; } if (strcasecmp (function, "done") == 0) { ELEMENT_LOOP (PCB->Data); { if (TEST_FLAG (FOUNDFLAG, element)) { CLEAR_FLAG (FOUNDFLAG, element); } else if (! EMPTY_STRING_P (NAMEONPCB_NAME (element))) { /* Unnamed elements should remain untouched */ SET_FLAG (SELECTEDFLAG, element); } } END_LOOP; if (number_of_footprints_not_found > 0) gui->confirm_dialog (_("Not all requested footprints were found.\n" "See the message log for details"), "Ok", NULL); return 0; } if (strcasecmp (function, "need") != 0) AFAIL (elementlist); if (argc != 4) AFAIL (elementlist); argc --; argv ++; refdes = ARG(0); footprint = ARG(1); value = ARG(2); args[0] = footprint; args[1] = refdes; args[2] = value; #ifdef DEBUG printf(" ... footprint = %s\n", footprint); printf(" ... refdes = %s\n", refdes); printf(" ... value = %s\n", value); #endif e = find_element_by_refdes (refdes); if (!e) { Coord nx, ny, d; #ifdef DEBUG printf(" ... Footprint not on board, need to add it.\n"); #endif /* Not on board, need to add it. */ if (LoadFootprint(argc, args, x, y)) { number_of_footprints_not_found ++; return 1; } nx = PCB->MaxWidth / 2; ny = PCB->MaxHeight / 2; d = MIN (PCB->MaxWidth, PCB->MaxHeight) / 10; nx = parse_layout_attribute_units ("import::newX", nx); ny = parse_layout_attribute_units ("import::newY", ny); d = parse_layout_attribute_units ("import::disperse", d); if (d > 0) { nx += rand () % (d*2) - d; ny += rand () % (d*2) - d; } if (nx < 0) nx = 0; if (nx >= PCB->MaxWidth) nx = PCB->MaxWidth - 1; if (ny < 0) ny = 0; if (ny >= PCB->MaxHeight) ny = PCB->MaxHeight - 1; /* Place components onto center of board. */ if (CopyPastebufferToLayout (nx, ny)) SetChangedFlag (true); } else if (e && DESCRIPTION_NAME(e) && strcmp (DESCRIPTION_NAME(e), footprint) != 0) { int er, pr, i; Coord mx, my; ElementType *pe; #ifdef DEBUG printf(" ... Footprint on board, but different from footprint loaded.\n"); #endif /* Different footprint, we need to swap them out. */ if (LoadFootprint(argc, args, x, y)) { number_of_footprints_not_found ++; return 1; } er = ElementOrientation (e); pe = PASTEBUFFER->Data->Element->data; if (!FRONT (e)) MirrorElementCoordinates (PASTEBUFFER->Data, pe, pe->MarkY*2 - PCB->MaxHeight); pr = ElementOrientation (pe); mx = e->MarkX; my = e->MarkY; if (er != pr) RotateElementLowLevel (PASTEBUFFER->Data, pe, pe->MarkX, pe->MarkY, (er-pr+4)%4); for (i=0; iName[i].X = e->Name[i].X - mx + pe->MarkX ; pe->Name[i].Y = e->Name[i].Y - my + pe->MarkY ; pe->Name[i].Direction = e->Name[i].Direction; pe->Name[i].Scale = e->Name[i].Scale; } RemoveElement (e); if (CopyPastebufferToLayout (mx, my)) SetChangedFlag (true); } /* Now reload footprint */ element_cache = NULL; e = find_element_by_refdes (refdes); old = ChangeElementText (PCB, PCB->Data, e, NAMEONPCB_INDEX, strdup (refdes)); if (old) free(old); old = ChangeElementText (PCB, PCB->Data, e, VALUE_INDEX, strdup (value)); if (old) free(old); SET_FLAG (FOUNDFLAG, e); #ifdef DEBUG printf(" ... Leaving ActionElementList.\n"); #endif return 0; } /* ---------------------------------------------------------------- */ static const char elementsetattr_syntax[] = N_("ElementSetAttr(refdes,name[,value])"); static const char elementsetattr_help[] = N_("Sets or clears an element-specific attribute."); /* %start-doc actions elementsetattr If a value is specified, the named attribute is added (if not already present) or changed (if it is) to the given value. If the value is not specified, the given attribute is removed if present. %end-doc */ static int ActionElementSetAttr (int argc, char **argv, Coord x, Coord y) { ElementType *e = NULL; char *refdes, *name, *value; AttributeType *attr; if (argc < 2) { AFAIL (elementsetattr); } refdes = argv[0]; name = argv[1]; value = ARG(2); ELEMENT_LOOP (PCB->Data); { if (NSTRCMP (refdes, NAMEONPCB_NAME (element)) == 0) { e = element; break; } } END_LOOP; if (!e) { Message(_("Cannot change attribute of %s - element not found\n"), refdes); return 1; } attr = lookup_attr (&e->Attributes, name); if (attr && value) { free (attr->value); attr->value = strdup (value); } if (attr && ! value) { delete_attr (& e->Attributes, attr); } if (!attr && value) { CreateNewAttribute (& e->Attributes, name, value); } return 0; } /* ---------------------------------------------------------------- */ static const char execcommand_syntax[] = N_("ExecCommand(command)"); static const char execcommand_help[] = N_("Runs a command."); /* %start-doc actions execcommand Runs the given command, which is a system executable. %end-doc */ static int ActionExecCommand (int argc, char **argv, Coord x, Coord y) { char *command; if (argc < 1) { AFAIL (execcommand); } command = ARG(0); if (system (command)) return 1; return 0; } /* ---------------------------------------------------------------- */ static int pcb_spawnvp (char **argv) { #ifdef HAVE__SPAWNVP int result = _spawnvp (_P_WAIT, argv[0], (const char * const *) argv); if (result == -1) return 1; else return 0; #else int pid; pid = fork (); if (pid < 0) { /* error */ Message(_("Cannot fork!")); return 1; } else if (pid == 0) { /* Child */ execvp (argv[0], argv); exit(1); } else { int rv; /* Parent */ wait (&rv); } return 0; #endif } /* ---------------------------------------------------------------- */ /*! * \brief Creates a new temporary file name. * * Hopefully the operating system provides a mkdtemp() function to * securily create a temporary directory with mode 0700.\n * If so then that directory is created and the returned string is made * up of the directory plus the name variable.\n * For example:\n * * tempfile_name_new ("myfile") might return * "/var/tmp/pcb.123456/myfile". * * If mkdtemp() is not available then 'name' is ignored and the * insecure tmpnam() function is used. * * Files/names created with tempfile_name_new() should be unlinked * with tempfile_unlink to make sure the temporary directory is also * removed when mkdtemp() is used. */ static char * tempfile_name_new (char * name) { char *tmpfile = NULL; #ifdef HAVE_MKDTEMP char *tmpdir, *mytmpdir; size_t len; #endif assert ( name != NULL ); #ifdef HAVE_MKDTEMP #define TEMPLATE "pcb.XXXXXXXX" tmpdir = getenv ("TMPDIR"); /* FIXME -- what about win32? */ if (tmpdir == NULL) { tmpdir = "/tmp"; } mytmpdir = (char *) malloc (sizeof(char) * (strlen (tmpdir) + 1 + strlen (TEMPLATE) + 1)); if (mytmpdir == NULL) { fprintf (stderr, "%s(): malloc failed()\n", __FUNCTION__); exit (1); } *mytmpdir = '\0'; (void)strcat (mytmpdir, tmpdir); (void)strcat (mytmpdir, PCB_DIR_SEPARATOR_S); (void)strcat (mytmpdir, TEMPLATE); if (mkdtemp (mytmpdir) == NULL) { fprintf (stderr, "%s(): mkdtemp (\"%s\") failed\n", __FUNCTION__, mytmpdir); free (mytmpdir); return NULL; } len = strlen (mytmpdir) + /* the temp directory name */ 1 + /* the directory sep. */ strlen (name) + /* the file name */ 1 /* the \0 termination */ ; tmpfile = (char *) malloc (sizeof (char) * len); *tmpfile = '\0'; (void)strcat (tmpfile, mytmpdir); (void)strcat (tmpfile, PCB_DIR_SEPARATOR_S); (void)strcat (tmpfile, name); free (mytmpdir); #undef TEMPLATE #else /* * tmpnam() uses a static buffer so strdup() the result right away * in case someone decides to create multiple temp names. */ tmpfile = strdup (tmpnam (NULL)); #ifdef __WIN32__ { /* Guile doesn't like \ separators */ char *c; for (c = tmpfile; *c; c++) if (*c == '\\') *c = '/'; } #endif #endif return tmpfile; } /* ---------------------------------------------------------------- */ /*! * \brief Unlink a temporary file. * * If we have mkdtemp() then our temp file lives in a temporary * directory and we need to remove that directory too. */ static int tempfile_unlink (char * name) { #ifdef DEBUG /* SDB says: Want to keep old temp files for examiniation when debugging */ return 0; #else /* DEBUG */ #ifdef HAVE_MKDTEMP int e, rc2 = 0; char *dname; unlink (name); /* it is possible that the file was never created so it is OK if the unlink fails */ /* now figure out the directory name to remove */ e = strlen (name) - 1; while (e > 0 && name[e] != PCB_DIR_SEPARATOR_C) {e--;} dname = strdup (name); dname[e] = '\0'; /* * at this point, e *should* point to the end of the directory part * but lets make sure. */ if (e > 0) { rc2 = rmdir (dname); if (rc2 != 0) { perror (dname); } } else { fprintf (stderr, _("%s(): Unable to determine temp directory name from the temp file\n"), __FUNCTION__); fprintf (stderr, "%s(): \"%s\"\n", __FUNCTION__, name); rc2 = -1; } /* name was allocated with malloc */ free (dname); free (name); /* * FIXME - should also return -1 if the temp file exists and was not * removed. */ if (rc2 != 0) { return -1; } #else /* HAVE_MKDTEMP */ int rc = unlink (name); if (rc != 0) { fprintf (stderr, _("Failed to unlink \"%s\"\n"), name); free (name); return rc; } free (name); #endif /* HAVE_MKDTEMP */ #endif /* DEBUG */ return 0; } /* ---------------------------------------------------------------- */ static const char tcad_import_syntax[] = N_("ImportTinyCAD()\n" "ImportTinyCAD(netlistfile)\n"); static const char tcad_import_help[] = N_("Import schematics from TinyCAD."); /* %start-doc actions ImportTinyCAD Imports netlist and parts from the TinyCAD. TinyCAD allows to export netlist in gEDA compatible format and part list in standard CSV format. The footprints should be defined as parameters of TinyCAD symbols. @code{Package} and @code{Footprint} parameters can be used, @code{Footprint} parameter has priority. Netlist and partlist files should have the same base name with @code{.net} and @code{.csv} extensions. During import only the netlist filename can be specified, parlist filename is derived from netlist filename by replacing @code{.net} extension by @code{.csv} extension or by adding @code{.csv} extension if netlist file does not have @code{.net} extension. @table @code @item ImportTinyCAD() Prompts the user to select netlist file. The netlist is imported, followed by partlist import. Parts are imported by sequence of @code{ElementList} actions. If existing schematics is being updated, existing parts are updated, new parts are added, removed parts are pre-selected to be easily deleted by user. @item ImportTinyCAD(netlistfile) Same as above, but specified file is used as netlist filename. @end table %end-doc */ #define CSVLEN 4096 static int ActionImportTinyCAD (int argc, char **argv, Coord x, Coord y) { netlist_loaded = false; if (argc < 2 ) { hid_actionl ("Load", "Netlist", NULL); } else { hid_actionl ("LoadFrom", "Netlist", argv[1], NULL); } if (netlist_loaded) { int l = strlen (PCB->Netlistname); char *s, *s2, *csvname = alloca(l+5); char line[CSVLEN]; FILE *f; bool header = TRUE; bool first_entry = TRUE; int maxhdr; int ix; int rhdr = -1, vhdr = -1, fhdr = -1, phdr = -1; char *rs, *vs, *fs, *ps; if (csvname == NULL) return 0; strcpy (csvname, PCB->Netlistname); if (l > 4 && strcasecmp (csvname+l-4, ".net") == 0) csvname[l-4] = '\0'; strcat(csvname, ".csv"); Message ("Importing TinyCAD Parts file (CSV): %s\n", csvname); f = fopen (csvname, "r"); if (f == NULL) return 0; fgets (line, sizeof(line), f); do { if((s = strchr (line, '\r')) != NULL) *s = '\0'; if((s = strchr (line, '\n')) != NULL) *s = '\0'; if (header) { /* Parse header line, no quotes expcted */ ix = 0; s = strtok (line, ","); while (s != NULL) { if (strcasecmp (s, "Reference") == 0) rhdr = ix; else if (strcasecmp (s, "Value") == 0) vhdr = ix; else if (strcasecmp (s, "Footprint") == 0) fhdr = ix; else if (strcasecmp (s, "Package") == 0) phdr = ix; s = strtok (NULL, ","); ix++; } if (rhdr == -1 || (fhdr == -1 && phdr == -1)) { Message ("Missing Reference and/or Footprint or Package column. Part list cannot be imported.\n"); return 0; } header = false; maxhdr = max (rhdr, max (vhdr, max (fhdr, phdr))); } else { s = line; ix = 0; rs = NULL; vs = NULL; fs = NULL; ps = NULL; while (s != NULL) { if (*s == '"') { s2 = strstr (s,"\","); if (s2 != NULL) { /* remove quote and move end pointer to conmma */ *s2 = '\0'; s2++; } else { s2 = strchr (s, '"'); } if (s2 != NULL) { /* skip leading quote */ s++; } } else s2 = strchr (s, ','); if (s2 != NULL) { *s2 = '\0'; s2++; } if (ix == rhdr) rs = s; else if (ix == vhdr) vs = s; else if (ix == fhdr) fs = s; else if (ix == phdr) ps = s; if (ix == maxhdr) break; s = s2; ix++; } if (ix == maxhdr) { char *afs; if (fs != NULL && strcmp (fs, "..") != 0 && strlen (fs) > 0) afs = fs; else if (ps != NULL && strcmp (ps, "..") != 0 && strlen (ps) > 0) afs = ps; else afs = NULL; if (afs != NULL) { if (strcmp (vs, "..") == 0) vs = ""; s = strtok (rs, ","); while (s != NULL) { #ifdef DEBUG Message ("Importing element: Refdes: \"%s\" - Value: \"%s\" - Footprint: \"%s\"\n", s, vs, afs); #endif if (first_entry) { hid_actionl("ElementList","Start", NULL); first_entry = FALSE; } hid_actionl("ElementList","Need", s, afs, vs, NULL); s = strtok (NULL, ","); } } else Message ("Element(s) \"%s\" have no Footprint or Package attribute. They cannot be imported.\n", rs); } } fgets (line, sizeof (line), f); } while (!feof (f)); fclose (f); if (!first_entry) { hid_actionl("ElementList","Done", NULL); } } return 0; } /* ---------------------------------------------------------------- */ static const char import_syntax[] = N_("Import()\n" "Import([gnetlist|make[,source,source,...]])\n" "Import(setnewpoint[,(mark|center|X,Y)])\n" "Import(setdisperse,D,units)\n"); static const char import_help[] = N_("Import schematics."); /* %start-doc actions Import Imports element and netlist data from the schematics (or some other source). The first parameter, which is optional, is the mode. If not specified, the @code{import::mode} attribute in the PCB is used. @code{gnetlist} means gnetlist is used to obtain the information from the schematics. @code{make} invokes @code{make}, assuming the user has a @code{Makefile} in the current directory. The @code{Makefile} will be invoked with the following variables set: @table @code @item PCB The name of the .pcb file @item SRCLIST A space-separated list of source files @item OUT The name of the file in which to put the command script, which may contain any @pcb{} actions. By default, this is a temporary file selected by @pcb{}, but if you specify an @code{import::outfile} attribute, that file name is used instead (and not automatically deleted afterwards). @end table The target specified to be built is the first of these that apply: @itemize @bullet @item The target specified by an @code{import::target} attribute. @item The output file specified by an @code{import::outfile} attribute. @item If nothing else is specified, the target is @code{pcb_import}. @end itemize If you specify an @code{import::makefile} attribute, then "-f " will be added to the command line. If you specify the mode, you may also specify the source files (schematics). If you do not specify any, the list of schematics is obtained by reading the @code{import::src@var{N}} attributes (like @code{import::src0}, @code{import::src1}, etc). For compatibility with future extensions to the import file format, the generated file @emph{must not} start with the two characters @code{#%}. If a temporary file is needed the @code{TMPDIR} environment variable is used to select its location. Note that the programs @code{gnetlist} and @code{make} may be overridden by the user via the @code{make-program} and @code{gnetlist} @code{pcb} settings (i.e. in @code{~/.pcb/settings} or on the command line). If @pcb{} cannot determine which schematic(s) to import from, the GUI is called to let user choose (see @code{ImportGUI()}). Note that Import() doesn't delete anything - after an Import, elements which shouldn't be on the board are selected and may be removed once it's determined that the deletion is appropriate. If @code{Import()} is called with @code{setnewpoint}, then the location of new components can be specified. This is where parts show up when they're added to the board. The default is the center of the board. @table @code @item Import(setnewpoint) Prompts the user to click on the board somewhere, uses that point. If called by a hotkey, uses the current location of the crosshair. @item Import(setnewpoint,mark) Uses the location of the mark. If no mark is present, the point is not changed. @item Import(setnewpoint,center) Resets the point to the center of the board. @item Import(setnewpoint,X,Y,units) Sets the point to the specific coordinates given. Example: @code{Import(setnewpoint,50,25,mm)} @end table Note that the X and Y locations are stored in attributes named @code{import::newX} and @code{import::newY} so you could change them manually if you wished. Calling @code{Import(setdisperse,D,units)} sets how much the newly placed elements are dispersed relative to the set point. For example, @code{Import(setdisperse,10,mm)} will offset each part randomly up to 10mm away from the point. The default dispersion is 1/10th of the smallest board dimension. Dispersion is saved in the @code{import::disperse} attribute. %end-doc */ static int ActionImport (int argc, char **argv, Coord x, Coord y) { char *mode; char **sources = NULL; int nsources = 0; #ifdef DEBUG printf("ActionImport: =========== Entering ActionImport ============\n"); #endif mode = ARG (0); if (mode && strcasecmp (mode, "setdisperse") == 0) { char *ds, *units; char buf[50]; ds = ARG (1); units = ARG (2); if (!ds) { const char *as = AttributeGet (PCB, "import::disperse"); ds = gui->prompt_for(_("Enter dispersion:"), as ? as : "0"); } if (units) { sprintf(buf, "%s%s", ds, units); AttributePut (PCB, "import::disperse", buf); } else AttributePut (PCB, "import::disperse", ds); if (ARG (1) == NULL) free (ds); return 0; } if (mode && strcasecmp (mode, "setnewpoint") == 0) { const char *xs, *ys, *units; Coord x, y; char buf[50]; xs = ARG (1); ys = ARG (2); units = ARG (3); if (!xs) { gui->get_coords (_("Click on a location"), &x, &y); } else if (strcasecmp (xs, "center") == 0) { AttributeRemove (PCB, "import::newX"); AttributeRemove (PCB, "import::newY"); return 0; } else if (strcasecmp (xs, "mark") == 0) { if (!Marked.status) return 0; x = Marked.X; y = Marked.Y; } else if (ys) { x = GetValue (xs, units, NULL); y = GetValue (ys, units, NULL); } else { Message (_("Bad syntax for Import(setnewpoint)")); return 1; } pcb_snprintf (buf, sizeof (buf), "%$ms", x); AttributePut (PCB, "import::newX", buf); pcb_snprintf (buf, sizeof (buf), "%$ms", y); AttributePut (PCB, "import::newY", buf); return 0; } if (! mode) mode = AttributeGet (PCB, "import::mode"); if (! mode) mode = "gnetlist"; if (argc > 1) { sources = argv + 1; nsources = argc - 1; } if (! sources) { char sname[40]; char *src; nsources = -1; do { nsources ++; sprintf(sname, "import::src%d", nsources); src = AttributeGet (PCB, sname); } while (src); if (nsources > 0) { sources = (char **) malloc ((nsources + 1) * sizeof (char *)); nsources = -1; do { nsources ++; sprintf(sname, "import::src%d", nsources); src = AttributeGet (PCB, sname); sources[nsources] = src; } while (src); } } if (! sources) { /* Replace .pcb with .sch and hope for the best. */ char *pcbname = PCB->Filename; char *schname; char *dot, *slash, *bslash; if (!pcbname) return hid_action("ImportGUI"); schname = (char *) malloc (strlen(pcbname) + 5); strcpy (schname, pcbname); dot = strchr (schname, '.'); slash = strchr (schname, '/'); bslash = strchr (schname, '\\'); if (dot && slash && dot < slash) dot = NULL; if (dot && bslash && dot < bslash) dot = NULL; if (dot) *dot = 0; strcat (schname, ".sch"); if (access (schname, F_OK)) { free (schname); return hid_action("ImportGUI"); } sources = (char **) malloc (2 * sizeof (char *)); sources[0] = schname; sources[1] = NULL; nsources = 1; } if (strcasecmp (mode, "gnetlist") == 0) { char *tmpfile = tempfile_name_new ("gnetlist_output"); char **cmd; int i; if (tmpfile == NULL) { Message (_("Could not create temp file")); return 1; } cmd = (char **) malloc ((7 + nsources) * sizeof (char *)); cmd[0] = Settings.GnetlistProgram; cmd[1] = "-g"; cmd[2] = "pcbfwd"; cmd[3] = "-o"; cmd[4] = tmpfile; cmd[5] = "--"; for (i=0; iedit_attributes) { Message (_("This GUI doesn't support Attribute Editing\n")); return 1; } switch (GetFunctionID (function)) { case F_Layout: { gui->edit_attributes(_("Layout Attributes"), &(PCB->Attributes)); return 0; } case F_Layer: { LayerType *layer = CURRENT; if (layername) { int i; layer = NULL; for (i=0; iData->Layer[i].Name, layername) == 0) { layer = & (PCB->Data->Layer[i]); break; } if (layer == NULL) { Message (_("No layer named %s\n"), layername); return 1; } } buf = (char *) malloc (strlen (layer->Name) + strlen (_("Layer %s Attributes"))); sprintf (buf, _("Layer %s Attributes"), layer->Name); gui->edit_attributes(buf, &(layer->Attributes)); free (buf); return 0; } case F_Element: { int n_found = 0; ElementType *e = NULL; ELEMENT_LOOP (PCB->Data); { if (TEST_FLAG (SELECTEDFLAG, element)) { e = element; n_found ++; } } END_LOOP; if (n_found > 1) { Message (_("Too many elements selected\n")); return 1; } if (n_found == 0) { void *ptrtmp; gui->get_coords (_("Click on an element"), &x, &y); if ((SearchScreen (x, y, ELEMENT_TYPE, &ptrtmp, &ptrtmp, &ptrtmp)) != NO_TYPE) e = (ElementType *) ptrtmp; else { Message (_("No element found there\n")); return 1; } } if (NAMEONPCB_NAME(e)) { buf = (char *) malloc (strlen (NAMEONPCB_NAME(e)) + strlen (_("Element %s Attributes"))); sprintf(buf, _("Element %s Attributes"), NAMEONPCB_NAME(e)); } else { buf = strdup (_("Unnamed Element Attributes")); } gui->edit_attributes(buf, &(e->Attributes)); free (buf); break; } default: AFAIL (attributes); } return 0; } /* --------------------------------------------------------------------------- */ static const char setvialayers_syntax[] = N_("SetViaLayers(Object|SelectedVias|Selected[,ThroughHole|TH])\n" "SetViaLayers(Object|SelectedVias|Selected,from,to)\n" "SetViaLayers(Object|SelectedVias|Selected,[c|-|from],[c|-|to])" ); static const char setvialayers_help[] = N_("Sets starting and ending layer for burried/blind/standard vias."); /* %start-doc actions setvialayers Specifies layers, which are connected by via. @table @code @item TH|ThroughHole The vias will be set as through-hole, connecting all layers @item from layer name or layer number of the first layer to be connected by via; "-" stands for unchanged, "c" stands for currently selected layer @item to layer name or layer number of the last layer to be connected by via; "-" stands for unchanged, "c" stands for currently selected layer @end table If no parameter us used, dialog is displayed (if implemented in the respective GUI HID). %end-doc */ static bool identify_layer (char *layer_name, Cardinal *layer_no) { int layer; if (strcmp (layer_name, "-") == 0) { *layer_no = -1; return true; } if (strcmp (layer_name, "c") == 0) { if ((unsigned int)INDEXOFCURRENT < max_copper_layer) { *layer_no = INDEXOFCURRENT; return true; } } layer = SearchLayerByName (PCB->Data, layer_name); if (layer == -1) { if (sscanf (layer_name, "%d", &layer) != 1) layer = -1; } if (layer != -1) *layer_no = layer; return (layer != -1); } static int ActionSetViaLayers (int argc, char **argv, Coord x, Coord y) { char *function = ARG (0); char *layername_from = ARG (1); char *layername_to = ARG (2); Cardinal layer_from ; Cardinal layer_to = -1; if (!function) AFAIL (setvialayers); if ( /* !gui->edit_attributes &&*/ argc < 2) { Message (_("This GUI doesn't support Via Layers editing\n")); return 1; } if (GetFunctionID (layername_from) == F_ThroughHole) { layer_from = 0; layer_to = 0; } else { if (!identify_layer (layername_from, &layer_from) || !identify_layer (layername_to, &layer_to)) { Message (_("Sorry, wrong layers specified.\n")); return 1; } } /* ensure that layer_from < layer_to */ if (layer_from != -1 && layer_to != -1 && layer_from > layer_to) { int tmp; tmp = layer_from; layer_from = layer_to; layer_to = tmp; } if (layer_to != -1) layer_to = min (layer_to, max_copper_layer-1); switch (GetFunctionID (function)) { case F_Object: { int type; void *ptr1, *ptr2, *ptr3; if ((type = SearchScreen (Crosshair.X, Crosshair.Y, VIA_TYPE, &ptr1, &ptr2, &ptr3)) != NO_TYPE) { if (TEST_FLAG (LOCKFLAG, (PinType *) ptr1)) Message (_("Sorry, the object is locked\n")); else { if (ChangeObjectViaLayers (ptr1, ptr2, ptr3, layer_from, layer_to)) { SetChangedFlag (true); } } } break; case F_SelectedVias: case F_Selected: if (ChangeSelectedViaLayers (layer_from, layer_to)) { SetChangedFlag (true); } break; } } return 0; } /* --------------------------------------------------------------------------- */ HID_Action action_action_list[] = { {"AddRats", 0, ActionAddRats, addrats_help, addrats_syntax} , {"Attributes", 0, ActionAttributes, attributes_help, attributes_syntax} , {"Atomic", 0, ActionAtomic, atomic_help, atomic_syntax} , {"AutoPlaceSelected", 0, ActionAutoPlaceSelected, autoplace_help, autoplace_syntax} , {"AutoRoute", 0, ActionAutoRoute, autoroute_help, autoroute_syntax} , {"ChangeClearSize", 0, ActionChangeClearSize, changeclearsize_help, changeclearsize_syntax} , {"ChangeDrillSize", 0, ActionChange2ndSize, changedrillsize_help, changedrillsize_syntax} , {"ChangeHole", 0, ActionChangeHole, changehold_help, changehold_syntax} , {"ChangeJoin", 0, ActionChangeJoin, changejoin_help, changejoin_syntax} , {"ChangeName", 0, ActionChangeName, changename_help, changename_syntax} , {"ChangePaste", 0, ActionChangePaste, changepaste_help, changepaste_syntax} , {"ChangePinName", 0, ActionChangePinName, changepinname_help, changepinname_syntax} , {"ChangeSize", 0, ActionChangeSize, changesize_help, changesize_syntax} , {"ChangeSquare", 0, ActionChangeSquare, changesquare_help, changesquare_syntax} , {"ChangeOctagon", 0, ActionChangeOctagon, changeoctagon_help, changeoctagon_syntax} , {"ClearSquare", 0, ActionClearSquare, clearsquare_help, clearsquare_syntax} , {"ClearOctagon", 0, ActionClearOctagon, clearoctagon_help, clearoctagon_syntax} , {"Connection", 0, ActionConnection, connection_help, connection_syntax} , {"Delete", 0, ActionDelete, delete_help, delete_syntax} , {"DeleteRats", 0, ActionDeleteRats, deleterats_help, deleterats_syntax} , {"DisperseElements", 0, ActionDisperseElements, disperseelements_help, disperseelements_syntax} , {"Display", 0, ActionDisplay, display_help, display_syntax} , {"DumpLibrary", 0, ActionDumpLibrary, dumplibrary_help, dumplibrary_syntax} , {"ExecuteFile", 0, ActionExecuteFile, executefile_help, executefile_syntax} , {"Flip", N_("Click on Object or Flip Point"), ActionFlip, flip_help, flip_syntax} , {"LoadFrom", 0, ActionLoadFrom, loadfrom_help, loadfrom_syntax} , {"MarkCrosshair", 0, ActionMarkCrosshair, markcrosshair_help, markcrosshair_syntax} , {"Message", 0, ActionMessage, message_help, message_syntax} , {"MinMaskGap", 0, ActionMinMaskGap, minmaskgap_help, minmaskgap_syntax} , {"MinClearGap", 0, ActionMinClearGap, mincleargap_help, mincleargap_syntax} , {"Mode", 0, ActionMode, mode_help, mode_syntax} , {"MorphPolygon", 0, ActionMorphPolygon, morphpolygon_help, morphpolygon_syntax} , {"PasteBuffer", 0, ActionPasteBuffer, pastebuffer_help, pastebuffer_syntax} , {"Quit", 0, ActionQuit, quit_help, quit_syntax} , {"RemoveSelected", 0, ActionRemoveSelected, removeselected_help, removeselected_syntax} , {"Renumber", 0, ActionRenumber, renumber_help, renumber_syntax} , {"RipUp", 0, ActionRipUp, ripup_help, ripup_syntax} , {"Select", 0, ActionSelect, select_help, select_syntax} , {"Unselect", 0, ActionUnselect, unselect_help, unselect_syntax} , {"SaveSettings", 0, ActionSaveSettings, savesettings_help, savesettings_syntax} , {"SaveTo", 0, ActionSaveTo, saveto_help, saveto_syntax} , {"SetSquare", 0, ActionSetSquare, setsquare_help, setsquare_syntax} , {"SetOctagon", 0, ActionSetOctagon, setoctagon_help, setoctagon_syntax} , {"SetThermal", 0, ActionSetThermal, setthermal_help, setthermal_syntax} , {"SetValue", 0, ActionSetValue, setvalue_help, setvalue_syntax} , {"ToggleHideName", 0, ActionToggleHideName, togglehidename_help, togglehidename_syntax} , {"Undo", 0, ActionUndo, undo_help, undo_syntax} , {"Redo", 0, ActionRedo, redo_help, redo_syntax} , {"SetSame", N_("Select item to use attributes from"), ActionSetSame, setsame_help, setsame_syntax} , {"SetFlag", 0, ActionSetFlag, setflag_help, setflag_syntax} , {"ClrFlag", 0, ActionClrFlag, clrflag_help, clrflag_syntax} , {"ChangeFlag", 0, ActionChangeFlag, changeflag_help, changeflag_syntax} , {"Polygon", 0, ActionPolygon, polygon_help, polygon_syntax} , {"RouteStyle", 0, ActionRouteStyle, routestyle_help, routestyle_syntax} , {"MoveObject", N_("Select an Object"), ActionMoveObject, moveobject_help, moveobject_syntax} , {"MoveToCurrentLayer", 0, ActionMoveToCurrentLayer, movetocurrentlayer_help, movetocurrentlayer_syntax} , {"New", 0, ActionNew, new_help, new_syntax} , {"pscalib", 0, ActionPSCalib} , {"ElementList", 0, ActionElementList, elementlist_help, elementlist_syntax} , {"ElementSetAttr", 0, ActionElementSetAttr, elementsetattr_help, elementsetattr_syntax} , {"ExecCommand", 0, ActionExecCommand, execcommand_help, execcommand_syntax} , {"ImportTinyCAD", 0, ActionImportTinyCAD, tcad_import_help, tcad_import_syntax} , {"Import", 0, ActionImport, import_help, import_syntax} , {"SetViaLayers", 0, ActionSetViaLayers, setvialayers_help, setvialayers_syntax} , }; REGISTER_ACTIONS (action_action_list) pcb-4.3.0/src/Makefile.in0000664000175000017500000125204114017000757012047 00000000000000# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = pcb$(EXEEXT) @WITH_TOPOROUTER_TRUE@am__append_1 = toporouter.c toporouter.h @WITH_TOPOROUTER_TRUE@am__append_2 = ../gts/libgts.a @WITH_TOPOROUTER_TRUE@am__append_3 = ../gts/libgts.a check_PROGRAMS = unittest$(EXEEXT) TESTS = unittest$(EXEEXT) @WITH_DBUS_TRUE@am__append_4 = ${DBUS_SRCS} @WITH_DBUS_TRUE@am__append_5 = dbus-introspect.h # If we are building with GL support, we need some extra files @USE_GL_TRUE@am__append_6 = ${GL_SRCS} @USE_GL_TRUE@am__append_7 = ${LIBGTK_GL_SRCS} @USE_GL_FALSE@am__append_8 = ${LIBGTK_GDK_SRCS} @WIN32_TRUE@am__append_9 = pcb_icon.o @WIN32_TRUE@am__append_10 = pcb_icon.o subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_gl.m4 \ $(top_srcdir)/m4/ax_check_glu.m4 \ $(top_srcdir)/m4/ax_lang_compiler_ms.m4 \ $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/codeset.m4 \ $(top_srcdir)/m4/extern-inline.m4 $(top_srcdir)/m4/fcntl-o.m4 \ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/glibc2.m4 \ $(top_srcdir)/m4/glibc21.m4 $(top_srcdir)/m4/iconv.m4 \ $(top_srcdir)/m4/intdiv0.m4 $(top_srcdir)/m4/intl.m4 \ $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/intmax.m4 \ $(top_srcdir)/m4/inttypes-pri.m4 \ $(top_srcdir)/m4/inttypes_h.m4 $(top_srcdir)/m4/lcmessage.m4 \ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/lock.m4 \ $(top_srcdir)/m4/longlong.m4 $(top_srcdir)/m4/nls.m4 \ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/printf-posix.m4 \ $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/size_max.m4 \ $(top_srcdir)/m4/stdint_h.m4 $(top_srcdir)/m4/threadlib.m4 \ $(top_srcdir)/m4/uintmax_t.m4 $(top_srcdir)/m4/visibility.m4 \ $(top_srcdir)/m4/wchar_t.m4 $(top_srcdir)/m4/wint_t.m4 \ $(top_srcdir)/m4/xsize.m4 $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/m4/m4_ax_func_mkdir.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pcblibdir)" PROGRAMS = $(bin_PROGRAMS) LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru AM_V_AR = $(am__v_AR_@AM_V@) am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) am__v_AR_0 = @echo " AR " $@; am__v_AR_1 = libbatch_a_AR = $(AR) $(ARFLAGS) libbatch_a_LIBADD = am__dirstamp = $(am__leading_dot)dirstamp am__objects_1 = hid/batch/libbatch_a-batch.$(OBJEXT) am_libbatch_a_OBJECTS = $(am__objects_1) libbatch_a_OBJECTS = $(am_libbatch_a_OBJECTS) libbom_a_AR = $(AR) $(ARFLAGS) libbom_a_LIBADD = am_libbom_a_OBJECTS = hid/bom/libbom_a-bom.$(OBJEXT) libbom_a_OBJECTS = $(am_libbom_a_OBJECTS) libbom_md_a_AR = $(AR) $(ARFLAGS) libbom_md_a_LIBADD = am_libbom_md_a_OBJECTS = hid/bom_md/libbom_md_a-bom_md.$(OBJEXT) libbom_md_a_OBJECTS = $(am_libbom_md_a_OBJECTS) libdrc_a_AR = $(AR) $(ARFLAGS) libdrc_a_LIBADD = am__objects_2 = drc/libdrc_a-drc.$(OBJEXT) \ drc/libdrc_a-drc_violation.$(OBJEXT) am_libdrc_a_OBJECTS = $(am__objects_2) libdrc_a_OBJECTS = $(am_libdrc_a_OBJECTS) libgcode_a_AR = $(AR) $(ARFLAGS) libgcode_a_LIBADD = am__objects_3 = hid/gcode/libgcode_a-gcode.$(OBJEXT) \ hid/gcode/libgcode_a-decompose.$(OBJEXT) \ hid/gcode/libgcode_a-trace.$(OBJEXT) \ hid/gcode/libgcode_a-curve.$(OBJEXT) am_libgcode_a_OBJECTS = $(am__objects_3) libgcode_a_OBJECTS = $(am_libgcode_a_OBJECTS) libgerber_a_AR = $(AR) $(ARFLAGS) libgerber_a_LIBADD = am_libgerber_a_OBJECTS = hid/gerber/libgerber_a-gerber.$(OBJEXT) libgerber_a_OBJECTS = $(am_libgerber_a_OBJECTS) libgsvit_a_AR = $(AR) $(ARFLAGS) libgsvit_a_LIBADD = am__objects_4 = hid/gsvit/libgsvit_a-gsvit.$(OBJEXT) am_libgsvit_a_OBJECTS = $(am__objects_4) libgsvit_a_OBJECTS = $(am_libgsvit_a_OBJECTS) libgtk_a_AR = $(AR) $(ARFLAGS) libgtk_a_LIBADD = am__libgtk_a_SOURCES_DIST = dolists.h hid/hidint.h \ hid/gtk/ghid-cell-renderer-visibility.c \ hid/gtk/ghid-cell-renderer-visibility.h \ hid/gtk/ghid-coord-entry.c hid/gtk/ghid-coord-entry.h \ hid/gtk/ghid-layer-selector.c hid/gtk/ghid-layer-selector.h \ hid/gtk/ghid-main-menu.c hid/gtk/ghid-main-menu.h \ hid/gtk/ghid-route-style-selector.c \ hid/gtk/ghid-route-style-selector.h hid/gtk/gtkhid-main.c \ hid/gtk/gtkhid.h hid/gtk/gui.h hid/gtk/gui-command-window.c \ hid/gtk/gui-config.c hid/gtk/gui-dialog-print.c \ hid/gtk/gui-dialog.c hid/gtk/gui-drc-window.c \ hid/gtk/gui-drc-window.h hid/gtk/gui-keyref-window.c \ hid/gtk/gui-library-window.c hid/gtk/gui-library-window.h \ hid/gtk/gui-log-window.c hid/gtk/gui-misc.c \ hid/gtk/gui-netlist-window.c hid/gtk/gui-output-events.c \ hid/gtk/gui-pinout-preview.c hid/gtk/gui-pinout-preview.h \ hid/gtk/gui-pinout-window.c hid/gtk/gui-top-window.c \ hid/gtk/gui-utils.c hid/gtk/gtkhid-gl.c \ hid/gtk/gui-trackball.c hid/gtk/gui-trackball.h \ hid/gtk/gtkhid-gdk.c hid/gtk/gtk_lists.h am__objects_5 = hid/gtk/libgtk_a-gtkhid-gl.$(OBJEXT) \ hid/gtk/libgtk_a-gui-trackball.$(OBJEXT) @USE_GL_TRUE@am__objects_6 = $(am__objects_5) am__objects_7 = hid/gtk/libgtk_a-gtkhid-gdk.$(OBJEXT) @USE_GL_FALSE@am__objects_8 = $(am__objects_7) am__objects_9 = \ hid/gtk/libgtk_a-ghid-cell-renderer-visibility.$(OBJEXT) \ hid/gtk/libgtk_a-ghid-coord-entry.$(OBJEXT) \ hid/gtk/libgtk_a-ghid-layer-selector.$(OBJEXT) \ hid/gtk/libgtk_a-ghid-main-menu.$(OBJEXT) \ hid/gtk/libgtk_a-ghid-route-style-selector.$(OBJEXT) \ hid/gtk/libgtk_a-gtkhid-main.$(OBJEXT) \ hid/gtk/libgtk_a-gui-command-window.$(OBJEXT) \ hid/gtk/libgtk_a-gui-config.$(OBJEXT) \ hid/gtk/libgtk_a-gui-dialog-print.$(OBJEXT) \ hid/gtk/libgtk_a-gui-dialog.$(OBJEXT) \ hid/gtk/libgtk_a-gui-drc-window.$(OBJEXT) \ hid/gtk/libgtk_a-gui-keyref-window.$(OBJEXT) \ hid/gtk/libgtk_a-gui-library-window.$(OBJEXT) \ hid/gtk/libgtk_a-gui-log-window.$(OBJEXT) \ hid/gtk/libgtk_a-gui-misc.$(OBJEXT) \ hid/gtk/libgtk_a-gui-netlist-window.$(OBJEXT) \ hid/gtk/libgtk_a-gui-output-events.$(OBJEXT) \ hid/gtk/libgtk_a-gui-pinout-preview.$(OBJEXT) \ hid/gtk/libgtk_a-gui-pinout-window.$(OBJEXT) \ hid/gtk/libgtk_a-gui-top-window.$(OBJEXT) \ hid/gtk/libgtk_a-gui-utils.$(OBJEXT) $(am__objects_6) \ $(am__objects_8) am_libgtk_a_OBJECTS = $(am__objects_9) libgtk_a_OBJECTS = $(am_libgtk_a_OBJECTS) libipcd356_a_AR = $(AR) $(ARFLAGS) libipcd356_a_LIBADD = am_libipcd356_a_OBJECTS = hid/ipcd356/libipcd356_a-ipcd356.$(OBJEXT) libipcd356_a_OBJECTS = $(am_libipcd356_a_OBJECTS) liblesstif_a_AR = $(AR) $(ARFLAGS) liblesstif_a_LIBADD = am__objects_10 = hid/lesstif/liblesstif_a-dialogs.$(OBJEXT) \ hid/lesstif/liblesstif_a-library.$(OBJEXT) \ hid/lesstif/liblesstif_a-main.$(OBJEXT) \ hid/lesstif/liblesstif_a-menu.$(OBJEXT) \ hid/lesstif/liblesstif_a-netlist.$(OBJEXT) \ hid/lesstif/liblesstif_a-styles.$(OBJEXT) am_liblesstif_a_OBJECTS = $(am__objects_10) liblesstif_a_OBJECTS = $(am_liblesstif_a_OBJECTS) liblpr_a_AR = $(AR) $(ARFLAGS) liblpr_a_LIBADD = am_liblpr_a_OBJECTS = hid/lpr/liblpr_a-lpr.$(OBJEXT) liblpr_a_OBJECTS = $(am_liblpr_a_OBJECTS) libnelma_a_AR = $(AR) $(ARFLAGS) libnelma_a_LIBADD = am__objects_11 = hid/nelma/libnelma_a-nelma.$(OBJEXT) am_libnelma_a_OBJECTS = $(am__objects_11) libnelma_a_OBJECTS = $(am_libnelma_a_OBJECTS) libpng_a_AR = $(AR) $(ARFLAGS) libpng_a_LIBADD = am__objects_12 = hid/png/libpng_a-png.$(OBJEXT) am_libpng_a_OBJECTS = $(am__objects_12) libpng_a_OBJECTS = $(am_libpng_a_OBJECTS) libps_a_AR = $(AR) $(ARFLAGS) libps_a_LIBADD = am__objects_13 = hid/ps/libps_a-ps.$(OBJEXT) \ hid/ps/libps_a-eps.$(OBJEXT) am_libps_a_OBJECTS = $(am__objects_13) libps_a_OBJECTS = $(am_libps_a_OBJECTS) am__pcb_SOURCES_DIST = action.c action.h autoplace.c autoplace.h \ autoroute.c autoroute.h box.h buffer.c buffer.h change.c \ change.h clip.c clip.h compat.c compat.h const.h copy.c copy.h \ create.c create.h crosshair.c crosshair.h data.c data.h \ djopt.c djopt.h dolists.h draw.c draw.h drill.c drill.h edif.y \ edif_parse.h error.c error.h file.c file.h find.c find.h \ flags.c flags.h fontmode.c free_atexit.c free_atexit.h \ getline.c gettext.h global.h heap.c heap.h hid.h hid_draw.h \ insert.c insert.h intersect.c intersect.h layerflags.c \ layerflags.h line.c line.h lrealpath.c lrealpath.h macro.h \ main.c mirror.c mirror.h misc.c misc.h move.c move.h mtspace.c \ mtspace.h mymem.c mymem.h netlist.c object_list.c \ object_list.h parse_l.h parse_l.l parse_y.y pcb-printf.c \ pcb-printf.h polygon.c polygon.h polygon1.c polyarea.h \ puller.c print.c print.h rats.c rats.h relocate.c remove.c \ remove.h renumber.c report.c report.h res_parse.y res_lex.l \ resource.h rotate.c rotate.h rtree.c rtree.h rubberband.c \ rubberband.h search.c search.h select.c select.h set.c set.h \ smartdisperse.c strcasestr.c strflags.c strflags.h teardrops.c \ thermal.c thermal.h undo.c undo.h vector.c vector.h vendor.c \ vendor.h hid/common/actions.c hid/common/actions.h \ hid/common/flags.c hid/common/hidinit.c hid/common/hidinit.h \ hid/common/hidnogui.c hid/common/hidnogui.h \ hid/common/extents.c hid/common/draw_helpers.c \ hid/common/draw_helpers.h hid/common/hid_resource.c \ hid/common/hid_resource.h hid/hidint.h toporouter.c \ toporouter.h dbus-pcbmain.c dbus-pcbmain.h dbus.h dbus.c \ hid/common/hidgl.c hid/common/hidgl.h hid/common/trackball.c \ hid/common/trackball.h core_lists.h @WITH_TOPOROUTER_TRUE@am__objects_14 = pcb-toporouter.$(OBJEXT) am__objects_15 = pcb-dbus-pcbmain.$(OBJEXT) pcb-dbus.$(OBJEXT) @WITH_DBUS_TRUE@am__objects_16 = $(am__objects_15) am__objects_17 = hid/common/pcb-hidgl.$(OBJEXT) \ hid/common/pcb-trackball.$(OBJEXT) @USE_GL_TRUE@am__objects_18 = $(am__objects_17) am__objects_19 = pcb-action.$(OBJEXT) pcb-autoplace.$(OBJEXT) \ pcb-autoroute.$(OBJEXT) pcb-buffer.$(OBJEXT) \ pcb-change.$(OBJEXT) pcb-clip.$(OBJEXT) pcb-compat.$(OBJEXT) \ pcb-copy.$(OBJEXT) pcb-create.$(OBJEXT) \ pcb-crosshair.$(OBJEXT) pcb-data.$(OBJEXT) pcb-djopt.$(OBJEXT) \ pcb-draw.$(OBJEXT) pcb-drill.$(OBJEXT) pcb-edif.$(OBJEXT) \ pcb-error.$(OBJEXT) pcb-file.$(OBJEXT) pcb-find.$(OBJEXT) \ pcb-flags.$(OBJEXT) pcb-fontmode.$(OBJEXT) \ pcb-free_atexit.$(OBJEXT) pcb-getline.$(OBJEXT) \ pcb-heap.$(OBJEXT) pcb-insert.$(OBJEXT) \ pcb-intersect.$(OBJEXT) pcb-layerflags.$(OBJEXT) \ pcb-line.$(OBJEXT) pcb-lrealpath.$(OBJEXT) pcb-main.$(OBJEXT) \ pcb-mirror.$(OBJEXT) pcb-misc.$(OBJEXT) pcb-move.$(OBJEXT) \ pcb-mtspace.$(OBJEXT) pcb-mymem.$(OBJEXT) \ pcb-netlist.$(OBJEXT) pcb-object_list.$(OBJEXT) \ pcb-parse_l.$(OBJEXT) pcb-parse_y.$(OBJEXT) \ pcb-pcb-printf.$(OBJEXT) pcb-polygon.$(OBJEXT) \ pcb-polygon1.$(OBJEXT) pcb-puller.$(OBJEXT) \ pcb-print.$(OBJEXT) pcb-rats.$(OBJEXT) pcb-relocate.$(OBJEXT) \ pcb-remove.$(OBJEXT) pcb-renumber.$(OBJEXT) \ pcb-report.$(OBJEXT) pcb-res_parse.$(OBJEXT) \ pcb-res_lex.$(OBJEXT) pcb-rotate.$(OBJEXT) pcb-rtree.$(OBJEXT) \ pcb-rubberband.$(OBJEXT) pcb-search.$(OBJEXT) \ pcb-select.$(OBJEXT) pcb-set.$(OBJEXT) \ pcb-smartdisperse.$(OBJEXT) pcb-strcasestr.$(OBJEXT) \ pcb-strflags.$(OBJEXT) pcb-teardrops.$(OBJEXT) \ pcb-thermal.$(OBJEXT) pcb-undo.$(OBJEXT) pcb-vector.$(OBJEXT) \ pcb-vendor.$(OBJEXT) hid/common/pcb-actions.$(OBJEXT) \ hid/common/pcb-flags.$(OBJEXT) \ hid/common/pcb-hidinit.$(OBJEXT) \ hid/common/pcb-hidnogui.$(OBJEXT) \ hid/common/pcb-extents.$(OBJEXT) \ hid/common/pcb-draw_helpers.$(OBJEXT) \ hid/common/pcb-hid_resource.$(OBJEXT) $(am__objects_14) \ $(am__objects_16) $(am__objects_18) am_pcb_OBJECTS = $(am__objects_19) pcb_OBJECTS = $(am_pcb_OBJECTS) am__objects_20 = unittest-pcb-printf.$(OBJEXT) \ unittest-object_list.$(OBJEXT) unittest-main-test.$(OBJEXT) am_unittest_OBJECTS = $(am__objects_20) unittest_OBJECTS = $(am_unittest_OBJECTS) unittest_LDADD = $(LDADD) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/pcb-action.Po \ ./$(DEPDIR)/pcb-autoplace.Po ./$(DEPDIR)/pcb-autoroute.Po \ ./$(DEPDIR)/pcb-buffer.Po ./$(DEPDIR)/pcb-change.Po \ ./$(DEPDIR)/pcb-clip.Po ./$(DEPDIR)/pcb-compat.Po \ ./$(DEPDIR)/pcb-copy.Po ./$(DEPDIR)/pcb-create.Po \ ./$(DEPDIR)/pcb-crosshair.Po ./$(DEPDIR)/pcb-data.Po \ ./$(DEPDIR)/pcb-dbus-pcbmain.Po ./$(DEPDIR)/pcb-dbus.Po \ ./$(DEPDIR)/pcb-djopt.Po ./$(DEPDIR)/pcb-draw.Po \ ./$(DEPDIR)/pcb-drill.Po ./$(DEPDIR)/pcb-edif.Po \ ./$(DEPDIR)/pcb-error.Po ./$(DEPDIR)/pcb-file.Po \ ./$(DEPDIR)/pcb-find.Po ./$(DEPDIR)/pcb-flags.Po \ ./$(DEPDIR)/pcb-fontmode.Po ./$(DEPDIR)/pcb-free_atexit.Po \ ./$(DEPDIR)/pcb-getline.Po ./$(DEPDIR)/pcb-heap.Po \ ./$(DEPDIR)/pcb-insert.Po ./$(DEPDIR)/pcb-intersect.Po \ ./$(DEPDIR)/pcb-layerflags.Po ./$(DEPDIR)/pcb-line.Po \ ./$(DEPDIR)/pcb-lrealpath.Po ./$(DEPDIR)/pcb-main.Po \ ./$(DEPDIR)/pcb-mirror.Po ./$(DEPDIR)/pcb-misc.Po \ ./$(DEPDIR)/pcb-move.Po ./$(DEPDIR)/pcb-mtspace.Po \ ./$(DEPDIR)/pcb-mymem.Po ./$(DEPDIR)/pcb-netlist.Po \ ./$(DEPDIR)/pcb-object_list.Po ./$(DEPDIR)/pcb-parse_l.Po \ ./$(DEPDIR)/pcb-parse_y.Po ./$(DEPDIR)/pcb-pcb-printf.Po \ ./$(DEPDIR)/pcb-polygon.Po ./$(DEPDIR)/pcb-polygon1.Po \ ./$(DEPDIR)/pcb-print.Po ./$(DEPDIR)/pcb-puller.Po \ ./$(DEPDIR)/pcb-rats.Po ./$(DEPDIR)/pcb-relocate.Po \ ./$(DEPDIR)/pcb-remove.Po ./$(DEPDIR)/pcb-renumber.Po \ ./$(DEPDIR)/pcb-report.Po ./$(DEPDIR)/pcb-res_lex.Po \ ./$(DEPDIR)/pcb-res_parse.Po ./$(DEPDIR)/pcb-rotate.Po \ ./$(DEPDIR)/pcb-rtree.Po ./$(DEPDIR)/pcb-rubberband.Po \ ./$(DEPDIR)/pcb-search.Po ./$(DEPDIR)/pcb-select.Po \ ./$(DEPDIR)/pcb-set.Po ./$(DEPDIR)/pcb-smartdisperse.Po \ ./$(DEPDIR)/pcb-strcasestr.Po ./$(DEPDIR)/pcb-strflags.Po \ ./$(DEPDIR)/pcb-teardrops.Po ./$(DEPDIR)/pcb-thermal.Po \ ./$(DEPDIR)/pcb-toporouter.Po ./$(DEPDIR)/pcb-undo.Po \ ./$(DEPDIR)/pcb-vector.Po ./$(DEPDIR)/pcb-vendor.Po \ ./$(DEPDIR)/unittest-main-test.Po \ ./$(DEPDIR)/unittest-object_list.Po \ ./$(DEPDIR)/unittest-pcb-printf.Po \ drc/$(DEPDIR)/libdrc_a-drc.Po \ drc/$(DEPDIR)/libdrc_a-drc_violation.Po \ hid/batch/$(DEPDIR)/libbatch_a-batch.Po \ hid/bom/$(DEPDIR)/libbom_a-bom.Po \ hid/bom_md/$(DEPDIR)/libbom_md_a-bom_md.Po \ hid/common/$(DEPDIR)/pcb-actions.Po \ hid/common/$(DEPDIR)/pcb-draw_helpers.Po \ hid/common/$(DEPDIR)/pcb-extents.Po \ hid/common/$(DEPDIR)/pcb-flags.Po \ hid/common/$(DEPDIR)/pcb-hid_resource.Po \ hid/common/$(DEPDIR)/pcb-hidgl.Po \ hid/common/$(DEPDIR)/pcb-hidinit.Po \ hid/common/$(DEPDIR)/pcb-hidnogui.Po \ hid/common/$(DEPDIR)/pcb-trackball.Po \ hid/gcode/$(DEPDIR)/libgcode_a-curve.Po \ hid/gcode/$(DEPDIR)/libgcode_a-decompose.Po \ hid/gcode/$(DEPDIR)/libgcode_a-gcode.Po \ hid/gcode/$(DEPDIR)/libgcode_a-trace.Po \ hid/gerber/$(DEPDIR)/libgerber_a-gerber.Po \ hid/gsvit/$(DEPDIR)/libgsvit_a-gsvit.Po \ hid/gtk/$(DEPDIR)/libgtk_a-ghid-cell-renderer-visibility.Po \ hid/gtk/$(DEPDIR)/libgtk_a-ghid-coord-entry.Po \ hid/gtk/$(DEPDIR)/libgtk_a-ghid-layer-selector.Po \ hid/gtk/$(DEPDIR)/libgtk_a-ghid-main-menu.Po \ hid/gtk/$(DEPDIR)/libgtk_a-ghid-route-style-selector.Po \ hid/gtk/$(DEPDIR)/libgtk_a-gtkhid-gdk.Po \ hid/gtk/$(DEPDIR)/libgtk_a-gtkhid-gl.Po \ hid/gtk/$(DEPDIR)/libgtk_a-gtkhid-main.Po \ hid/gtk/$(DEPDIR)/libgtk_a-gui-command-window.Po \ hid/gtk/$(DEPDIR)/libgtk_a-gui-config.Po \ hid/gtk/$(DEPDIR)/libgtk_a-gui-dialog-print.Po \ hid/gtk/$(DEPDIR)/libgtk_a-gui-dialog.Po \ hid/gtk/$(DEPDIR)/libgtk_a-gui-drc-window.Po \ hid/gtk/$(DEPDIR)/libgtk_a-gui-keyref-window.Po \ hid/gtk/$(DEPDIR)/libgtk_a-gui-library-window.Po \ hid/gtk/$(DEPDIR)/libgtk_a-gui-log-window.Po \ hid/gtk/$(DEPDIR)/libgtk_a-gui-misc.Po \ hid/gtk/$(DEPDIR)/libgtk_a-gui-netlist-window.Po \ hid/gtk/$(DEPDIR)/libgtk_a-gui-output-events.Po \ hid/gtk/$(DEPDIR)/libgtk_a-gui-pinout-preview.Po \ hid/gtk/$(DEPDIR)/libgtk_a-gui-pinout-window.Po \ hid/gtk/$(DEPDIR)/libgtk_a-gui-top-window.Po \ hid/gtk/$(DEPDIR)/libgtk_a-gui-trackball.Po \ hid/gtk/$(DEPDIR)/libgtk_a-gui-utils.Po \ hid/ipcd356/$(DEPDIR)/libipcd356_a-ipcd356.Po \ hid/lesstif/$(DEPDIR)/liblesstif_a-dialogs.Po \ hid/lesstif/$(DEPDIR)/liblesstif_a-library.Po \ hid/lesstif/$(DEPDIR)/liblesstif_a-main.Po \ hid/lesstif/$(DEPDIR)/liblesstif_a-menu.Po \ hid/lesstif/$(DEPDIR)/liblesstif_a-netlist.Po \ hid/lesstif/$(DEPDIR)/liblesstif_a-styles.Po \ hid/lpr/$(DEPDIR)/liblpr_a-lpr.Po \ hid/nelma/$(DEPDIR)/libnelma_a-nelma.Po \ hid/png/$(DEPDIR)/libpng_a-png.Po \ hid/ps/$(DEPDIR)/libps_a-eps.Po hid/ps/$(DEPDIR)/libps_a-ps.Po am__mv = mv -f AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = LEXCOMPILE = $(LEX) $(AM_LFLAGS) $(LFLAGS) AM_V_LEX = $(am__v_LEX_@AM_V@) am__v_LEX_ = $(am__v_LEX_@AM_DEFAULT_V@) am__v_LEX_0 = @echo " LEX " $@; am__v_LEX_1 = YLWRAP = $(top_srcdir)/ylwrap am__yacc_c2h = sed -e s/cc$$/hh/ -e s/cpp$$/hpp/ -e s/cxx$$/hxx/ \ -e s/c++$$/h++/ -e s/c$$/h/ YACCCOMPILE = $(YACC) $(AM_YFLAGS) $(YFLAGS) AM_V_YACC = $(am__v_YACC_@AM_V@) am__v_YACC_ = $(am__v_YACC_@AM_DEFAULT_V@) am__v_YACC_0 = @echo " YACC " $@; am__v_YACC_1 = SOURCES = $(libbatch_a_SOURCES) $(libbom_a_SOURCES) \ $(libbom_md_a_SOURCES) $(libdrc_a_SOURCES) \ $(libgcode_a_SOURCES) $(libgerber_a_SOURCES) \ $(libgsvit_a_SOURCES) $(libgtk_a_SOURCES) \ $(libipcd356_a_SOURCES) $(liblesstif_a_SOURCES) \ $(liblpr_a_SOURCES) $(libnelma_a_SOURCES) $(libpng_a_SOURCES) \ $(libps_a_SOURCES) $(pcb_SOURCES) $(EXTRA_pcb_SOURCES) \ $(unittest_SOURCES) DIST_SOURCES = $(libbatch_a_SOURCES) $(libbom_a_SOURCES) \ $(libbom_md_a_SOURCES) $(libdrc_a_SOURCES) \ $(libgcode_a_SOURCES) $(libgerber_a_SOURCES) \ $(libgsvit_a_SOURCES) $(am__libgtk_a_SOURCES_DIST) \ $(libipcd356_a_SOURCES) $(liblesstif_a_SOURCES) \ $(liblpr_a_SOURCES) $(libnelma_a_SOURCES) $(libpng_a_SOURCES) \ $(libps_a_SOURCES) $(am__pcb_SOURCES_DIST) \ $(EXTRA_pcb_SOURCES) $(unittest_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } DATA = $(pcblib_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ check recheck distdir distdir-am am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` RECHECK_LOGS = $(TEST_LOGS) TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ $(top_srcdir)/test-driver $(top_srcdir)/ylwrap edif.c edif.h \ parse_l.c parse_y.c parse_y.h res_lex.c res_parse.c \ res_parse.h DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BTNMOD = @BTNMOD@ BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@ CAIRO_CFLAGS = @CAIRO_CFLAGS@ CAIRO_LIBS = @CAIRO_LIBS@ CATOBJEXT = @CATOBJEXT@ CC = @CC_OR_CXX@ CCDEPMODE = @CCDEPMODE@ CC_OR_CXX = @CC_OR_CXX@ CFLAGS = @CFLAGS@ CFLAG_VISIBILITY = @CFLAG_VISIBILITY@ CONVERT = @CONVERT@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIRNAME = @DATADIRNAME@ DBUS_CFLAGS = @DBUS_CFLAGS@ DBUS_LIBS = @DBUS_LIBS@ DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@ DEPDIR = @DEPDIR@ DOC = @DOC@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FONTFILENAME = @FONTFILENAME@ GAFDATADIR = @GAFDATADIR@ GDLIB_CFLAGS = @GDLIB_CFLAGS@ GDLIB_CONFIG = @GDLIB_CONFIG@ GDLIB_LIBS = @GDLIB_LIBS@ GENCAT = @GENCAT@ GERBV = @GERBV@ GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ GLIBC2 = @GLIBC2@ GLIBC21 = @GLIBC21@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GLU_CFLAGS = @GLU_CFLAGS@ GLU_LIBS = @GLU_LIBS@ GL_CFLAGS = @GL_CFLAGS@ GL_LIBS = @GL_LIBS@ GMSGFMT = @GMSGFMT@ GMSGFMT_015 = @GMSGFMT_015@ GNUM4 = @GNUM4@ GREP = @GREP@ GSCHEM = @GSCHEM@ GTKGLEXT_CFLAGS = @GTKGLEXT_CFLAGS@ GTKGLEXT_LIBS = @GTKGLEXT_LIBS@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_LIBS = @GTK_LIBS@ GTK_UPDATE_ICON_CACHE_BIN = @GTK_UPDATE_ICON_CACHE_BIN@ HAVE_ASPRINTF = @HAVE_ASPRINTF@ HAVE_NEWLOCALE = @HAVE_NEWLOCALE@ HAVE_POSIX_PRINTF = @HAVE_POSIX_PRINTF@ HAVE_SNPRINTF = @HAVE_SNPRINTF@ HAVE_VISIBILITY = @HAVE_VISIBILITY@ HAVE_WPRINTF = @HAVE_WPRINTF@ HIDLIBS = @HIDLIBS@ HIDLIST = @HIDLIST@ IM_ANIMATE = @IM_ANIMATE@ IM_COMPARE = @IM_COMPARE@ IM_COMPOSITE = @IM_COMPOSITE@ IM_CONVERT = @IM_CONVERT@ IM_DISPLAY = @IM_DISPLAY@ IM_MONTAGE = @IM_MONTAGE@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTOBJEXT = @INSTOBJEXT@ INTLBISON = @INTLBISON@ INTLLIBS = @INTLLIBS@ INTLOBJS = @INTLOBJS@ INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ INTLTOOL_MERGE = @INTLTOOL_MERGE@ INTLTOOL_PERL = @INTLTOOL_PERL@ INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@ INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@ INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@ INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ INTL_DEFAULT_VERBOSITY = @INTL_DEFAULT_VERBOSITY@ INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ KDEDATADIR = @KDEDATADIR@ KPSEWHICH = @KPSEWHICH@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LEX_PATH = @LEX_PATH@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBMULTITHREAD = @LIBMULTITHREAD@ LIBOBJS = @LIBOBJS@ LIBPTH = @LIBPTH@ LIBPTH_PREFIX = @LIBPTH_PREFIX@ LIBRARYFILENAME = @LIBRARYFILENAME@ LIBS = @LIBS@ LIBTHREAD = @LIBTHREAD@ LTLIBC = @LTLIBC@ LTLIBICONV = @LTLIBICONV@ LTLIBINTL = @LTLIBINTL@ LTLIBMULTITHREAD = @LTLIBMULTITHREAD@ LTLIBOBJS = @LTLIBOBJS@ LTLIBPTH = @LTLIBPTH@ LTLIBTHREAD = @LTLIBTHREAD@ M4 = @M4@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MKINFO = @MKINFO@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCB = @PCB@ PCBLIBDIR = @PCBLIBDIR@ PCBTREEDIR = @PCBTREEDIR@ PCBTREEPATH = @PCBTREEPATH@ PDFLATEX = @PDFLATEX@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POSUB = @POSUB@ PPMTOWINICON = @PPMTOWINICON@ PRI_MACROS_BROKEN = @PRI_MACROS_BROKEN@ PS2PDF = @PS2PDF@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SETENV = @SETENV@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TEXI2DVI = @TEXI2DVI@ TOPDIRS = @TOPDIRS@ UPDATE_DESKTOP_DATABASE = @UPDATE_DESKTOP_DATABASE@ UPDATE_MIME_DATABASE = @UPDATE_MIME_DATABASE@ USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ WIN32 = @WIN32@ WINDRES = @WINDRES@ WISH = @WISH@ WITHGUI = @WITHGUI@ WOE32 = @WOE32@ WOE32DLL = @WOE32DLL@ XDGDATADIR = @XDGDATADIR@ XGETTEXT = @XGETTEXT@ XGETTEXT_015 = @XGETTEXT_015@ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ XHOST = @XHOST@ XMKMF = @XMKMF@ XPMTOPPM = @XPMTOPPM@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ YACC = @YACC@ YACC_PATH = @YACC_PATH@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ intltool__v_merge_options_ = @intltool__v_merge_options_@ intltool__v_merge_options_0 = @intltool__v_merge_options_0@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = icons pcbtreedir = @PCBTREEDIR@ pcblibdir = @PCBLIBDIR@ AUTOMAKE_OPTIONS = subdir-objects noinst_LIBRARIES = @HIDLIBS@ libdrc.a EXTRA_LIBRARIES = \ libdrc.a \ libgtk.a liblesstif.a libbatch.a \ liblpr.a libgerber.a libbom.a libbom_md.a libpng.a libps.a libnelma.a \ libgcode.a libipcd356.a libgsvit.a pcblib_DATA = \ default_font \ gpcb-menu.res \ pcb-menu.res # don't disable assert() @DEBUG_BUILD_FALSE@AM_CFLAGS = -DNDEBUG PCB_SRCS = action.c action.h autoplace.c autoplace.h autoroute.c \ autoroute.h box.h buffer.c buffer.h change.c change.h clip.c \ clip.h compat.c compat.h const.h copy.c copy.h create.c \ create.h crosshair.c crosshair.h data.c data.h djopt.c djopt.h \ dolists.h draw.c draw.h drill.c drill.h edif.y edif_parse.h \ error.c error.h file.c file.h find.c find.h flags.c flags.h \ fontmode.c free_atexit.c free_atexit.h getline.c gettext.h \ global.h heap.c heap.h hid.h hid_draw.h insert.c insert.h \ intersect.c intersect.h layerflags.c layerflags.h line.c \ line.h lrealpath.c lrealpath.h macro.h main.c mirror.c \ mirror.h misc.c misc.h move.c move.h mtspace.c mtspace.h \ mymem.c mymem.h netlist.c object_list.c object_list.h \ parse_l.h parse_l.l parse_y.y pcb-printf.c pcb-printf.h \ polygon.c polygon.h polygon1.c polyarea.h puller.c print.c \ print.h rats.c rats.h relocate.c remove.c remove.h renumber.c \ report.c report.h res_parse.y res_lex.l resource.h rotate.c \ rotate.h rtree.c rtree.h rubberband.c rubberband.h search.c \ search.h select.c select.h set.c set.h smartdisperse.c \ strcasestr.c strflags.c strflags.h teardrops.c thermal.c \ thermal.h undo.c undo.h vector.c vector.h vendor.c vendor.h \ hid/common/actions.c hid/common/actions.h hid/common/flags.c \ hid/common/hidinit.c hid/common/hidinit.h \ hid/common/hidnogui.c hid/common/hidnogui.h \ hid/common/extents.c hid/common/draw_helpers.c \ hid/common/draw_helpers.h hid/common/hid_resource.c \ hid/common/hid_resource.h hid/hidint.h $(am__append_1) \ $(am__append_4) $(am__append_6) LIST_SRCS = ${PCB_SRCS} ${LIBDRC_SRCS} EXTRA_pcb_SOURCES = ${DBUS_SRCS} ${GL_SRCS} toporouter.c toporouter.h DBUS_SRCS = \ dbus-pcbmain.c \ dbus-pcbmain.h \ dbus.h \ dbus.c LIBGTK_GDK_SRCS = \ hid/gtk/gtkhid-gdk.c LIBGTK_GL_SRCS = \ hid/gtk/gtkhid-gl.c \ hid/gtk/gui-trackball.c \ hid/gtk/gui-trackball.h GL_SRCS = \ hid/common/hidgl.c \ hid/common/hidgl.h \ hid/common/trackball.c \ hid/common/trackball.h BUILT_SOURCES = core_lists.h gpcb-menu.h hid/gtk/gtk_lists.h \ hid/lesstif/lesstif_lists.h hid/batch/batch_lists.h \ hid/png/png_lists.h hid/gcode/gcode_lists.h \ hid/nelma/nelma_lists.h hid/gsvit/gsvit_lists.h \ hid/ps/ps_lists.h parse_y.h pcb-menu.h res_parse.h \ hid/common/hidlist.h $(am__append_5) pcb_LDADD = @HIDLIBS@ libdrc.a $(am__append_2) $(am__append_9) pcb_DEPENDENCIES = @HIDLIBS@ libdrc.a $(am__append_3) $(am__append_10) # All these -I$(top_srcdir) in this file are for globalconst.h. pcb_CPPFLAGS = -I$(top_srcdir) -I$(srcdir)/../gts pcb_SOURCES = ${PCB_SRCS} core_lists.h TEST_SRCS = \ pcb-printf.c \ object_list.c \ main-test.c unittest_CPPFLAGS = -I$(top_srcdir) -DPCB_UNIT_TEST unittest_SOURCES = ${TEST_SRCS} check_SCRIPTS = unittest EXTRA_DIST = \ check_icon.data \ default_font \ $(srcdir)/hid/batch/hid.conf \ $(srcdir)/hid/bom/hid.conf \ $(srcdir)/hid/bom_md/hid.conf \ $(srcdir)/hid/gcode/hid.conf \ $(srcdir)/hid/gerber/hid.conf \ $(srcdir)/hid/gtk/gui-icons-misc.data \ $(srcdir)/hid/gtk/gui-icons-mode-buttons.data \ $(srcdir)/hid/gtk/hid.conf \ $(srcdir)/hid/gtk/pcb.rc \ $(srcdir)/hid/ipcd356/hid.conf \ $(srcdir)/hid/lesstif/hid.conf \ $(srcdir)/hid/lpr/hid.conf \ $(srcdir)/hid/png/hid.conf \ $(srcdir)/hid/nelma/hid.conf \ $(srcdir)/hid/gsvit/hid.conf \ $(srcdir)/hid/ps/hid.conf \ gpcb-menu.res.in \ pcb-menu.res.in \ gpcb-menu.res.h \ pcb-menu.res.h \ pcbtest.sh.in \ dbus.xml AM_YFLAGS = -d libdrc_a_CPPFLAGS = -I$(top_srcdir) -I./drc LIBDRC_SRCS = drc/drc.h drc/drc.c \ drc/drc_violation.h drc/drc_violation.c \ drc/drc_object.h libdrc_a_SOURCES = ${LIBDRC_SRCS} libgtk_a_CPPFLAGS = -I$(top_srcdir) -I./hid/gtk LIBGTK_SRCS = dolists.h hid/hidint.h \ hid/gtk/ghid-cell-renderer-visibility.c \ hid/gtk/ghid-cell-renderer-visibility.h \ hid/gtk/ghid-coord-entry.c hid/gtk/ghid-coord-entry.h \ hid/gtk/ghid-layer-selector.c hid/gtk/ghid-layer-selector.h \ hid/gtk/ghid-main-menu.c hid/gtk/ghid-main-menu.h \ hid/gtk/ghid-route-style-selector.c \ hid/gtk/ghid-route-style-selector.h hid/gtk/gtkhid-main.c \ hid/gtk/gtkhid.h hid/gtk/gui.h hid/gtk/gui-command-window.c \ hid/gtk/gui-config.c hid/gtk/gui-dialog-print.c \ hid/gtk/gui-dialog.c hid/gtk/gui-drc-window.c \ hid/gtk/gui-drc-window.h hid/gtk/gui-keyref-window.c \ hid/gtk/gui-library-window.c hid/gtk/gui-library-window.h \ hid/gtk/gui-log-window.c hid/gtk/gui-misc.c \ hid/gtk/gui-netlist-window.c hid/gtk/gui-output-events.c \ hid/gtk/gui-pinout-preview.c hid/gtk/gui-pinout-preview.h \ hid/gtk/gui-pinout-window.c hid/gtk/gui-top-window.c \ hid/gtk/gui-utils.c $(am__append_7) $(am__append_8) libgtk_a_SOURCES = ${LIBGTK_SRCS} hid/gtk/gtk_lists.h liblesstif_a_CPPFLAGS = -I$(top_srcdir) -I./hid/lesstif LIBLESSTIF_SRCS = \ dolists.h \ hid/hidint.h \ hid/lesstif/dialogs.c \ hid/lesstif/lesstif.h \ hid/lesstif/library.c \ hid/lesstif/main.c \ hid/lesstif/menu.c \ hid/lesstif/netlist.c \ hid/lesstif/styles.c \ hid/lesstif/xincludes.h liblesstif_a_SOURCES = ${LIBLESSTIF_SRCS} hid/lesstif/lesstif_lists.h libbatch_a_CPPFLAGS = -I$(top_srcdir) -I./hid/batch LIBBATCH_SRCS = \ hid/hidint.h \ hid/batch/batch.c libbatch_a_SOURCES = ${LIBBATCH_SRCS} hid/batch/batch_lists.h libgerber_a_CPPFLAGS = -I$(top_srcdir) libgerber_a_SOURCES = \ hid/hidint.h \ hid/gerber/gerber.c libbom_a_CPPFLAGS = -I$(top_srcdir) libbom_a_SOURCES = \ hid/hidint.h \ hid/bom/bom.c libbom_md_a_CPPFLAGS = -I$(top_srcdir) libbom_md_a_SOURCES = \ hid/hidint.h \ hid/bom_md/bom_md.c libipcd356_a_CPPFLAGS = -I$(top_srcdir) libipcd356_a_SOURCES = \ hid/hidint.h \ hid/ipcd356/ipcd356.c libps_a_CPPFLAGS = -I$(top_srcdir) -I./hid/ps LIBPS_SRCS = \ dolists.h \ hid/hidint.h \ hid/ps/ps.c \ hid/ps/ps.h \ hid/ps/eps.c libps_a_SOURCES = ${LIBPS_SRCS} hid/ps/ps_lists.h libpng_a_CPPFLAGS = -I$(top_srcdir) -I./hid/png LIBPNG_SRCS = \ dolists.h \ hid/hidint.h \ hid/png/png.c \ hid/png/png.h libpng_a_SOURCES = ${LIBPNG_SRCS} hid/png/png_lists.h libgcode_a_CPPFLAGS = -I$(top_srcdir) -I./hid/gcode LIBGCODE_SRCS = \ dolists.h \ hid/hidint.h \ hid/gcode/gcode.c \ hid/gcode/decompose.c \ hid/gcode/decompose.h \ hid/gcode/trace.c \ hid/gcode/trace.h \ hid/gcode/curve.c \ hid/gcode/curve.h \ hid/gcode/auxiliary.h \ hid/gcode/bitmap.h \ hid/gcode/lists.h \ hid/gcode/potracelib.h libgcode_a_SOURCES = ${LIBGCODE_SRCS} hid/gcode/gcode_lists.h libnelma_a_CPPFLAGS = -I$(top_srcdir) -I./hid/nelma LIBNELMA_SRCS = \ dolists.h \ hid/hidint.h \ hid/nelma/nelma.c libnelma_a_SOURCES = ${LIBNELMA_SRCS} hid/nelma/nelma_lists.h libgsvit_a_CPPFLAGS = -I$(top_srcdir) -I./hid/gsvit LIBGSVIT_SRCS = \ dolists.h \ hid/hidint.h \ hid/gsvit/xmlout.h \ hid/gsvit/gsvit.c libgsvit_a_SOURCES = ${LIBGSVIT_SRCS} hid/gsvit/gsvit_lists.h liblpr_a_CPPFLAGS = -I$(top_srcdir) liblpr_a_SOURCES = \ hid/hidint.h \ hid/lpr/lpr.c DISTCLEANFILES = pcbtest.sh gpcb-menu.h pcb-menu.h \ hid/batch/batch_lists.h \ hid/common/hidlist.h \ hid/gtk/gtk_lists.h \ hid/lesstif/lesstif_lists.h \ hid/png/png_lists.h \ hid/gcode/gcode_lists.h \ hid/gsvit/gsvit_lists.h \ hid/nelma/nelma_lists.h \ hid/ps/ps_lists.h \ core_lists.h \ dbus-introspect.h \ gpcb-menu.res \ pcb-menu.res \ gpcb-menu.res.h \ pcb-menu.res.h \ pcb_icon.ico \ ${PCBTEST_BAT} with_gui = @WITHGUI@ @WIN32_TRUE@PCBTEST_BAT = pcbtest.bat all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: .SUFFIXES: .c .l .log .o .obj .test .test$(EXEEXT) .trs .y $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) clean-checkPROGRAMS: -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS) clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) hid/batch/$(am__dirstamp): @$(MKDIR_P) hid/batch @: > hid/batch/$(am__dirstamp) hid/batch/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) hid/batch/$(DEPDIR) @: > hid/batch/$(DEPDIR)/$(am__dirstamp) hid/batch/libbatch_a-batch.$(OBJEXT): hid/batch/$(am__dirstamp) \ hid/batch/$(DEPDIR)/$(am__dirstamp) libbatch.a: $(libbatch_a_OBJECTS) $(libbatch_a_DEPENDENCIES) $(EXTRA_libbatch_a_DEPENDENCIES) $(AM_V_at)-rm -f libbatch.a $(AM_V_AR)$(libbatch_a_AR) libbatch.a $(libbatch_a_OBJECTS) $(libbatch_a_LIBADD) $(AM_V_at)$(RANLIB) libbatch.a hid/bom/$(am__dirstamp): @$(MKDIR_P) hid/bom @: > hid/bom/$(am__dirstamp) hid/bom/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) hid/bom/$(DEPDIR) @: > hid/bom/$(DEPDIR)/$(am__dirstamp) hid/bom/libbom_a-bom.$(OBJEXT): hid/bom/$(am__dirstamp) \ hid/bom/$(DEPDIR)/$(am__dirstamp) libbom.a: $(libbom_a_OBJECTS) $(libbom_a_DEPENDENCIES) $(EXTRA_libbom_a_DEPENDENCIES) $(AM_V_at)-rm -f libbom.a $(AM_V_AR)$(libbom_a_AR) libbom.a $(libbom_a_OBJECTS) $(libbom_a_LIBADD) $(AM_V_at)$(RANLIB) libbom.a hid/bom_md/$(am__dirstamp): @$(MKDIR_P) hid/bom_md @: > hid/bom_md/$(am__dirstamp) hid/bom_md/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) hid/bom_md/$(DEPDIR) @: > hid/bom_md/$(DEPDIR)/$(am__dirstamp) hid/bom_md/libbom_md_a-bom_md.$(OBJEXT): hid/bom_md/$(am__dirstamp) \ hid/bom_md/$(DEPDIR)/$(am__dirstamp) libbom_md.a: $(libbom_md_a_OBJECTS) $(libbom_md_a_DEPENDENCIES) $(EXTRA_libbom_md_a_DEPENDENCIES) $(AM_V_at)-rm -f libbom_md.a $(AM_V_AR)$(libbom_md_a_AR) libbom_md.a $(libbom_md_a_OBJECTS) $(libbom_md_a_LIBADD) $(AM_V_at)$(RANLIB) libbom_md.a drc/$(am__dirstamp): @$(MKDIR_P) drc @: > drc/$(am__dirstamp) drc/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) drc/$(DEPDIR) @: > drc/$(DEPDIR)/$(am__dirstamp) drc/libdrc_a-drc.$(OBJEXT): drc/$(am__dirstamp) \ drc/$(DEPDIR)/$(am__dirstamp) drc/libdrc_a-drc_violation.$(OBJEXT): drc/$(am__dirstamp) \ drc/$(DEPDIR)/$(am__dirstamp) libdrc.a: $(libdrc_a_OBJECTS) $(libdrc_a_DEPENDENCIES) $(EXTRA_libdrc_a_DEPENDENCIES) $(AM_V_at)-rm -f libdrc.a $(AM_V_AR)$(libdrc_a_AR) libdrc.a $(libdrc_a_OBJECTS) $(libdrc_a_LIBADD) $(AM_V_at)$(RANLIB) libdrc.a hid/gcode/$(am__dirstamp): @$(MKDIR_P) hid/gcode @: > hid/gcode/$(am__dirstamp) hid/gcode/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) hid/gcode/$(DEPDIR) @: > hid/gcode/$(DEPDIR)/$(am__dirstamp) hid/gcode/libgcode_a-gcode.$(OBJEXT): hid/gcode/$(am__dirstamp) \ hid/gcode/$(DEPDIR)/$(am__dirstamp) hid/gcode/libgcode_a-decompose.$(OBJEXT): hid/gcode/$(am__dirstamp) \ hid/gcode/$(DEPDIR)/$(am__dirstamp) hid/gcode/libgcode_a-trace.$(OBJEXT): hid/gcode/$(am__dirstamp) \ hid/gcode/$(DEPDIR)/$(am__dirstamp) hid/gcode/libgcode_a-curve.$(OBJEXT): hid/gcode/$(am__dirstamp) \ hid/gcode/$(DEPDIR)/$(am__dirstamp) libgcode.a: $(libgcode_a_OBJECTS) $(libgcode_a_DEPENDENCIES) $(EXTRA_libgcode_a_DEPENDENCIES) $(AM_V_at)-rm -f libgcode.a $(AM_V_AR)$(libgcode_a_AR) libgcode.a $(libgcode_a_OBJECTS) $(libgcode_a_LIBADD) $(AM_V_at)$(RANLIB) libgcode.a hid/gerber/$(am__dirstamp): @$(MKDIR_P) hid/gerber @: > hid/gerber/$(am__dirstamp) hid/gerber/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) hid/gerber/$(DEPDIR) @: > hid/gerber/$(DEPDIR)/$(am__dirstamp) hid/gerber/libgerber_a-gerber.$(OBJEXT): hid/gerber/$(am__dirstamp) \ hid/gerber/$(DEPDIR)/$(am__dirstamp) libgerber.a: $(libgerber_a_OBJECTS) $(libgerber_a_DEPENDENCIES) $(EXTRA_libgerber_a_DEPENDENCIES) $(AM_V_at)-rm -f libgerber.a $(AM_V_AR)$(libgerber_a_AR) libgerber.a $(libgerber_a_OBJECTS) $(libgerber_a_LIBADD) $(AM_V_at)$(RANLIB) libgerber.a hid/gsvit/$(am__dirstamp): @$(MKDIR_P) hid/gsvit @: > hid/gsvit/$(am__dirstamp) hid/gsvit/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) hid/gsvit/$(DEPDIR) @: > hid/gsvit/$(DEPDIR)/$(am__dirstamp) hid/gsvit/libgsvit_a-gsvit.$(OBJEXT): hid/gsvit/$(am__dirstamp) \ hid/gsvit/$(DEPDIR)/$(am__dirstamp) libgsvit.a: $(libgsvit_a_OBJECTS) $(libgsvit_a_DEPENDENCIES) $(EXTRA_libgsvit_a_DEPENDENCIES) $(AM_V_at)-rm -f libgsvit.a $(AM_V_AR)$(libgsvit_a_AR) libgsvit.a $(libgsvit_a_OBJECTS) $(libgsvit_a_LIBADD) $(AM_V_at)$(RANLIB) libgsvit.a hid/gtk/$(am__dirstamp): @$(MKDIR_P) hid/gtk @: > hid/gtk/$(am__dirstamp) hid/gtk/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) hid/gtk/$(DEPDIR) @: > hid/gtk/$(DEPDIR)/$(am__dirstamp) hid/gtk/libgtk_a-ghid-cell-renderer-visibility.$(OBJEXT): \ hid/gtk/$(am__dirstamp) hid/gtk/$(DEPDIR)/$(am__dirstamp) hid/gtk/libgtk_a-ghid-coord-entry.$(OBJEXT): hid/gtk/$(am__dirstamp) \ hid/gtk/$(DEPDIR)/$(am__dirstamp) hid/gtk/libgtk_a-ghid-layer-selector.$(OBJEXT): \ hid/gtk/$(am__dirstamp) hid/gtk/$(DEPDIR)/$(am__dirstamp) hid/gtk/libgtk_a-ghid-main-menu.$(OBJEXT): hid/gtk/$(am__dirstamp) \ hid/gtk/$(DEPDIR)/$(am__dirstamp) hid/gtk/libgtk_a-ghid-route-style-selector.$(OBJEXT): \ hid/gtk/$(am__dirstamp) hid/gtk/$(DEPDIR)/$(am__dirstamp) hid/gtk/libgtk_a-gtkhid-main.$(OBJEXT): hid/gtk/$(am__dirstamp) \ hid/gtk/$(DEPDIR)/$(am__dirstamp) hid/gtk/libgtk_a-gui-command-window.$(OBJEXT): \ hid/gtk/$(am__dirstamp) hid/gtk/$(DEPDIR)/$(am__dirstamp) hid/gtk/libgtk_a-gui-config.$(OBJEXT): hid/gtk/$(am__dirstamp) \ hid/gtk/$(DEPDIR)/$(am__dirstamp) hid/gtk/libgtk_a-gui-dialog-print.$(OBJEXT): hid/gtk/$(am__dirstamp) \ hid/gtk/$(DEPDIR)/$(am__dirstamp) hid/gtk/libgtk_a-gui-dialog.$(OBJEXT): hid/gtk/$(am__dirstamp) \ hid/gtk/$(DEPDIR)/$(am__dirstamp) hid/gtk/libgtk_a-gui-drc-window.$(OBJEXT): hid/gtk/$(am__dirstamp) \ hid/gtk/$(DEPDIR)/$(am__dirstamp) hid/gtk/libgtk_a-gui-keyref-window.$(OBJEXT): hid/gtk/$(am__dirstamp) \ hid/gtk/$(DEPDIR)/$(am__dirstamp) hid/gtk/libgtk_a-gui-library-window.$(OBJEXT): \ hid/gtk/$(am__dirstamp) hid/gtk/$(DEPDIR)/$(am__dirstamp) hid/gtk/libgtk_a-gui-log-window.$(OBJEXT): hid/gtk/$(am__dirstamp) \ hid/gtk/$(DEPDIR)/$(am__dirstamp) hid/gtk/libgtk_a-gui-misc.$(OBJEXT): hid/gtk/$(am__dirstamp) \ hid/gtk/$(DEPDIR)/$(am__dirstamp) hid/gtk/libgtk_a-gui-netlist-window.$(OBJEXT): \ hid/gtk/$(am__dirstamp) hid/gtk/$(DEPDIR)/$(am__dirstamp) hid/gtk/libgtk_a-gui-output-events.$(OBJEXT): hid/gtk/$(am__dirstamp) \ hid/gtk/$(DEPDIR)/$(am__dirstamp) hid/gtk/libgtk_a-gui-pinout-preview.$(OBJEXT): \ hid/gtk/$(am__dirstamp) hid/gtk/$(DEPDIR)/$(am__dirstamp) hid/gtk/libgtk_a-gui-pinout-window.$(OBJEXT): hid/gtk/$(am__dirstamp) \ hid/gtk/$(DEPDIR)/$(am__dirstamp) hid/gtk/libgtk_a-gui-top-window.$(OBJEXT): hid/gtk/$(am__dirstamp) \ hid/gtk/$(DEPDIR)/$(am__dirstamp) hid/gtk/libgtk_a-gui-utils.$(OBJEXT): hid/gtk/$(am__dirstamp) \ hid/gtk/$(DEPDIR)/$(am__dirstamp) hid/gtk/libgtk_a-gtkhid-gl.$(OBJEXT): hid/gtk/$(am__dirstamp) \ hid/gtk/$(DEPDIR)/$(am__dirstamp) hid/gtk/libgtk_a-gui-trackball.$(OBJEXT): hid/gtk/$(am__dirstamp) \ hid/gtk/$(DEPDIR)/$(am__dirstamp) hid/gtk/libgtk_a-gtkhid-gdk.$(OBJEXT): hid/gtk/$(am__dirstamp) \ hid/gtk/$(DEPDIR)/$(am__dirstamp) libgtk.a: $(libgtk_a_OBJECTS) $(libgtk_a_DEPENDENCIES) $(EXTRA_libgtk_a_DEPENDENCIES) $(AM_V_at)-rm -f libgtk.a $(AM_V_AR)$(libgtk_a_AR) libgtk.a $(libgtk_a_OBJECTS) $(libgtk_a_LIBADD) $(AM_V_at)$(RANLIB) libgtk.a hid/ipcd356/$(am__dirstamp): @$(MKDIR_P) hid/ipcd356 @: > hid/ipcd356/$(am__dirstamp) hid/ipcd356/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) hid/ipcd356/$(DEPDIR) @: > hid/ipcd356/$(DEPDIR)/$(am__dirstamp) hid/ipcd356/libipcd356_a-ipcd356.$(OBJEXT): \ hid/ipcd356/$(am__dirstamp) \ hid/ipcd356/$(DEPDIR)/$(am__dirstamp) libipcd356.a: $(libipcd356_a_OBJECTS) $(libipcd356_a_DEPENDENCIES) $(EXTRA_libipcd356_a_DEPENDENCIES) $(AM_V_at)-rm -f libipcd356.a $(AM_V_AR)$(libipcd356_a_AR) libipcd356.a $(libipcd356_a_OBJECTS) $(libipcd356_a_LIBADD) $(AM_V_at)$(RANLIB) libipcd356.a hid/lesstif/$(am__dirstamp): @$(MKDIR_P) hid/lesstif @: > hid/lesstif/$(am__dirstamp) hid/lesstif/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) hid/lesstif/$(DEPDIR) @: > hid/lesstif/$(DEPDIR)/$(am__dirstamp) hid/lesstif/liblesstif_a-dialogs.$(OBJEXT): \ hid/lesstif/$(am__dirstamp) \ hid/lesstif/$(DEPDIR)/$(am__dirstamp) hid/lesstif/liblesstif_a-library.$(OBJEXT): \ hid/lesstif/$(am__dirstamp) \ hid/lesstif/$(DEPDIR)/$(am__dirstamp) hid/lesstif/liblesstif_a-main.$(OBJEXT): hid/lesstif/$(am__dirstamp) \ hid/lesstif/$(DEPDIR)/$(am__dirstamp) hid/lesstif/liblesstif_a-menu.$(OBJEXT): hid/lesstif/$(am__dirstamp) \ hid/lesstif/$(DEPDIR)/$(am__dirstamp) hid/lesstif/liblesstif_a-netlist.$(OBJEXT): \ hid/lesstif/$(am__dirstamp) \ hid/lesstif/$(DEPDIR)/$(am__dirstamp) hid/lesstif/liblesstif_a-styles.$(OBJEXT): \ hid/lesstif/$(am__dirstamp) \ hid/lesstif/$(DEPDIR)/$(am__dirstamp) liblesstif.a: $(liblesstif_a_OBJECTS) $(liblesstif_a_DEPENDENCIES) $(EXTRA_liblesstif_a_DEPENDENCIES) $(AM_V_at)-rm -f liblesstif.a $(AM_V_AR)$(liblesstif_a_AR) liblesstif.a $(liblesstif_a_OBJECTS) $(liblesstif_a_LIBADD) $(AM_V_at)$(RANLIB) liblesstif.a hid/lpr/$(am__dirstamp): @$(MKDIR_P) hid/lpr @: > hid/lpr/$(am__dirstamp) hid/lpr/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) hid/lpr/$(DEPDIR) @: > hid/lpr/$(DEPDIR)/$(am__dirstamp) hid/lpr/liblpr_a-lpr.$(OBJEXT): hid/lpr/$(am__dirstamp) \ hid/lpr/$(DEPDIR)/$(am__dirstamp) liblpr.a: $(liblpr_a_OBJECTS) $(liblpr_a_DEPENDENCIES) $(EXTRA_liblpr_a_DEPENDENCIES) $(AM_V_at)-rm -f liblpr.a $(AM_V_AR)$(liblpr_a_AR) liblpr.a $(liblpr_a_OBJECTS) $(liblpr_a_LIBADD) $(AM_V_at)$(RANLIB) liblpr.a hid/nelma/$(am__dirstamp): @$(MKDIR_P) hid/nelma @: > hid/nelma/$(am__dirstamp) hid/nelma/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) hid/nelma/$(DEPDIR) @: > hid/nelma/$(DEPDIR)/$(am__dirstamp) hid/nelma/libnelma_a-nelma.$(OBJEXT): hid/nelma/$(am__dirstamp) \ hid/nelma/$(DEPDIR)/$(am__dirstamp) libnelma.a: $(libnelma_a_OBJECTS) $(libnelma_a_DEPENDENCIES) $(EXTRA_libnelma_a_DEPENDENCIES) $(AM_V_at)-rm -f libnelma.a $(AM_V_AR)$(libnelma_a_AR) libnelma.a $(libnelma_a_OBJECTS) $(libnelma_a_LIBADD) $(AM_V_at)$(RANLIB) libnelma.a hid/png/$(am__dirstamp): @$(MKDIR_P) hid/png @: > hid/png/$(am__dirstamp) hid/png/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) hid/png/$(DEPDIR) @: > hid/png/$(DEPDIR)/$(am__dirstamp) hid/png/libpng_a-png.$(OBJEXT): hid/png/$(am__dirstamp) \ hid/png/$(DEPDIR)/$(am__dirstamp) libpng.a: $(libpng_a_OBJECTS) $(libpng_a_DEPENDENCIES) $(EXTRA_libpng_a_DEPENDENCIES) $(AM_V_at)-rm -f libpng.a $(AM_V_AR)$(libpng_a_AR) libpng.a $(libpng_a_OBJECTS) $(libpng_a_LIBADD) $(AM_V_at)$(RANLIB) libpng.a hid/ps/$(am__dirstamp): @$(MKDIR_P) hid/ps @: > hid/ps/$(am__dirstamp) hid/ps/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) hid/ps/$(DEPDIR) @: > hid/ps/$(DEPDIR)/$(am__dirstamp) hid/ps/libps_a-ps.$(OBJEXT): hid/ps/$(am__dirstamp) \ hid/ps/$(DEPDIR)/$(am__dirstamp) hid/ps/libps_a-eps.$(OBJEXT): hid/ps/$(am__dirstamp) \ hid/ps/$(DEPDIR)/$(am__dirstamp) libps.a: $(libps_a_OBJECTS) $(libps_a_DEPENDENCIES) $(EXTRA_libps_a_DEPENDENCIES) $(AM_V_at)-rm -f libps.a $(AM_V_AR)$(libps_a_AR) libps.a $(libps_a_OBJECTS) $(libps_a_LIBADD) $(AM_V_at)$(RANLIB) libps.a edif.h: edif.c @if test ! -f $@; then rm -f edif.c; else :; fi @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) edif.c; else :; fi parse_y.h: parse_y.c @if test ! -f $@; then rm -f parse_y.c; else :; fi @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) parse_y.c; else :; fi res_parse.h: res_parse.c @if test ! -f $@; then rm -f res_parse.c; else :; fi @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) res_parse.c; else :; fi hid/common/$(am__dirstamp): @$(MKDIR_P) hid/common @: > hid/common/$(am__dirstamp) hid/common/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) hid/common/$(DEPDIR) @: > hid/common/$(DEPDIR)/$(am__dirstamp) hid/common/pcb-actions.$(OBJEXT): hid/common/$(am__dirstamp) \ hid/common/$(DEPDIR)/$(am__dirstamp) hid/common/pcb-flags.$(OBJEXT): hid/common/$(am__dirstamp) \ hid/common/$(DEPDIR)/$(am__dirstamp) hid/common/pcb-hidinit.$(OBJEXT): hid/common/$(am__dirstamp) \ hid/common/$(DEPDIR)/$(am__dirstamp) hid/common/pcb-hidnogui.$(OBJEXT): hid/common/$(am__dirstamp) \ hid/common/$(DEPDIR)/$(am__dirstamp) hid/common/pcb-extents.$(OBJEXT): hid/common/$(am__dirstamp) \ hid/common/$(DEPDIR)/$(am__dirstamp) hid/common/pcb-draw_helpers.$(OBJEXT): hid/common/$(am__dirstamp) \ hid/common/$(DEPDIR)/$(am__dirstamp) hid/common/pcb-hid_resource.$(OBJEXT): hid/common/$(am__dirstamp) \ hid/common/$(DEPDIR)/$(am__dirstamp) hid/common/pcb-hidgl.$(OBJEXT): hid/common/$(am__dirstamp) \ hid/common/$(DEPDIR)/$(am__dirstamp) hid/common/pcb-trackball.$(OBJEXT): hid/common/$(am__dirstamp) \ hid/common/$(DEPDIR)/$(am__dirstamp) pcb$(EXEEXT): $(pcb_OBJECTS) $(pcb_DEPENDENCIES) $(EXTRA_pcb_DEPENDENCIES) @rm -f pcb$(EXEEXT) $(AM_V_CCLD)$(LINK) $(pcb_OBJECTS) $(pcb_LDADD) $(LIBS) unittest$(EXEEXT): $(unittest_OBJECTS) $(unittest_DEPENDENCIES) $(EXTRA_unittest_DEPENDENCIES) @rm -f unittest$(EXEEXT) $(AM_V_CCLD)$(LINK) $(unittest_OBJECTS) $(unittest_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f drc/*.$(OBJEXT) -rm -f hid/batch/*.$(OBJEXT) -rm -f hid/bom/*.$(OBJEXT) -rm -f hid/bom_md/*.$(OBJEXT) -rm -f hid/common/*.$(OBJEXT) -rm -f hid/gcode/*.$(OBJEXT) -rm -f hid/gerber/*.$(OBJEXT) -rm -f hid/gsvit/*.$(OBJEXT) -rm -f hid/gtk/*.$(OBJEXT) -rm -f hid/ipcd356/*.$(OBJEXT) -rm -f hid/lesstif/*.$(OBJEXT) -rm -f hid/lpr/*.$(OBJEXT) -rm -f hid/nelma/*.$(OBJEXT) -rm -f hid/png/*.$(OBJEXT) -rm -f hid/ps/*.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-action.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-autoplace.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-autoroute.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-buffer.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-change.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-clip.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-compat.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-copy.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-create.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-crosshair.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-data.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-dbus-pcbmain.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-dbus.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-djopt.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-draw.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-drill.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-edif.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-error.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-file.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-find.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-flags.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-fontmode.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-free_atexit.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-getline.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-heap.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-insert.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-intersect.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-layerflags.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-line.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-lrealpath.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-main.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-mirror.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-misc.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-move.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-mtspace.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-mymem.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-netlist.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-object_list.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-parse_l.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-parse_y.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-pcb-printf.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-polygon.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-polygon1.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-print.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-puller.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-rats.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-relocate.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-remove.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-renumber.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-report.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-res_lex.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-res_parse.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-rotate.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-rtree.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-rubberband.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-search.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-select.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-set.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-smartdisperse.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-strcasestr.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-strflags.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-teardrops.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-thermal.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-toporouter.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-undo.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-vector.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcb-vendor.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unittest-main-test.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unittest-object_list.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unittest-pcb-printf.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@drc/$(DEPDIR)/libdrc_a-drc.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@drc/$(DEPDIR)/libdrc_a-drc_violation.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/batch/$(DEPDIR)/libbatch_a-batch.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/bom/$(DEPDIR)/libbom_a-bom.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/bom_md/$(DEPDIR)/libbom_md_a-bom_md.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/common/$(DEPDIR)/pcb-actions.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/common/$(DEPDIR)/pcb-draw_helpers.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/common/$(DEPDIR)/pcb-extents.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/common/$(DEPDIR)/pcb-flags.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/common/$(DEPDIR)/pcb-hid_resource.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/common/$(DEPDIR)/pcb-hidgl.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/common/$(DEPDIR)/pcb-hidinit.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/common/$(DEPDIR)/pcb-hidnogui.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/common/$(DEPDIR)/pcb-trackball.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/gcode/$(DEPDIR)/libgcode_a-curve.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/gcode/$(DEPDIR)/libgcode_a-decompose.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/gcode/$(DEPDIR)/libgcode_a-gcode.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/gcode/$(DEPDIR)/libgcode_a-trace.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/gerber/$(DEPDIR)/libgerber_a-gerber.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/gsvit/$(DEPDIR)/libgsvit_a-gsvit.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/gtk/$(DEPDIR)/libgtk_a-ghid-cell-renderer-visibility.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/gtk/$(DEPDIR)/libgtk_a-ghid-coord-entry.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/gtk/$(DEPDIR)/libgtk_a-ghid-layer-selector.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/gtk/$(DEPDIR)/libgtk_a-ghid-main-menu.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/gtk/$(DEPDIR)/libgtk_a-ghid-route-style-selector.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/gtk/$(DEPDIR)/libgtk_a-gtkhid-gdk.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/gtk/$(DEPDIR)/libgtk_a-gtkhid-gl.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/gtk/$(DEPDIR)/libgtk_a-gtkhid-main.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/gtk/$(DEPDIR)/libgtk_a-gui-command-window.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/gtk/$(DEPDIR)/libgtk_a-gui-config.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/gtk/$(DEPDIR)/libgtk_a-gui-dialog-print.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/gtk/$(DEPDIR)/libgtk_a-gui-dialog.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/gtk/$(DEPDIR)/libgtk_a-gui-drc-window.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/gtk/$(DEPDIR)/libgtk_a-gui-keyref-window.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/gtk/$(DEPDIR)/libgtk_a-gui-library-window.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/gtk/$(DEPDIR)/libgtk_a-gui-log-window.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/gtk/$(DEPDIR)/libgtk_a-gui-misc.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/gtk/$(DEPDIR)/libgtk_a-gui-netlist-window.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/gtk/$(DEPDIR)/libgtk_a-gui-output-events.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/gtk/$(DEPDIR)/libgtk_a-gui-pinout-preview.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/gtk/$(DEPDIR)/libgtk_a-gui-pinout-window.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/gtk/$(DEPDIR)/libgtk_a-gui-top-window.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/gtk/$(DEPDIR)/libgtk_a-gui-trackball.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/gtk/$(DEPDIR)/libgtk_a-gui-utils.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/ipcd356/$(DEPDIR)/libipcd356_a-ipcd356.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/lesstif/$(DEPDIR)/liblesstif_a-dialogs.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/lesstif/$(DEPDIR)/liblesstif_a-library.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/lesstif/$(DEPDIR)/liblesstif_a-main.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/lesstif/$(DEPDIR)/liblesstif_a-menu.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/lesstif/$(DEPDIR)/liblesstif_a-netlist.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/lesstif/$(DEPDIR)/liblesstif_a-styles.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/lpr/$(DEPDIR)/liblpr_a-lpr.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/nelma/$(DEPDIR)/libnelma_a-nelma.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/png/$(DEPDIR)/libpng_a-png.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/ps/$(DEPDIR)/libps_a-eps.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@hid/ps/$(DEPDIR)/libps_a-ps.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` hid/batch/libbatch_a-batch.o: hid/batch/batch.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libbatch_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/batch/libbatch_a-batch.o -MD -MP -MF hid/batch/$(DEPDIR)/libbatch_a-batch.Tpo -c -o hid/batch/libbatch_a-batch.o `test -f 'hid/batch/batch.c' || echo '$(srcdir)/'`hid/batch/batch.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/batch/$(DEPDIR)/libbatch_a-batch.Tpo hid/batch/$(DEPDIR)/libbatch_a-batch.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/batch/batch.c' object='hid/batch/libbatch_a-batch.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libbatch_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/batch/libbatch_a-batch.o `test -f 'hid/batch/batch.c' || echo '$(srcdir)/'`hid/batch/batch.c hid/batch/libbatch_a-batch.obj: hid/batch/batch.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libbatch_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/batch/libbatch_a-batch.obj -MD -MP -MF hid/batch/$(DEPDIR)/libbatch_a-batch.Tpo -c -o hid/batch/libbatch_a-batch.obj `if test -f 'hid/batch/batch.c'; then $(CYGPATH_W) 'hid/batch/batch.c'; else $(CYGPATH_W) '$(srcdir)/hid/batch/batch.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/batch/$(DEPDIR)/libbatch_a-batch.Tpo hid/batch/$(DEPDIR)/libbatch_a-batch.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/batch/batch.c' object='hid/batch/libbatch_a-batch.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libbatch_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/batch/libbatch_a-batch.obj `if test -f 'hid/batch/batch.c'; then $(CYGPATH_W) 'hid/batch/batch.c'; else $(CYGPATH_W) '$(srcdir)/hid/batch/batch.c'; fi` hid/bom/libbom_a-bom.o: hid/bom/bom.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libbom_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/bom/libbom_a-bom.o -MD -MP -MF hid/bom/$(DEPDIR)/libbom_a-bom.Tpo -c -o hid/bom/libbom_a-bom.o `test -f 'hid/bom/bom.c' || echo '$(srcdir)/'`hid/bom/bom.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/bom/$(DEPDIR)/libbom_a-bom.Tpo hid/bom/$(DEPDIR)/libbom_a-bom.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/bom/bom.c' object='hid/bom/libbom_a-bom.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libbom_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/bom/libbom_a-bom.o `test -f 'hid/bom/bom.c' || echo '$(srcdir)/'`hid/bom/bom.c hid/bom/libbom_a-bom.obj: hid/bom/bom.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libbom_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/bom/libbom_a-bom.obj -MD -MP -MF hid/bom/$(DEPDIR)/libbom_a-bom.Tpo -c -o hid/bom/libbom_a-bom.obj `if test -f 'hid/bom/bom.c'; then $(CYGPATH_W) 'hid/bom/bom.c'; else $(CYGPATH_W) '$(srcdir)/hid/bom/bom.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/bom/$(DEPDIR)/libbom_a-bom.Tpo hid/bom/$(DEPDIR)/libbom_a-bom.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/bom/bom.c' object='hid/bom/libbom_a-bom.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libbom_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/bom/libbom_a-bom.obj `if test -f 'hid/bom/bom.c'; then $(CYGPATH_W) 'hid/bom/bom.c'; else $(CYGPATH_W) '$(srcdir)/hid/bom/bom.c'; fi` hid/bom_md/libbom_md_a-bom_md.o: hid/bom_md/bom_md.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libbom_md_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/bom_md/libbom_md_a-bom_md.o -MD -MP -MF hid/bom_md/$(DEPDIR)/libbom_md_a-bom_md.Tpo -c -o hid/bom_md/libbom_md_a-bom_md.o `test -f 'hid/bom_md/bom_md.c' || echo '$(srcdir)/'`hid/bom_md/bom_md.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/bom_md/$(DEPDIR)/libbom_md_a-bom_md.Tpo hid/bom_md/$(DEPDIR)/libbom_md_a-bom_md.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/bom_md/bom_md.c' object='hid/bom_md/libbom_md_a-bom_md.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libbom_md_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/bom_md/libbom_md_a-bom_md.o `test -f 'hid/bom_md/bom_md.c' || echo '$(srcdir)/'`hid/bom_md/bom_md.c hid/bom_md/libbom_md_a-bom_md.obj: hid/bom_md/bom_md.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libbom_md_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/bom_md/libbom_md_a-bom_md.obj -MD -MP -MF hid/bom_md/$(DEPDIR)/libbom_md_a-bom_md.Tpo -c -o hid/bom_md/libbom_md_a-bom_md.obj `if test -f 'hid/bom_md/bom_md.c'; then $(CYGPATH_W) 'hid/bom_md/bom_md.c'; else $(CYGPATH_W) '$(srcdir)/hid/bom_md/bom_md.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/bom_md/$(DEPDIR)/libbom_md_a-bom_md.Tpo hid/bom_md/$(DEPDIR)/libbom_md_a-bom_md.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/bom_md/bom_md.c' object='hid/bom_md/libbom_md_a-bom_md.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libbom_md_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/bom_md/libbom_md_a-bom_md.obj `if test -f 'hid/bom_md/bom_md.c'; then $(CYGPATH_W) 'hid/bom_md/bom_md.c'; else $(CYGPATH_W) '$(srcdir)/hid/bom_md/bom_md.c'; fi` drc/libdrc_a-drc.o: drc/drc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdrc_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT drc/libdrc_a-drc.o -MD -MP -MF drc/$(DEPDIR)/libdrc_a-drc.Tpo -c -o drc/libdrc_a-drc.o `test -f 'drc/drc.c' || echo '$(srcdir)/'`drc/drc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) drc/$(DEPDIR)/libdrc_a-drc.Tpo drc/$(DEPDIR)/libdrc_a-drc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='drc/drc.c' object='drc/libdrc_a-drc.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdrc_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o drc/libdrc_a-drc.o `test -f 'drc/drc.c' || echo '$(srcdir)/'`drc/drc.c drc/libdrc_a-drc.obj: drc/drc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdrc_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT drc/libdrc_a-drc.obj -MD -MP -MF drc/$(DEPDIR)/libdrc_a-drc.Tpo -c -o drc/libdrc_a-drc.obj `if test -f 'drc/drc.c'; then $(CYGPATH_W) 'drc/drc.c'; else $(CYGPATH_W) '$(srcdir)/drc/drc.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) drc/$(DEPDIR)/libdrc_a-drc.Tpo drc/$(DEPDIR)/libdrc_a-drc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='drc/drc.c' object='drc/libdrc_a-drc.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdrc_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o drc/libdrc_a-drc.obj `if test -f 'drc/drc.c'; then $(CYGPATH_W) 'drc/drc.c'; else $(CYGPATH_W) '$(srcdir)/drc/drc.c'; fi` drc/libdrc_a-drc_violation.o: drc/drc_violation.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdrc_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT drc/libdrc_a-drc_violation.o -MD -MP -MF drc/$(DEPDIR)/libdrc_a-drc_violation.Tpo -c -o drc/libdrc_a-drc_violation.o `test -f 'drc/drc_violation.c' || echo '$(srcdir)/'`drc/drc_violation.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) drc/$(DEPDIR)/libdrc_a-drc_violation.Tpo drc/$(DEPDIR)/libdrc_a-drc_violation.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='drc/drc_violation.c' object='drc/libdrc_a-drc_violation.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdrc_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o drc/libdrc_a-drc_violation.o `test -f 'drc/drc_violation.c' || echo '$(srcdir)/'`drc/drc_violation.c drc/libdrc_a-drc_violation.obj: drc/drc_violation.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdrc_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT drc/libdrc_a-drc_violation.obj -MD -MP -MF drc/$(DEPDIR)/libdrc_a-drc_violation.Tpo -c -o drc/libdrc_a-drc_violation.obj `if test -f 'drc/drc_violation.c'; then $(CYGPATH_W) 'drc/drc_violation.c'; else $(CYGPATH_W) '$(srcdir)/drc/drc_violation.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) drc/$(DEPDIR)/libdrc_a-drc_violation.Tpo drc/$(DEPDIR)/libdrc_a-drc_violation.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='drc/drc_violation.c' object='drc/libdrc_a-drc_violation.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdrc_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o drc/libdrc_a-drc_violation.obj `if test -f 'drc/drc_violation.c'; then $(CYGPATH_W) 'drc/drc_violation.c'; else $(CYGPATH_W) '$(srcdir)/drc/drc_violation.c'; fi` hid/gcode/libgcode_a-gcode.o: hid/gcode/gcode.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgcode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gcode/libgcode_a-gcode.o -MD -MP -MF hid/gcode/$(DEPDIR)/libgcode_a-gcode.Tpo -c -o hid/gcode/libgcode_a-gcode.o `test -f 'hid/gcode/gcode.c' || echo '$(srcdir)/'`hid/gcode/gcode.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gcode/$(DEPDIR)/libgcode_a-gcode.Tpo hid/gcode/$(DEPDIR)/libgcode_a-gcode.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gcode/gcode.c' object='hid/gcode/libgcode_a-gcode.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgcode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gcode/libgcode_a-gcode.o `test -f 'hid/gcode/gcode.c' || echo '$(srcdir)/'`hid/gcode/gcode.c hid/gcode/libgcode_a-gcode.obj: hid/gcode/gcode.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgcode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gcode/libgcode_a-gcode.obj -MD -MP -MF hid/gcode/$(DEPDIR)/libgcode_a-gcode.Tpo -c -o hid/gcode/libgcode_a-gcode.obj `if test -f 'hid/gcode/gcode.c'; then $(CYGPATH_W) 'hid/gcode/gcode.c'; else $(CYGPATH_W) '$(srcdir)/hid/gcode/gcode.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gcode/$(DEPDIR)/libgcode_a-gcode.Tpo hid/gcode/$(DEPDIR)/libgcode_a-gcode.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gcode/gcode.c' object='hid/gcode/libgcode_a-gcode.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgcode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gcode/libgcode_a-gcode.obj `if test -f 'hid/gcode/gcode.c'; then $(CYGPATH_W) 'hid/gcode/gcode.c'; else $(CYGPATH_W) '$(srcdir)/hid/gcode/gcode.c'; fi` hid/gcode/libgcode_a-decompose.o: hid/gcode/decompose.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgcode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gcode/libgcode_a-decompose.o -MD -MP -MF hid/gcode/$(DEPDIR)/libgcode_a-decompose.Tpo -c -o hid/gcode/libgcode_a-decompose.o `test -f 'hid/gcode/decompose.c' || echo '$(srcdir)/'`hid/gcode/decompose.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gcode/$(DEPDIR)/libgcode_a-decompose.Tpo hid/gcode/$(DEPDIR)/libgcode_a-decompose.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gcode/decompose.c' object='hid/gcode/libgcode_a-decompose.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgcode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gcode/libgcode_a-decompose.o `test -f 'hid/gcode/decompose.c' || echo '$(srcdir)/'`hid/gcode/decompose.c hid/gcode/libgcode_a-decompose.obj: hid/gcode/decompose.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgcode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gcode/libgcode_a-decompose.obj -MD -MP -MF hid/gcode/$(DEPDIR)/libgcode_a-decompose.Tpo -c -o hid/gcode/libgcode_a-decompose.obj `if test -f 'hid/gcode/decompose.c'; then $(CYGPATH_W) 'hid/gcode/decompose.c'; else $(CYGPATH_W) '$(srcdir)/hid/gcode/decompose.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gcode/$(DEPDIR)/libgcode_a-decompose.Tpo hid/gcode/$(DEPDIR)/libgcode_a-decompose.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gcode/decompose.c' object='hid/gcode/libgcode_a-decompose.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgcode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gcode/libgcode_a-decompose.obj `if test -f 'hid/gcode/decompose.c'; then $(CYGPATH_W) 'hid/gcode/decompose.c'; else $(CYGPATH_W) '$(srcdir)/hid/gcode/decompose.c'; fi` hid/gcode/libgcode_a-trace.o: hid/gcode/trace.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgcode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gcode/libgcode_a-trace.o -MD -MP -MF hid/gcode/$(DEPDIR)/libgcode_a-trace.Tpo -c -o hid/gcode/libgcode_a-trace.o `test -f 'hid/gcode/trace.c' || echo '$(srcdir)/'`hid/gcode/trace.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gcode/$(DEPDIR)/libgcode_a-trace.Tpo hid/gcode/$(DEPDIR)/libgcode_a-trace.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gcode/trace.c' object='hid/gcode/libgcode_a-trace.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgcode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gcode/libgcode_a-trace.o `test -f 'hid/gcode/trace.c' || echo '$(srcdir)/'`hid/gcode/trace.c hid/gcode/libgcode_a-trace.obj: hid/gcode/trace.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgcode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gcode/libgcode_a-trace.obj -MD -MP -MF hid/gcode/$(DEPDIR)/libgcode_a-trace.Tpo -c -o hid/gcode/libgcode_a-trace.obj `if test -f 'hid/gcode/trace.c'; then $(CYGPATH_W) 'hid/gcode/trace.c'; else $(CYGPATH_W) '$(srcdir)/hid/gcode/trace.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gcode/$(DEPDIR)/libgcode_a-trace.Tpo hid/gcode/$(DEPDIR)/libgcode_a-trace.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gcode/trace.c' object='hid/gcode/libgcode_a-trace.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgcode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gcode/libgcode_a-trace.obj `if test -f 'hid/gcode/trace.c'; then $(CYGPATH_W) 'hid/gcode/trace.c'; else $(CYGPATH_W) '$(srcdir)/hid/gcode/trace.c'; fi` hid/gcode/libgcode_a-curve.o: hid/gcode/curve.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgcode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gcode/libgcode_a-curve.o -MD -MP -MF hid/gcode/$(DEPDIR)/libgcode_a-curve.Tpo -c -o hid/gcode/libgcode_a-curve.o `test -f 'hid/gcode/curve.c' || echo '$(srcdir)/'`hid/gcode/curve.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gcode/$(DEPDIR)/libgcode_a-curve.Tpo hid/gcode/$(DEPDIR)/libgcode_a-curve.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gcode/curve.c' object='hid/gcode/libgcode_a-curve.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgcode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gcode/libgcode_a-curve.o `test -f 'hid/gcode/curve.c' || echo '$(srcdir)/'`hid/gcode/curve.c hid/gcode/libgcode_a-curve.obj: hid/gcode/curve.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgcode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gcode/libgcode_a-curve.obj -MD -MP -MF hid/gcode/$(DEPDIR)/libgcode_a-curve.Tpo -c -o hid/gcode/libgcode_a-curve.obj `if test -f 'hid/gcode/curve.c'; then $(CYGPATH_W) 'hid/gcode/curve.c'; else $(CYGPATH_W) '$(srcdir)/hid/gcode/curve.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gcode/$(DEPDIR)/libgcode_a-curve.Tpo hid/gcode/$(DEPDIR)/libgcode_a-curve.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gcode/curve.c' object='hid/gcode/libgcode_a-curve.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgcode_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gcode/libgcode_a-curve.obj `if test -f 'hid/gcode/curve.c'; then $(CYGPATH_W) 'hid/gcode/curve.c'; else $(CYGPATH_W) '$(srcdir)/hid/gcode/curve.c'; fi` hid/gerber/libgerber_a-gerber.o: hid/gerber/gerber.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgerber_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gerber/libgerber_a-gerber.o -MD -MP -MF hid/gerber/$(DEPDIR)/libgerber_a-gerber.Tpo -c -o hid/gerber/libgerber_a-gerber.o `test -f 'hid/gerber/gerber.c' || echo '$(srcdir)/'`hid/gerber/gerber.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gerber/$(DEPDIR)/libgerber_a-gerber.Tpo hid/gerber/$(DEPDIR)/libgerber_a-gerber.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gerber/gerber.c' object='hid/gerber/libgerber_a-gerber.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgerber_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gerber/libgerber_a-gerber.o `test -f 'hid/gerber/gerber.c' || echo '$(srcdir)/'`hid/gerber/gerber.c hid/gerber/libgerber_a-gerber.obj: hid/gerber/gerber.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgerber_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gerber/libgerber_a-gerber.obj -MD -MP -MF hid/gerber/$(DEPDIR)/libgerber_a-gerber.Tpo -c -o hid/gerber/libgerber_a-gerber.obj `if test -f 'hid/gerber/gerber.c'; then $(CYGPATH_W) 'hid/gerber/gerber.c'; else $(CYGPATH_W) '$(srcdir)/hid/gerber/gerber.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gerber/$(DEPDIR)/libgerber_a-gerber.Tpo hid/gerber/$(DEPDIR)/libgerber_a-gerber.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gerber/gerber.c' object='hid/gerber/libgerber_a-gerber.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgerber_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gerber/libgerber_a-gerber.obj `if test -f 'hid/gerber/gerber.c'; then $(CYGPATH_W) 'hid/gerber/gerber.c'; else $(CYGPATH_W) '$(srcdir)/hid/gerber/gerber.c'; fi` hid/gsvit/libgsvit_a-gsvit.o: hid/gsvit/gsvit.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgsvit_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gsvit/libgsvit_a-gsvit.o -MD -MP -MF hid/gsvit/$(DEPDIR)/libgsvit_a-gsvit.Tpo -c -o hid/gsvit/libgsvit_a-gsvit.o `test -f 'hid/gsvit/gsvit.c' || echo '$(srcdir)/'`hid/gsvit/gsvit.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gsvit/$(DEPDIR)/libgsvit_a-gsvit.Tpo hid/gsvit/$(DEPDIR)/libgsvit_a-gsvit.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gsvit/gsvit.c' object='hid/gsvit/libgsvit_a-gsvit.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgsvit_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gsvit/libgsvit_a-gsvit.o `test -f 'hid/gsvit/gsvit.c' || echo '$(srcdir)/'`hid/gsvit/gsvit.c hid/gsvit/libgsvit_a-gsvit.obj: hid/gsvit/gsvit.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgsvit_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gsvit/libgsvit_a-gsvit.obj -MD -MP -MF hid/gsvit/$(DEPDIR)/libgsvit_a-gsvit.Tpo -c -o hid/gsvit/libgsvit_a-gsvit.obj `if test -f 'hid/gsvit/gsvit.c'; then $(CYGPATH_W) 'hid/gsvit/gsvit.c'; else $(CYGPATH_W) '$(srcdir)/hid/gsvit/gsvit.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gsvit/$(DEPDIR)/libgsvit_a-gsvit.Tpo hid/gsvit/$(DEPDIR)/libgsvit_a-gsvit.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gsvit/gsvit.c' object='hid/gsvit/libgsvit_a-gsvit.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgsvit_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gsvit/libgsvit_a-gsvit.obj `if test -f 'hid/gsvit/gsvit.c'; then $(CYGPATH_W) 'hid/gsvit/gsvit.c'; else $(CYGPATH_W) '$(srcdir)/hid/gsvit/gsvit.c'; fi` hid/gtk/libgtk_a-ghid-cell-renderer-visibility.o: hid/gtk/ghid-cell-renderer-visibility.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-ghid-cell-renderer-visibility.o -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-ghid-cell-renderer-visibility.Tpo -c -o hid/gtk/libgtk_a-ghid-cell-renderer-visibility.o `test -f 'hid/gtk/ghid-cell-renderer-visibility.c' || echo '$(srcdir)/'`hid/gtk/ghid-cell-renderer-visibility.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-ghid-cell-renderer-visibility.Tpo hid/gtk/$(DEPDIR)/libgtk_a-ghid-cell-renderer-visibility.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/ghid-cell-renderer-visibility.c' object='hid/gtk/libgtk_a-ghid-cell-renderer-visibility.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-ghid-cell-renderer-visibility.o `test -f 'hid/gtk/ghid-cell-renderer-visibility.c' || echo '$(srcdir)/'`hid/gtk/ghid-cell-renderer-visibility.c hid/gtk/libgtk_a-ghid-cell-renderer-visibility.obj: hid/gtk/ghid-cell-renderer-visibility.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-ghid-cell-renderer-visibility.obj -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-ghid-cell-renderer-visibility.Tpo -c -o hid/gtk/libgtk_a-ghid-cell-renderer-visibility.obj `if test -f 'hid/gtk/ghid-cell-renderer-visibility.c'; then $(CYGPATH_W) 'hid/gtk/ghid-cell-renderer-visibility.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/ghid-cell-renderer-visibility.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-ghid-cell-renderer-visibility.Tpo hid/gtk/$(DEPDIR)/libgtk_a-ghid-cell-renderer-visibility.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/ghid-cell-renderer-visibility.c' object='hid/gtk/libgtk_a-ghid-cell-renderer-visibility.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-ghid-cell-renderer-visibility.obj `if test -f 'hid/gtk/ghid-cell-renderer-visibility.c'; then $(CYGPATH_W) 'hid/gtk/ghid-cell-renderer-visibility.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/ghid-cell-renderer-visibility.c'; fi` hid/gtk/libgtk_a-ghid-coord-entry.o: hid/gtk/ghid-coord-entry.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-ghid-coord-entry.o -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-ghid-coord-entry.Tpo -c -o hid/gtk/libgtk_a-ghid-coord-entry.o `test -f 'hid/gtk/ghid-coord-entry.c' || echo '$(srcdir)/'`hid/gtk/ghid-coord-entry.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-ghid-coord-entry.Tpo hid/gtk/$(DEPDIR)/libgtk_a-ghid-coord-entry.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/ghid-coord-entry.c' object='hid/gtk/libgtk_a-ghid-coord-entry.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-ghid-coord-entry.o `test -f 'hid/gtk/ghid-coord-entry.c' || echo '$(srcdir)/'`hid/gtk/ghid-coord-entry.c hid/gtk/libgtk_a-ghid-coord-entry.obj: hid/gtk/ghid-coord-entry.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-ghid-coord-entry.obj -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-ghid-coord-entry.Tpo -c -o hid/gtk/libgtk_a-ghid-coord-entry.obj `if test -f 'hid/gtk/ghid-coord-entry.c'; then $(CYGPATH_W) 'hid/gtk/ghid-coord-entry.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/ghid-coord-entry.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-ghid-coord-entry.Tpo hid/gtk/$(DEPDIR)/libgtk_a-ghid-coord-entry.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/ghid-coord-entry.c' object='hid/gtk/libgtk_a-ghid-coord-entry.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-ghid-coord-entry.obj `if test -f 'hid/gtk/ghid-coord-entry.c'; then $(CYGPATH_W) 'hid/gtk/ghid-coord-entry.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/ghid-coord-entry.c'; fi` hid/gtk/libgtk_a-ghid-layer-selector.o: hid/gtk/ghid-layer-selector.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-ghid-layer-selector.o -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-ghid-layer-selector.Tpo -c -o hid/gtk/libgtk_a-ghid-layer-selector.o `test -f 'hid/gtk/ghid-layer-selector.c' || echo '$(srcdir)/'`hid/gtk/ghid-layer-selector.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-ghid-layer-selector.Tpo hid/gtk/$(DEPDIR)/libgtk_a-ghid-layer-selector.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/ghid-layer-selector.c' object='hid/gtk/libgtk_a-ghid-layer-selector.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-ghid-layer-selector.o `test -f 'hid/gtk/ghid-layer-selector.c' || echo '$(srcdir)/'`hid/gtk/ghid-layer-selector.c hid/gtk/libgtk_a-ghid-layer-selector.obj: hid/gtk/ghid-layer-selector.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-ghid-layer-selector.obj -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-ghid-layer-selector.Tpo -c -o hid/gtk/libgtk_a-ghid-layer-selector.obj `if test -f 'hid/gtk/ghid-layer-selector.c'; then $(CYGPATH_W) 'hid/gtk/ghid-layer-selector.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/ghid-layer-selector.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-ghid-layer-selector.Tpo hid/gtk/$(DEPDIR)/libgtk_a-ghid-layer-selector.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/ghid-layer-selector.c' object='hid/gtk/libgtk_a-ghid-layer-selector.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-ghid-layer-selector.obj `if test -f 'hid/gtk/ghid-layer-selector.c'; then $(CYGPATH_W) 'hid/gtk/ghid-layer-selector.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/ghid-layer-selector.c'; fi` hid/gtk/libgtk_a-ghid-main-menu.o: hid/gtk/ghid-main-menu.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-ghid-main-menu.o -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-ghid-main-menu.Tpo -c -o hid/gtk/libgtk_a-ghid-main-menu.o `test -f 'hid/gtk/ghid-main-menu.c' || echo '$(srcdir)/'`hid/gtk/ghid-main-menu.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-ghid-main-menu.Tpo hid/gtk/$(DEPDIR)/libgtk_a-ghid-main-menu.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/ghid-main-menu.c' object='hid/gtk/libgtk_a-ghid-main-menu.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-ghid-main-menu.o `test -f 'hid/gtk/ghid-main-menu.c' || echo '$(srcdir)/'`hid/gtk/ghid-main-menu.c hid/gtk/libgtk_a-ghid-main-menu.obj: hid/gtk/ghid-main-menu.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-ghid-main-menu.obj -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-ghid-main-menu.Tpo -c -o hid/gtk/libgtk_a-ghid-main-menu.obj `if test -f 'hid/gtk/ghid-main-menu.c'; then $(CYGPATH_W) 'hid/gtk/ghid-main-menu.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/ghid-main-menu.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-ghid-main-menu.Tpo hid/gtk/$(DEPDIR)/libgtk_a-ghid-main-menu.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/ghid-main-menu.c' object='hid/gtk/libgtk_a-ghid-main-menu.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-ghid-main-menu.obj `if test -f 'hid/gtk/ghid-main-menu.c'; then $(CYGPATH_W) 'hid/gtk/ghid-main-menu.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/ghid-main-menu.c'; fi` hid/gtk/libgtk_a-ghid-route-style-selector.o: hid/gtk/ghid-route-style-selector.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-ghid-route-style-selector.o -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-ghid-route-style-selector.Tpo -c -o hid/gtk/libgtk_a-ghid-route-style-selector.o `test -f 'hid/gtk/ghid-route-style-selector.c' || echo '$(srcdir)/'`hid/gtk/ghid-route-style-selector.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-ghid-route-style-selector.Tpo hid/gtk/$(DEPDIR)/libgtk_a-ghid-route-style-selector.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/ghid-route-style-selector.c' object='hid/gtk/libgtk_a-ghid-route-style-selector.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-ghid-route-style-selector.o `test -f 'hid/gtk/ghid-route-style-selector.c' || echo '$(srcdir)/'`hid/gtk/ghid-route-style-selector.c hid/gtk/libgtk_a-ghid-route-style-selector.obj: hid/gtk/ghid-route-style-selector.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-ghid-route-style-selector.obj -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-ghid-route-style-selector.Tpo -c -o hid/gtk/libgtk_a-ghid-route-style-selector.obj `if test -f 'hid/gtk/ghid-route-style-selector.c'; then $(CYGPATH_W) 'hid/gtk/ghid-route-style-selector.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/ghid-route-style-selector.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-ghid-route-style-selector.Tpo hid/gtk/$(DEPDIR)/libgtk_a-ghid-route-style-selector.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/ghid-route-style-selector.c' object='hid/gtk/libgtk_a-ghid-route-style-selector.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-ghid-route-style-selector.obj `if test -f 'hid/gtk/ghid-route-style-selector.c'; then $(CYGPATH_W) 'hid/gtk/ghid-route-style-selector.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/ghid-route-style-selector.c'; fi` hid/gtk/libgtk_a-gtkhid-main.o: hid/gtk/gtkhid-main.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gtkhid-main.o -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gtkhid-main.Tpo -c -o hid/gtk/libgtk_a-gtkhid-main.o `test -f 'hid/gtk/gtkhid-main.c' || echo '$(srcdir)/'`hid/gtk/gtkhid-main.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gtkhid-main.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gtkhid-main.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gtkhid-main.c' object='hid/gtk/libgtk_a-gtkhid-main.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gtkhid-main.o `test -f 'hid/gtk/gtkhid-main.c' || echo '$(srcdir)/'`hid/gtk/gtkhid-main.c hid/gtk/libgtk_a-gtkhid-main.obj: hid/gtk/gtkhid-main.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gtkhid-main.obj -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gtkhid-main.Tpo -c -o hid/gtk/libgtk_a-gtkhid-main.obj `if test -f 'hid/gtk/gtkhid-main.c'; then $(CYGPATH_W) 'hid/gtk/gtkhid-main.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gtkhid-main.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gtkhid-main.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gtkhid-main.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gtkhid-main.c' object='hid/gtk/libgtk_a-gtkhid-main.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gtkhid-main.obj `if test -f 'hid/gtk/gtkhid-main.c'; then $(CYGPATH_W) 'hid/gtk/gtkhid-main.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gtkhid-main.c'; fi` hid/gtk/libgtk_a-gui-command-window.o: hid/gtk/gui-command-window.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-command-window.o -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-command-window.Tpo -c -o hid/gtk/libgtk_a-gui-command-window.o `test -f 'hid/gtk/gui-command-window.c' || echo '$(srcdir)/'`hid/gtk/gui-command-window.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-command-window.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-command-window.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-command-window.c' object='hid/gtk/libgtk_a-gui-command-window.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-command-window.o `test -f 'hid/gtk/gui-command-window.c' || echo '$(srcdir)/'`hid/gtk/gui-command-window.c hid/gtk/libgtk_a-gui-command-window.obj: hid/gtk/gui-command-window.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-command-window.obj -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-command-window.Tpo -c -o hid/gtk/libgtk_a-gui-command-window.obj `if test -f 'hid/gtk/gui-command-window.c'; then $(CYGPATH_W) 'hid/gtk/gui-command-window.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-command-window.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-command-window.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-command-window.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-command-window.c' object='hid/gtk/libgtk_a-gui-command-window.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-command-window.obj `if test -f 'hid/gtk/gui-command-window.c'; then $(CYGPATH_W) 'hid/gtk/gui-command-window.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-command-window.c'; fi` hid/gtk/libgtk_a-gui-config.o: hid/gtk/gui-config.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-config.o -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-config.Tpo -c -o hid/gtk/libgtk_a-gui-config.o `test -f 'hid/gtk/gui-config.c' || echo '$(srcdir)/'`hid/gtk/gui-config.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-config.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-config.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-config.c' object='hid/gtk/libgtk_a-gui-config.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-config.o `test -f 'hid/gtk/gui-config.c' || echo '$(srcdir)/'`hid/gtk/gui-config.c hid/gtk/libgtk_a-gui-config.obj: hid/gtk/gui-config.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-config.obj -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-config.Tpo -c -o hid/gtk/libgtk_a-gui-config.obj `if test -f 'hid/gtk/gui-config.c'; then $(CYGPATH_W) 'hid/gtk/gui-config.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-config.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-config.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-config.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-config.c' object='hid/gtk/libgtk_a-gui-config.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-config.obj `if test -f 'hid/gtk/gui-config.c'; then $(CYGPATH_W) 'hid/gtk/gui-config.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-config.c'; fi` hid/gtk/libgtk_a-gui-dialog-print.o: hid/gtk/gui-dialog-print.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-dialog-print.o -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-dialog-print.Tpo -c -o hid/gtk/libgtk_a-gui-dialog-print.o `test -f 'hid/gtk/gui-dialog-print.c' || echo '$(srcdir)/'`hid/gtk/gui-dialog-print.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-dialog-print.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-dialog-print.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-dialog-print.c' object='hid/gtk/libgtk_a-gui-dialog-print.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-dialog-print.o `test -f 'hid/gtk/gui-dialog-print.c' || echo '$(srcdir)/'`hid/gtk/gui-dialog-print.c hid/gtk/libgtk_a-gui-dialog-print.obj: hid/gtk/gui-dialog-print.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-dialog-print.obj -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-dialog-print.Tpo -c -o hid/gtk/libgtk_a-gui-dialog-print.obj `if test -f 'hid/gtk/gui-dialog-print.c'; then $(CYGPATH_W) 'hid/gtk/gui-dialog-print.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-dialog-print.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-dialog-print.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-dialog-print.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-dialog-print.c' object='hid/gtk/libgtk_a-gui-dialog-print.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-dialog-print.obj `if test -f 'hid/gtk/gui-dialog-print.c'; then $(CYGPATH_W) 'hid/gtk/gui-dialog-print.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-dialog-print.c'; fi` hid/gtk/libgtk_a-gui-dialog.o: hid/gtk/gui-dialog.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-dialog.o -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-dialog.Tpo -c -o hid/gtk/libgtk_a-gui-dialog.o `test -f 'hid/gtk/gui-dialog.c' || echo '$(srcdir)/'`hid/gtk/gui-dialog.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-dialog.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-dialog.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-dialog.c' object='hid/gtk/libgtk_a-gui-dialog.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-dialog.o `test -f 'hid/gtk/gui-dialog.c' || echo '$(srcdir)/'`hid/gtk/gui-dialog.c hid/gtk/libgtk_a-gui-dialog.obj: hid/gtk/gui-dialog.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-dialog.obj -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-dialog.Tpo -c -o hid/gtk/libgtk_a-gui-dialog.obj `if test -f 'hid/gtk/gui-dialog.c'; then $(CYGPATH_W) 'hid/gtk/gui-dialog.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-dialog.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-dialog.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-dialog.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-dialog.c' object='hid/gtk/libgtk_a-gui-dialog.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-dialog.obj `if test -f 'hid/gtk/gui-dialog.c'; then $(CYGPATH_W) 'hid/gtk/gui-dialog.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-dialog.c'; fi` hid/gtk/libgtk_a-gui-drc-window.o: hid/gtk/gui-drc-window.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-drc-window.o -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-drc-window.Tpo -c -o hid/gtk/libgtk_a-gui-drc-window.o `test -f 'hid/gtk/gui-drc-window.c' || echo '$(srcdir)/'`hid/gtk/gui-drc-window.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-drc-window.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-drc-window.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-drc-window.c' object='hid/gtk/libgtk_a-gui-drc-window.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-drc-window.o `test -f 'hid/gtk/gui-drc-window.c' || echo '$(srcdir)/'`hid/gtk/gui-drc-window.c hid/gtk/libgtk_a-gui-drc-window.obj: hid/gtk/gui-drc-window.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-drc-window.obj -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-drc-window.Tpo -c -o hid/gtk/libgtk_a-gui-drc-window.obj `if test -f 'hid/gtk/gui-drc-window.c'; then $(CYGPATH_W) 'hid/gtk/gui-drc-window.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-drc-window.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-drc-window.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-drc-window.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-drc-window.c' object='hid/gtk/libgtk_a-gui-drc-window.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-drc-window.obj `if test -f 'hid/gtk/gui-drc-window.c'; then $(CYGPATH_W) 'hid/gtk/gui-drc-window.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-drc-window.c'; fi` hid/gtk/libgtk_a-gui-keyref-window.o: hid/gtk/gui-keyref-window.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-keyref-window.o -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-keyref-window.Tpo -c -o hid/gtk/libgtk_a-gui-keyref-window.o `test -f 'hid/gtk/gui-keyref-window.c' || echo '$(srcdir)/'`hid/gtk/gui-keyref-window.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-keyref-window.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-keyref-window.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-keyref-window.c' object='hid/gtk/libgtk_a-gui-keyref-window.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-keyref-window.o `test -f 'hid/gtk/gui-keyref-window.c' || echo '$(srcdir)/'`hid/gtk/gui-keyref-window.c hid/gtk/libgtk_a-gui-keyref-window.obj: hid/gtk/gui-keyref-window.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-keyref-window.obj -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-keyref-window.Tpo -c -o hid/gtk/libgtk_a-gui-keyref-window.obj `if test -f 'hid/gtk/gui-keyref-window.c'; then $(CYGPATH_W) 'hid/gtk/gui-keyref-window.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-keyref-window.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-keyref-window.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-keyref-window.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-keyref-window.c' object='hid/gtk/libgtk_a-gui-keyref-window.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-keyref-window.obj `if test -f 'hid/gtk/gui-keyref-window.c'; then $(CYGPATH_W) 'hid/gtk/gui-keyref-window.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-keyref-window.c'; fi` hid/gtk/libgtk_a-gui-library-window.o: hid/gtk/gui-library-window.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-library-window.o -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-library-window.Tpo -c -o hid/gtk/libgtk_a-gui-library-window.o `test -f 'hid/gtk/gui-library-window.c' || echo '$(srcdir)/'`hid/gtk/gui-library-window.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-library-window.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-library-window.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-library-window.c' object='hid/gtk/libgtk_a-gui-library-window.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-library-window.o `test -f 'hid/gtk/gui-library-window.c' || echo '$(srcdir)/'`hid/gtk/gui-library-window.c hid/gtk/libgtk_a-gui-library-window.obj: hid/gtk/gui-library-window.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-library-window.obj -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-library-window.Tpo -c -o hid/gtk/libgtk_a-gui-library-window.obj `if test -f 'hid/gtk/gui-library-window.c'; then $(CYGPATH_W) 'hid/gtk/gui-library-window.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-library-window.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-library-window.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-library-window.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-library-window.c' object='hid/gtk/libgtk_a-gui-library-window.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-library-window.obj `if test -f 'hid/gtk/gui-library-window.c'; then $(CYGPATH_W) 'hid/gtk/gui-library-window.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-library-window.c'; fi` hid/gtk/libgtk_a-gui-log-window.o: hid/gtk/gui-log-window.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-log-window.o -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-log-window.Tpo -c -o hid/gtk/libgtk_a-gui-log-window.o `test -f 'hid/gtk/gui-log-window.c' || echo '$(srcdir)/'`hid/gtk/gui-log-window.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-log-window.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-log-window.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-log-window.c' object='hid/gtk/libgtk_a-gui-log-window.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-log-window.o `test -f 'hid/gtk/gui-log-window.c' || echo '$(srcdir)/'`hid/gtk/gui-log-window.c hid/gtk/libgtk_a-gui-log-window.obj: hid/gtk/gui-log-window.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-log-window.obj -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-log-window.Tpo -c -o hid/gtk/libgtk_a-gui-log-window.obj `if test -f 'hid/gtk/gui-log-window.c'; then $(CYGPATH_W) 'hid/gtk/gui-log-window.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-log-window.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-log-window.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-log-window.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-log-window.c' object='hid/gtk/libgtk_a-gui-log-window.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-log-window.obj `if test -f 'hid/gtk/gui-log-window.c'; then $(CYGPATH_W) 'hid/gtk/gui-log-window.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-log-window.c'; fi` hid/gtk/libgtk_a-gui-misc.o: hid/gtk/gui-misc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-misc.o -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-misc.Tpo -c -o hid/gtk/libgtk_a-gui-misc.o `test -f 'hid/gtk/gui-misc.c' || echo '$(srcdir)/'`hid/gtk/gui-misc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-misc.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-misc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-misc.c' object='hid/gtk/libgtk_a-gui-misc.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-misc.o `test -f 'hid/gtk/gui-misc.c' || echo '$(srcdir)/'`hid/gtk/gui-misc.c hid/gtk/libgtk_a-gui-misc.obj: hid/gtk/gui-misc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-misc.obj -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-misc.Tpo -c -o hid/gtk/libgtk_a-gui-misc.obj `if test -f 'hid/gtk/gui-misc.c'; then $(CYGPATH_W) 'hid/gtk/gui-misc.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-misc.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-misc.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-misc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-misc.c' object='hid/gtk/libgtk_a-gui-misc.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-misc.obj `if test -f 'hid/gtk/gui-misc.c'; then $(CYGPATH_W) 'hid/gtk/gui-misc.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-misc.c'; fi` hid/gtk/libgtk_a-gui-netlist-window.o: hid/gtk/gui-netlist-window.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-netlist-window.o -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-netlist-window.Tpo -c -o hid/gtk/libgtk_a-gui-netlist-window.o `test -f 'hid/gtk/gui-netlist-window.c' || echo '$(srcdir)/'`hid/gtk/gui-netlist-window.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-netlist-window.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-netlist-window.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-netlist-window.c' object='hid/gtk/libgtk_a-gui-netlist-window.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-netlist-window.o `test -f 'hid/gtk/gui-netlist-window.c' || echo '$(srcdir)/'`hid/gtk/gui-netlist-window.c hid/gtk/libgtk_a-gui-netlist-window.obj: hid/gtk/gui-netlist-window.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-netlist-window.obj -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-netlist-window.Tpo -c -o hid/gtk/libgtk_a-gui-netlist-window.obj `if test -f 'hid/gtk/gui-netlist-window.c'; then $(CYGPATH_W) 'hid/gtk/gui-netlist-window.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-netlist-window.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-netlist-window.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-netlist-window.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-netlist-window.c' object='hid/gtk/libgtk_a-gui-netlist-window.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-netlist-window.obj `if test -f 'hid/gtk/gui-netlist-window.c'; then $(CYGPATH_W) 'hid/gtk/gui-netlist-window.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-netlist-window.c'; fi` hid/gtk/libgtk_a-gui-output-events.o: hid/gtk/gui-output-events.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-output-events.o -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-output-events.Tpo -c -o hid/gtk/libgtk_a-gui-output-events.o `test -f 'hid/gtk/gui-output-events.c' || echo '$(srcdir)/'`hid/gtk/gui-output-events.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-output-events.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-output-events.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-output-events.c' object='hid/gtk/libgtk_a-gui-output-events.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-output-events.o `test -f 'hid/gtk/gui-output-events.c' || echo '$(srcdir)/'`hid/gtk/gui-output-events.c hid/gtk/libgtk_a-gui-output-events.obj: hid/gtk/gui-output-events.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-output-events.obj -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-output-events.Tpo -c -o hid/gtk/libgtk_a-gui-output-events.obj `if test -f 'hid/gtk/gui-output-events.c'; then $(CYGPATH_W) 'hid/gtk/gui-output-events.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-output-events.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-output-events.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-output-events.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-output-events.c' object='hid/gtk/libgtk_a-gui-output-events.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-output-events.obj `if test -f 'hid/gtk/gui-output-events.c'; then $(CYGPATH_W) 'hid/gtk/gui-output-events.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-output-events.c'; fi` hid/gtk/libgtk_a-gui-pinout-preview.o: hid/gtk/gui-pinout-preview.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-pinout-preview.o -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-pinout-preview.Tpo -c -o hid/gtk/libgtk_a-gui-pinout-preview.o `test -f 'hid/gtk/gui-pinout-preview.c' || echo '$(srcdir)/'`hid/gtk/gui-pinout-preview.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-pinout-preview.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-pinout-preview.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-pinout-preview.c' object='hid/gtk/libgtk_a-gui-pinout-preview.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-pinout-preview.o `test -f 'hid/gtk/gui-pinout-preview.c' || echo '$(srcdir)/'`hid/gtk/gui-pinout-preview.c hid/gtk/libgtk_a-gui-pinout-preview.obj: hid/gtk/gui-pinout-preview.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-pinout-preview.obj -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-pinout-preview.Tpo -c -o hid/gtk/libgtk_a-gui-pinout-preview.obj `if test -f 'hid/gtk/gui-pinout-preview.c'; then $(CYGPATH_W) 'hid/gtk/gui-pinout-preview.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-pinout-preview.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-pinout-preview.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-pinout-preview.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-pinout-preview.c' object='hid/gtk/libgtk_a-gui-pinout-preview.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-pinout-preview.obj `if test -f 'hid/gtk/gui-pinout-preview.c'; then $(CYGPATH_W) 'hid/gtk/gui-pinout-preview.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-pinout-preview.c'; fi` hid/gtk/libgtk_a-gui-pinout-window.o: hid/gtk/gui-pinout-window.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-pinout-window.o -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-pinout-window.Tpo -c -o hid/gtk/libgtk_a-gui-pinout-window.o `test -f 'hid/gtk/gui-pinout-window.c' || echo '$(srcdir)/'`hid/gtk/gui-pinout-window.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-pinout-window.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-pinout-window.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-pinout-window.c' object='hid/gtk/libgtk_a-gui-pinout-window.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-pinout-window.o `test -f 'hid/gtk/gui-pinout-window.c' || echo '$(srcdir)/'`hid/gtk/gui-pinout-window.c hid/gtk/libgtk_a-gui-pinout-window.obj: hid/gtk/gui-pinout-window.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-pinout-window.obj -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-pinout-window.Tpo -c -o hid/gtk/libgtk_a-gui-pinout-window.obj `if test -f 'hid/gtk/gui-pinout-window.c'; then $(CYGPATH_W) 'hid/gtk/gui-pinout-window.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-pinout-window.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-pinout-window.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-pinout-window.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-pinout-window.c' object='hid/gtk/libgtk_a-gui-pinout-window.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-pinout-window.obj `if test -f 'hid/gtk/gui-pinout-window.c'; then $(CYGPATH_W) 'hid/gtk/gui-pinout-window.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-pinout-window.c'; fi` hid/gtk/libgtk_a-gui-top-window.o: hid/gtk/gui-top-window.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-top-window.o -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-top-window.Tpo -c -o hid/gtk/libgtk_a-gui-top-window.o `test -f 'hid/gtk/gui-top-window.c' || echo '$(srcdir)/'`hid/gtk/gui-top-window.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-top-window.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-top-window.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-top-window.c' object='hid/gtk/libgtk_a-gui-top-window.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-top-window.o `test -f 'hid/gtk/gui-top-window.c' || echo '$(srcdir)/'`hid/gtk/gui-top-window.c hid/gtk/libgtk_a-gui-top-window.obj: hid/gtk/gui-top-window.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-top-window.obj -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-top-window.Tpo -c -o hid/gtk/libgtk_a-gui-top-window.obj `if test -f 'hid/gtk/gui-top-window.c'; then $(CYGPATH_W) 'hid/gtk/gui-top-window.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-top-window.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-top-window.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-top-window.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-top-window.c' object='hid/gtk/libgtk_a-gui-top-window.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-top-window.obj `if test -f 'hid/gtk/gui-top-window.c'; then $(CYGPATH_W) 'hid/gtk/gui-top-window.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-top-window.c'; fi` hid/gtk/libgtk_a-gui-utils.o: hid/gtk/gui-utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-utils.o -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-utils.Tpo -c -o hid/gtk/libgtk_a-gui-utils.o `test -f 'hid/gtk/gui-utils.c' || echo '$(srcdir)/'`hid/gtk/gui-utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-utils.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-utils.c' object='hid/gtk/libgtk_a-gui-utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-utils.o `test -f 'hid/gtk/gui-utils.c' || echo '$(srcdir)/'`hid/gtk/gui-utils.c hid/gtk/libgtk_a-gui-utils.obj: hid/gtk/gui-utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-utils.obj -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-utils.Tpo -c -o hid/gtk/libgtk_a-gui-utils.obj `if test -f 'hid/gtk/gui-utils.c'; then $(CYGPATH_W) 'hid/gtk/gui-utils.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-utils.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-utils.c' object='hid/gtk/libgtk_a-gui-utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-utils.obj `if test -f 'hid/gtk/gui-utils.c'; then $(CYGPATH_W) 'hid/gtk/gui-utils.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-utils.c'; fi` hid/gtk/libgtk_a-gtkhid-gl.o: hid/gtk/gtkhid-gl.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gtkhid-gl.o -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gtkhid-gl.Tpo -c -o hid/gtk/libgtk_a-gtkhid-gl.o `test -f 'hid/gtk/gtkhid-gl.c' || echo '$(srcdir)/'`hid/gtk/gtkhid-gl.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gtkhid-gl.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gtkhid-gl.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gtkhid-gl.c' object='hid/gtk/libgtk_a-gtkhid-gl.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gtkhid-gl.o `test -f 'hid/gtk/gtkhid-gl.c' || echo '$(srcdir)/'`hid/gtk/gtkhid-gl.c hid/gtk/libgtk_a-gtkhid-gl.obj: hid/gtk/gtkhid-gl.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gtkhid-gl.obj -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gtkhid-gl.Tpo -c -o hid/gtk/libgtk_a-gtkhid-gl.obj `if test -f 'hid/gtk/gtkhid-gl.c'; then $(CYGPATH_W) 'hid/gtk/gtkhid-gl.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gtkhid-gl.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gtkhid-gl.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gtkhid-gl.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gtkhid-gl.c' object='hid/gtk/libgtk_a-gtkhid-gl.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gtkhid-gl.obj `if test -f 'hid/gtk/gtkhid-gl.c'; then $(CYGPATH_W) 'hid/gtk/gtkhid-gl.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gtkhid-gl.c'; fi` hid/gtk/libgtk_a-gui-trackball.o: hid/gtk/gui-trackball.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-trackball.o -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-trackball.Tpo -c -o hid/gtk/libgtk_a-gui-trackball.o `test -f 'hid/gtk/gui-trackball.c' || echo '$(srcdir)/'`hid/gtk/gui-trackball.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-trackball.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-trackball.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-trackball.c' object='hid/gtk/libgtk_a-gui-trackball.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-trackball.o `test -f 'hid/gtk/gui-trackball.c' || echo '$(srcdir)/'`hid/gtk/gui-trackball.c hid/gtk/libgtk_a-gui-trackball.obj: hid/gtk/gui-trackball.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gui-trackball.obj -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gui-trackball.Tpo -c -o hid/gtk/libgtk_a-gui-trackball.obj `if test -f 'hid/gtk/gui-trackball.c'; then $(CYGPATH_W) 'hid/gtk/gui-trackball.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-trackball.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gui-trackball.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gui-trackball.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gui-trackball.c' object='hid/gtk/libgtk_a-gui-trackball.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gui-trackball.obj `if test -f 'hid/gtk/gui-trackball.c'; then $(CYGPATH_W) 'hid/gtk/gui-trackball.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gui-trackball.c'; fi` hid/gtk/libgtk_a-gtkhid-gdk.o: hid/gtk/gtkhid-gdk.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gtkhid-gdk.o -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gtkhid-gdk.Tpo -c -o hid/gtk/libgtk_a-gtkhid-gdk.o `test -f 'hid/gtk/gtkhid-gdk.c' || echo '$(srcdir)/'`hid/gtk/gtkhid-gdk.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gtkhid-gdk.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gtkhid-gdk.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gtkhid-gdk.c' object='hid/gtk/libgtk_a-gtkhid-gdk.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gtkhid-gdk.o `test -f 'hid/gtk/gtkhid-gdk.c' || echo '$(srcdir)/'`hid/gtk/gtkhid-gdk.c hid/gtk/libgtk_a-gtkhid-gdk.obj: hid/gtk/gtkhid-gdk.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/gtk/libgtk_a-gtkhid-gdk.obj -MD -MP -MF hid/gtk/$(DEPDIR)/libgtk_a-gtkhid-gdk.Tpo -c -o hid/gtk/libgtk_a-gtkhid-gdk.obj `if test -f 'hid/gtk/gtkhid-gdk.c'; then $(CYGPATH_W) 'hid/gtk/gtkhid-gdk.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gtkhid-gdk.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/gtk/$(DEPDIR)/libgtk_a-gtkhid-gdk.Tpo hid/gtk/$(DEPDIR)/libgtk_a-gtkhid-gdk.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/gtk/gtkhid-gdk.c' object='hid/gtk/libgtk_a-gtkhid-gdk.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtk_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/gtk/libgtk_a-gtkhid-gdk.obj `if test -f 'hid/gtk/gtkhid-gdk.c'; then $(CYGPATH_W) 'hid/gtk/gtkhid-gdk.c'; else $(CYGPATH_W) '$(srcdir)/hid/gtk/gtkhid-gdk.c'; fi` hid/ipcd356/libipcd356_a-ipcd356.o: hid/ipcd356/ipcd356.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libipcd356_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/ipcd356/libipcd356_a-ipcd356.o -MD -MP -MF hid/ipcd356/$(DEPDIR)/libipcd356_a-ipcd356.Tpo -c -o hid/ipcd356/libipcd356_a-ipcd356.o `test -f 'hid/ipcd356/ipcd356.c' || echo '$(srcdir)/'`hid/ipcd356/ipcd356.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/ipcd356/$(DEPDIR)/libipcd356_a-ipcd356.Tpo hid/ipcd356/$(DEPDIR)/libipcd356_a-ipcd356.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/ipcd356/ipcd356.c' object='hid/ipcd356/libipcd356_a-ipcd356.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libipcd356_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/ipcd356/libipcd356_a-ipcd356.o `test -f 'hid/ipcd356/ipcd356.c' || echo '$(srcdir)/'`hid/ipcd356/ipcd356.c hid/ipcd356/libipcd356_a-ipcd356.obj: hid/ipcd356/ipcd356.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libipcd356_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/ipcd356/libipcd356_a-ipcd356.obj -MD -MP -MF hid/ipcd356/$(DEPDIR)/libipcd356_a-ipcd356.Tpo -c -o hid/ipcd356/libipcd356_a-ipcd356.obj `if test -f 'hid/ipcd356/ipcd356.c'; then $(CYGPATH_W) 'hid/ipcd356/ipcd356.c'; else $(CYGPATH_W) '$(srcdir)/hid/ipcd356/ipcd356.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/ipcd356/$(DEPDIR)/libipcd356_a-ipcd356.Tpo hid/ipcd356/$(DEPDIR)/libipcd356_a-ipcd356.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/ipcd356/ipcd356.c' object='hid/ipcd356/libipcd356_a-ipcd356.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libipcd356_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/ipcd356/libipcd356_a-ipcd356.obj `if test -f 'hid/ipcd356/ipcd356.c'; then $(CYGPATH_W) 'hid/ipcd356/ipcd356.c'; else $(CYGPATH_W) '$(srcdir)/hid/ipcd356/ipcd356.c'; fi` hid/lesstif/liblesstif_a-dialogs.o: hid/lesstif/dialogs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblesstif_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/lesstif/liblesstif_a-dialogs.o -MD -MP -MF hid/lesstif/$(DEPDIR)/liblesstif_a-dialogs.Tpo -c -o hid/lesstif/liblesstif_a-dialogs.o `test -f 'hid/lesstif/dialogs.c' || echo '$(srcdir)/'`hid/lesstif/dialogs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/lesstif/$(DEPDIR)/liblesstif_a-dialogs.Tpo hid/lesstif/$(DEPDIR)/liblesstif_a-dialogs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/lesstif/dialogs.c' object='hid/lesstif/liblesstif_a-dialogs.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblesstif_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/lesstif/liblesstif_a-dialogs.o `test -f 'hid/lesstif/dialogs.c' || echo '$(srcdir)/'`hid/lesstif/dialogs.c hid/lesstif/liblesstif_a-dialogs.obj: hid/lesstif/dialogs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblesstif_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/lesstif/liblesstif_a-dialogs.obj -MD -MP -MF hid/lesstif/$(DEPDIR)/liblesstif_a-dialogs.Tpo -c -o hid/lesstif/liblesstif_a-dialogs.obj `if test -f 'hid/lesstif/dialogs.c'; then $(CYGPATH_W) 'hid/lesstif/dialogs.c'; else $(CYGPATH_W) '$(srcdir)/hid/lesstif/dialogs.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/lesstif/$(DEPDIR)/liblesstif_a-dialogs.Tpo hid/lesstif/$(DEPDIR)/liblesstif_a-dialogs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/lesstif/dialogs.c' object='hid/lesstif/liblesstif_a-dialogs.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblesstif_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/lesstif/liblesstif_a-dialogs.obj `if test -f 'hid/lesstif/dialogs.c'; then $(CYGPATH_W) 'hid/lesstif/dialogs.c'; else $(CYGPATH_W) '$(srcdir)/hid/lesstif/dialogs.c'; fi` hid/lesstif/liblesstif_a-library.o: hid/lesstif/library.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblesstif_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/lesstif/liblesstif_a-library.o -MD -MP -MF hid/lesstif/$(DEPDIR)/liblesstif_a-library.Tpo -c -o hid/lesstif/liblesstif_a-library.o `test -f 'hid/lesstif/library.c' || echo '$(srcdir)/'`hid/lesstif/library.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/lesstif/$(DEPDIR)/liblesstif_a-library.Tpo hid/lesstif/$(DEPDIR)/liblesstif_a-library.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/lesstif/library.c' object='hid/lesstif/liblesstif_a-library.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblesstif_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/lesstif/liblesstif_a-library.o `test -f 'hid/lesstif/library.c' || echo '$(srcdir)/'`hid/lesstif/library.c hid/lesstif/liblesstif_a-library.obj: hid/lesstif/library.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblesstif_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/lesstif/liblesstif_a-library.obj -MD -MP -MF hid/lesstif/$(DEPDIR)/liblesstif_a-library.Tpo -c -o hid/lesstif/liblesstif_a-library.obj `if test -f 'hid/lesstif/library.c'; then $(CYGPATH_W) 'hid/lesstif/library.c'; else $(CYGPATH_W) '$(srcdir)/hid/lesstif/library.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/lesstif/$(DEPDIR)/liblesstif_a-library.Tpo hid/lesstif/$(DEPDIR)/liblesstif_a-library.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/lesstif/library.c' object='hid/lesstif/liblesstif_a-library.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblesstif_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/lesstif/liblesstif_a-library.obj `if test -f 'hid/lesstif/library.c'; then $(CYGPATH_W) 'hid/lesstif/library.c'; else $(CYGPATH_W) '$(srcdir)/hid/lesstif/library.c'; fi` hid/lesstif/liblesstif_a-main.o: hid/lesstif/main.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblesstif_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/lesstif/liblesstif_a-main.o -MD -MP -MF hid/lesstif/$(DEPDIR)/liblesstif_a-main.Tpo -c -o hid/lesstif/liblesstif_a-main.o `test -f 'hid/lesstif/main.c' || echo '$(srcdir)/'`hid/lesstif/main.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/lesstif/$(DEPDIR)/liblesstif_a-main.Tpo hid/lesstif/$(DEPDIR)/liblesstif_a-main.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/lesstif/main.c' object='hid/lesstif/liblesstif_a-main.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblesstif_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/lesstif/liblesstif_a-main.o `test -f 'hid/lesstif/main.c' || echo '$(srcdir)/'`hid/lesstif/main.c hid/lesstif/liblesstif_a-main.obj: hid/lesstif/main.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblesstif_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/lesstif/liblesstif_a-main.obj -MD -MP -MF hid/lesstif/$(DEPDIR)/liblesstif_a-main.Tpo -c -o hid/lesstif/liblesstif_a-main.obj `if test -f 'hid/lesstif/main.c'; then $(CYGPATH_W) 'hid/lesstif/main.c'; else $(CYGPATH_W) '$(srcdir)/hid/lesstif/main.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/lesstif/$(DEPDIR)/liblesstif_a-main.Tpo hid/lesstif/$(DEPDIR)/liblesstif_a-main.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/lesstif/main.c' object='hid/lesstif/liblesstif_a-main.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblesstif_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/lesstif/liblesstif_a-main.obj `if test -f 'hid/lesstif/main.c'; then $(CYGPATH_W) 'hid/lesstif/main.c'; else $(CYGPATH_W) '$(srcdir)/hid/lesstif/main.c'; fi` hid/lesstif/liblesstif_a-menu.o: hid/lesstif/menu.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblesstif_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/lesstif/liblesstif_a-menu.o -MD -MP -MF hid/lesstif/$(DEPDIR)/liblesstif_a-menu.Tpo -c -o hid/lesstif/liblesstif_a-menu.o `test -f 'hid/lesstif/menu.c' || echo '$(srcdir)/'`hid/lesstif/menu.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/lesstif/$(DEPDIR)/liblesstif_a-menu.Tpo hid/lesstif/$(DEPDIR)/liblesstif_a-menu.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/lesstif/menu.c' object='hid/lesstif/liblesstif_a-menu.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblesstif_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/lesstif/liblesstif_a-menu.o `test -f 'hid/lesstif/menu.c' || echo '$(srcdir)/'`hid/lesstif/menu.c hid/lesstif/liblesstif_a-menu.obj: hid/lesstif/menu.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblesstif_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/lesstif/liblesstif_a-menu.obj -MD -MP -MF hid/lesstif/$(DEPDIR)/liblesstif_a-menu.Tpo -c -o hid/lesstif/liblesstif_a-menu.obj `if test -f 'hid/lesstif/menu.c'; then $(CYGPATH_W) 'hid/lesstif/menu.c'; else $(CYGPATH_W) '$(srcdir)/hid/lesstif/menu.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/lesstif/$(DEPDIR)/liblesstif_a-menu.Tpo hid/lesstif/$(DEPDIR)/liblesstif_a-menu.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/lesstif/menu.c' object='hid/lesstif/liblesstif_a-menu.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblesstif_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/lesstif/liblesstif_a-menu.obj `if test -f 'hid/lesstif/menu.c'; then $(CYGPATH_W) 'hid/lesstif/menu.c'; else $(CYGPATH_W) '$(srcdir)/hid/lesstif/menu.c'; fi` hid/lesstif/liblesstif_a-netlist.o: hid/lesstif/netlist.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblesstif_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/lesstif/liblesstif_a-netlist.o -MD -MP -MF hid/lesstif/$(DEPDIR)/liblesstif_a-netlist.Tpo -c -o hid/lesstif/liblesstif_a-netlist.o `test -f 'hid/lesstif/netlist.c' || echo '$(srcdir)/'`hid/lesstif/netlist.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/lesstif/$(DEPDIR)/liblesstif_a-netlist.Tpo hid/lesstif/$(DEPDIR)/liblesstif_a-netlist.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/lesstif/netlist.c' object='hid/lesstif/liblesstif_a-netlist.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblesstif_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/lesstif/liblesstif_a-netlist.o `test -f 'hid/lesstif/netlist.c' || echo '$(srcdir)/'`hid/lesstif/netlist.c hid/lesstif/liblesstif_a-netlist.obj: hid/lesstif/netlist.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblesstif_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/lesstif/liblesstif_a-netlist.obj -MD -MP -MF hid/lesstif/$(DEPDIR)/liblesstif_a-netlist.Tpo -c -o hid/lesstif/liblesstif_a-netlist.obj `if test -f 'hid/lesstif/netlist.c'; then $(CYGPATH_W) 'hid/lesstif/netlist.c'; else $(CYGPATH_W) '$(srcdir)/hid/lesstif/netlist.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/lesstif/$(DEPDIR)/liblesstif_a-netlist.Tpo hid/lesstif/$(DEPDIR)/liblesstif_a-netlist.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/lesstif/netlist.c' object='hid/lesstif/liblesstif_a-netlist.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblesstif_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/lesstif/liblesstif_a-netlist.obj `if test -f 'hid/lesstif/netlist.c'; then $(CYGPATH_W) 'hid/lesstif/netlist.c'; else $(CYGPATH_W) '$(srcdir)/hid/lesstif/netlist.c'; fi` hid/lesstif/liblesstif_a-styles.o: hid/lesstif/styles.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblesstif_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/lesstif/liblesstif_a-styles.o -MD -MP -MF hid/lesstif/$(DEPDIR)/liblesstif_a-styles.Tpo -c -o hid/lesstif/liblesstif_a-styles.o `test -f 'hid/lesstif/styles.c' || echo '$(srcdir)/'`hid/lesstif/styles.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/lesstif/$(DEPDIR)/liblesstif_a-styles.Tpo hid/lesstif/$(DEPDIR)/liblesstif_a-styles.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/lesstif/styles.c' object='hid/lesstif/liblesstif_a-styles.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblesstif_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/lesstif/liblesstif_a-styles.o `test -f 'hid/lesstif/styles.c' || echo '$(srcdir)/'`hid/lesstif/styles.c hid/lesstif/liblesstif_a-styles.obj: hid/lesstif/styles.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblesstif_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/lesstif/liblesstif_a-styles.obj -MD -MP -MF hid/lesstif/$(DEPDIR)/liblesstif_a-styles.Tpo -c -o hid/lesstif/liblesstif_a-styles.obj `if test -f 'hid/lesstif/styles.c'; then $(CYGPATH_W) 'hid/lesstif/styles.c'; else $(CYGPATH_W) '$(srcdir)/hid/lesstif/styles.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/lesstif/$(DEPDIR)/liblesstif_a-styles.Tpo hid/lesstif/$(DEPDIR)/liblesstif_a-styles.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/lesstif/styles.c' object='hid/lesstif/liblesstif_a-styles.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblesstif_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/lesstif/liblesstif_a-styles.obj `if test -f 'hid/lesstif/styles.c'; then $(CYGPATH_W) 'hid/lesstif/styles.c'; else $(CYGPATH_W) '$(srcdir)/hid/lesstif/styles.c'; fi` hid/lpr/liblpr_a-lpr.o: hid/lpr/lpr.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblpr_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/lpr/liblpr_a-lpr.o -MD -MP -MF hid/lpr/$(DEPDIR)/liblpr_a-lpr.Tpo -c -o hid/lpr/liblpr_a-lpr.o `test -f 'hid/lpr/lpr.c' || echo '$(srcdir)/'`hid/lpr/lpr.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/lpr/$(DEPDIR)/liblpr_a-lpr.Tpo hid/lpr/$(DEPDIR)/liblpr_a-lpr.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/lpr/lpr.c' object='hid/lpr/liblpr_a-lpr.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblpr_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/lpr/liblpr_a-lpr.o `test -f 'hid/lpr/lpr.c' || echo '$(srcdir)/'`hid/lpr/lpr.c hid/lpr/liblpr_a-lpr.obj: hid/lpr/lpr.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblpr_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/lpr/liblpr_a-lpr.obj -MD -MP -MF hid/lpr/$(DEPDIR)/liblpr_a-lpr.Tpo -c -o hid/lpr/liblpr_a-lpr.obj `if test -f 'hid/lpr/lpr.c'; then $(CYGPATH_W) 'hid/lpr/lpr.c'; else $(CYGPATH_W) '$(srcdir)/hid/lpr/lpr.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/lpr/$(DEPDIR)/liblpr_a-lpr.Tpo hid/lpr/$(DEPDIR)/liblpr_a-lpr.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/lpr/lpr.c' object='hid/lpr/liblpr_a-lpr.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblpr_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/lpr/liblpr_a-lpr.obj `if test -f 'hid/lpr/lpr.c'; then $(CYGPATH_W) 'hid/lpr/lpr.c'; else $(CYGPATH_W) '$(srcdir)/hid/lpr/lpr.c'; fi` hid/nelma/libnelma_a-nelma.o: hid/nelma/nelma.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnelma_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/nelma/libnelma_a-nelma.o -MD -MP -MF hid/nelma/$(DEPDIR)/libnelma_a-nelma.Tpo -c -o hid/nelma/libnelma_a-nelma.o `test -f 'hid/nelma/nelma.c' || echo '$(srcdir)/'`hid/nelma/nelma.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/nelma/$(DEPDIR)/libnelma_a-nelma.Tpo hid/nelma/$(DEPDIR)/libnelma_a-nelma.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/nelma/nelma.c' object='hid/nelma/libnelma_a-nelma.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnelma_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/nelma/libnelma_a-nelma.o `test -f 'hid/nelma/nelma.c' || echo '$(srcdir)/'`hid/nelma/nelma.c hid/nelma/libnelma_a-nelma.obj: hid/nelma/nelma.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnelma_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/nelma/libnelma_a-nelma.obj -MD -MP -MF hid/nelma/$(DEPDIR)/libnelma_a-nelma.Tpo -c -o hid/nelma/libnelma_a-nelma.obj `if test -f 'hid/nelma/nelma.c'; then $(CYGPATH_W) 'hid/nelma/nelma.c'; else $(CYGPATH_W) '$(srcdir)/hid/nelma/nelma.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/nelma/$(DEPDIR)/libnelma_a-nelma.Tpo hid/nelma/$(DEPDIR)/libnelma_a-nelma.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/nelma/nelma.c' object='hid/nelma/libnelma_a-nelma.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnelma_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/nelma/libnelma_a-nelma.obj `if test -f 'hid/nelma/nelma.c'; then $(CYGPATH_W) 'hid/nelma/nelma.c'; else $(CYGPATH_W) '$(srcdir)/hid/nelma/nelma.c'; fi` hid/png/libpng_a-png.o: hid/png/png.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/png/libpng_a-png.o -MD -MP -MF hid/png/$(DEPDIR)/libpng_a-png.Tpo -c -o hid/png/libpng_a-png.o `test -f 'hid/png/png.c' || echo '$(srcdir)/'`hid/png/png.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/png/$(DEPDIR)/libpng_a-png.Tpo hid/png/$(DEPDIR)/libpng_a-png.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/png/png.c' object='hid/png/libpng_a-png.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/png/libpng_a-png.o `test -f 'hid/png/png.c' || echo '$(srcdir)/'`hid/png/png.c hid/png/libpng_a-png.obj: hid/png/png.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/png/libpng_a-png.obj -MD -MP -MF hid/png/$(DEPDIR)/libpng_a-png.Tpo -c -o hid/png/libpng_a-png.obj `if test -f 'hid/png/png.c'; then $(CYGPATH_W) 'hid/png/png.c'; else $(CYGPATH_W) '$(srcdir)/hid/png/png.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/png/$(DEPDIR)/libpng_a-png.Tpo hid/png/$(DEPDIR)/libpng_a-png.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/png/png.c' object='hid/png/libpng_a-png.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/png/libpng_a-png.obj `if test -f 'hid/png/png.c'; then $(CYGPATH_W) 'hid/png/png.c'; else $(CYGPATH_W) '$(srcdir)/hid/png/png.c'; fi` hid/ps/libps_a-ps.o: hid/ps/ps.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libps_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/ps/libps_a-ps.o -MD -MP -MF hid/ps/$(DEPDIR)/libps_a-ps.Tpo -c -o hid/ps/libps_a-ps.o `test -f 'hid/ps/ps.c' || echo '$(srcdir)/'`hid/ps/ps.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/ps/$(DEPDIR)/libps_a-ps.Tpo hid/ps/$(DEPDIR)/libps_a-ps.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/ps/ps.c' object='hid/ps/libps_a-ps.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libps_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/ps/libps_a-ps.o `test -f 'hid/ps/ps.c' || echo '$(srcdir)/'`hid/ps/ps.c hid/ps/libps_a-ps.obj: hid/ps/ps.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libps_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/ps/libps_a-ps.obj -MD -MP -MF hid/ps/$(DEPDIR)/libps_a-ps.Tpo -c -o hid/ps/libps_a-ps.obj `if test -f 'hid/ps/ps.c'; then $(CYGPATH_W) 'hid/ps/ps.c'; else $(CYGPATH_W) '$(srcdir)/hid/ps/ps.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/ps/$(DEPDIR)/libps_a-ps.Tpo hid/ps/$(DEPDIR)/libps_a-ps.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/ps/ps.c' object='hid/ps/libps_a-ps.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libps_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/ps/libps_a-ps.obj `if test -f 'hid/ps/ps.c'; then $(CYGPATH_W) 'hid/ps/ps.c'; else $(CYGPATH_W) '$(srcdir)/hid/ps/ps.c'; fi` hid/ps/libps_a-eps.o: hid/ps/eps.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libps_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/ps/libps_a-eps.o -MD -MP -MF hid/ps/$(DEPDIR)/libps_a-eps.Tpo -c -o hid/ps/libps_a-eps.o `test -f 'hid/ps/eps.c' || echo '$(srcdir)/'`hid/ps/eps.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/ps/$(DEPDIR)/libps_a-eps.Tpo hid/ps/$(DEPDIR)/libps_a-eps.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/ps/eps.c' object='hid/ps/libps_a-eps.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libps_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/ps/libps_a-eps.o `test -f 'hid/ps/eps.c' || echo '$(srcdir)/'`hid/ps/eps.c hid/ps/libps_a-eps.obj: hid/ps/eps.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libps_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/ps/libps_a-eps.obj -MD -MP -MF hid/ps/$(DEPDIR)/libps_a-eps.Tpo -c -o hid/ps/libps_a-eps.obj `if test -f 'hid/ps/eps.c'; then $(CYGPATH_W) 'hid/ps/eps.c'; else $(CYGPATH_W) '$(srcdir)/hid/ps/eps.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/ps/$(DEPDIR)/libps_a-eps.Tpo hid/ps/$(DEPDIR)/libps_a-eps.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/ps/eps.c' object='hid/ps/libps_a-eps.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libps_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/ps/libps_a-eps.obj `if test -f 'hid/ps/eps.c'; then $(CYGPATH_W) 'hid/ps/eps.c'; else $(CYGPATH_W) '$(srcdir)/hid/ps/eps.c'; fi` pcb-action.o: action.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-action.o -MD -MP -MF $(DEPDIR)/pcb-action.Tpo -c -o pcb-action.o `test -f 'action.c' || echo '$(srcdir)/'`action.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-action.Tpo $(DEPDIR)/pcb-action.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='action.c' object='pcb-action.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-action.o `test -f 'action.c' || echo '$(srcdir)/'`action.c pcb-action.obj: action.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-action.obj -MD -MP -MF $(DEPDIR)/pcb-action.Tpo -c -o pcb-action.obj `if test -f 'action.c'; then $(CYGPATH_W) 'action.c'; else $(CYGPATH_W) '$(srcdir)/action.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-action.Tpo $(DEPDIR)/pcb-action.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='action.c' object='pcb-action.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-action.obj `if test -f 'action.c'; then $(CYGPATH_W) 'action.c'; else $(CYGPATH_W) '$(srcdir)/action.c'; fi` pcb-autoplace.o: autoplace.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-autoplace.o -MD -MP -MF $(DEPDIR)/pcb-autoplace.Tpo -c -o pcb-autoplace.o `test -f 'autoplace.c' || echo '$(srcdir)/'`autoplace.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-autoplace.Tpo $(DEPDIR)/pcb-autoplace.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='autoplace.c' object='pcb-autoplace.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-autoplace.o `test -f 'autoplace.c' || echo '$(srcdir)/'`autoplace.c pcb-autoplace.obj: autoplace.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-autoplace.obj -MD -MP -MF $(DEPDIR)/pcb-autoplace.Tpo -c -o pcb-autoplace.obj `if test -f 'autoplace.c'; then $(CYGPATH_W) 'autoplace.c'; else $(CYGPATH_W) '$(srcdir)/autoplace.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-autoplace.Tpo $(DEPDIR)/pcb-autoplace.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='autoplace.c' object='pcb-autoplace.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-autoplace.obj `if test -f 'autoplace.c'; then $(CYGPATH_W) 'autoplace.c'; else $(CYGPATH_W) '$(srcdir)/autoplace.c'; fi` pcb-autoroute.o: autoroute.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-autoroute.o -MD -MP -MF $(DEPDIR)/pcb-autoroute.Tpo -c -o pcb-autoroute.o `test -f 'autoroute.c' || echo '$(srcdir)/'`autoroute.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-autoroute.Tpo $(DEPDIR)/pcb-autoroute.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='autoroute.c' object='pcb-autoroute.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-autoroute.o `test -f 'autoroute.c' || echo '$(srcdir)/'`autoroute.c pcb-autoroute.obj: autoroute.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-autoroute.obj -MD -MP -MF $(DEPDIR)/pcb-autoroute.Tpo -c -o pcb-autoroute.obj `if test -f 'autoroute.c'; then $(CYGPATH_W) 'autoroute.c'; else $(CYGPATH_W) '$(srcdir)/autoroute.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-autoroute.Tpo $(DEPDIR)/pcb-autoroute.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='autoroute.c' object='pcb-autoroute.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-autoroute.obj `if test -f 'autoroute.c'; then $(CYGPATH_W) 'autoroute.c'; else $(CYGPATH_W) '$(srcdir)/autoroute.c'; fi` pcb-buffer.o: buffer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-buffer.o -MD -MP -MF $(DEPDIR)/pcb-buffer.Tpo -c -o pcb-buffer.o `test -f 'buffer.c' || echo '$(srcdir)/'`buffer.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-buffer.Tpo $(DEPDIR)/pcb-buffer.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='buffer.c' object='pcb-buffer.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-buffer.o `test -f 'buffer.c' || echo '$(srcdir)/'`buffer.c pcb-buffer.obj: buffer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-buffer.obj -MD -MP -MF $(DEPDIR)/pcb-buffer.Tpo -c -o pcb-buffer.obj `if test -f 'buffer.c'; then $(CYGPATH_W) 'buffer.c'; else $(CYGPATH_W) '$(srcdir)/buffer.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-buffer.Tpo $(DEPDIR)/pcb-buffer.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='buffer.c' object='pcb-buffer.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-buffer.obj `if test -f 'buffer.c'; then $(CYGPATH_W) 'buffer.c'; else $(CYGPATH_W) '$(srcdir)/buffer.c'; fi` pcb-change.o: change.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-change.o -MD -MP -MF $(DEPDIR)/pcb-change.Tpo -c -o pcb-change.o `test -f 'change.c' || echo '$(srcdir)/'`change.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-change.Tpo $(DEPDIR)/pcb-change.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='change.c' object='pcb-change.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-change.o `test -f 'change.c' || echo '$(srcdir)/'`change.c pcb-change.obj: change.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-change.obj -MD -MP -MF $(DEPDIR)/pcb-change.Tpo -c -o pcb-change.obj `if test -f 'change.c'; then $(CYGPATH_W) 'change.c'; else $(CYGPATH_W) '$(srcdir)/change.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-change.Tpo $(DEPDIR)/pcb-change.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='change.c' object='pcb-change.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-change.obj `if test -f 'change.c'; then $(CYGPATH_W) 'change.c'; else $(CYGPATH_W) '$(srcdir)/change.c'; fi` pcb-clip.o: clip.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-clip.o -MD -MP -MF $(DEPDIR)/pcb-clip.Tpo -c -o pcb-clip.o `test -f 'clip.c' || echo '$(srcdir)/'`clip.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-clip.Tpo $(DEPDIR)/pcb-clip.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clip.c' object='pcb-clip.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-clip.o `test -f 'clip.c' || echo '$(srcdir)/'`clip.c pcb-clip.obj: clip.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-clip.obj -MD -MP -MF $(DEPDIR)/pcb-clip.Tpo -c -o pcb-clip.obj `if test -f 'clip.c'; then $(CYGPATH_W) 'clip.c'; else $(CYGPATH_W) '$(srcdir)/clip.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-clip.Tpo $(DEPDIR)/pcb-clip.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clip.c' object='pcb-clip.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-clip.obj `if test -f 'clip.c'; then $(CYGPATH_W) 'clip.c'; else $(CYGPATH_W) '$(srcdir)/clip.c'; fi` pcb-compat.o: compat.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-compat.o -MD -MP -MF $(DEPDIR)/pcb-compat.Tpo -c -o pcb-compat.o `test -f 'compat.c' || echo '$(srcdir)/'`compat.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-compat.Tpo $(DEPDIR)/pcb-compat.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='compat.c' object='pcb-compat.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-compat.o `test -f 'compat.c' || echo '$(srcdir)/'`compat.c pcb-compat.obj: compat.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-compat.obj -MD -MP -MF $(DEPDIR)/pcb-compat.Tpo -c -o pcb-compat.obj `if test -f 'compat.c'; then $(CYGPATH_W) 'compat.c'; else $(CYGPATH_W) '$(srcdir)/compat.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-compat.Tpo $(DEPDIR)/pcb-compat.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='compat.c' object='pcb-compat.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-compat.obj `if test -f 'compat.c'; then $(CYGPATH_W) 'compat.c'; else $(CYGPATH_W) '$(srcdir)/compat.c'; fi` pcb-copy.o: copy.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-copy.o -MD -MP -MF $(DEPDIR)/pcb-copy.Tpo -c -o pcb-copy.o `test -f 'copy.c' || echo '$(srcdir)/'`copy.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-copy.Tpo $(DEPDIR)/pcb-copy.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='copy.c' object='pcb-copy.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-copy.o `test -f 'copy.c' || echo '$(srcdir)/'`copy.c pcb-copy.obj: copy.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-copy.obj -MD -MP -MF $(DEPDIR)/pcb-copy.Tpo -c -o pcb-copy.obj `if test -f 'copy.c'; then $(CYGPATH_W) 'copy.c'; else $(CYGPATH_W) '$(srcdir)/copy.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-copy.Tpo $(DEPDIR)/pcb-copy.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='copy.c' object='pcb-copy.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-copy.obj `if test -f 'copy.c'; then $(CYGPATH_W) 'copy.c'; else $(CYGPATH_W) '$(srcdir)/copy.c'; fi` pcb-create.o: create.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-create.o -MD -MP -MF $(DEPDIR)/pcb-create.Tpo -c -o pcb-create.o `test -f 'create.c' || echo '$(srcdir)/'`create.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-create.Tpo $(DEPDIR)/pcb-create.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='create.c' object='pcb-create.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-create.o `test -f 'create.c' || echo '$(srcdir)/'`create.c pcb-create.obj: create.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-create.obj -MD -MP -MF $(DEPDIR)/pcb-create.Tpo -c -o pcb-create.obj `if test -f 'create.c'; then $(CYGPATH_W) 'create.c'; else $(CYGPATH_W) '$(srcdir)/create.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-create.Tpo $(DEPDIR)/pcb-create.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='create.c' object='pcb-create.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-create.obj `if test -f 'create.c'; then $(CYGPATH_W) 'create.c'; else $(CYGPATH_W) '$(srcdir)/create.c'; fi` pcb-crosshair.o: crosshair.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-crosshair.o -MD -MP -MF $(DEPDIR)/pcb-crosshair.Tpo -c -o pcb-crosshair.o `test -f 'crosshair.c' || echo '$(srcdir)/'`crosshair.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-crosshair.Tpo $(DEPDIR)/pcb-crosshair.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='crosshair.c' object='pcb-crosshair.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-crosshair.o `test -f 'crosshair.c' || echo '$(srcdir)/'`crosshair.c pcb-crosshair.obj: crosshair.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-crosshair.obj -MD -MP -MF $(DEPDIR)/pcb-crosshair.Tpo -c -o pcb-crosshair.obj `if test -f 'crosshair.c'; then $(CYGPATH_W) 'crosshair.c'; else $(CYGPATH_W) '$(srcdir)/crosshair.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-crosshair.Tpo $(DEPDIR)/pcb-crosshair.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='crosshair.c' object='pcb-crosshair.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-crosshair.obj `if test -f 'crosshair.c'; then $(CYGPATH_W) 'crosshair.c'; else $(CYGPATH_W) '$(srcdir)/crosshair.c'; fi` pcb-data.o: data.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-data.o -MD -MP -MF $(DEPDIR)/pcb-data.Tpo -c -o pcb-data.o `test -f 'data.c' || echo '$(srcdir)/'`data.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-data.Tpo $(DEPDIR)/pcb-data.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='data.c' object='pcb-data.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-data.o `test -f 'data.c' || echo '$(srcdir)/'`data.c pcb-data.obj: data.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-data.obj -MD -MP -MF $(DEPDIR)/pcb-data.Tpo -c -o pcb-data.obj `if test -f 'data.c'; then $(CYGPATH_W) 'data.c'; else $(CYGPATH_W) '$(srcdir)/data.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-data.Tpo $(DEPDIR)/pcb-data.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='data.c' object='pcb-data.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-data.obj `if test -f 'data.c'; then $(CYGPATH_W) 'data.c'; else $(CYGPATH_W) '$(srcdir)/data.c'; fi` pcb-djopt.o: djopt.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-djopt.o -MD -MP -MF $(DEPDIR)/pcb-djopt.Tpo -c -o pcb-djopt.o `test -f 'djopt.c' || echo '$(srcdir)/'`djopt.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-djopt.Tpo $(DEPDIR)/pcb-djopt.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='djopt.c' object='pcb-djopt.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-djopt.o `test -f 'djopt.c' || echo '$(srcdir)/'`djopt.c pcb-djopt.obj: djopt.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-djopt.obj -MD -MP -MF $(DEPDIR)/pcb-djopt.Tpo -c -o pcb-djopt.obj `if test -f 'djopt.c'; then $(CYGPATH_W) 'djopt.c'; else $(CYGPATH_W) '$(srcdir)/djopt.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-djopt.Tpo $(DEPDIR)/pcb-djopt.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='djopt.c' object='pcb-djopt.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-djopt.obj `if test -f 'djopt.c'; then $(CYGPATH_W) 'djopt.c'; else $(CYGPATH_W) '$(srcdir)/djopt.c'; fi` pcb-draw.o: draw.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-draw.o -MD -MP -MF $(DEPDIR)/pcb-draw.Tpo -c -o pcb-draw.o `test -f 'draw.c' || echo '$(srcdir)/'`draw.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-draw.Tpo $(DEPDIR)/pcb-draw.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='draw.c' object='pcb-draw.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-draw.o `test -f 'draw.c' || echo '$(srcdir)/'`draw.c pcb-draw.obj: draw.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-draw.obj -MD -MP -MF $(DEPDIR)/pcb-draw.Tpo -c -o pcb-draw.obj `if test -f 'draw.c'; then $(CYGPATH_W) 'draw.c'; else $(CYGPATH_W) '$(srcdir)/draw.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-draw.Tpo $(DEPDIR)/pcb-draw.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='draw.c' object='pcb-draw.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-draw.obj `if test -f 'draw.c'; then $(CYGPATH_W) 'draw.c'; else $(CYGPATH_W) '$(srcdir)/draw.c'; fi` pcb-drill.o: drill.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-drill.o -MD -MP -MF $(DEPDIR)/pcb-drill.Tpo -c -o pcb-drill.o `test -f 'drill.c' || echo '$(srcdir)/'`drill.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-drill.Tpo $(DEPDIR)/pcb-drill.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='drill.c' object='pcb-drill.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-drill.o `test -f 'drill.c' || echo '$(srcdir)/'`drill.c pcb-drill.obj: drill.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-drill.obj -MD -MP -MF $(DEPDIR)/pcb-drill.Tpo -c -o pcb-drill.obj `if test -f 'drill.c'; then $(CYGPATH_W) 'drill.c'; else $(CYGPATH_W) '$(srcdir)/drill.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-drill.Tpo $(DEPDIR)/pcb-drill.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='drill.c' object='pcb-drill.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-drill.obj `if test -f 'drill.c'; then $(CYGPATH_W) 'drill.c'; else $(CYGPATH_W) '$(srcdir)/drill.c'; fi` pcb-edif.o: edif.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-edif.o -MD -MP -MF $(DEPDIR)/pcb-edif.Tpo -c -o pcb-edif.o `test -f 'edif.c' || echo '$(srcdir)/'`edif.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-edif.Tpo $(DEPDIR)/pcb-edif.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='edif.c' object='pcb-edif.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-edif.o `test -f 'edif.c' || echo '$(srcdir)/'`edif.c pcb-edif.obj: edif.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-edif.obj -MD -MP -MF $(DEPDIR)/pcb-edif.Tpo -c -o pcb-edif.obj `if test -f 'edif.c'; then $(CYGPATH_W) 'edif.c'; else $(CYGPATH_W) '$(srcdir)/edif.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-edif.Tpo $(DEPDIR)/pcb-edif.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='edif.c' object='pcb-edif.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-edif.obj `if test -f 'edif.c'; then $(CYGPATH_W) 'edif.c'; else $(CYGPATH_W) '$(srcdir)/edif.c'; fi` pcb-error.o: error.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-error.o -MD -MP -MF $(DEPDIR)/pcb-error.Tpo -c -o pcb-error.o `test -f 'error.c' || echo '$(srcdir)/'`error.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-error.Tpo $(DEPDIR)/pcb-error.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='error.c' object='pcb-error.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-error.o `test -f 'error.c' || echo '$(srcdir)/'`error.c pcb-error.obj: error.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-error.obj -MD -MP -MF $(DEPDIR)/pcb-error.Tpo -c -o pcb-error.obj `if test -f 'error.c'; then $(CYGPATH_W) 'error.c'; else $(CYGPATH_W) '$(srcdir)/error.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-error.Tpo $(DEPDIR)/pcb-error.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='error.c' object='pcb-error.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-error.obj `if test -f 'error.c'; then $(CYGPATH_W) 'error.c'; else $(CYGPATH_W) '$(srcdir)/error.c'; fi` pcb-file.o: file.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-file.o -MD -MP -MF $(DEPDIR)/pcb-file.Tpo -c -o pcb-file.o `test -f 'file.c' || echo '$(srcdir)/'`file.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-file.Tpo $(DEPDIR)/pcb-file.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='file.c' object='pcb-file.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-file.o `test -f 'file.c' || echo '$(srcdir)/'`file.c pcb-file.obj: file.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-file.obj -MD -MP -MF $(DEPDIR)/pcb-file.Tpo -c -o pcb-file.obj `if test -f 'file.c'; then $(CYGPATH_W) 'file.c'; else $(CYGPATH_W) '$(srcdir)/file.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-file.Tpo $(DEPDIR)/pcb-file.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='file.c' object='pcb-file.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-file.obj `if test -f 'file.c'; then $(CYGPATH_W) 'file.c'; else $(CYGPATH_W) '$(srcdir)/file.c'; fi` pcb-find.o: find.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-find.o -MD -MP -MF $(DEPDIR)/pcb-find.Tpo -c -o pcb-find.o `test -f 'find.c' || echo '$(srcdir)/'`find.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-find.Tpo $(DEPDIR)/pcb-find.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='find.c' object='pcb-find.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-find.o `test -f 'find.c' || echo '$(srcdir)/'`find.c pcb-find.obj: find.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-find.obj -MD -MP -MF $(DEPDIR)/pcb-find.Tpo -c -o pcb-find.obj `if test -f 'find.c'; then $(CYGPATH_W) 'find.c'; else $(CYGPATH_W) '$(srcdir)/find.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-find.Tpo $(DEPDIR)/pcb-find.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='find.c' object='pcb-find.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-find.obj `if test -f 'find.c'; then $(CYGPATH_W) 'find.c'; else $(CYGPATH_W) '$(srcdir)/find.c'; fi` pcb-flags.o: flags.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-flags.o -MD -MP -MF $(DEPDIR)/pcb-flags.Tpo -c -o pcb-flags.o `test -f 'flags.c' || echo '$(srcdir)/'`flags.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-flags.Tpo $(DEPDIR)/pcb-flags.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='flags.c' object='pcb-flags.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-flags.o `test -f 'flags.c' || echo '$(srcdir)/'`flags.c pcb-flags.obj: flags.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-flags.obj -MD -MP -MF $(DEPDIR)/pcb-flags.Tpo -c -o pcb-flags.obj `if test -f 'flags.c'; then $(CYGPATH_W) 'flags.c'; else $(CYGPATH_W) '$(srcdir)/flags.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-flags.Tpo $(DEPDIR)/pcb-flags.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='flags.c' object='pcb-flags.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-flags.obj `if test -f 'flags.c'; then $(CYGPATH_W) 'flags.c'; else $(CYGPATH_W) '$(srcdir)/flags.c'; fi` pcb-fontmode.o: fontmode.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-fontmode.o -MD -MP -MF $(DEPDIR)/pcb-fontmode.Tpo -c -o pcb-fontmode.o `test -f 'fontmode.c' || echo '$(srcdir)/'`fontmode.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-fontmode.Tpo $(DEPDIR)/pcb-fontmode.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fontmode.c' object='pcb-fontmode.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-fontmode.o `test -f 'fontmode.c' || echo '$(srcdir)/'`fontmode.c pcb-fontmode.obj: fontmode.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-fontmode.obj -MD -MP -MF $(DEPDIR)/pcb-fontmode.Tpo -c -o pcb-fontmode.obj `if test -f 'fontmode.c'; then $(CYGPATH_W) 'fontmode.c'; else $(CYGPATH_W) '$(srcdir)/fontmode.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-fontmode.Tpo $(DEPDIR)/pcb-fontmode.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fontmode.c' object='pcb-fontmode.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-fontmode.obj `if test -f 'fontmode.c'; then $(CYGPATH_W) 'fontmode.c'; else $(CYGPATH_W) '$(srcdir)/fontmode.c'; fi` pcb-free_atexit.o: free_atexit.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-free_atexit.o -MD -MP -MF $(DEPDIR)/pcb-free_atexit.Tpo -c -o pcb-free_atexit.o `test -f 'free_atexit.c' || echo '$(srcdir)/'`free_atexit.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-free_atexit.Tpo $(DEPDIR)/pcb-free_atexit.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='free_atexit.c' object='pcb-free_atexit.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-free_atexit.o `test -f 'free_atexit.c' || echo '$(srcdir)/'`free_atexit.c pcb-free_atexit.obj: free_atexit.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-free_atexit.obj -MD -MP -MF $(DEPDIR)/pcb-free_atexit.Tpo -c -o pcb-free_atexit.obj `if test -f 'free_atexit.c'; then $(CYGPATH_W) 'free_atexit.c'; else $(CYGPATH_W) '$(srcdir)/free_atexit.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-free_atexit.Tpo $(DEPDIR)/pcb-free_atexit.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='free_atexit.c' object='pcb-free_atexit.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-free_atexit.obj `if test -f 'free_atexit.c'; then $(CYGPATH_W) 'free_atexit.c'; else $(CYGPATH_W) '$(srcdir)/free_atexit.c'; fi` pcb-getline.o: getline.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-getline.o -MD -MP -MF $(DEPDIR)/pcb-getline.Tpo -c -o pcb-getline.o `test -f 'getline.c' || echo '$(srcdir)/'`getline.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-getline.Tpo $(DEPDIR)/pcb-getline.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getline.c' object='pcb-getline.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-getline.o `test -f 'getline.c' || echo '$(srcdir)/'`getline.c pcb-getline.obj: getline.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-getline.obj -MD -MP -MF $(DEPDIR)/pcb-getline.Tpo -c -o pcb-getline.obj `if test -f 'getline.c'; then $(CYGPATH_W) 'getline.c'; else $(CYGPATH_W) '$(srcdir)/getline.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-getline.Tpo $(DEPDIR)/pcb-getline.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getline.c' object='pcb-getline.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-getline.obj `if test -f 'getline.c'; then $(CYGPATH_W) 'getline.c'; else $(CYGPATH_W) '$(srcdir)/getline.c'; fi` pcb-heap.o: heap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-heap.o -MD -MP -MF $(DEPDIR)/pcb-heap.Tpo -c -o pcb-heap.o `test -f 'heap.c' || echo '$(srcdir)/'`heap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-heap.Tpo $(DEPDIR)/pcb-heap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='heap.c' object='pcb-heap.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-heap.o `test -f 'heap.c' || echo '$(srcdir)/'`heap.c pcb-heap.obj: heap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-heap.obj -MD -MP -MF $(DEPDIR)/pcb-heap.Tpo -c -o pcb-heap.obj `if test -f 'heap.c'; then $(CYGPATH_W) 'heap.c'; else $(CYGPATH_W) '$(srcdir)/heap.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-heap.Tpo $(DEPDIR)/pcb-heap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='heap.c' object='pcb-heap.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-heap.obj `if test -f 'heap.c'; then $(CYGPATH_W) 'heap.c'; else $(CYGPATH_W) '$(srcdir)/heap.c'; fi` pcb-insert.o: insert.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-insert.o -MD -MP -MF $(DEPDIR)/pcb-insert.Tpo -c -o pcb-insert.o `test -f 'insert.c' || echo '$(srcdir)/'`insert.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-insert.Tpo $(DEPDIR)/pcb-insert.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='insert.c' object='pcb-insert.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-insert.o `test -f 'insert.c' || echo '$(srcdir)/'`insert.c pcb-insert.obj: insert.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-insert.obj -MD -MP -MF $(DEPDIR)/pcb-insert.Tpo -c -o pcb-insert.obj `if test -f 'insert.c'; then $(CYGPATH_W) 'insert.c'; else $(CYGPATH_W) '$(srcdir)/insert.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-insert.Tpo $(DEPDIR)/pcb-insert.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='insert.c' object='pcb-insert.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-insert.obj `if test -f 'insert.c'; then $(CYGPATH_W) 'insert.c'; else $(CYGPATH_W) '$(srcdir)/insert.c'; fi` pcb-intersect.o: intersect.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-intersect.o -MD -MP -MF $(DEPDIR)/pcb-intersect.Tpo -c -o pcb-intersect.o `test -f 'intersect.c' || echo '$(srcdir)/'`intersect.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-intersect.Tpo $(DEPDIR)/pcb-intersect.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='intersect.c' object='pcb-intersect.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-intersect.o `test -f 'intersect.c' || echo '$(srcdir)/'`intersect.c pcb-intersect.obj: intersect.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-intersect.obj -MD -MP -MF $(DEPDIR)/pcb-intersect.Tpo -c -o pcb-intersect.obj `if test -f 'intersect.c'; then $(CYGPATH_W) 'intersect.c'; else $(CYGPATH_W) '$(srcdir)/intersect.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-intersect.Tpo $(DEPDIR)/pcb-intersect.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='intersect.c' object='pcb-intersect.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-intersect.obj `if test -f 'intersect.c'; then $(CYGPATH_W) 'intersect.c'; else $(CYGPATH_W) '$(srcdir)/intersect.c'; fi` pcb-layerflags.o: layerflags.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-layerflags.o -MD -MP -MF $(DEPDIR)/pcb-layerflags.Tpo -c -o pcb-layerflags.o `test -f 'layerflags.c' || echo '$(srcdir)/'`layerflags.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-layerflags.Tpo $(DEPDIR)/pcb-layerflags.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='layerflags.c' object='pcb-layerflags.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-layerflags.o `test -f 'layerflags.c' || echo '$(srcdir)/'`layerflags.c pcb-layerflags.obj: layerflags.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-layerflags.obj -MD -MP -MF $(DEPDIR)/pcb-layerflags.Tpo -c -o pcb-layerflags.obj `if test -f 'layerflags.c'; then $(CYGPATH_W) 'layerflags.c'; else $(CYGPATH_W) '$(srcdir)/layerflags.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-layerflags.Tpo $(DEPDIR)/pcb-layerflags.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='layerflags.c' object='pcb-layerflags.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-layerflags.obj `if test -f 'layerflags.c'; then $(CYGPATH_W) 'layerflags.c'; else $(CYGPATH_W) '$(srcdir)/layerflags.c'; fi` pcb-line.o: line.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-line.o -MD -MP -MF $(DEPDIR)/pcb-line.Tpo -c -o pcb-line.o `test -f 'line.c' || echo '$(srcdir)/'`line.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-line.Tpo $(DEPDIR)/pcb-line.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='line.c' object='pcb-line.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-line.o `test -f 'line.c' || echo '$(srcdir)/'`line.c pcb-line.obj: line.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-line.obj -MD -MP -MF $(DEPDIR)/pcb-line.Tpo -c -o pcb-line.obj `if test -f 'line.c'; then $(CYGPATH_W) 'line.c'; else $(CYGPATH_W) '$(srcdir)/line.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-line.Tpo $(DEPDIR)/pcb-line.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='line.c' object='pcb-line.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-line.obj `if test -f 'line.c'; then $(CYGPATH_W) 'line.c'; else $(CYGPATH_W) '$(srcdir)/line.c'; fi` pcb-lrealpath.o: lrealpath.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-lrealpath.o -MD -MP -MF $(DEPDIR)/pcb-lrealpath.Tpo -c -o pcb-lrealpath.o `test -f 'lrealpath.c' || echo '$(srcdir)/'`lrealpath.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-lrealpath.Tpo $(DEPDIR)/pcb-lrealpath.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lrealpath.c' object='pcb-lrealpath.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-lrealpath.o `test -f 'lrealpath.c' || echo '$(srcdir)/'`lrealpath.c pcb-lrealpath.obj: lrealpath.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-lrealpath.obj -MD -MP -MF $(DEPDIR)/pcb-lrealpath.Tpo -c -o pcb-lrealpath.obj `if test -f 'lrealpath.c'; then $(CYGPATH_W) 'lrealpath.c'; else $(CYGPATH_W) '$(srcdir)/lrealpath.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-lrealpath.Tpo $(DEPDIR)/pcb-lrealpath.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lrealpath.c' object='pcb-lrealpath.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-lrealpath.obj `if test -f 'lrealpath.c'; then $(CYGPATH_W) 'lrealpath.c'; else $(CYGPATH_W) '$(srcdir)/lrealpath.c'; fi` pcb-main.o: main.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-main.o -MD -MP -MF $(DEPDIR)/pcb-main.Tpo -c -o pcb-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-main.Tpo $(DEPDIR)/pcb-main.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='main.c' object='pcb-main.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c pcb-main.obj: main.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-main.obj -MD -MP -MF $(DEPDIR)/pcb-main.Tpo -c -o pcb-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-main.Tpo $(DEPDIR)/pcb-main.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='main.c' object='pcb-main.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi` pcb-mirror.o: mirror.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-mirror.o -MD -MP -MF $(DEPDIR)/pcb-mirror.Tpo -c -o pcb-mirror.o `test -f 'mirror.c' || echo '$(srcdir)/'`mirror.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-mirror.Tpo $(DEPDIR)/pcb-mirror.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mirror.c' object='pcb-mirror.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-mirror.o `test -f 'mirror.c' || echo '$(srcdir)/'`mirror.c pcb-mirror.obj: mirror.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-mirror.obj -MD -MP -MF $(DEPDIR)/pcb-mirror.Tpo -c -o pcb-mirror.obj `if test -f 'mirror.c'; then $(CYGPATH_W) 'mirror.c'; else $(CYGPATH_W) '$(srcdir)/mirror.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-mirror.Tpo $(DEPDIR)/pcb-mirror.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mirror.c' object='pcb-mirror.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-mirror.obj `if test -f 'mirror.c'; then $(CYGPATH_W) 'mirror.c'; else $(CYGPATH_W) '$(srcdir)/mirror.c'; fi` pcb-misc.o: misc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-misc.o -MD -MP -MF $(DEPDIR)/pcb-misc.Tpo -c -o pcb-misc.o `test -f 'misc.c' || echo '$(srcdir)/'`misc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-misc.Tpo $(DEPDIR)/pcb-misc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='misc.c' object='pcb-misc.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-misc.o `test -f 'misc.c' || echo '$(srcdir)/'`misc.c pcb-misc.obj: misc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-misc.obj -MD -MP -MF $(DEPDIR)/pcb-misc.Tpo -c -o pcb-misc.obj `if test -f 'misc.c'; then $(CYGPATH_W) 'misc.c'; else $(CYGPATH_W) '$(srcdir)/misc.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-misc.Tpo $(DEPDIR)/pcb-misc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='misc.c' object='pcb-misc.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-misc.obj `if test -f 'misc.c'; then $(CYGPATH_W) 'misc.c'; else $(CYGPATH_W) '$(srcdir)/misc.c'; fi` pcb-move.o: move.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-move.o -MD -MP -MF $(DEPDIR)/pcb-move.Tpo -c -o pcb-move.o `test -f 'move.c' || echo '$(srcdir)/'`move.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-move.Tpo $(DEPDIR)/pcb-move.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='move.c' object='pcb-move.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-move.o `test -f 'move.c' || echo '$(srcdir)/'`move.c pcb-move.obj: move.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-move.obj -MD -MP -MF $(DEPDIR)/pcb-move.Tpo -c -o pcb-move.obj `if test -f 'move.c'; then $(CYGPATH_W) 'move.c'; else $(CYGPATH_W) '$(srcdir)/move.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-move.Tpo $(DEPDIR)/pcb-move.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='move.c' object='pcb-move.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-move.obj `if test -f 'move.c'; then $(CYGPATH_W) 'move.c'; else $(CYGPATH_W) '$(srcdir)/move.c'; fi` pcb-mtspace.o: mtspace.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-mtspace.o -MD -MP -MF $(DEPDIR)/pcb-mtspace.Tpo -c -o pcb-mtspace.o `test -f 'mtspace.c' || echo '$(srcdir)/'`mtspace.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-mtspace.Tpo $(DEPDIR)/pcb-mtspace.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mtspace.c' object='pcb-mtspace.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-mtspace.o `test -f 'mtspace.c' || echo '$(srcdir)/'`mtspace.c pcb-mtspace.obj: mtspace.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-mtspace.obj -MD -MP -MF $(DEPDIR)/pcb-mtspace.Tpo -c -o pcb-mtspace.obj `if test -f 'mtspace.c'; then $(CYGPATH_W) 'mtspace.c'; else $(CYGPATH_W) '$(srcdir)/mtspace.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-mtspace.Tpo $(DEPDIR)/pcb-mtspace.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mtspace.c' object='pcb-mtspace.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-mtspace.obj `if test -f 'mtspace.c'; then $(CYGPATH_W) 'mtspace.c'; else $(CYGPATH_W) '$(srcdir)/mtspace.c'; fi` pcb-mymem.o: mymem.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-mymem.o -MD -MP -MF $(DEPDIR)/pcb-mymem.Tpo -c -o pcb-mymem.o `test -f 'mymem.c' || echo '$(srcdir)/'`mymem.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-mymem.Tpo $(DEPDIR)/pcb-mymem.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mymem.c' object='pcb-mymem.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-mymem.o `test -f 'mymem.c' || echo '$(srcdir)/'`mymem.c pcb-mymem.obj: mymem.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-mymem.obj -MD -MP -MF $(DEPDIR)/pcb-mymem.Tpo -c -o pcb-mymem.obj `if test -f 'mymem.c'; then $(CYGPATH_W) 'mymem.c'; else $(CYGPATH_W) '$(srcdir)/mymem.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-mymem.Tpo $(DEPDIR)/pcb-mymem.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mymem.c' object='pcb-mymem.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-mymem.obj `if test -f 'mymem.c'; then $(CYGPATH_W) 'mymem.c'; else $(CYGPATH_W) '$(srcdir)/mymem.c'; fi` pcb-netlist.o: netlist.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-netlist.o -MD -MP -MF $(DEPDIR)/pcb-netlist.Tpo -c -o pcb-netlist.o `test -f 'netlist.c' || echo '$(srcdir)/'`netlist.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-netlist.Tpo $(DEPDIR)/pcb-netlist.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlist.c' object='pcb-netlist.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-netlist.o `test -f 'netlist.c' || echo '$(srcdir)/'`netlist.c pcb-netlist.obj: netlist.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-netlist.obj -MD -MP -MF $(DEPDIR)/pcb-netlist.Tpo -c -o pcb-netlist.obj `if test -f 'netlist.c'; then $(CYGPATH_W) 'netlist.c'; else $(CYGPATH_W) '$(srcdir)/netlist.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-netlist.Tpo $(DEPDIR)/pcb-netlist.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netlist.c' object='pcb-netlist.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-netlist.obj `if test -f 'netlist.c'; then $(CYGPATH_W) 'netlist.c'; else $(CYGPATH_W) '$(srcdir)/netlist.c'; fi` pcb-object_list.o: object_list.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-object_list.o -MD -MP -MF $(DEPDIR)/pcb-object_list.Tpo -c -o pcb-object_list.o `test -f 'object_list.c' || echo '$(srcdir)/'`object_list.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-object_list.Tpo $(DEPDIR)/pcb-object_list.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='object_list.c' object='pcb-object_list.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-object_list.o `test -f 'object_list.c' || echo '$(srcdir)/'`object_list.c pcb-object_list.obj: object_list.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-object_list.obj -MD -MP -MF $(DEPDIR)/pcb-object_list.Tpo -c -o pcb-object_list.obj `if test -f 'object_list.c'; then $(CYGPATH_W) 'object_list.c'; else $(CYGPATH_W) '$(srcdir)/object_list.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-object_list.Tpo $(DEPDIR)/pcb-object_list.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='object_list.c' object='pcb-object_list.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-object_list.obj `if test -f 'object_list.c'; then $(CYGPATH_W) 'object_list.c'; else $(CYGPATH_W) '$(srcdir)/object_list.c'; fi` pcb-parse_l.o: parse_l.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-parse_l.o -MD -MP -MF $(DEPDIR)/pcb-parse_l.Tpo -c -o pcb-parse_l.o `test -f 'parse_l.c' || echo '$(srcdir)/'`parse_l.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-parse_l.Tpo $(DEPDIR)/pcb-parse_l.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='parse_l.c' object='pcb-parse_l.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-parse_l.o `test -f 'parse_l.c' || echo '$(srcdir)/'`parse_l.c pcb-parse_l.obj: parse_l.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-parse_l.obj -MD -MP -MF $(DEPDIR)/pcb-parse_l.Tpo -c -o pcb-parse_l.obj `if test -f 'parse_l.c'; then $(CYGPATH_W) 'parse_l.c'; else $(CYGPATH_W) '$(srcdir)/parse_l.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-parse_l.Tpo $(DEPDIR)/pcb-parse_l.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='parse_l.c' object='pcb-parse_l.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-parse_l.obj `if test -f 'parse_l.c'; then $(CYGPATH_W) 'parse_l.c'; else $(CYGPATH_W) '$(srcdir)/parse_l.c'; fi` pcb-parse_y.o: parse_y.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-parse_y.o -MD -MP -MF $(DEPDIR)/pcb-parse_y.Tpo -c -o pcb-parse_y.o `test -f 'parse_y.c' || echo '$(srcdir)/'`parse_y.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-parse_y.Tpo $(DEPDIR)/pcb-parse_y.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='parse_y.c' object='pcb-parse_y.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-parse_y.o `test -f 'parse_y.c' || echo '$(srcdir)/'`parse_y.c pcb-parse_y.obj: parse_y.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-parse_y.obj -MD -MP -MF $(DEPDIR)/pcb-parse_y.Tpo -c -o pcb-parse_y.obj `if test -f 'parse_y.c'; then $(CYGPATH_W) 'parse_y.c'; else $(CYGPATH_W) '$(srcdir)/parse_y.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-parse_y.Tpo $(DEPDIR)/pcb-parse_y.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='parse_y.c' object='pcb-parse_y.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-parse_y.obj `if test -f 'parse_y.c'; then $(CYGPATH_W) 'parse_y.c'; else $(CYGPATH_W) '$(srcdir)/parse_y.c'; fi` pcb-pcb-printf.o: pcb-printf.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-pcb-printf.o -MD -MP -MF $(DEPDIR)/pcb-pcb-printf.Tpo -c -o pcb-pcb-printf.o `test -f 'pcb-printf.c' || echo '$(srcdir)/'`pcb-printf.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-pcb-printf.Tpo $(DEPDIR)/pcb-pcb-printf.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcb-printf.c' object='pcb-pcb-printf.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-pcb-printf.o `test -f 'pcb-printf.c' || echo '$(srcdir)/'`pcb-printf.c pcb-pcb-printf.obj: pcb-printf.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-pcb-printf.obj -MD -MP -MF $(DEPDIR)/pcb-pcb-printf.Tpo -c -o pcb-pcb-printf.obj `if test -f 'pcb-printf.c'; then $(CYGPATH_W) 'pcb-printf.c'; else $(CYGPATH_W) '$(srcdir)/pcb-printf.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-pcb-printf.Tpo $(DEPDIR)/pcb-pcb-printf.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcb-printf.c' object='pcb-pcb-printf.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-pcb-printf.obj `if test -f 'pcb-printf.c'; then $(CYGPATH_W) 'pcb-printf.c'; else $(CYGPATH_W) '$(srcdir)/pcb-printf.c'; fi` pcb-polygon.o: polygon.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-polygon.o -MD -MP -MF $(DEPDIR)/pcb-polygon.Tpo -c -o pcb-polygon.o `test -f 'polygon.c' || echo '$(srcdir)/'`polygon.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-polygon.Tpo $(DEPDIR)/pcb-polygon.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='polygon.c' object='pcb-polygon.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-polygon.o `test -f 'polygon.c' || echo '$(srcdir)/'`polygon.c pcb-polygon.obj: polygon.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-polygon.obj -MD -MP -MF $(DEPDIR)/pcb-polygon.Tpo -c -o pcb-polygon.obj `if test -f 'polygon.c'; then $(CYGPATH_W) 'polygon.c'; else $(CYGPATH_W) '$(srcdir)/polygon.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-polygon.Tpo $(DEPDIR)/pcb-polygon.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='polygon.c' object='pcb-polygon.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-polygon.obj `if test -f 'polygon.c'; then $(CYGPATH_W) 'polygon.c'; else $(CYGPATH_W) '$(srcdir)/polygon.c'; fi` pcb-polygon1.o: polygon1.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-polygon1.o -MD -MP -MF $(DEPDIR)/pcb-polygon1.Tpo -c -o pcb-polygon1.o `test -f 'polygon1.c' || echo '$(srcdir)/'`polygon1.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-polygon1.Tpo $(DEPDIR)/pcb-polygon1.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='polygon1.c' object='pcb-polygon1.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-polygon1.o `test -f 'polygon1.c' || echo '$(srcdir)/'`polygon1.c pcb-polygon1.obj: polygon1.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-polygon1.obj -MD -MP -MF $(DEPDIR)/pcb-polygon1.Tpo -c -o pcb-polygon1.obj `if test -f 'polygon1.c'; then $(CYGPATH_W) 'polygon1.c'; else $(CYGPATH_W) '$(srcdir)/polygon1.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-polygon1.Tpo $(DEPDIR)/pcb-polygon1.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='polygon1.c' object='pcb-polygon1.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-polygon1.obj `if test -f 'polygon1.c'; then $(CYGPATH_W) 'polygon1.c'; else $(CYGPATH_W) '$(srcdir)/polygon1.c'; fi` pcb-puller.o: puller.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-puller.o -MD -MP -MF $(DEPDIR)/pcb-puller.Tpo -c -o pcb-puller.o `test -f 'puller.c' || echo '$(srcdir)/'`puller.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-puller.Tpo $(DEPDIR)/pcb-puller.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='puller.c' object='pcb-puller.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-puller.o `test -f 'puller.c' || echo '$(srcdir)/'`puller.c pcb-puller.obj: puller.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-puller.obj -MD -MP -MF $(DEPDIR)/pcb-puller.Tpo -c -o pcb-puller.obj `if test -f 'puller.c'; then $(CYGPATH_W) 'puller.c'; else $(CYGPATH_W) '$(srcdir)/puller.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-puller.Tpo $(DEPDIR)/pcb-puller.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='puller.c' object='pcb-puller.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-puller.obj `if test -f 'puller.c'; then $(CYGPATH_W) 'puller.c'; else $(CYGPATH_W) '$(srcdir)/puller.c'; fi` pcb-print.o: print.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-print.o -MD -MP -MF $(DEPDIR)/pcb-print.Tpo -c -o pcb-print.o `test -f 'print.c' || echo '$(srcdir)/'`print.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-print.Tpo $(DEPDIR)/pcb-print.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print.c' object='pcb-print.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-print.o `test -f 'print.c' || echo '$(srcdir)/'`print.c pcb-print.obj: print.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-print.obj -MD -MP -MF $(DEPDIR)/pcb-print.Tpo -c -o pcb-print.obj `if test -f 'print.c'; then $(CYGPATH_W) 'print.c'; else $(CYGPATH_W) '$(srcdir)/print.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-print.Tpo $(DEPDIR)/pcb-print.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print.c' object='pcb-print.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-print.obj `if test -f 'print.c'; then $(CYGPATH_W) 'print.c'; else $(CYGPATH_W) '$(srcdir)/print.c'; fi` pcb-rats.o: rats.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-rats.o -MD -MP -MF $(DEPDIR)/pcb-rats.Tpo -c -o pcb-rats.o `test -f 'rats.c' || echo '$(srcdir)/'`rats.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-rats.Tpo $(DEPDIR)/pcb-rats.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rats.c' object='pcb-rats.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-rats.o `test -f 'rats.c' || echo '$(srcdir)/'`rats.c pcb-rats.obj: rats.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-rats.obj -MD -MP -MF $(DEPDIR)/pcb-rats.Tpo -c -o pcb-rats.obj `if test -f 'rats.c'; then $(CYGPATH_W) 'rats.c'; else $(CYGPATH_W) '$(srcdir)/rats.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-rats.Tpo $(DEPDIR)/pcb-rats.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rats.c' object='pcb-rats.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-rats.obj `if test -f 'rats.c'; then $(CYGPATH_W) 'rats.c'; else $(CYGPATH_W) '$(srcdir)/rats.c'; fi` pcb-relocate.o: relocate.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-relocate.o -MD -MP -MF $(DEPDIR)/pcb-relocate.Tpo -c -o pcb-relocate.o `test -f 'relocate.c' || echo '$(srcdir)/'`relocate.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-relocate.Tpo $(DEPDIR)/pcb-relocate.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='relocate.c' object='pcb-relocate.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-relocate.o `test -f 'relocate.c' || echo '$(srcdir)/'`relocate.c pcb-relocate.obj: relocate.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-relocate.obj -MD -MP -MF $(DEPDIR)/pcb-relocate.Tpo -c -o pcb-relocate.obj `if test -f 'relocate.c'; then $(CYGPATH_W) 'relocate.c'; else $(CYGPATH_W) '$(srcdir)/relocate.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-relocate.Tpo $(DEPDIR)/pcb-relocate.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='relocate.c' object='pcb-relocate.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-relocate.obj `if test -f 'relocate.c'; then $(CYGPATH_W) 'relocate.c'; else $(CYGPATH_W) '$(srcdir)/relocate.c'; fi` pcb-remove.o: remove.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-remove.o -MD -MP -MF $(DEPDIR)/pcb-remove.Tpo -c -o pcb-remove.o `test -f 'remove.c' || echo '$(srcdir)/'`remove.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-remove.Tpo $(DEPDIR)/pcb-remove.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='remove.c' object='pcb-remove.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-remove.o `test -f 'remove.c' || echo '$(srcdir)/'`remove.c pcb-remove.obj: remove.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-remove.obj -MD -MP -MF $(DEPDIR)/pcb-remove.Tpo -c -o pcb-remove.obj `if test -f 'remove.c'; then $(CYGPATH_W) 'remove.c'; else $(CYGPATH_W) '$(srcdir)/remove.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-remove.Tpo $(DEPDIR)/pcb-remove.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='remove.c' object='pcb-remove.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-remove.obj `if test -f 'remove.c'; then $(CYGPATH_W) 'remove.c'; else $(CYGPATH_W) '$(srcdir)/remove.c'; fi` pcb-renumber.o: renumber.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-renumber.o -MD -MP -MF $(DEPDIR)/pcb-renumber.Tpo -c -o pcb-renumber.o `test -f 'renumber.c' || echo '$(srcdir)/'`renumber.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-renumber.Tpo $(DEPDIR)/pcb-renumber.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='renumber.c' object='pcb-renumber.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-renumber.o `test -f 'renumber.c' || echo '$(srcdir)/'`renumber.c pcb-renumber.obj: renumber.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-renumber.obj -MD -MP -MF $(DEPDIR)/pcb-renumber.Tpo -c -o pcb-renumber.obj `if test -f 'renumber.c'; then $(CYGPATH_W) 'renumber.c'; else $(CYGPATH_W) '$(srcdir)/renumber.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-renumber.Tpo $(DEPDIR)/pcb-renumber.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='renumber.c' object='pcb-renumber.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-renumber.obj `if test -f 'renumber.c'; then $(CYGPATH_W) 'renumber.c'; else $(CYGPATH_W) '$(srcdir)/renumber.c'; fi` pcb-report.o: report.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-report.o -MD -MP -MF $(DEPDIR)/pcb-report.Tpo -c -o pcb-report.o `test -f 'report.c' || echo '$(srcdir)/'`report.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-report.Tpo $(DEPDIR)/pcb-report.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='report.c' object='pcb-report.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-report.o `test -f 'report.c' || echo '$(srcdir)/'`report.c pcb-report.obj: report.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-report.obj -MD -MP -MF $(DEPDIR)/pcb-report.Tpo -c -o pcb-report.obj `if test -f 'report.c'; then $(CYGPATH_W) 'report.c'; else $(CYGPATH_W) '$(srcdir)/report.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-report.Tpo $(DEPDIR)/pcb-report.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='report.c' object='pcb-report.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-report.obj `if test -f 'report.c'; then $(CYGPATH_W) 'report.c'; else $(CYGPATH_W) '$(srcdir)/report.c'; fi` pcb-res_parse.o: res_parse.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-res_parse.o -MD -MP -MF $(DEPDIR)/pcb-res_parse.Tpo -c -o pcb-res_parse.o `test -f 'res_parse.c' || echo '$(srcdir)/'`res_parse.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-res_parse.Tpo $(DEPDIR)/pcb-res_parse.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='res_parse.c' object='pcb-res_parse.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-res_parse.o `test -f 'res_parse.c' || echo '$(srcdir)/'`res_parse.c pcb-res_parse.obj: res_parse.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-res_parse.obj -MD -MP -MF $(DEPDIR)/pcb-res_parse.Tpo -c -o pcb-res_parse.obj `if test -f 'res_parse.c'; then $(CYGPATH_W) 'res_parse.c'; else $(CYGPATH_W) '$(srcdir)/res_parse.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-res_parse.Tpo $(DEPDIR)/pcb-res_parse.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='res_parse.c' object='pcb-res_parse.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-res_parse.obj `if test -f 'res_parse.c'; then $(CYGPATH_W) 'res_parse.c'; else $(CYGPATH_W) '$(srcdir)/res_parse.c'; fi` pcb-res_lex.o: res_lex.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-res_lex.o -MD -MP -MF $(DEPDIR)/pcb-res_lex.Tpo -c -o pcb-res_lex.o `test -f 'res_lex.c' || echo '$(srcdir)/'`res_lex.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-res_lex.Tpo $(DEPDIR)/pcb-res_lex.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='res_lex.c' object='pcb-res_lex.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-res_lex.o `test -f 'res_lex.c' || echo '$(srcdir)/'`res_lex.c pcb-res_lex.obj: res_lex.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-res_lex.obj -MD -MP -MF $(DEPDIR)/pcb-res_lex.Tpo -c -o pcb-res_lex.obj `if test -f 'res_lex.c'; then $(CYGPATH_W) 'res_lex.c'; else $(CYGPATH_W) '$(srcdir)/res_lex.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-res_lex.Tpo $(DEPDIR)/pcb-res_lex.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='res_lex.c' object='pcb-res_lex.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-res_lex.obj `if test -f 'res_lex.c'; then $(CYGPATH_W) 'res_lex.c'; else $(CYGPATH_W) '$(srcdir)/res_lex.c'; fi` pcb-rotate.o: rotate.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-rotate.o -MD -MP -MF $(DEPDIR)/pcb-rotate.Tpo -c -o pcb-rotate.o `test -f 'rotate.c' || echo '$(srcdir)/'`rotate.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-rotate.Tpo $(DEPDIR)/pcb-rotate.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rotate.c' object='pcb-rotate.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-rotate.o `test -f 'rotate.c' || echo '$(srcdir)/'`rotate.c pcb-rotate.obj: rotate.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-rotate.obj -MD -MP -MF $(DEPDIR)/pcb-rotate.Tpo -c -o pcb-rotate.obj `if test -f 'rotate.c'; then $(CYGPATH_W) 'rotate.c'; else $(CYGPATH_W) '$(srcdir)/rotate.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-rotate.Tpo $(DEPDIR)/pcb-rotate.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rotate.c' object='pcb-rotate.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-rotate.obj `if test -f 'rotate.c'; then $(CYGPATH_W) 'rotate.c'; else $(CYGPATH_W) '$(srcdir)/rotate.c'; fi` pcb-rtree.o: rtree.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-rtree.o -MD -MP -MF $(DEPDIR)/pcb-rtree.Tpo -c -o pcb-rtree.o `test -f 'rtree.c' || echo '$(srcdir)/'`rtree.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-rtree.Tpo $(DEPDIR)/pcb-rtree.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rtree.c' object='pcb-rtree.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-rtree.o `test -f 'rtree.c' || echo '$(srcdir)/'`rtree.c pcb-rtree.obj: rtree.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-rtree.obj -MD -MP -MF $(DEPDIR)/pcb-rtree.Tpo -c -o pcb-rtree.obj `if test -f 'rtree.c'; then $(CYGPATH_W) 'rtree.c'; else $(CYGPATH_W) '$(srcdir)/rtree.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-rtree.Tpo $(DEPDIR)/pcb-rtree.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rtree.c' object='pcb-rtree.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-rtree.obj `if test -f 'rtree.c'; then $(CYGPATH_W) 'rtree.c'; else $(CYGPATH_W) '$(srcdir)/rtree.c'; fi` pcb-rubberband.o: rubberband.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-rubberband.o -MD -MP -MF $(DEPDIR)/pcb-rubberband.Tpo -c -o pcb-rubberband.o `test -f 'rubberband.c' || echo '$(srcdir)/'`rubberband.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-rubberband.Tpo $(DEPDIR)/pcb-rubberband.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rubberband.c' object='pcb-rubberband.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-rubberband.o `test -f 'rubberband.c' || echo '$(srcdir)/'`rubberband.c pcb-rubberband.obj: rubberband.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-rubberband.obj -MD -MP -MF $(DEPDIR)/pcb-rubberband.Tpo -c -o pcb-rubberband.obj `if test -f 'rubberband.c'; then $(CYGPATH_W) 'rubberband.c'; else $(CYGPATH_W) '$(srcdir)/rubberband.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-rubberband.Tpo $(DEPDIR)/pcb-rubberband.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rubberband.c' object='pcb-rubberband.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-rubberband.obj `if test -f 'rubberband.c'; then $(CYGPATH_W) 'rubberband.c'; else $(CYGPATH_W) '$(srcdir)/rubberband.c'; fi` pcb-search.o: search.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-search.o -MD -MP -MF $(DEPDIR)/pcb-search.Tpo -c -o pcb-search.o `test -f 'search.c' || echo '$(srcdir)/'`search.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-search.Tpo $(DEPDIR)/pcb-search.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='search.c' object='pcb-search.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-search.o `test -f 'search.c' || echo '$(srcdir)/'`search.c pcb-search.obj: search.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-search.obj -MD -MP -MF $(DEPDIR)/pcb-search.Tpo -c -o pcb-search.obj `if test -f 'search.c'; then $(CYGPATH_W) 'search.c'; else $(CYGPATH_W) '$(srcdir)/search.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-search.Tpo $(DEPDIR)/pcb-search.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='search.c' object='pcb-search.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-search.obj `if test -f 'search.c'; then $(CYGPATH_W) 'search.c'; else $(CYGPATH_W) '$(srcdir)/search.c'; fi` pcb-select.o: select.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-select.o -MD -MP -MF $(DEPDIR)/pcb-select.Tpo -c -o pcb-select.o `test -f 'select.c' || echo '$(srcdir)/'`select.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-select.Tpo $(DEPDIR)/pcb-select.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='select.c' object='pcb-select.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-select.o `test -f 'select.c' || echo '$(srcdir)/'`select.c pcb-select.obj: select.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-select.obj -MD -MP -MF $(DEPDIR)/pcb-select.Tpo -c -o pcb-select.obj `if test -f 'select.c'; then $(CYGPATH_W) 'select.c'; else $(CYGPATH_W) '$(srcdir)/select.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-select.Tpo $(DEPDIR)/pcb-select.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='select.c' object='pcb-select.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-select.obj `if test -f 'select.c'; then $(CYGPATH_W) 'select.c'; else $(CYGPATH_W) '$(srcdir)/select.c'; fi` pcb-set.o: set.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-set.o -MD -MP -MF $(DEPDIR)/pcb-set.Tpo -c -o pcb-set.o `test -f 'set.c' || echo '$(srcdir)/'`set.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-set.Tpo $(DEPDIR)/pcb-set.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='set.c' object='pcb-set.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-set.o `test -f 'set.c' || echo '$(srcdir)/'`set.c pcb-set.obj: set.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-set.obj -MD -MP -MF $(DEPDIR)/pcb-set.Tpo -c -o pcb-set.obj `if test -f 'set.c'; then $(CYGPATH_W) 'set.c'; else $(CYGPATH_W) '$(srcdir)/set.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-set.Tpo $(DEPDIR)/pcb-set.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='set.c' object='pcb-set.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-set.obj `if test -f 'set.c'; then $(CYGPATH_W) 'set.c'; else $(CYGPATH_W) '$(srcdir)/set.c'; fi` pcb-smartdisperse.o: smartdisperse.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-smartdisperse.o -MD -MP -MF $(DEPDIR)/pcb-smartdisperse.Tpo -c -o pcb-smartdisperse.o `test -f 'smartdisperse.c' || echo '$(srcdir)/'`smartdisperse.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-smartdisperse.Tpo $(DEPDIR)/pcb-smartdisperse.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='smartdisperse.c' object='pcb-smartdisperse.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-smartdisperse.o `test -f 'smartdisperse.c' || echo '$(srcdir)/'`smartdisperse.c pcb-smartdisperse.obj: smartdisperse.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-smartdisperse.obj -MD -MP -MF $(DEPDIR)/pcb-smartdisperse.Tpo -c -o pcb-smartdisperse.obj `if test -f 'smartdisperse.c'; then $(CYGPATH_W) 'smartdisperse.c'; else $(CYGPATH_W) '$(srcdir)/smartdisperse.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-smartdisperse.Tpo $(DEPDIR)/pcb-smartdisperse.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='smartdisperse.c' object='pcb-smartdisperse.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-smartdisperse.obj `if test -f 'smartdisperse.c'; then $(CYGPATH_W) 'smartdisperse.c'; else $(CYGPATH_W) '$(srcdir)/smartdisperse.c'; fi` pcb-strcasestr.o: strcasestr.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-strcasestr.o -MD -MP -MF $(DEPDIR)/pcb-strcasestr.Tpo -c -o pcb-strcasestr.o `test -f 'strcasestr.c' || echo '$(srcdir)/'`strcasestr.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-strcasestr.Tpo $(DEPDIR)/pcb-strcasestr.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strcasestr.c' object='pcb-strcasestr.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-strcasestr.o `test -f 'strcasestr.c' || echo '$(srcdir)/'`strcasestr.c pcb-strcasestr.obj: strcasestr.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-strcasestr.obj -MD -MP -MF $(DEPDIR)/pcb-strcasestr.Tpo -c -o pcb-strcasestr.obj `if test -f 'strcasestr.c'; then $(CYGPATH_W) 'strcasestr.c'; else $(CYGPATH_W) '$(srcdir)/strcasestr.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-strcasestr.Tpo $(DEPDIR)/pcb-strcasestr.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strcasestr.c' object='pcb-strcasestr.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-strcasestr.obj `if test -f 'strcasestr.c'; then $(CYGPATH_W) 'strcasestr.c'; else $(CYGPATH_W) '$(srcdir)/strcasestr.c'; fi` pcb-strflags.o: strflags.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-strflags.o -MD -MP -MF $(DEPDIR)/pcb-strflags.Tpo -c -o pcb-strflags.o `test -f 'strflags.c' || echo '$(srcdir)/'`strflags.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-strflags.Tpo $(DEPDIR)/pcb-strflags.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strflags.c' object='pcb-strflags.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-strflags.o `test -f 'strflags.c' || echo '$(srcdir)/'`strflags.c pcb-strflags.obj: strflags.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-strflags.obj -MD -MP -MF $(DEPDIR)/pcb-strflags.Tpo -c -o pcb-strflags.obj `if test -f 'strflags.c'; then $(CYGPATH_W) 'strflags.c'; else $(CYGPATH_W) '$(srcdir)/strflags.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-strflags.Tpo $(DEPDIR)/pcb-strflags.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strflags.c' object='pcb-strflags.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-strflags.obj `if test -f 'strflags.c'; then $(CYGPATH_W) 'strflags.c'; else $(CYGPATH_W) '$(srcdir)/strflags.c'; fi` pcb-teardrops.o: teardrops.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-teardrops.o -MD -MP -MF $(DEPDIR)/pcb-teardrops.Tpo -c -o pcb-teardrops.o `test -f 'teardrops.c' || echo '$(srcdir)/'`teardrops.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-teardrops.Tpo $(DEPDIR)/pcb-teardrops.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='teardrops.c' object='pcb-teardrops.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-teardrops.o `test -f 'teardrops.c' || echo '$(srcdir)/'`teardrops.c pcb-teardrops.obj: teardrops.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-teardrops.obj -MD -MP -MF $(DEPDIR)/pcb-teardrops.Tpo -c -o pcb-teardrops.obj `if test -f 'teardrops.c'; then $(CYGPATH_W) 'teardrops.c'; else $(CYGPATH_W) '$(srcdir)/teardrops.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-teardrops.Tpo $(DEPDIR)/pcb-teardrops.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='teardrops.c' object='pcb-teardrops.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-teardrops.obj `if test -f 'teardrops.c'; then $(CYGPATH_W) 'teardrops.c'; else $(CYGPATH_W) '$(srcdir)/teardrops.c'; fi` pcb-thermal.o: thermal.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-thermal.o -MD -MP -MF $(DEPDIR)/pcb-thermal.Tpo -c -o pcb-thermal.o `test -f 'thermal.c' || echo '$(srcdir)/'`thermal.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-thermal.Tpo $(DEPDIR)/pcb-thermal.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='thermal.c' object='pcb-thermal.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-thermal.o `test -f 'thermal.c' || echo '$(srcdir)/'`thermal.c pcb-thermal.obj: thermal.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-thermal.obj -MD -MP -MF $(DEPDIR)/pcb-thermal.Tpo -c -o pcb-thermal.obj `if test -f 'thermal.c'; then $(CYGPATH_W) 'thermal.c'; else $(CYGPATH_W) '$(srcdir)/thermal.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-thermal.Tpo $(DEPDIR)/pcb-thermal.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='thermal.c' object='pcb-thermal.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-thermal.obj `if test -f 'thermal.c'; then $(CYGPATH_W) 'thermal.c'; else $(CYGPATH_W) '$(srcdir)/thermal.c'; fi` pcb-undo.o: undo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-undo.o -MD -MP -MF $(DEPDIR)/pcb-undo.Tpo -c -o pcb-undo.o `test -f 'undo.c' || echo '$(srcdir)/'`undo.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-undo.Tpo $(DEPDIR)/pcb-undo.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='undo.c' object='pcb-undo.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-undo.o `test -f 'undo.c' || echo '$(srcdir)/'`undo.c pcb-undo.obj: undo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-undo.obj -MD -MP -MF $(DEPDIR)/pcb-undo.Tpo -c -o pcb-undo.obj `if test -f 'undo.c'; then $(CYGPATH_W) 'undo.c'; else $(CYGPATH_W) '$(srcdir)/undo.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-undo.Tpo $(DEPDIR)/pcb-undo.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='undo.c' object='pcb-undo.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-undo.obj `if test -f 'undo.c'; then $(CYGPATH_W) 'undo.c'; else $(CYGPATH_W) '$(srcdir)/undo.c'; fi` pcb-vector.o: vector.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-vector.o -MD -MP -MF $(DEPDIR)/pcb-vector.Tpo -c -o pcb-vector.o `test -f 'vector.c' || echo '$(srcdir)/'`vector.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-vector.Tpo $(DEPDIR)/pcb-vector.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vector.c' object='pcb-vector.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-vector.o `test -f 'vector.c' || echo '$(srcdir)/'`vector.c pcb-vector.obj: vector.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-vector.obj -MD -MP -MF $(DEPDIR)/pcb-vector.Tpo -c -o pcb-vector.obj `if test -f 'vector.c'; then $(CYGPATH_W) 'vector.c'; else $(CYGPATH_W) '$(srcdir)/vector.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-vector.Tpo $(DEPDIR)/pcb-vector.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vector.c' object='pcb-vector.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-vector.obj `if test -f 'vector.c'; then $(CYGPATH_W) 'vector.c'; else $(CYGPATH_W) '$(srcdir)/vector.c'; fi` pcb-vendor.o: vendor.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-vendor.o -MD -MP -MF $(DEPDIR)/pcb-vendor.Tpo -c -o pcb-vendor.o `test -f 'vendor.c' || echo '$(srcdir)/'`vendor.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-vendor.Tpo $(DEPDIR)/pcb-vendor.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vendor.c' object='pcb-vendor.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-vendor.o `test -f 'vendor.c' || echo '$(srcdir)/'`vendor.c pcb-vendor.obj: vendor.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-vendor.obj -MD -MP -MF $(DEPDIR)/pcb-vendor.Tpo -c -o pcb-vendor.obj `if test -f 'vendor.c'; then $(CYGPATH_W) 'vendor.c'; else $(CYGPATH_W) '$(srcdir)/vendor.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-vendor.Tpo $(DEPDIR)/pcb-vendor.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vendor.c' object='pcb-vendor.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-vendor.obj `if test -f 'vendor.c'; then $(CYGPATH_W) 'vendor.c'; else $(CYGPATH_W) '$(srcdir)/vendor.c'; fi` hid/common/pcb-actions.o: hid/common/actions.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/common/pcb-actions.o -MD -MP -MF hid/common/$(DEPDIR)/pcb-actions.Tpo -c -o hid/common/pcb-actions.o `test -f 'hid/common/actions.c' || echo '$(srcdir)/'`hid/common/actions.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/common/$(DEPDIR)/pcb-actions.Tpo hid/common/$(DEPDIR)/pcb-actions.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/common/actions.c' object='hid/common/pcb-actions.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/common/pcb-actions.o `test -f 'hid/common/actions.c' || echo '$(srcdir)/'`hid/common/actions.c hid/common/pcb-actions.obj: hid/common/actions.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/common/pcb-actions.obj -MD -MP -MF hid/common/$(DEPDIR)/pcb-actions.Tpo -c -o hid/common/pcb-actions.obj `if test -f 'hid/common/actions.c'; then $(CYGPATH_W) 'hid/common/actions.c'; else $(CYGPATH_W) '$(srcdir)/hid/common/actions.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/common/$(DEPDIR)/pcb-actions.Tpo hid/common/$(DEPDIR)/pcb-actions.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/common/actions.c' object='hid/common/pcb-actions.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/common/pcb-actions.obj `if test -f 'hid/common/actions.c'; then $(CYGPATH_W) 'hid/common/actions.c'; else $(CYGPATH_W) '$(srcdir)/hid/common/actions.c'; fi` hid/common/pcb-flags.o: hid/common/flags.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/common/pcb-flags.o -MD -MP -MF hid/common/$(DEPDIR)/pcb-flags.Tpo -c -o hid/common/pcb-flags.o `test -f 'hid/common/flags.c' || echo '$(srcdir)/'`hid/common/flags.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/common/$(DEPDIR)/pcb-flags.Tpo hid/common/$(DEPDIR)/pcb-flags.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/common/flags.c' object='hid/common/pcb-flags.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/common/pcb-flags.o `test -f 'hid/common/flags.c' || echo '$(srcdir)/'`hid/common/flags.c hid/common/pcb-flags.obj: hid/common/flags.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/common/pcb-flags.obj -MD -MP -MF hid/common/$(DEPDIR)/pcb-flags.Tpo -c -o hid/common/pcb-flags.obj `if test -f 'hid/common/flags.c'; then $(CYGPATH_W) 'hid/common/flags.c'; else $(CYGPATH_W) '$(srcdir)/hid/common/flags.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/common/$(DEPDIR)/pcb-flags.Tpo hid/common/$(DEPDIR)/pcb-flags.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/common/flags.c' object='hid/common/pcb-flags.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/common/pcb-flags.obj `if test -f 'hid/common/flags.c'; then $(CYGPATH_W) 'hid/common/flags.c'; else $(CYGPATH_W) '$(srcdir)/hid/common/flags.c'; fi` hid/common/pcb-hidinit.o: hid/common/hidinit.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/common/pcb-hidinit.o -MD -MP -MF hid/common/$(DEPDIR)/pcb-hidinit.Tpo -c -o hid/common/pcb-hidinit.o `test -f 'hid/common/hidinit.c' || echo '$(srcdir)/'`hid/common/hidinit.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/common/$(DEPDIR)/pcb-hidinit.Tpo hid/common/$(DEPDIR)/pcb-hidinit.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/common/hidinit.c' object='hid/common/pcb-hidinit.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/common/pcb-hidinit.o `test -f 'hid/common/hidinit.c' || echo '$(srcdir)/'`hid/common/hidinit.c hid/common/pcb-hidinit.obj: hid/common/hidinit.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/common/pcb-hidinit.obj -MD -MP -MF hid/common/$(DEPDIR)/pcb-hidinit.Tpo -c -o hid/common/pcb-hidinit.obj `if test -f 'hid/common/hidinit.c'; then $(CYGPATH_W) 'hid/common/hidinit.c'; else $(CYGPATH_W) '$(srcdir)/hid/common/hidinit.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/common/$(DEPDIR)/pcb-hidinit.Tpo hid/common/$(DEPDIR)/pcb-hidinit.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/common/hidinit.c' object='hid/common/pcb-hidinit.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/common/pcb-hidinit.obj `if test -f 'hid/common/hidinit.c'; then $(CYGPATH_W) 'hid/common/hidinit.c'; else $(CYGPATH_W) '$(srcdir)/hid/common/hidinit.c'; fi` hid/common/pcb-hidnogui.o: hid/common/hidnogui.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/common/pcb-hidnogui.o -MD -MP -MF hid/common/$(DEPDIR)/pcb-hidnogui.Tpo -c -o hid/common/pcb-hidnogui.o `test -f 'hid/common/hidnogui.c' || echo '$(srcdir)/'`hid/common/hidnogui.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/common/$(DEPDIR)/pcb-hidnogui.Tpo hid/common/$(DEPDIR)/pcb-hidnogui.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/common/hidnogui.c' object='hid/common/pcb-hidnogui.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/common/pcb-hidnogui.o `test -f 'hid/common/hidnogui.c' || echo '$(srcdir)/'`hid/common/hidnogui.c hid/common/pcb-hidnogui.obj: hid/common/hidnogui.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/common/pcb-hidnogui.obj -MD -MP -MF hid/common/$(DEPDIR)/pcb-hidnogui.Tpo -c -o hid/common/pcb-hidnogui.obj `if test -f 'hid/common/hidnogui.c'; then $(CYGPATH_W) 'hid/common/hidnogui.c'; else $(CYGPATH_W) '$(srcdir)/hid/common/hidnogui.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/common/$(DEPDIR)/pcb-hidnogui.Tpo hid/common/$(DEPDIR)/pcb-hidnogui.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/common/hidnogui.c' object='hid/common/pcb-hidnogui.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/common/pcb-hidnogui.obj `if test -f 'hid/common/hidnogui.c'; then $(CYGPATH_W) 'hid/common/hidnogui.c'; else $(CYGPATH_W) '$(srcdir)/hid/common/hidnogui.c'; fi` hid/common/pcb-extents.o: hid/common/extents.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/common/pcb-extents.o -MD -MP -MF hid/common/$(DEPDIR)/pcb-extents.Tpo -c -o hid/common/pcb-extents.o `test -f 'hid/common/extents.c' || echo '$(srcdir)/'`hid/common/extents.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/common/$(DEPDIR)/pcb-extents.Tpo hid/common/$(DEPDIR)/pcb-extents.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/common/extents.c' object='hid/common/pcb-extents.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/common/pcb-extents.o `test -f 'hid/common/extents.c' || echo '$(srcdir)/'`hid/common/extents.c hid/common/pcb-extents.obj: hid/common/extents.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/common/pcb-extents.obj -MD -MP -MF hid/common/$(DEPDIR)/pcb-extents.Tpo -c -o hid/common/pcb-extents.obj `if test -f 'hid/common/extents.c'; then $(CYGPATH_W) 'hid/common/extents.c'; else $(CYGPATH_W) '$(srcdir)/hid/common/extents.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/common/$(DEPDIR)/pcb-extents.Tpo hid/common/$(DEPDIR)/pcb-extents.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/common/extents.c' object='hid/common/pcb-extents.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/common/pcb-extents.obj `if test -f 'hid/common/extents.c'; then $(CYGPATH_W) 'hid/common/extents.c'; else $(CYGPATH_W) '$(srcdir)/hid/common/extents.c'; fi` hid/common/pcb-draw_helpers.o: hid/common/draw_helpers.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/common/pcb-draw_helpers.o -MD -MP -MF hid/common/$(DEPDIR)/pcb-draw_helpers.Tpo -c -o hid/common/pcb-draw_helpers.o `test -f 'hid/common/draw_helpers.c' || echo '$(srcdir)/'`hid/common/draw_helpers.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/common/$(DEPDIR)/pcb-draw_helpers.Tpo hid/common/$(DEPDIR)/pcb-draw_helpers.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/common/draw_helpers.c' object='hid/common/pcb-draw_helpers.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/common/pcb-draw_helpers.o `test -f 'hid/common/draw_helpers.c' || echo '$(srcdir)/'`hid/common/draw_helpers.c hid/common/pcb-draw_helpers.obj: hid/common/draw_helpers.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/common/pcb-draw_helpers.obj -MD -MP -MF hid/common/$(DEPDIR)/pcb-draw_helpers.Tpo -c -o hid/common/pcb-draw_helpers.obj `if test -f 'hid/common/draw_helpers.c'; then $(CYGPATH_W) 'hid/common/draw_helpers.c'; else $(CYGPATH_W) '$(srcdir)/hid/common/draw_helpers.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/common/$(DEPDIR)/pcb-draw_helpers.Tpo hid/common/$(DEPDIR)/pcb-draw_helpers.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/common/draw_helpers.c' object='hid/common/pcb-draw_helpers.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/common/pcb-draw_helpers.obj `if test -f 'hid/common/draw_helpers.c'; then $(CYGPATH_W) 'hid/common/draw_helpers.c'; else $(CYGPATH_W) '$(srcdir)/hid/common/draw_helpers.c'; fi` hid/common/pcb-hid_resource.o: hid/common/hid_resource.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/common/pcb-hid_resource.o -MD -MP -MF hid/common/$(DEPDIR)/pcb-hid_resource.Tpo -c -o hid/common/pcb-hid_resource.o `test -f 'hid/common/hid_resource.c' || echo '$(srcdir)/'`hid/common/hid_resource.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/common/$(DEPDIR)/pcb-hid_resource.Tpo hid/common/$(DEPDIR)/pcb-hid_resource.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/common/hid_resource.c' object='hid/common/pcb-hid_resource.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/common/pcb-hid_resource.o `test -f 'hid/common/hid_resource.c' || echo '$(srcdir)/'`hid/common/hid_resource.c hid/common/pcb-hid_resource.obj: hid/common/hid_resource.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/common/pcb-hid_resource.obj -MD -MP -MF hid/common/$(DEPDIR)/pcb-hid_resource.Tpo -c -o hid/common/pcb-hid_resource.obj `if test -f 'hid/common/hid_resource.c'; then $(CYGPATH_W) 'hid/common/hid_resource.c'; else $(CYGPATH_W) '$(srcdir)/hid/common/hid_resource.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/common/$(DEPDIR)/pcb-hid_resource.Tpo hid/common/$(DEPDIR)/pcb-hid_resource.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/common/hid_resource.c' object='hid/common/pcb-hid_resource.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/common/pcb-hid_resource.obj `if test -f 'hid/common/hid_resource.c'; then $(CYGPATH_W) 'hid/common/hid_resource.c'; else $(CYGPATH_W) '$(srcdir)/hid/common/hid_resource.c'; fi` pcb-toporouter.o: toporouter.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-toporouter.o -MD -MP -MF $(DEPDIR)/pcb-toporouter.Tpo -c -o pcb-toporouter.o `test -f 'toporouter.c' || echo '$(srcdir)/'`toporouter.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-toporouter.Tpo $(DEPDIR)/pcb-toporouter.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='toporouter.c' object='pcb-toporouter.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-toporouter.o `test -f 'toporouter.c' || echo '$(srcdir)/'`toporouter.c pcb-toporouter.obj: toporouter.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-toporouter.obj -MD -MP -MF $(DEPDIR)/pcb-toporouter.Tpo -c -o pcb-toporouter.obj `if test -f 'toporouter.c'; then $(CYGPATH_W) 'toporouter.c'; else $(CYGPATH_W) '$(srcdir)/toporouter.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-toporouter.Tpo $(DEPDIR)/pcb-toporouter.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='toporouter.c' object='pcb-toporouter.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-toporouter.obj `if test -f 'toporouter.c'; then $(CYGPATH_W) 'toporouter.c'; else $(CYGPATH_W) '$(srcdir)/toporouter.c'; fi` pcb-dbus-pcbmain.o: dbus-pcbmain.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-dbus-pcbmain.o -MD -MP -MF $(DEPDIR)/pcb-dbus-pcbmain.Tpo -c -o pcb-dbus-pcbmain.o `test -f 'dbus-pcbmain.c' || echo '$(srcdir)/'`dbus-pcbmain.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-dbus-pcbmain.Tpo $(DEPDIR)/pcb-dbus-pcbmain.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dbus-pcbmain.c' object='pcb-dbus-pcbmain.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-dbus-pcbmain.o `test -f 'dbus-pcbmain.c' || echo '$(srcdir)/'`dbus-pcbmain.c pcb-dbus-pcbmain.obj: dbus-pcbmain.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-dbus-pcbmain.obj -MD -MP -MF $(DEPDIR)/pcb-dbus-pcbmain.Tpo -c -o pcb-dbus-pcbmain.obj `if test -f 'dbus-pcbmain.c'; then $(CYGPATH_W) 'dbus-pcbmain.c'; else $(CYGPATH_W) '$(srcdir)/dbus-pcbmain.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-dbus-pcbmain.Tpo $(DEPDIR)/pcb-dbus-pcbmain.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dbus-pcbmain.c' object='pcb-dbus-pcbmain.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-dbus-pcbmain.obj `if test -f 'dbus-pcbmain.c'; then $(CYGPATH_W) 'dbus-pcbmain.c'; else $(CYGPATH_W) '$(srcdir)/dbus-pcbmain.c'; fi` pcb-dbus.o: dbus.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-dbus.o -MD -MP -MF $(DEPDIR)/pcb-dbus.Tpo -c -o pcb-dbus.o `test -f 'dbus.c' || echo '$(srcdir)/'`dbus.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-dbus.Tpo $(DEPDIR)/pcb-dbus.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dbus.c' object='pcb-dbus.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-dbus.o `test -f 'dbus.c' || echo '$(srcdir)/'`dbus.c pcb-dbus.obj: dbus.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pcb-dbus.obj -MD -MP -MF $(DEPDIR)/pcb-dbus.Tpo -c -o pcb-dbus.obj `if test -f 'dbus.c'; then $(CYGPATH_W) 'dbus.c'; else $(CYGPATH_W) '$(srcdir)/dbus.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcb-dbus.Tpo $(DEPDIR)/pcb-dbus.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dbus.c' object='pcb-dbus.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pcb-dbus.obj `if test -f 'dbus.c'; then $(CYGPATH_W) 'dbus.c'; else $(CYGPATH_W) '$(srcdir)/dbus.c'; fi` hid/common/pcb-hidgl.o: hid/common/hidgl.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/common/pcb-hidgl.o -MD -MP -MF hid/common/$(DEPDIR)/pcb-hidgl.Tpo -c -o hid/common/pcb-hidgl.o `test -f 'hid/common/hidgl.c' || echo '$(srcdir)/'`hid/common/hidgl.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/common/$(DEPDIR)/pcb-hidgl.Tpo hid/common/$(DEPDIR)/pcb-hidgl.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/common/hidgl.c' object='hid/common/pcb-hidgl.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/common/pcb-hidgl.o `test -f 'hid/common/hidgl.c' || echo '$(srcdir)/'`hid/common/hidgl.c hid/common/pcb-hidgl.obj: hid/common/hidgl.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/common/pcb-hidgl.obj -MD -MP -MF hid/common/$(DEPDIR)/pcb-hidgl.Tpo -c -o hid/common/pcb-hidgl.obj `if test -f 'hid/common/hidgl.c'; then $(CYGPATH_W) 'hid/common/hidgl.c'; else $(CYGPATH_W) '$(srcdir)/hid/common/hidgl.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/common/$(DEPDIR)/pcb-hidgl.Tpo hid/common/$(DEPDIR)/pcb-hidgl.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/common/hidgl.c' object='hid/common/pcb-hidgl.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/common/pcb-hidgl.obj `if test -f 'hid/common/hidgl.c'; then $(CYGPATH_W) 'hid/common/hidgl.c'; else $(CYGPATH_W) '$(srcdir)/hid/common/hidgl.c'; fi` hid/common/pcb-trackball.o: hid/common/trackball.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/common/pcb-trackball.o -MD -MP -MF hid/common/$(DEPDIR)/pcb-trackball.Tpo -c -o hid/common/pcb-trackball.o `test -f 'hid/common/trackball.c' || echo '$(srcdir)/'`hid/common/trackball.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/common/$(DEPDIR)/pcb-trackball.Tpo hid/common/$(DEPDIR)/pcb-trackball.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/common/trackball.c' object='hid/common/pcb-trackball.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/common/pcb-trackball.o `test -f 'hid/common/trackball.c' || echo '$(srcdir)/'`hid/common/trackball.c hid/common/pcb-trackball.obj: hid/common/trackball.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hid/common/pcb-trackball.obj -MD -MP -MF hid/common/$(DEPDIR)/pcb-trackball.Tpo -c -o hid/common/pcb-trackball.obj `if test -f 'hid/common/trackball.c'; then $(CYGPATH_W) 'hid/common/trackball.c'; else $(CYGPATH_W) '$(srcdir)/hid/common/trackball.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) hid/common/$(DEPDIR)/pcb-trackball.Tpo hid/common/$(DEPDIR)/pcb-trackball.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hid/common/trackball.c' object='hid/common/pcb-trackball.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pcb_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hid/common/pcb-trackball.obj `if test -f 'hid/common/trackball.c'; then $(CYGPATH_W) 'hid/common/trackball.c'; else $(CYGPATH_W) '$(srcdir)/hid/common/trackball.c'; fi` unittest-pcb-printf.o: pcb-printf.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unittest-pcb-printf.o -MD -MP -MF $(DEPDIR)/unittest-pcb-printf.Tpo -c -o unittest-pcb-printf.o `test -f 'pcb-printf.c' || echo '$(srcdir)/'`pcb-printf.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/unittest-pcb-printf.Tpo $(DEPDIR)/unittest-pcb-printf.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcb-printf.c' object='unittest-pcb-printf.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unittest-pcb-printf.o `test -f 'pcb-printf.c' || echo '$(srcdir)/'`pcb-printf.c unittest-pcb-printf.obj: pcb-printf.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unittest-pcb-printf.obj -MD -MP -MF $(DEPDIR)/unittest-pcb-printf.Tpo -c -o unittest-pcb-printf.obj `if test -f 'pcb-printf.c'; then $(CYGPATH_W) 'pcb-printf.c'; else $(CYGPATH_W) '$(srcdir)/pcb-printf.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/unittest-pcb-printf.Tpo $(DEPDIR)/unittest-pcb-printf.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pcb-printf.c' object='unittest-pcb-printf.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unittest-pcb-printf.obj `if test -f 'pcb-printf.c'; then $(CYGPATH_W) 'pcb-printf.c'; else $(CYGPATH_W) '$(srcdir)/pcb-printf.c'; fi` unittest-object_list.o: object_list.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unittest-object_list.o -MD -MP -MF $(DEPDIR)/unittest-object_list.Tpo -c -o unittest-object_list.o `test -f 'object_list.c' || echo '$(srcdir)/'`object_list.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/unittest-object_list.Tpo $(DEPDIR)/unittest-object_list.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='object_list.c' object='unittest-object_list.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unittest-object_list.o `test -f 'object_list.c' || echo '$(srcdir)/'`object_list.c unittest-object_list.obj: object_list.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unittest-object_list.obj -MD -MP -MF $(DEPDIR)/unittest-object_list.Tpo -c -o unittest-object_list.obj `if test -f 'object_list.c'; then $(CYGPATH_W) 'object_list.c'; else $(CYGPATH_W) '$(srcdir)/object_list.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/unittest-object_list.Tpo $(DEPDIR)/unittest-object_list.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='object_list.c' object='unittest-object_list.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unittest-object_list.obj `if test -f 'object_list.c'; then $(CYGPATH_W) 'object_list.c'; else $(CYGPATH_W) '$(srcdir)/object_list.c'; fi` unittest-main-test.o: main-test.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unittest-main-test.o -MD -MP -MF $(DEPDIR)/unittest-main-test.Tpo -c -o unittest-main-test.o `test -f 'main-test.c' || echo '$(srcdir)/'`main-test.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/unittest-main-test.Tpo $(DEPDIR)/unittest-main-test.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='main-test.c' object='unittest-main-test.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unittest-main-test.o `test -f 'main-test.c' || echo '$(srcdir)/'`main-test.c unittest-main-test.obj: main-test.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unittest-main-test.obj -MD -MP -MF $(DEPDIR)/unittest-main-test.Tpo -c -o unittest-main-test.obj `if test -f 'main-test.c'; then $(CYGPATH_W) 'main-test.c'; else $(CYGPATH_W) '$(srcdir)/main-test.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/unittest-main-test.Tpo $(DEPDIR)/unittest-main-test.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='main-test.c' object='unittest-main-test.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unittest-main-test.obj `if test -f 'main-test.c'; then $(CYGPATH_W) 'main-test.c'; else $(CYGPATH_W) '$(srcdir)/main-test.c'; fi` .l.c: $(AM_V_LEX)$(am__skiplex) $(SHELL) $(YLWRAP) $< $(LEX_OUTPUT_ROOT).c $@ -- $(LEXCOMPILE) .y.c: $(AM_V_YACC)$(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h `echo $@ | $(am__yacc_c2h)` y.output $*.output -- $(YACCCOMPILE) install-pcblibDATA: $(pcblib_DATA) @$(NORMAL_INSTALL) @list='$(pcblib_DATA)'; test -n "$(pcblibdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pcblibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pcblibdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pcblibdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pcblibdir)" || exit $$?; \ done uninstall-pcblibDATA: @$(NORMAL_UNINSTALL) @list='$(pcblib_DATA)'; test -n "$(pcblibdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pcblibdir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: $(check_PROGRAMS) $(check_SCRIPTS) @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all $(check_PROGRAMS) $(check_SCRIPTS) @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? unittest.log: unittest$(EXEEXT) @p='unittest$(EXEEXT)'; \ b='unittest'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(check_SCRIPTS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check-local check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-recursive all-am: Makefile $(PROGRAMS) $(LIBRARIES) $(DATA) all-local installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pcblibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f drc/$(DEPDIR)/$(am__dirstamp) -rm -f drc/$(am__dirstamp) -rm -f hid/batch/$(DEPDIR)/$(am__dirstamp) -rm -f hid/batch/$(am__dirstamp) -rm -f hid/bom/$(DEPDIR)/$(am__dirstamp) -rm -f hid/bom/$(am__dirstamp) -rm -f hid/bom_md/$(DEPDIR)/$(am__dirstamp) -rm -f hid/bom_md/$(am__dirstamp) -rm -f hid/common/$(DEPDIR)/$(am__dirstamp) -rm -f hid/common/$(am__dirstamp) -rm -f hid/gcode/$(DEPDIR)/$(am__dirstamp) -rm -f hid/gcode/$(am__dirstamp) -rm -f hid/gerber/$(DEPDIR)/$(am__dirstamp) -rm -f hid/gerber/$(am__dirstamp) -rm -f hid/gsvit/$(DEPDIR)/$(am__dirstamp) -rm -f hid/gsvit/$(am__dirstamp) -rm -f hid/gtk/$(DEPDIR)/$(am__dirstamp) -rm -f hid/gtk/$(am__dirstamp) -rm -f hid/ipcd356/$(DEPDIR)/$(am__dirstamp) -rm -f hid/ipcd356/$(am__dirstamp) -rm -f hid/lesstif/$(DEPDIR)/$(am__dirstamp) -rm -f hid/lesstif/$(am__dirstamp) -rm -f hid/lpr/$(DEPDIR)/$(am__dirstamp) -rm -f hid/lpr/$(am__dirstamp) -rm -f hid/nelma/$(DEPDIR)/$(am__dirstamp) -rm -f hid/nelma/$(am__dirstamp) -rm -f hid/png/$(DEPDIR)/$(am__dirstamp) -rm -f hid/png/$(am__dirstamp) -rm -f hid/ps/$(DEPDIR)/$(am__dirstamp) -rm -f hid/ps/$(am__dirstamp) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -rm -f edif.c -rm -f edif.h -rm -f parse_l.c -rm -f parse_y.c -rm -f parse_y.h -rm -f res_lex.c -rm -f res_parse.c -rm -f res_parse.h -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-recursive clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ clean-noinstLIBRARIES mostlyclean-am distclean: distclean-recursive -rm -f ./$(DEPDIR)/pcb-action.Po -rm -f ./$(DEPDIR)/pcb-autoplace.Po -rm -f ./$(DEPDIR)/pcb-autoroute.Po -rm -f ./$(DEPDIR)/pcb-buffer.Po -rm -f ./$(DEPDIR)/pcb-change.Po -rm -f ./$(DEPDIR)/pcb-clip.Po -rm -f ./$(DEPDIR)/pcb-compat.Po -rm -f ./$(DEPDIR)/pcb-copy.Po -rm -f ./$(DEPDIR)/pcb-create.Po -rm -f ./$(DEPDIR)/pcb-crosshair.Po -rm -f ./$(DEPDIR)/pcb-data.Po -rm -f ./$(DEPDIR)/pcb-dbus-pcbmain.Po -rm -f ./$(DEPDIR)/pcb-dbus.Po -rm -f ./$(DEPDIR)/pcb-djopt.Po -rm -f ./$(DEPDIR)/pcb-draw.Po -rm -f ./$(DEPDIR)/pcb-drill.Po -rm -f ./$(DEPDIR)/pcb-edif.Po -rm -f ./$(DEPDIR)/pcb-error.Po -rm -f ./$(DEPDIR)/pcb-file.Po -rm -f ./$(DEPDIR)/pcb-find.Po -rm -f ./$(DEPDIR)/pcb-flags.Po -rm -f ./$(DEPDIR)/pcb-fontmode.Po -rm -f ./$(DEPDIR)/pcb-free_atexit.Po -rm -f ./$(DEPDIR)/pcb-getline.Po -rm -f ./$(DEPDIR)/pcb-heap.Po -rm -f ./$(DEPDIR)/pcb-insert.Po -rm -f ./$(DEPDIR)/pcb-intersect.Po -rm -f ./$(DEPDIR)/pcb-layerflags.Po -rm -f ./$(DEPDIR)/pcb-line.Po -rm -f ./$(DEPDIR)/pcb-lrealpath.Po -rm -f ./$(DEPDIR)/pcb-main.Po -rm -f ./$(DEPDIR)/pcb-mirror.Po -rm -f ./$(DEPDIR)/pcb-misc.Po -rm -f ./$(DEPDIR)/pcb-move.Po -rm -f ./$(DEPDIR)/pcb-mtspace.Po -rm -f ./$(DEPDIR)/pcb-mymem.Po -rm -f ./$(DEPDIR)/pcb-netlist.Po -rm -f ./$(DEPDIR)/pcb-object_list.Po -rm -f ./$(DEPDIR)/pcb-parse_l.Po -rm -f ./$(DEPDIR)/pcb-parse_y.Po -rm -f ./$(DEPDIR)/pcb-pcb-printf.Po -rm -f ./$(DEPDIR)/pcb-polygon.Po -rm -f ./$(DEPDIR)/pcb-polygon1.Po -rm -f ./$(DEPDIR)/pcb-print.Po -rm -f ./$(DEPDIR)/pcb-puller.Po -rm -f ./$(DEPDIR)/pcb-rats.Po -rm -f ./$(DEPDIR)/pcb-relocate.Po -rm -f ./$(DEPDIR)/pcb-remove.Po -rm -f ./$(DEPDIR)/pcb-renumber.Po -rm -f ./$(DEPDIR)/pcb-report.Po -rm -f ./$(DEPDIR)/pcb-res_lex.Po -rm -f ./$(DEPDIR)/pcb-res_parse.Po -rm -f ./$(DEPDIR)/pcb-rotate.Po -rm -f ./$(DEPDIR)/pcb-rtree.Po -rm -f ./$(DEPDIR)/pcb-rubberband.Po -rm -f ./$(DEPDIR)/pcb-search.Po -rm -f ./$(DEPDIR)/pcb-select.Po -rm -f ./$(DEPDIR)/pcb-set.Po -rm -f ./$(DEPDIR)/pcb-smartdisperse.Po -rm -f ./$(DEPDIR)/pcb-strcasestr.Po -rm -f ./$(DEPDIR)/pcb-strflags.Po -rm -f ./$(DEPDIR)/pcb-teardrops.Po -rm -f ./$(DEPDIR)/pcb-thermal.Po -rm -f ./$(DEPDIR)/pcb-toporouter.Po -rm -f ./$(DEPDIR)/pcb-undo.Po -rm -f ./$(DEPDIR)/pcb-vector.Po -rm -f ./$(DEPDIR)/pcb-vendor.Po -rm -f ./$(DEPDIR)/unittest-main-test.Po -rm -f ./$(DEPDIR)/unittest-object_list.Po -rm -f ./$(DEPDIR)/unittest-pcb-printf.Po -rm -f drc/$(DEPDIR)/libdrc_a-drc.Po -rm -f drc/$(DEPDIR)/libdrc_a-drc_violation.Po -rm -f hid/batch/$(DEPDIR)/libbatch_a-batch.Po -rm -f hid/bom/$(DEPDIR)/libbom_a-bom.Po -rm -f hid/bom_md/$(DEPDIR)/libbom_md_a-bom_md.Po -rm -f hid/common/$(DEPDIR)/pcb-actions.Po -rm -f hid/common/$(DEPDIR)/pcb-draw_helpers.Po -rm -f hid/common/$(DEPDIR)/pcb-extents.Po -rm -f hid/common/$(DEPDIR)/pcb-flags.Po -rm -f hid/common/$(DEPDIR)/pcb-hid_resource.Po -rm -f hid/common/$(DEPDIR)/pcb-hidgl.Po -rm -f hid/common/$(DEPDIR)/pcb-hidinit.Po -rm -f hid/common/$(DEPDIR)/pcb-hidnogui.Po -rm -f hid/common/$(DEPDIR)/pcb-trackball.Po -rm -f hid/gcode/$(DEPDIR)/libgcode_a-curve.Po -rm -f hid/gcode/$(DEPDIR)/libgcode_a-decompose.Po -rm -f hid/gcode/$(DEPDIR)/libgcode_a-gcode.Po -rm -f hid/gcode/$(DEPDIR)/libgcode_a-trace.Po -rm -f hid/gerber/$(DEPDIR)/libgerber_a-gerber.Po -rm -f hid/gsvit/$(DEPDIR)/libgsvit_a-gsvit.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-ghid-cell-renderer-visibility.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-ghid-coord-entry.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-ghid-layer-selector.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-ghid-main-menu.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-ghid-route-style-selector.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gtkhid-gdk.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gtkhid-gl.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gtkhid-main.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-command-window.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-config.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-dialog-print.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-dialog.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-drc-window.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-keyref-window.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-library-window.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-log-window.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-misc.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-netlist-window.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-output-events.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-pinout-preview.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-pinout-window.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-top-window.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-trackball.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-utils.Po -rm -f hid/ipcd356/$(DEPDIR)/libipcd356_a-ipcd356.Po -rm -f hid/lesstif/$(DEPDIR)/liblesstif_a-dialogs.Po -rm -f hid/lesstif/$(DEPDIR)/liblesstif_a-library.Po -rm -f hid/lesstif/$(DEPDIR)/liblesstif_a-main.Po -rm -f hid/lesstif/$(DEPDIR)/liblesstif_a-menu.Po -rm -f hid/lesstif/$(DEPDIR)/liblesstif_a-netlist.Po -rm -f hid/lesstif/$(DEPDIR)/liblesstif_a-styles.Po -rm -f hid/lpr/$(DEPDIR)/liblpr_a-lpr.Po -rm -f hid/nelma/$(DEPDIR)/libnelma_a-nelma.Po -rm -f hid/png/$(DEPDIR)/libpng_a-png.Po -rm -f hid/ps/$(DEPDIR)/libps_a-eps.Po -rm -f hid/ps/$(DEPDIR)/libps_a-ps.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-pcblibDATA install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f ./$(DEPDIR)/pcb-action.Po -rm -f ./$(DEPDIR)/pcb-autoplace.Po -rm -f ./$(DEPDIR)/pcb-autoroute.Po -rm -f ./$(DEPDIR)/pcb-buffer.Po -rm -f ./$(DEPDIR)/pcb-change.Po -rm -f ./$(DEPDIR)/pcb-clip.Po -rm -f ./$(DEPDIR)/pcb-compat.Po -rm -f ./$(DEPDIR)/pcb-copy.Po -rm -f ./$(DEPDIR)/pcb-create.Po -rm -f ./$(DEPDIR)/pcb-crosshair.Po -rm -f ./$(DEPDIR)/pcb-data.Po -rm -f ./$(DEPDIR)/pcb-dbus-pcbmain.Po -rm -f ./$(DEPDIR)/pcb-dbus.Po -rm -f ./$(DEPDIR)/pcb-djopt.Po -rm -f ./$(DEPDIR)/pcb-draw.Po -rm -f ./$(DEPDIR)/pcb-drill.Po -rm -f ./$(DEPDIR)/pcb-edif.Po -rm -f ./$(DEPDIR)/pcb-error.Po -rm -f ./$(DEPDIR)/pcb-file.Po -rm -f ./$(DEPDIR)/pcb-find.Po -rm -f ./$(DEPDIR)/pcb-flags.Po -rm -f ./$(DEPDIR)/pcb-fontmode.Po -rm -f ./$(DEPDIR)/pcb-free_atexit.Po -rm -f ./$(DEPDIR)/pcb-getline.Po -rm -f ./$(DEPDIR)/pcb-heap.Po -rm -f ./$(DEPDIR)/pcb-insert.Po -rm -f ./$(DEPDIR)/pcb-intersect.Po -rm -f ./$(DEPDIR)/pcb-layerflags.Po -rm -f ./$(DEPDIR)/pcb-line.Po -rm -f ./$(DEPDIR)/pcb-lrealpath.Po -rm -f ./$(DEPDIR)/pcb-main.Po -rm -f ./$(DEPDIR)/pcb-mirror.Po -rm -f ./$(DEPDIR)/pcb-misc.Po -rm -f ./$(DEPDIR)/pcb-move.Po -rm -f ./$(DEPDIR)/pcb-mtspace.Po -rm -f ./$(DEPDIR)/pcb-mymem.Po -rm -f ./$(DEPDIR)/pcb-netlist.Po -rm -f ./$(DEPDIR)/pcb-object_list.Po -rm -f ./$(DEPDIR)/pcb-parse_l.Po -rm -f ./$(DEPDIR)/pcb-parse_y.Po -rm -f ./$(DEPDIR)/pcb-pcb-printf.Po -rm -f ./$(DEPDIR)/pcb-polygon.Po -rm -f ./$(DEPDIR)/pcb-polygon1.Po -rm -f ./$(DEPDIR)/pcb-print.Po -rm -f ./$(DEPDIR)/pcb-puller.Po -rm -f ./$(DEPDIR)/pcb-rats.Po -rm -f ./$(DEPDIR)/pcb-relocate.Po -rm -f ./$(DEPDIR)/pcb-remove.Po -rm -f ./$(DEPDIR)/pcb-renumber.Po -rm -f ./$(DEPDIR)/pcb-report.Po -rm -f ./$(DEPDIR)/pcb-res_lex.Po -rm -f ./$(DEPDIR)/pcb-res_parse.Po -rm -f ./$(DEPDIR)/pcb-rotate.Po -rm -f ./$(DEPDIR)/pcb-rtree.Po -rm -f ./$(DEPDIR)/pcb-rubberband.Po -rm -f ./$(DEPDIR)/pcb-search.Po -rm -f ./$(DEPDIR)/pcb-select.Po -rm -f ./$(DEPDIR)/pcb-set.Po -rm -f ./$(DEPDIR)/pcb-smartdisperse.Po -rm -f ./$(DEPDIR)/pcb-strcasestr.Po -rm -f ./$(DEPDIR)/pcb-strflags.Po -rm -f ./$(DEPDIR)/pcb-teardrops.Po -rm -f ./$(DEPDIR)/pcb-thermal.Po -rm -f ./$(DEPDIR)/pcb-toporouter.Po -rm -f ./$(DEPDIR)/pcb-undo.Po -rm -f ./$(DEPDIR)/pcb-vector.Po -rm -f ./$(DEPDIR)/pcb-vendor.Po -rm -f ./$(DEPDIR)/unittest-main-test.Po -rm -f ./$(DEPDIR)/unittest-object_list.Po -rm -f ./$(DEPDIR)/unittest-pcb-printf.Po -rm -f drc/$(DEPDIR)/libdrc_a-drc.Po -rm -f drc/$(DEPDIR)/libdrc_a-drc_violation.Po -rm -f hid/batch/$(DEPDIR)/libbatch_a-batch.Po -rm -f hid/bom/$(DEPDIR)/libbom_a-bom.Po -rm -f hid/bom_md/$(DEPDIR)/libbom_md_a-bom_md.Po -rm -f hid/common/$(DEPDIR)/pcb-actions.Po -rm -f hid/common/$(DEPDIR)/pcb-draw_helpers.Po -rm -f hid/common/$(DEPDIR)/pcb-extents.Po -rm -f hid/common/$(DEPDIR)/pcb-flags.Po -rm -f hid/common/$(DEPDIR)/pcb-hid_resource.Po -rm -f hid/common/$(DEPDIR)/pcb-hidgl.Po -rm -f hid/common/$(DEPDIR)/pcb-hidinit.Po -rm -f hid/common/$(DEPDIR)/pcb-hidnogui.Po -rm -f hid/common/$(DEPDIR)/pcb-trackball.Po -rm -f hid/gcode/$(DEPDIR)/libgcode_a-curve.Po -rm -f hid/gcode/$(DEPDIR)/libgcode_a-decompose.Po -rm -f hid/gcode/$(DEPDIR)/libgcode_a-gcode.Po -rm -f hid/gcode/$(DEPDIR)/libgcode_a-trace.Po -rm -f hid/gerber/$(DEPDIR)/libgerber_a-gerber.Po -rm -f hid/gsvit/$(DEPDIR)/libgsvit_a-gsvit.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-ghid-cell-renderer-visibility.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-ghid-coord-entry.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-ghid-layer-selector.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-ghid-main-menu.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-ghid-route-style-selector.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gtkhid-gdk.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gtkhid-gl.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gtkhid-main.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-command-window.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-config.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-dialog-print.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-dialog.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-drc-window.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-keyref-window.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-library-window.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-log-window.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-misc.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-netlist-window.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-output-events.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-pinout-preview.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-pinout-window.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-top-window.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-trackball.Po -rm -f hid/gtk/$(DEPDIR)/libgtk_a-gui-utils.Po -rm -f hid/ipcd356/$(DEPDIR)/libipcd356_a-ipcd356.Po -rm -f hid/lesstif/$(DEPDIR)/liblesstif_a-dialogs.Po -rm -f hid/lesstif/$(DEPDIR)/liblesstif_a-library.Po -rm -f hid/lesstif/$(DEPDIR)/liblesstif_a-main.Po -rm -f hid/lesstif/$(DEPDIR)/liblesstif_a-menu.Po -rm -f hid/lesstif/$(DEPDIR)/liblesstif_a-netlist.Po -rm -f hid/lesstif/$(DEPDIR)/liblesstif_a-styles.Po -rm -f hid/lpr/$(DEPDIR)/liblpr_a-lpr.Po -rm -f hid/nelma/$(DEPDIR)/libnelma_a-nelma.Po -rm -f hid/png/$(DEPDIR)/libpng_a-png.Po -rm -f hid/ps/$(DEPDIR)/libps_a-eps.Po -rm -f hid/ps/$(DEPDIR)/libps_a-ps.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-pcblibDATA .MAKE: $(am__recursive_targets) all check check-am install install-am \ install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am all-local \ am--depfiles check check-TESTS check-am check-local clean \ clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-binPROGRAMS install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pcblibDATA install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am recheck tags tags-am \ uninstall uninstall-am uninstall-binPROGRAMS \ uninstall-pcblibDATA .PRECIOUS: Makefile all-local: pcbtest.sh ${PCBTEST_BAT} pcb-menu.res : pcb-menu.res.in Makefile echo '/* AUTOMATICALLY GENERATED FROM pcb-menu.res.in DO NOT EDIT */' > $@ @WITH_TOPOROUTER_TRUE@ cat ${srcdir}/pcb-menu.res.in >> $@ @WITH_TOPOROUTER_FALSE@ echo 'removed Toporouter menu item from pcb-menu.res\n'; @WITH_TOPOROUTER_FALSE@ cat ${srcdir}/pcb-menu.res.in >> $@.tmp @WITH_TOPOROUTER_FALSE@ sed 's/ {"Toporouter" Toporouter()}//' < ${srcdir}/pcb-menu.res.tmp >> $@ @WITH_TOPOROUTER_FALSE@ rm -f $@.tmp pcb-menu.h : pcb-menu.res echo '/* AUTOMATICALLY GENERATED FROM pcb-menu.res DO NOT EDIT */' > $@ echo 'const char *pcb_menu_default[] = {' >> $@ sed 's/\\/\\\\/g; s/"/\\"/g; s/^/"/; s/$$/",/' < pcb-menu.res >> $@ echo '0};' >> $@ gpcb-menu.res : gpcb-menu.res.in Makefile echo '/* AUTOMATICALLY GENERATED FROM gpcb-menu.res.in DO NOT EDIT */' > $@ cat ${srcdir}/gpcb-menu.res.in >> $@.tmp @WITH_TOPOROUTER_TRUE@ cat ${srcdir}/gpcb-menu.res.in >> $@ @WITH_TOPOROUTER_FALSE@ cat ${srcdir}/gpcb-menu.res.in >> $@.tmp @WITH_TOPOROUTER_FALSE@ echo 'removed Toporouter menu item from gpcb-menu.res\n'; @WITH_TOPOROUTER_FALSE@ sed 's/ {"Toporouter" Toporouter()}//' < ${srcdir}/gpcb-menu.res.tmp >> $@ @WITH_TOPOROUTER_FALSE@ rm -f $@.tmp gpcb-menu.h : gpcb-menu.res echo '/* AUTOMATICALLY GENERATED FROM gpcb-menu.res DO NOT EDIT */' > $@ echo 'const char *gpcb_menu_default[] = {' >> $@ sed 's/\\/\\\\/g; s/"/\\"/g; s/^/"/; s/$$/",/' < gpcb-menu.res >> $@ echo '0};' >> $@ # Menus i18n. The .res.h files are used simply to give strings which # feed into ../po/pcb.pot for translation. This is the only place # these files are used. When menu resources are parsed, the strings # are translated. We likely should find a way to not try to copy # back to srcdir all the time but it is possible that the gettext/intltool # flow can't really deal with getting strings from built sources. %.res.h : %.res $(INTLTOOL_EXTRACT) --type=gettext/quoted $^ mv -f $@ ${srcdir}/$@ || true check-local: gpcb-menu.res.h pcb-menu.res.h # Action, Attribute, and Flag lists. core_lists.h : ${LIST_SRCS} Makefile true > $@ (for f in ${LIST_SRCS}; do cat $(srcdir)/$$f ; done) | grep "^REGISTER" > $@.tmp mv $@.tmp $@ hid/common/hidlist.h : Makefile $(MKDIR_P) hid/common true > $@ for e in ${HIDLIST}; do \ echo "HID_DEF($${e})" >> $@; \ done hid/gtk/gtk_lists.h : ${LIBGTK_SRCS} Makefile $(MKDIR_P) hid/gtk true > $@ (for f in ${LIBGTK_SRCS} ; do cat $(srcdir)/$$f ; done) | grep "^REGISTER" > $@.tmp mv $@.tmp $@ # If we are building with dbus support, we need some extra files @WITH_DBUS_TRUE@dbus-introspect.h : dbus.xml Makefile @WITH_DBUS_TRUE@ echo '/* AUTOMATICALLY GENERATED FROM dbus.xml DO NOT EDIT */' > $@.tmp @WITH_DBUS_TRUE@ echo "static char *pcb_dbus_introspect_xml =" > $@.tmp @WITH_DBUS_TRUE@ sed 's/\\/\\\\/g; s/"/\\"/g; s/^/"/; s/$$/"/' < $(srcdir)/dbus.xml >> $@.tmp @WITH_DBUS_TRUE@ echo ";" >> $@.tmp @WITH_DBUS_TRUE@ mv $@.tmp $@ # If we are building on win32, then compile in some icons for the # desktop and application toolbar @WIN32_TRUE@pcb_icon.o : pcb_icon.ico $(srcdir)/hid/gtk/pcb.rc @WIN32_TRUE@ $(WINDRES) $(srcdir)/hid/gtk/pcb.rc $@ @WIN32_TRUE@pcb_icon.ico: $(top_srcdir)/data/pcb_icon.ico @WIN32_TRUE@ cp $(top_srcdir)/data/pcb_icon.ico $@ hid/lesstif/lesstif_lists.h : ${LIBLESSTIF_SRCS} Makefile $(MKDIR_P) hid/lesstif true > $@ (for f in ${LIBLESSTIF_SRCS} ; do cat $(srcdir)/$$f ; done) | grep "^REGISTER" > $@.tmp mv $@.tmp $@ hid/batch/batch_lists.h : ${LIBBATCH_SRCS} Makefile $(MKDIR_P) hid/batch true > $@ (for f in ${LIBBATCH_SRCS} ; do cat $(srcdir)/$$f ; done) | grep "^REGISTER" > $@.tmp mv $@.tmp $@ hid/ps/ps_lists.h : ${LIBPS_SRCS} Makefile $(MKDIR_P) hid/ps true > $@ (for f in ${LIBPS_SRCS} ; do cat $(srcdir)/$$f ; done) | grep "^REGISTER" > $@.tmp mv $@.tmp $@ hid/png/png_lists.h : ${LIBPNG_SRCS} Makefile $(MKDIR_P) hid/png true > $@ (for f in ${LIBPNG_SRCS} ; do cat $(srcdir)/$$f ; done) | grep "^REGISTER" > $@.tmp mv $@.tmp $@ hid/gcode/gcode_lists.h : ${LIBGCODE_SRCS} Makefile $(MKDIR_P) hid/gcode true > $@ (for f in ${LIBGCODE_SRCS} ; do cat $(srcdir)/$$f ; done) | grep "^REGISTER" > $@.tmp mv $@.tmp $@ hid/nelma/nelma_lists.h : ${LIBNELMA_SRCS} Makefile $(MKDIR_P) hid/nelma true > $@ (for f in ${LIBNELMA_SRCS} ; do cat $(srcdir)/$$f ; done) | grep "^REGISTER" > $@.tmp mv $@.tmp $@ hid/gsvit/gsvit_lists.h : ${LIBGSVIT_SRCS} Makefile $(MKDIR_P) hid/gsvit true > $@ (for f in ${LIBGSVIT_SRCS} ; do cat $(srcdir)/$$f ; done) | grep "^REGISTER" > $@.tmp mv $@.tmp $@ # create wrapper script that lets you test pcb prior to installation pcbtest.sh: $(srcdir)/pcbtest.sh.in Makefile sed -e 's;@BUILDDIR@;${abs_builddir};g' -e 's;@TOP_BUILDDIR@;${abs_top_builddir};g' \ -e 's;@TOPSRCDIR@;${abs_top_srcdir};g' -e 's;WITH_GUI;${with_gui};' \ $(srcdir)/pcbtest.sh.in > $@ chmod 755 $@ # create a wrapper script that lets you test pcb prior to installation # when building under cygwin with the mingw cross compilers @WIN32_TRUE@pcbtest.bat: Makefile @WIN32_TRUE@ cygpath --windows ${abs_top_builddir} | awk '{printf("set PCB_TOP_BUILD=%s\n", $$0)}' > $@ @WIN32_TRUE@ cygpath --windows ${abs_top_srcdir} | awk '{printf("set PCB_TOP_SRC=%s\n", $$0)}' >> $@ @WIN32_TRUE@ cygpath --windows `${CC} -print-sysroot` | awk '{printf("set SYS_ROOT=%s\n", $$0)}' >> $@ @WIN32_TRUE@ echo 'set PCBSRCDIR=%PCB_TOP_BUILD%\src' >> $@ @WIN32_TRUE@ echo 'set PCBLIBDIR=%PCB_TOP_BUILD%\lib' >> $@ @WIN32_TRUE@ echo 'set PCBLIBNEWLIBDIR=%PCB_TOP_BUILD%\lib\pcblib-newlib' >> $@ @WIN32_TRUE@ echo 'set PCBNEWLIBDIR=%PCB_TOP_BUILD%\newlib' >> $@ @WIN32_TRUE@ echo 'set PCBFONTDIR=%PCB_TOP_SRC%\lib' >> $@ @WIN32_TRUE@ echo 'set PATH=%SYS_ROOT%\mingw\bin;%SYS_ROOT%\mingw\lib;%PATH%' >> $@ @WIN32_TRUE@ echo '%PCBSRCDIR%\pcb.exe %* --lib-path %PCBLIBDIR% --lib-newlib %PCBLIBNEWLIBDIR% --element-path %PCBNEWLIBDIR% --font-path %PCBFONTDIR% --lib-command-dir %PCBLIBDIR%' >> $@ @WIN32_TRUE@ chmod 755 $@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: pcb-4.3.0/src/strflags.c0000664000175000017500000003564013773431044012003 00000000000000/*! * \file src/strflags.c * * \brief strflags. * * The purpose of this interface is to make the file format able to * handle more than 32 flags, and to hide the internal details of * flags from the file format. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 2005 DJ Delorie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * * DJ Delorie, 334 North Road, Deerfield NH 03037-1110, USA * * dj@delorie.com */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_STRING_H #include #endif #include "globalconst.h" #include "global.h" #include "compat.h" #include "hid.h" #include "strflags.h" #ifdef HAVE_LIBDMALLOC #include #endif /* Because all the macros expect it, that's why. */ typedef struct { FlagType Flags; } FlagHolder; /*! * Be careful to list more specific flags first, followed by general * flags, when two flags use the same bit. For example, "onsolder" is * for elements only, while "auto" is for everything else. They use * the same bit, but onsolder is listed first so that elements will * use it and not auto. * * Thermals are handled separately, as they're layer-selective. */ typedef struct { int mask; /*!< This is the bit that we're setting. */ char *name; /*!< The name used in the output file. */ int nlen; #define N(x) x, sizeof(x)-1 int object_types; /*!< If set, this entry won't be output unless the * object type is one of these. */ } FlagBitsType; static FlagBitsType object_flagbits[] = { { PINFLAG, N ("pin"), ALL_TYPES }, { VIAFLAG, N ("via"), ALL_TYPES }, { FOUNDFLAG, N ("found"), ALL_TYPES }, { HOLEFLAG, N ("hole"), PIN_TYPES }, { RATFLAG, N ("rat"), RATLINE_TYPE }, { PININPOLYFLAG, N ("pininpoly"), PIN_TYPES | PAD_TYPE }, { CLEARPOLYFLAG, N ("clearpoly"), POLYGON_TYPE }, { HIDENAMEFLAG, N ("hidename"), ELEMENT_TYPE }, { DISPLAYNAMEFLAG, N ("showname"), ELEMENT_TYPE }, { CLEARLINEFLAG, N ("clearline"), LINE_TYPE | ARC_TYPE | TEXT_TYPE }, { SELECTEDFLAG, N ("selected"), ALL_TYPES }, { ONSOLDERFLAG, N ("onsolder"), ELEMENT_TYPE | PAD_TYPE | TEXT_TYPE | ELEMENTNAME_TYPE }, { AUTOFLAG, N ("auto"), ALL_TYPES }, { SQUAREFLAG, N ("square"), PIN_TYPES | PAD_TYPE }, { RUBBERENDFLAG, N ("rubberend"), LINE_TYPE | ARC_TYPE }, { WARNFLAG, N ("warn"), PIN_TYPES | PAD_TYPE }, { USETHERMALFLAG, N ("usetherm"), PIN_TYPES | LINE_TYPE | ARC_TYPE }, { OCTAGONFLAG, N ("octagon"), PIN_TYPES | PAD_TYPE }, { DRCFLAG, N ("drc"), ALL_TYPES }, { LOCKFLAG, N ("lock"), ALL_TYPES }, { EDGE2FLAG, N ("edge2"), ALL_TYPES }, { FULLPOLYFLAG, N ("fullpoly"), POLYGON_TYPE}, { NOPASTEFLAG, N ("nopaste"), PAD_TYPE }, { CONNECTEDFLAG, N ("connected"), ALL_TYPES } }; static FlagBitsType pcb_flagbits[] = { { SHOWNUMBERFLAG, N ("shownumber"), ALL_TYPES }, { LOCALREFFLAG, N ("localref"), ALL_TYPES }, { CHECKPLANESFLAG, N ("checkplanes"), ALL_TYPES }, { SHOWDRCFLAG, N ("showdrc"), ALL_TYPES }, { RUBBERBANDFLAG, N ("rubberband"), ALL_TYPES }, { DESCRIPTIONFLAG, N ("description"), ALL_TYPES }, { NAMEONPCBFLAG, N ("nameonpcb"), ALL_TYPES }, { AUTODRCFLAG, N ("autodrc"), ALL_TYPES }, { ALLDIRECTIONFLAG, N ("alldirection"), ALL_TYPES }, { SWAPSTARTDIRFLAG, N ("swapstartdir"), ALL_TYPES }, { UNIQUENAMEFLAG, N ("uniquename"), ALL_TYPES }, { CLEARNEWFLAG, N ("clearnew"), ALL_TYPES }, { NEWFULLPOLYFLAG, N ("newfullpoly"), ALL_TYPES }, { SNAPPINFLAG, N ("snappin"), ALL_TYPES }, { SHOWMASKFLAG, N ("showmask"), ALL_TYPES }, { THINDRAWFLAG, N ("thindraw"), ALL_TYPES }, { ORTHOMOVEFLAG, N ("orthomove"), ALL_TYPES }, { LIVEROUTEFLAG, N ("liveroute"), ALL_TYPES }, { THINDRAWPOLYFLAG, N ("thindrawpoly"), ALL_TYPES }, { LOCKNAMESFLAG, N ("locknames"), ALL_TYPES }, { ONLYNAMESFLAG, N ("onlynames"), ALL_TYPES }, { HIDENAMESFLAG, N ("hidenames"), ALL_TYPES }, { AUTOBURIEDVIASFLAG, N ("autoburiedvias"), ALL_TYPES }, }; #undef N /* * This helper function maintains a small list of buffers which are * used by flags_to_string(). Each buffer is allocated from the heap, * but the caller must not free them (they get realloced when they're * reused, but never completely freed). */ static struct { char *ptr; int len; } buffers[10]; static int bufptr = 0; static char * alloc_buf (int len) { #define B buffers[bufptr] len++; bufptr = (bufptr + 1) % 10; if (B.len < len) { if (B.ptr) B.ptr = (char *) realloc (B.ptr, len); else B.ptr = (char *) malloc (len); B.len = len; } return B.ptr; #undef B } void uninit_strflags_buf (void) { int n; for (n = 0; n < 10; n++) { if (buffers[n].ptr != NULL) { free (buffers[n].ptr); buffers[n].ptr = NULL; } } } static char *layers = 0; static int max_layers = 0, num_layers = 0; /*! * \brief Grow layer list. * * This routine manages a list of layer-specific flags. * * Callers should call grow_layer_list(0) to reset the list, and * set_layer_list(layer,1) to set bits in the layer list. * * The results are stored in layers[], which has \c num_layers valid * entries. */ static void grow_layer_list (int num) { if (layers == 0) { layers = (char *) calloc (num > 0 ? num : 1, 1); max_layers = num; } else if (num > max_layers) { max_layers = num; layers = (char *) realloc (layers, max_layers); } if (num > num_layers) memset (layers + num_layers, 0, num - num_layers - 1); num_layers = num; return; } void uninit_strflags_layerlist (void) { if (layers != NULL) { free (layers); layers = NULL; num_layers = max_layers = 0; } } /*! * \brief Set layer list. * * This routine manages a list of layer-specific flags. * * Callers should call grow_layer_list(0) to reset the list, and * set_layer_list(layer,1) to set bits in the layer list. * * The results are stored in layers[], which has \c num_layers valid * entries. */ static inline void set_layer_list (int layer, int v) { if (layer >= num_layers) grow_layer_list (layer + 1); layers[layer] = v; } /*! * \brief Parse layer list. * * parse_layer_list() is passed a pointer to a string, and parses a * list of integer which reflect layers to be flagged. * * It returns a pointer to the first character following the list. * * The syntax of the list is a paren-surrounded, comma-separated list of * integers and/or pairs of integers separated by a dash * (like "(1,2,3-7)"). * * Spaces and other punctuation are not allowed. * * The results are stored in \c layers[]. * * \return a pointer to the first character past the list. */ static const char * parse_layer_list (const char *bp, int (*error) (const char *)) { const char *orig_bp = bp; int l = 0, range = -1; int value = 1; grow_layer_list (0); while (*bp) { if (*bp == '+') value = 2; else if (*bp == 'S') value = 3; else if (*bp == 'X') value = 4; else if (*bp == 't') value = 5; else if (*bp == ')' || *bp == ',' || *bp == '-') { if (range == -1) range = l; while (range <= l) set_layer_list (range++, value); if (*bp == '-') range = l; else range = -1; value = 1; l = 0; } else if (isdigit ((int) *bp)) l = l * 10 + (*bp - '0'); else if (error) { char *fmt = "Syntax error parsing layer list \"%.*s\" at %c"; char *msg = alloc_buf (strlen (fmt) + strlen (orig_bp)); sprintf (msg, fmt, bp - orig_bp + 5, orig_bp, *bp); error (msg); error = NULL; } if (*bp == ')') return bp + 1; bp++; } return bp; } /*! * \brief Number of character the value "i" requires when printed. */ static int printed_int_length (int i, int j) { int rv; if (i < 10) return 1 + (j ? 1 : 0); if (i < 100) return 2 + (j ? 1 : 0); for (rv = 1; i >= 10; rv++) i /= 10; return rv + (j ? 1 : 0); } /*! * \brief Print layer list. * * print_layer_list() uses the flags set in layers[] to build a string * that represents them, using the syntax described below. * * The syntax of the list is a paren-surrounded, comma-separated list of * integers and/or pairs of integers separated by a dash * (like "(1,2,3-7)"). * * Spaces and other punctuation are not allowed. * * \return a pointer to an internal buffer which is overwritten with * each new call. */ static char * print_layer_list () { static char *buf = 0; static int buflen = 0; int len, i, j; char *bp; len = 2; for (i = 0; i < num_layers; i++) if (layers[i]) len += 1 + printed_int_length (i, layers[i]); if (buflen < len) { if (buf) buf = (char *) realloc (buf, len); else buf = (char *) malloc (len); buflen = len; } bp = buf; *bp++ = '('; for (i = 0; i < num_layers; i++) if (layers[i]) { /* 0 0 1 1 1 0 0 */ /* i j */ for (j = i + 1; j < num_layers && layers[j] == 1; j++) ; if (j > i + 2) { sprintf (bp, "%d-%d,", i, j - 1); i = j - 1; } else switch (layers[i]) { case 1: sprintf (bp, "%d,", i); break; case 2: sprintf (bp, "%d+,", i); break; case 3: sprintf (bp, "%dS,", i); break; case 4: sprintf (bp, "%dX,", i); break; case 5: default: sprintf (bp, "%dt,", i); break; } bp += strlen (bp); } bp[-1] = ')'; *bp = 0; return buf; } static int error_ignore (const char *msg) { /* do nothing */ return 0; } static FlagType empty_flags; static FlagType common_string_to_flags (const char *flagstring, int (*error) (const char *msg), FlagBitsType *flagbits, int n_flagbits) { const char *fp, *ep; int flen; FlagHolder rv; int i; rv.Flags = empty_flags; if (error == 0) error = error_ignore; if (flagstring == NULL) return empty_flags; fp = ep = flagstring; if (*fp == '"') ep = ++fp; while (*ep && *ep != '"') { int found = 0; for (ep = fp; *ep && *ep != ',' && *ep != '"' && *ep != '('; ep++) ; flen = ep - fp; if (*ep == '(') ep = parse_layer_list (ep + 1, error); if (flen == 7 && memcmp (fp, "thermal", 7) == 0) { for (i = 0; i < MAX_LAYER && i < num_layers; i++) if (layers[i]) ASSIGN_THERM (i, layers[i], &rv); } else { for (i = 0; i < n_flagbits; i++) if (flagbits[i].nlen == flen && memcmp (flagbits[i].name, fp, flen) == 0) { found = 1; SET_FLAG (flagbits[i].mask, &rv); break; } if (!found) { const char *fmt = "Unknown flag: \"%.*s\" ignored"; char *msg = alloc_buf (strlen (fmt) + flen); sprintf (msg, fmt, flen, fp); error (msg); } } fp = ep + 1; } return rv.Flags; } /*! * \brief Convert strings to flags. * * When passed a string, parse it and return an appropriate set of * flags. * * Errors cause error() to be called with a suitable message; * if error is NULL, errors are ignored. */ FlagType string_to_flags (const char *flagstring, int (*error) (const char *msg)) { return common_string_to_flags (flagstring, error, object_flagbits, ENTRIES (object_flagbits)); } /*! * \brief Convert strings to PCB flags. * * When passed a string, parse it and return an appropriate set of * flags. * * Errors cause error() to be called with a suitable message; * if error is NULL, errors are ignored. */ FlagType string_to_pcbflags (const char *flagstring, int (*error) (const char *msg)) { return common_string_to_flags (flagstring, error, pcb_flagbits, ENTRIES (pcb_flagbits)); } /*! * \brief Common flags converted to strings. * * Given a set of flags for a given type of object, return a string * which reflects those flags. * * The only requirement is that this string be parseable by string_to_flags. * * \note This function knows a little about what kinds of flags * will be automatically set by parsing, so it won't (for example) * include the "via" flag for VIA_TYPEs because it knows those get * forcibly set when vias are parsed. * * \warning Currently, there is no error handling :-P */ static char * common_flags_to_string (FlagType flags, int object_type, FlagBitsType *flagbits, int n_flagbits) { int len; int i; FlagHolder fh, savef; char *buf, *bp; fh.Flags = flags; switch (object_type) { case VIA_TYPE: CLEAR_FLAG (VIAFLAG, &fh); break; case RATLINE_TYPE: CLEAR_FLAG (RATFLAG, &fh); break; case PIN_TYPE: CLEAR_FLAG (PINFLAG, &fh); break; } savef = fh; len = 3; /* for "()\0" */ for (i = 0; i < n_flagbits; i++) if ((flagbits[i].object_types & object_type) && (TEST_FLAG (flagbits[i].mask, &fh))) { len += flagbits[i].nlen + 1; CLEAR_FLAG (flagbits[i].mask, &fh); } if (TEST_ANY_THERMS (&fh)) { len += sizeof ("thermal()"); for (i = 0; i < MAX_LAYER; i++) if (TEST_THERM (i, &fh)) len += printed_int_length (i, GET_THERM (i, &fh)) + 1; } bp = buf = alloc_buf (len + 2); *bp++ = '"'; fh = savef; for (i = 0; i < n_flagbits; i++) if (flagbits[i].object_types & object_type && (TEST_FLAG (flagbits[i].mask, &fh))) { if (bp != buf + 1) *bp++ = ','; strcpy (bp, flagbits[i].name); bp += flagbits[i].nlen; CLEAR_FLAG (flagbits[i].mask, &fh); } if (TEST_ANY_THERMS (&fh)) { if (bp != buf + 1) *bp++ = ','; strcpy (bp, "thermal"); bp += strlen ("thermal"); grow_layer_list (0); for (i = 0; i < MAX_LAYER; i++) if (TEST_THERM (i, &fh)) set_layer_list (i, GET_THERM (i, &fh)); strcpy (bp, print_layer_list ()); bp += strlen (bp); } *bp++ = '"'; *bp = 0; return buf; } /*! * \brief Object flags converted to strings. * * Given a set of flags for a given object type, return a string which * can be output to a file. * * The returned pointer must not be freed. */ char * flags_to_string (FlagType flags, int object_type) { return common_flags_to_string (flags, object_type, object_flagbits, ENTRIES (object_flagbits)); } /*! * \brief PCB flags converted to strings. */ char * pcbflags_to_string (FlagType flags) { return common_flags_to_string (flags, ALL_TYPES, pcb_flagbits, ENTRIES (pcb_flagbits)); } pcb-4.3.0/src/find.c0000664000175000017500000027725313773431044011106 00000000000000/*! * \file src/find.c * * \brief Routines to find connections between pins, vias, lines ... * * Short description:\n *
    *
  • Lists for pins and vias, lines, arcs, pads and for polygons are * created.\n * Every object that has to be checked is added to its list.\n * Coarse searching is accomplished with the data rtrees.
  • *
  • There's no 'speed-up' mechanism for polygons because they are * not used as often as other objects.
  • *
  • The maximum distance between line and pin ... would depend on * the angle between them. To speed up computation the limit is set * to one half of the thickness of the objects (cause of square * pins).
  • *
* * PV: means pin or via (objects that connect layers).\n * LO: all non PV objects (layer objects like lines, arcs, polygons, * pads). * *
    *
  1. First, the LO or PV at the given coordinates is looked * up.
  2. *
  3. All LO connections to that PV are looked up next.
  4. *
  5. Lookup of all LOs connected to LOs from (2).\n * This step is repeated until no more new connections are found.
  6. *
  7. Lookup all PVs connected to the LOs from (2) and (3).
  8. *
  9. Start again with (1) for all new PVs from (4).
  10. *
* * Intersection of line <--> circle:\n *
    *
  • Calculate the signed distance from the line to the center, * return false if abs(distance) > R.
  • *
  • Get the distance from the line <--> distancevector intersection * to (X1,Y1) in range [0,1], return true if 0 <= distance <= 1.
  • *
  • Depending on (r > 1.0 or r < 0.0) check the distance of X2,Y2 or * X1,Y1 to X,Y.
  • *
* * Intersection of line <--> line:\n *
    *
  • See the description of 'LineLineIntersect()'.
  • *
* *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996, 2005 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Contact addresses for paper mail and Email: * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * Thomas.Nau@rz.uni-ulm.de */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "global.h" #include "data.h" #include "draw.h" #include "drc/drc.h" #include "error.h" #include "find.h" #include "flags.h" #include "misc.h" #include "rtree.h" #include "polygon.h" #include "pcb-printf.h" #include "search.h" #include "set.h" #include "undo.h" #include "rats.h" #ifdef HAVE_LIBDMALLOC #include #endif #undef DEBUG /* --------------------------------------------------------------------------- * some local macros */ #define SEPARATE(FP) \ { \ int i; \ fputc('#', (FP)); \ for (i = Settings.CharPerLine; i; i--) \ fputc('=', (FP)); \ fputc('\n', (FP)); \ } /* ----------------------------------------------------------------------- * * * Global State * * ----------------------------------------------------------------------- */ /* Bloat is used to change the size of objects before checking for overlaps. * This is used in the DRC check to detect things that are too close, or * don't overlap enough.*/ static Coord Bloat = 0; /*!< Whether to stop if finding something not found. * * Ultimately, this global state variable needs to disappear, along with the calls to set thing 1 * and thing 2. */ static bool drc = false; /* --------------------------------------------------------------------------- * some local prototypes */ static bool LookupLOConnectionsToLine (LineType *, Cardinal, int, bool, bool); static bool LookupLOConnectionsToPad (PadType *, Cardinal, int, bool); static bool LookupLOConnectionsToPolygon (PolygonType *, Cardinal, int, bool); static bool LookupLOConnectionsToArc (ArcType *, Cardinal, int, bool); static bool LookupLOConnectionsToRatEnd (PointType *, Cardinal, int); static bool PrepareNextLoop (FILE *); static void DrawNewConnections (void); /* ----------------------------------------------------------------------- * * * Object Lists and Function Stuff * * ----------------------------------------------------------------------- */ #define LIST_ENTRY(list,I) (((AnyObjectType **)list->Data)[(I)]) #define PADLIST_ENTRY(L,I) (((PadType **)PadList[(L)].Data)[(I)]) #define LINELIST_ENTRY(L,I) (((LineType **)LineList[(L)].Data)[(I)]) #define ARCLIST_ENTRY(L,I) (((ArcType **)ArcList[(L)].Data)[(I)]) #define RATLIST_ENTRY(I) (((RatType **)RatList.Data)[(I)]) #define POLYGONLIST_ENTRY(L,I) (((PolygonType **)PolygonList[(L)].Data)[(I)]) #define PVLIST_ENTRY(I) (((PinType **)PVList.Data)[(I)]) /*! * \brief Some local types. * * The two 'dummy' structs for PVs and Pads are necessary for creating * connection lists which include the element's name. */ typedef struct { void **Data; /*!< Pointer to index data. */ Cardinal Location, /*!< Currently used position. */ DrawLocation, Number, /*!< Number of objects in list. */ Size; } ListType; static Cardinal TotalP, TotalV; static ListType LineList[MAX_LAYER], /*!< List of objects to. */ PolygonList[MAX_LAYER], ArcList[MAX_LAYER], PadList[2], RatList, PVList; /* * Add an object to the specified list. * * Returning true will (always?) abort the algorithm, false will allow it to * continue. * */ static bool add_object_to_list (ListType *list, int type, void *ptr1, void *ptr2, void *ptr3, int flag) { AnyObjectType *object = (AnyObjectType *)ptr2; /* Set the appropriate flag to indicate the object appears in one of the * lists. This is how we later compare runs. */ AddObjectToFlagUndoList (type, ptr1, ptr2, ptr3); SET_FLAG (flag, object); /* Add the object to the list. */ LIST_ENTRY (list, list->Number) = object; list->Number++; #ifdef DEBUG if (list->Number > list->Size) printf ("add_object_to_list overflow! type=%i num=%d size=%d\n", type, list->Number, list->Size); #endif /* if drc is true, then we want to abort the algorithm if a new object is * found. The first time through, the SELECTEDFLAG is set on all objects * that are found. So, if SELECTEDFLAG is set, then the object is already * known. * * TODO: This is not very flexible and requires pre-ordained knowledge of * how to use the SELECTEDFLAG. */ if (drc && !TEST_FLAG (SELECTEDFLAG, object)) return (SetThing (2, type, ptr1, ptr2, ptr3)); return false; } static bool ADD_PV_TO_LIST (PinType *Pin, int flag) { return add_object_to_list (&PVList, Pin->Element ? PIN_TYPE : VIA_TYPE, Pin->Element ? Pin->Element : Pin, Pin, Pin, flag); } static bool ADD_PAD_TO_LIST (Cardinal L, PadType *Pad, int flag) { return add_object_to_list (&PadList[L], PAD_TYPE, Pad->Element, Pad, Pad, flag); } static bool ADD_LINE_TO_LIST (Cardinal L, LineType *Ptr, int flag) { return add_object_to_list (&LineList[L], LINE_TYPE, LAYER_PTR (L), Ptr, Ptr, flag); } static bool ADD_ARC_TO_LIST (Cardinal L, ArcType *Ptr, int flag) { return add_object_to_list (&ArcList[L], ARC_TYPE, LAYER_PTR (L), Ptr, Ptr, flag); } static bool ADD_RAT_TO_LIST (RatType *Ptr, int flag) { return add_object_to_list (&RatList, RATLINE_TYPE, Ptr, Ptr, Ptr, flag); } static bool ADD_POLYGON_TO_LIST (Cardinal L, PolygonType *Ptr, int flag) { return add_object_to_list (&PolygonList[L], POLYGON_TYPE, LAYER_PTR (L), Ptr, Ptr, flag); } /*! * \brief Checks if all lists of new objects are handled. */ static bool ListsEmpty (bool AndRats) { bool empty; int i; empty = (PVList.Location >= PVList.Number); if (AndRats) empty = empty && (RatList.Location >= RatList.Number); for (i = 0; i < max_copper_layer && empty; i++) if (!LAYER_PTR (i)->no_drc) empty = empty && LineList[i].Location >= LineList[i].Number && ArcList[i].Location >= ArcList[i].Number && PolygonList[i].Location >= PolygonList[i].Number; return (empty); } /*! * \brief Add the starting object to the list of found objects. */ /*static*/ bool ListStart (int type, void *ptr1, void *ptr2, void *ptr3, int flag) { DumpList (); switch (type) { case PIN_TYPE: case VIA_TYPE: { if (ADD_PV_TO_LIST ((PinType *) ptr2, flag)) return true; break; } case RATLINE_TYPE: { if (ADD_RAT_TO_LIST ((RatType *) ptr1, flag)) return true; break; } case LINE_TYPE: { int layer = GetLayerNumber (PCB->Data, (LayerType *) ptr1); if (ADD_LINE_TO_LIST (layer, (LineType *) ptr2, flag)) return true; break; } case ARC_TYPE: { int layer = GetLayerNumber (PCB->Data, (LayerType *) ptr1); if (ADD_ARC_TO_LIST (layer, (ArcType *) ptr2, flag)) return true; break; } case POLYGON_TYPE: { int layer = GetLayerNumber (PCB->Data, (LayerType *) ptr1); if (ADD_POLYGON_TO_LIST (layer, (PolygonType *) ptr2, flag)) return true; break; } case PAD_TYPE: { PadType *pad = (PadType *) ptr2; if (ADD_PAD_TO_LIST (TEST_FLAG (ONSOLDERFLAG, pad) ? BOTTOM_SIDE : TOP_SIDE, pad, flag)) return true; break; } } return (false); } /*! * \brief Dumps the list contents. */ /* static */ void DumpList (void) { Cardinal i; for (i = 0; i < 2; i++) { PadList[i].Number = 0; PadList[i].Location = 0; PadList[i].DrawLocation = 0; } PVList.Number = 0; PVList.Location = 0; for (i = 0; i < max_copper_layer; i++) { LineList[i].Location = 0; LineList[i].DrawLocation = 0; LineList[i].Number = 0; ArcList[i].Location = 0; ArcList[i].DrawLocation = 0; ArcList[i].Number = 0; PolygonList[i].Location = 0; PolygonList[i].DrawLocation = 0; PolygonList[i].Number = 0; } RatList.Number = 0; RatList.Location = 0; RatList.DrawLocation = 0; } /*! * \brief Allocates memory for component related stacks ... * * Initializes index and sorts it by X1 and X2. */ static void InitComponentLookup (void) { Cardinal NumberOfPads[2]; Cardinal i; /* initialize pad data; start by counting the total number * on each of the two possible layers */ NumberOfPads[TOP_SIDE] = NumberOfPads[BOTTOM_SIDE] = 0; ALLPAD_LOOP (PCB->Data); { if (TEST_FLAG (ONSOLDERFLAG, pad)) NumberOfPads[BOTTOM_SIDE]++; else NumberOfPads[TOP_SIDE]++; } ENDALL_LOOP; for (i = 0; i < 2; i++) { /* allocate memory for working list */ PadList[i].Data = (void **)calloc (NumberOfPads[i], sizeof (PadType *)); /* clear some struct members */ PadList[i].Location = 0; PadList[i].DrawLocation = 0; PadList[i].Number = 0; PadList[i].Size = NumberOfPads[i]; } } /*! * \brief Allocates memory for layout related stacks ... * * Initializes index and sorts it by X1 and X2. */ static void InitLayoutLookup (void) { Cardinal i; /* initialize line arc and polygon data */ for (i = 0; i < max_copper_layer; i++) { LayerType *layer = LAYER_PTR (i); if (layer->LineN) { /* allocate memory for line pointer lists */ LineList[i].Data = (void **)calloc (layer->LineN, sizeof (LineType *)); LineList[i].Size = layer->LineN; } if (layer->ArcN) { ArcList[i].Data = (void **)calloc (layer->ArcN, sizeof (ArcType *)); ArcList[i].Size = layer->ArcN; } /* allocate memory for polygon list */ if (layer->PolygonN) { PolygonList[i].Data = (void **)calloc (layer->PolygonN, sizeof (PolygonType *)); PolygonList[i].Size = layer->PolygonN; } /* clear some struct members */ LineList[i].Location = 0; LineList[i].DrawLocation = 0; LineList[i].Number = 0; ArcList[i].Location = 0; ArcList[i].DrawLocation = 0; ArcList[i].Number = 0; PolygonList[i].Location = 0; PolygonList[i].DrawLocation = 0; PolygonList[i].Number = 0; } if (PCB->Data->pin_tree) TotalP = PCB->Data->pin_tree->size; else TotalP = 0; if (PCB->Data->via_tree) TotalV = PCB->Data->via_tree->size; else TotalV = 0; /* allocate memory for 'new PV to check' list and clear struct */ PVList.Data = (void **)calloc (TotalP + TotalV, sizeof (PinType *)); PVList.Size = TotalP + TotalV; PVList.Location = 0; PVList.DrawLocation = 0; PVList.Number = 0; /* Initialize ratline data */ RatList.Data = (void **)calloc (PCB->Data->RatN, sizeof (RatType *)); RatList.Size = PCB->Data->RatN; RatList.Location = 0; RatList.DrawLocation = 0; RatList.Number = 0; } void InitConnectionLookup (void) { InitComponentLookup (); InitLayoutLookup (); } /*! * \brief Releases all allocated memory. */ static void FreeLayoutLookupMemory (void) { Cardinal i; for (i = 0; i < max_copper_layer; i++) { free (LineList[i].Data); LineList[i].Data = NULL; free (ArcList[i].Data); ArcList[i].Data = NULL; free (PolygonList[i].Data); PolygonList[i].Data = NULL; } free (PVList.Data); PVList.Data = NULL; free (RatList.Data); RatList.Data = NULL; } static void FreeComponentLookupMemory (void) { free (PadList[0].Data); PadList[0].Data = NULL; free (PadList[1].Data); PadList[1].Data = NULL; } void FreeConnectionLookupMemory (void) { FreeComponentLookupMemory (); FreeLayoutLookupMemory (); } /* ----------------------------------------------------------------------- * * * Geometry Stuff * * ----------------------------------------------------------------------- */ #define IS_PV_ON_RAT(PV, Rat) \ (IsPointOnLineEnd((PV)->X,(PV)->Y, (Rat))) #define IS_PV_ON_ARC(PV, Arc) \ (TEST_FLAG(SQUAREFLAG, (PV)) ? \ IsArcInRectangle( \ (PV)->X -MAX(((PV)->Thickness+1)/2,0), (PV)->Y -MAX(((PV)->Thickness+1)/2,0), \ (PV)->X +MAX(((PV)->Thickness+1)/2,0), (PV)->Y +MAX(((PV)->Thickness+1)/2,0), \ (Arc)) : \ IsPointOnArc((PV)->X,(PV)->Y,MAX((PV)->Thickness/2.0 + Bloat,0.0), (Arc))) #define IS_PV_ON_PAD(PV,Pad) \ ( IsPointInPad((PV)->X, (PV)->Y, MAX((PV)->Thickness/2 +Bloat,0), (Pad))) static bool IsRatPointOnLineEnd (PointType *, LineType *); static bool ArcArcIntersect (ArcType *, ArcType *); /*! * \brief. * * Some of the 'pad' routines are the same as for lines because the 'pad' * struct starts with a line struct. See global.h for details. */ bool LinePadIntersect (LineType *Line, PadType *Pad) { return LineLineIntersect ((Line), (LineType *)Pad); } bool ArcPadIntersect (ArcType *Arc, PadType *Pad) { return LineArcIntersect ((LineType *) (Pad), (Arc)); } static BoxType expand_bounds (BoxType *box_in) { BoxType box_out = *box_in; if (Bloat > 0) { box_out.X1 -= Bloat; box_out.X2 += Bloat; box_out.Y1 -= Bloat; box_out.Y2 += Bloat; } return box_out; } bool PinLineIntersect (PinType *PV, LineType *Line) { /* IsLineInRectangle already has Bloat factor */ return TEST_FLAG (SQUAREFLAG, PV) ? IsLineInRectangle (PV->X - (PIN_SIZE (PV) + 1) / 2, PV->Y - (PIN_SIZE (PV) + 1) / 2, PV->X + (PIN_SIZE (PV) + 1) / 2, PV->Y + (PIN_SIZE (PV) + 1) / 2, Line) : IsPointInPad (PV->X, PV->Y, MAX (PIN_SIZE (PV) / 2.0 + Bloat, 0.0), (PadType *)Line); } bool BoxBoxIntersection (BoxType *b1, BoxType *b2) { if (b2->X2 < b1->X1 || b2->X1 > b1->X2) return false; if (b2->Y2 < b1->Y1 || b2->Y1 > b1->Y2) return false; return true; } static bool PadPadIntersect (PadType *p1, PadType *p2) { return LinePadIntersect ((LineType *) p1, p2); } static inline bool PV_TOUCH_PV (PinType *PV1, PinType *PV2) { double t1, t2; BoxType b1, b2; t1 = MAX (PV1->Thickness / 2.0 + Bloat, 0); t2 = MAX (PV2->Thickness / 2.0 + Bloat, 0); if (IsPointOnPin (PV1->X, PV1->Y, t1, PV2) || IsPointOnPin (PV2->X, PV2->Y, t2, PV1)) return true; if (!TEST_FLAG (SQUAREFLAG, PV1) || !TEST_FLAG (SQUAREFLAG, PV2)) return false; /* check for square/square overlap */ b1.X1 = PV1->X - t1; b1.X2 = PV1->X + t1; b1.Y1 = PV1->Y - t1; b1.Y2 = PV1->Y + t1; t2 = PV2->Thickness / 2.0; b2.X1 = PV2->X - t2; b2.X2 = PV2->X + t2; b2.Y1 = PV2->Y - t2; b2.Y2 = PV2->Y + t2; return BoxBoxIntersection (&b1, &b2); } /*! * \brief Reduce arc start angle and delta to 0..360. */ static void normalize_angles (Angle *sa, Angle *d) { if (*d < 0) { *sa += *d; *d = - *d; } if (*d > 360) /* full circle */ *d = 360; *sa = NormalizeAngle (*sa); } static int radius_crosses_arc (double x, double y, ArcType *arc) { double alpha = atan2 (y - arc->Y, -x + arc->X) * RAD_TO_DEG; Angle sa = arc->StartAngle, d = arc->Delta; normalize_angles (&sa, &d); if (alpha < 0) alpha += 360; if (sa <= alpha) return (sa + d) >= alpha; return (sa + d - 360) >= alpha; } static void get_arc_ends (Coord *box, ArcType *arc) { box[0] = arc->X - arc->Width * cos (M180 * arc->StartAngle); box[1] = arc->Y + arc->Height * sin (M180 * arc->StartAngle); box[2] = arc->X - arc->Width * cos (M180 * (arc->StartAngle + arc->Delta)); box[3] = arc->Y + arc->Height * sin (M180 * (arc->StartAngle + arc->Delta)); } /*! * \brief Check if two arcs intersect. * * First we check for circle intersections, * then find the actual points of intersection * and test them to see if they are on arcs. * * Consider a, the distance from the center of arc 1 * to the point perpendicular to the intersecting points. * * \ta = (r1^2 - r2^2 + l^2)/(2l) * * The perpendicular distance to the point of intersection * is then: * * \td = sqrt(r1^2 - a^2) * * The points of intersection would then be: * * \tx = X1 + a/l dx +- d/l dy * * \ty = Y1 + a/l dy -+ d/l dx * * Where dx = X2 - X1 and dy = Y2 - Y1. */ static bool ArcArcIntersect (ArcType *Arc1, ArcType *Arc2) { double x, y, dx, dy, r1, r2, a, d, l, t, t1, t2, dl; Coord pdx, pdy; Coord box[8]; t = MAX (0.5 * Arc1->Thickness + Bloat, 0); t2 = 0.5 * Arc2->Thickness; t1 = MAX (t2 + Bloat, 0); /* too thin arc */ if (t < 0 || t1 < 0) return false; /* try the end points first */ get_arc_ends (&box[0], Arc1); get_arc_ends (&box[4], Arc2); if (IsPointOnArc (box[0], box[1], t, Arc2) || IsPointOnArc (box[2], box[3], t, Arc2) || IsPointOnArc (box[4], box[5], t, Arc1) || IsPointOnArc (box[6], box[7], t, Arc1)) return true; pdx = Arc2->X - Arc1->X; pdy = Arc2->Y - Arc1->Y; dl = Distance (Arc1->X, Arc1->Y, Arc2->X, Arc2->Y); /* concentric arcs, simpler intersection conditions */ if (dl < 0.5) { if ((Arc1->Width - t >= Arc2->Width - t2 && Arc1->Width - t <= Arc2->Width + t2) || (Arc1->Width + t >= Arc2->Width - t2 && Arc1->Width + t <= Arc2->Width + t2)) { Angle sa1 = Arc1->StartAngle, d1 = Arc1->Delta; Angle sa2 = Arc2->StartAngle, d2 = Arc2->Delta; /* NB the endpoints have already been checked, so we just compare the angles */ normalize_angles (&sa1, &d1); normalize_angles (&sa2, &d2); /* sa1 == sa2 was caught when checking endpoints */ if (sa1 > sa2) if (sa1 < sa2 + d2 || sa1 + d1 - 360 > sa2) return true; if (sa2 > sa1) if (sa2 < sa1 + d1 || sa2 + d2 - 360 > sa1) return true; } return false; } r1 = Arc1->Width; r2 = Arc2->Width; /* arcs centerlines are too far or too near */ if (dl > r1 + r2 || dl + r1 < r2 || dl + r2 < r1) { /* check the nearest to the other arc's center point */ dx = pdx * r1 / dl; dy = pdy * r1 / dl; if (dl + r1 < r2) /* Arc1 inside Arc2 */ { dx = - dx; dy = - dy; } if (radius_crosses_arc (Arc1->X + dx, Arc1->Y + dy, Arc1) && IsPointOnArc (Arc1->X + dx, Arc1->Y + dy, t, Arc2)) return true; dx = - pdx * r2 / dl; dy = - pdy * r2 / dl; if (dl + r2 < r1) /* Arc2 inside Arc1 */ { dx = - dx; dy = - dy; } if (radius_crosses_arc (Arc2->X + dx, Arc2->Y + dy, Arc2) && IsPointOnArc (Arc2->X + dx, Arc2->Y + dy, t1, Arc1)) return true; return false; } l = dl * dl; r1 *= r1; r2 *= r2; a = 0.5 * (r1 - r2 + l) / l; r1 = r1 / l; d = r1 - a * a; /* the circles are too far apart to touch or probably just touch: check the nearest point */ if (d < 0) d = 0; else d = sqrt (d); x = Arc1->X + a * pdx; y = Arc1->Y + a * pdy; dx = d * pdx; dy = d * pdy; if (radius_crosses_arc (x + dy, y - dx, Arc1) && IsPointOnArc (x + dy, y - dx, t, Arc2)) return true; if (radius_crosses_arc (x + dy, y - dx, Arc2) && IsPointOnArc (x + dy, y - dx, t1, Arc1)) return true; if (radius_crosses_arc (x - dy, y + dx, Arc1) && IsPointOnArc (x - dy, y + dx, t, Arc2)) return true; if (radius_crosses_arc (x - dy, y + dx, Arc2) && IsPointOnArc (x - dy, y + dx, t1, Arc1)) return true; return false; } /*! * \brief Tests if point is same as line end point. */ static bool IsRatPointOnLineEnd (PointType *Point, LineType *Line) { if ((Point->X == Line->Point1.X && Point->Y == Line->Point1.Y) || (Point->X == Line->Point2.X && Point->Y == Line->Point2.Y)) return (true); return (false); } /*! * \brief Writes vertices of a squared line. */ static void form_slanted_rectangle (PointType p[4], LineType *l) { double dwx = 0, dwy = 0; if (l->Point1.Y == l->Point2.Y) dwx = l->Thickness / 2.0; else if (l->Point1.X == l->Point2.X) dwy = l->Thickness / 2.0; else { Coord dX = l->Point2.X - l->Point1.X; Coord dY = l->Point2.Y - l->Point1.Y; double r = Distance (l->Point1.X, l->Point1.Y, l->Point2.X, l->Point2.Y); dwx = l->Thickness / 2.0 / r * dX; dwy = l->Thickness / 2.0 / r * dY; } p[0].X = l->Point1.X - dwx + dwy; p[0].Y = l->Point1.Y - dwy - dwx; p[1].X = l->Point1.X - dwx - dwy; p[1].Y = l->Point1.Y - dwy + dwx; p[2].X = l->Point2.X + dwx - dwy; p[2].Y = l->Point2.Y + dwy + dwx; p[3].X = l->Point2.X + dwx + dwy; p[3].Y = l->Point2.Y + dwy - dwx; } /*! * \brief Checks if two lines intersect. * *
 * From news FAQ:
 *
 * Let A,B,C,D be 2-space position vectors.
 *
 * Then the directed line segments AB & CD are given by:
 *
 *      AB=A+r(B-A), r in [0,1]
 *
 *      CD=C+s(D-C), s in [0,1]
 *
 * If AB & CD intersect, then
 *
 *      A+r(B-A)=C+s(D-C), or
 *
 *      XA+r(XB-XA)=XC+s*(XD-XC)
 *
 *      YA+r(YB-YA)=YC+s(YD-YC)  for some r,s in [0,1]
 *
 * Solving the above for r and s yields
 *
 *          (YA-YC)(XD-XC)-(XA-XC)(YD-YC)
 *      r = -----------------------------  (eqn 1)
 *          (XB-XA)(YD-YC)-(YB-YA)(XD-XC)
 *
 *          (YA-YC)(XB-XA)-(XA-XC)(YB-YA)
 *      s = -----------------------------  (eqn 2)
 *          (XB-XA)(YD-YC)-(YB-YA)(XD-XC)
 *
 * Let I be the position vector of the intersection point, then:
 *
 *      I=A+r(B-A) or
 *
 *      XI=XA+r(XB-XA)
 *
 *      YI=YA+r(YB-YA)
 *
 * By examining the values of r & s, you can also determine some
 * other limiting conditions:
 *
 *      If 0<=r<=1 & 0<=s<=1, intersection exists
 *
 *          r<0 or r>1 or s<0 or s>1 line segments do not intersect
 *
 *      If the denominator in eqn 1 is zero, AB & CD are parallel
 *
 *      If the numerator in eqn 1 is also zero, AB & CD are coincident
 *
 * If the intersection point of the 2 lines are needed (lines in this
 * context mean infinite lines) regardless whether the two line
 * segments intersect, then
 *
 *      If r>1, I is located on extension of AB
 *      If r<0, I is located on extension of BA
 *      If s>1, I is located on extension of CD
 *      If s<0, I is located on extension of DC
 *
 * Also note that the denominators of eqn 1 & 2 are identical.
 * 
*/ bool LineLineIntersect (LineType *Line1, LineType *Line2) { double s, r; double line1_dx, line1_dy, line2_dx, line2_dy, point1_dx, point1_dy; if (TEST_FLAG (SQUAREFLAG, Line1))/* pretty reckless recursion */ { PointType p[4]; form_slanted_rectangle (p, Line1); return IsLineInQuadrangle (p, Line2); } /* here come only round Line1 because IsLineInQuadrangle() calls LineLineIntersect() with first argument rounded*/ if (TEST_FLAG (SQUAREFLAG, Line2)) { PointType p[4]; form_slanted_rectangle (p, Line2); return IsLineInQuadrangle (p, Line1); } /* now all lines are round */ /* Check endpoints: this provides a quick exit, catches * cases where the "real" lines don't intersect but the * thick lines touch, and ensures that the dx/dy business * below does not cause a divide-by-zero. */ if (IsPointInPad (Line2->Point1.X, Line2->Point1.Y, MAX (Line2->Thickness / 2 + Bloat, 0), (PadType *) Line1) || IsPointInPad (Line2->Point2.X, Line2->Point2.Y, MAX (Line2->Thickness / 2 + Bloat, 0), (PadType *) Line1) || IsPointInPad (Line1->Point1.X, Line1->Point1.Y, MAX (Line1->Thickness / 2 + Bloat, 0), (PadType *) Line2) || IsPointInPad (Line1->Point2.X, Line1->Point2.Y, MAX (Line1->Thickness / 2 + Bloat, 0), (PadType *) Line2)) return true; /* setup some constants */ line1_dx = Line1->Point2.X - Line1->Point1.X; line1_dy = Line1->Point2.Y - Line1->Point1.Y; line2_dx = Line2->Point2.X - Line2->Point1.X; line2_dy = Line2->Point2.Y - Line2->Point1.Y; point1_dx = Line1->Point1.X - Line2->Point1.X; point1_dy = Line1->Point1.Y - Line2->Point1.Y; /* If either line is a point, we have failed already, since the * endpoint check above will have caught an "intersection". */ if ((line1_dx == 0 && line1_dy == 0) || (line2_dx == 0 && line2_dy == 0)) return false; /* set s to cross product of Line1 and the line * Line1.Point1--Line2.Point1 (as vectors) */ s = point1_dy * line1_dx - point1_dx * line1_dy; /* set r to cross product of both lines (as vectors) */ r = line1_dx * line2_dy - line1_dy * line2_dx; /* No cross product means parallel lines, or maybe Line2 is * zero-length. In either case, since we did a bounding-box * check before getting here, the above IsPointInPad() checks * will have caught any intersections. */ if (r == 0.0) return false; s /= r; r = (point1_dy * line2_dx - point1_dx * line2_dy) / r; /* intersection is at least on AB */ if (r >= 0.0 && r <= 1.0) return (s >= 0.0 && s <= 1.0); /* intersection is at least on CD */ /* [removed this case since it always returns false --asp] */ return false; } /*! * \brief Check for line intersection with an arc. * * Mostly this is like the circle/line intersection * found in IsPointOnLine (search.c) see the detailed * discussion for the basics there. * * Some definitions (as in search.c:IsPointOnLine): * * Q - The point on the line segment where a line perpendicular to the * segment would intersect the center of the circle. * * D1 - The distance along the line from the first point to Q. * * D2 - The perpendicular distance from Q to the center of the circle. * * L - The length of the line segment. * * delta - the distance along the line segment from Q to the location where * the circle intersects the line. * * Since this is only an arc, not a full circle we need * to find the actual points of intersection with the * circle, and see if they are on the arc. To do this, we translate along the * line from the point Q plus or minus delta: * * delta = sqrt(Radius^2 - D2^2) * * The coordinates of the points of intersection can be calculated using * similar triangles: * * Px = X1 + (D1 +/- delta)(X2 - X1) / L * Py = Y1 + (D1 +/- delta)(Y2 - Y1) / L * * * The math below makes some substitutions: * * r = D1 * d = D2 * L * r2 = delta = sqrt(Radius^2 * L^2 - d^2) / L^2 * * Some older comments... * *
 * The projection is now of the form:
 *
 *      Px = X1 + (r +- r2)(X2 - X1)
 *      Py = Y1 + (r +- r2)(Y2 - Y1)
 * 
* * Where r2 sqrt(Radius^2 l^2 - d^2)/l^2 * note that this is the variable d, not the symbol d described in * IsPointOnLine (variable d = symbol d * l). * * The end points are hell so they are checked individually. */ bool LineArcIntersect (LineType *Line, ArcType *Arc) { double dx, dy, dx1, dy1, l, d, r, r2, Radius; BoxType *box; dx = Line->Point2.X - Line->Point1.X; dy = Line->Point2.Y - Line->Point1.Y; dx1 = Line->Point1.X - Arc->X; dy1 = Line->Point1.Y - Arc->Y; /* length of the line, squared */ l = dx * dx + dy * dy; /* minimum distance from the line to the center of the arc, times the * length of the line (D2*L from search.c equations) */ d = dx * dy1 - dy * dx1; d *= d; /* (D2*L)^2 */ /* Check the outer edge of the arc first. * Note: I'm not not entirely sure that this is the right way to * incorporate the line thickness... * */ Radius = Arc->Width + MAX (0.5 * (Arc->Thickness + Line->Thickness) + Bloat, 0.0); Radius *= Radius; /* If the argument to the square root is negative, then the arc is too far * away to be able to intersect the line. * */ r2 = Radius * l - d; if (r2 < 0) return (false); /* check the ends of the line in case the projected point */ /* of intersection is beyond the line end */ if (IsPointOnArc (Line->Point1.X, Line->Point1.Y, MAX (0.5 * Line->Thickness + Bloat, 0.0), Arc)) return (true); if (IsPointOnArc (Line->Point2.X, Line->Point2.Y, MAX (0.5 * Line->Thickness + Bloat, 0.0), Arc)) return (true); /* Zero length lines have some thickness, so, could still intersect. * However, they would have been caught by the previous tests. So, at this * point zero length means no intersection. * */ if (l == 0.0) return (false); /* Okay, fine... I guess we have to do some math. * */ r2 = sqrt (r2); /* delta * L^2 */ Radius = -(dx * dx1 + dy * dy1); /* Actually D1*L */ r = (Radius + r2) / l; /* (D1*L + delta*L^2) / L = (D1 + delta*L) */ /* r is now (supposed to be) the distance from the first point to the * further intersection, normalized to the length of the segment. * If r < 0, we're behind the segment, and if r > 1 we're beyond the segment. * */ if (r >= 0 && r <= 1 && IsPointOnArc (Line->Point1.X + r * dx, Line->Point1.Y + r * dy, MAX (0.5 * Line->Thickness + Bloat, 0.0), Arc)) return (true); /* Now check the other side. * */ r = (Radius - r2) / l; if (r >= 0 && r <= 1 && IsPointOnArc (Line->Point1.X + r * dx, Line->Point1.Y + r * dy, MAX (0.5 * Line->Thickness + Bloat, 0.0), Arc)) return (true); /* check arc end points */ box = GetArcEnds (Arc); if (IsPointInPad (box->X1, box->Y1, Arc->Thickness * 0.5 + Bloat, (PadType *)Line)) return true; if (IsPointInPad (box->X2, box->Y2, Arc->Thickness * 0.5 + Bloat, (PadType *)Line)) return true; return false; } /*! * \brief Checks if an arc has a connection to a polygon. * * - first check if the arc can intersect with the polygon by * evaluating the bounding boxes. * - check the two end points of the arc. If none of them matches * - check all segments of the polygon against the arc. */ /*static*/ bool IsArcInPolygon (ArcType *Arc, PolygonType *Polygon) { BoxType *Box = (BoxType *) Arc; /* arcs with clearance never touch polys */ if (TEST_FLAG (CLEARPOLYFLAG, Polygon) && TEST_FLAG (CLEARLINEFLAG, Arc)) return false; if (!Polygon->Clipped) return false; if (Box->X1 <= Polygon->Clipped->contours->xmax + Bloat && Box->X2 >= Polygon->Clipped->contours->xmin - Bloat && Box->Y1 <= Polygon->Clipped->contours->ymax + Bloat && Box->Y2 >= Polygon->Clipped->contours->ymin - Bloat) { POLYAREA *ap; if (!(ap = ArcPoly (Arc, Arc->Thickness + Bloat))) return false; /* error */ return isects (ap, Polygon, true); } return false; } /*! * \brief Checks if a line has a connection to a polygon. * * - first check if the line can intersect with the polygon by * evaluating the bounding boxes * - check the two end points of the line. If none of them matches * - check all segments of the polygon against the line. */ /*static*/ bool IsLineInPolygon (LineType *Line, PolygonType *Polygon) { BoxType *Box = (BoxType *) Line; POLYAREA *lp; /* lines with clearance never touch polygons */ if (TEST_FLAG (CLEARPOLYFLAG, Polygon) && TEST_FLAG (CLEARLINEFLAG, Line)) return false; if (!Polygon->Clipped) return false; if (TEST_FLAG(SQUAREFLAG,Line) /* Line has square ends */ && ( Line->Point1.X==Line->Point2.X /* Line is vertical */ || Line->Point1.Y==Line->Point2.Y)) /* Line is horizontal */ { /* Then a rectangle check will do. */ /* This condition is often the case with the pads of elements. */ Coord wid = (Line->Thickness + Bloat + 1) / 2; Coord x1, x2, y1, y2; x1 = MIN (Line->Point1.X, Line->Point2.X) - wid; y1 = MIN (Line->Point1.Y, Line->Point2.Y) - wid; x2 = MAX (Line->Point1.X, Line->Point2.X) + wid; y2 = MAX (Line->Point1.Y, Line->Point2.Y) + wid; return IsRectangleInPolygon (x1, y1, x2, y2, Polygon); } if (Box->X1 <= Polygon->Clipped->contours->xmax + Bloat && Box->X2 >= Polygon->Clipped->contours->xmin - Bloat && Box->Y1 <= Polygon->Clipped->contours->ymax + Bloat && Box->Y2 >= Polygon->Clipped->contours->ymin - Bloat) { if (!(lp = LinePoly (Line, Line->Thickness + Bloat))) return FALSE; /* error */ return isects (lp, Polygon, true); } return false; } /*! * \brief Checks if a pad connects to a non-clearing polygon. * * The polygon is assumed to already have been proven non-clearing. */ /*static*/ bool IsPadInPolygon (PadType *pad, PolygonType *polygon) { return IsLineInPolygon ((LineType *) pad, polygon); } /*! * \brief Checks if a polygon has a connection to a second one. * * First check all points out of P1 against P2 and vice versa. * If both fail check all lines of P1 against the ones of P2. */ /*static*/ bool IsPolygonInPolygon (PolygonType *P1, PolygonType *P2) { if (!P1->Clipped || !P2->Clipped) return false; assert (P1->Clipped->contours); assert (P2->Clipped->contours); /* first check if both bounding boxes intersect. If not, return quickly */ if (P1->Clipped->contours->xmin - Bloat > P2->Clipped->contours->xmax || P1->Clipped->contours->xmax + Bloat < P2->Clipped->contours->xmin || P1->Clipped->contours->ymin - Bloat > P2->Clipped->contours->ymax || P1->Clipped->contours->ymax + Bloat < P2->Clipped->contours->ymin) return false; /* first check un-bloated case */ if (isects (P1->Clipped, P2, false)) return TRUE; /* now the difficult case of bloated */ if (Bloat > 0) { PLINE *c; for (c = P1->Clipped->contours; c; c = c->next) { LineType line; VNODE *v = &c->head; if (c->xmin - Bloat <= P2->Clipped->contours->xmax && c->xmax + Bloat >= P2->Clipped->contours->xmin && c->ymin - Bloat <= P2->Clipped->contours->ymax && c->ymax + Bloat >= P2->Clipped->contours->ymin) { line.Point1.X = v->point[0]; line.Point1.Y = v->point[1]; line.Thickness = Bloat; /* Another Bloat is added by IsLineInPolygon, making the correct * 2x Bloat. Perhaps we should change it there, but doing so * breaks some other DRC checks which rely on the behaviour * in IsLineInPolygon. */ line.Clearance = 0; line.Flags = NoFlags (); for (v = v->next; v != &c->head; v = v->next) { line.Point2.X = v->point[0]; line.Point2.Y = v->point[1]; SetLineBoundingBox (&line); if (IsLineInPolygon (&line, P2)) return (true); line.Point1.X = line.Point2.X; line.Point1.Y = line.Point2.Y; } } } } return (false); } /*! * \brief Checks if a pin connects to a non-clearing polygon. * * The polygon is assumed to already have been proven non-clearing. * The pin/via is assumed to have been checked to intersect the polygon's * layer. * */ /*static*/ bool IsPinInPolygon (PinType *pin, PolygonType *polygon) { double wide = MAX (0.5 * pin->Thickness + Bloat, 0); if (TEST_FLAG (SQUAREFLAG, pin)) { Coord x1 = pin->X - (pin->Thickness + 1 + Bloat) / 2; Coord x2 = pin->X + (pin->Thickness + 1 + Bloat) / 2; Coord y1 = pin->Y - (pin->Thickness + 1 + Bloat) / 2; Coord y2 = pin->Y + (pin->Thickness + 1 + Bloat) / 2; if (IsRectangleInPolygon (x1, y1, x2, y2, polygon)) return true; } else if (TEST_FLAG (OCTAGONFLAG, pin)) { POLYAREA *oct = OctagonPoly (pin->X, pin->Y, pin->Thickness / 2); if (isects (oct, polygon, true)) return true; } else if (IsPointInPolygon (pin->X, pin->Y, wide, polygon)) return true; return false; } /* ----------------------------------------------------------------------- * * * Connection Lookup Stuff * * ----------------------------------------------------------------------- */ struct pv_info { Cardinal layer; PinType *pv; int flag; jmp_buf env; }; static int LOCtoPVline_callback (const BoxType * b, void *cl) { LineType *line = (LineType *) b; struct pv_info *i = (struct pv_info *) cl; if (!ViaIsOnLayerGroup (i->pv, GetLayerGroupNumberByNumber (i->layer))) return 0; if (!TEST_FLAG (i->flag, line) && PinLineIntersect (i->pv, line) && !TEST_FLAG (HOLEFLAG, i->pv)) { if (ADD_LINE_TO_LIST (i->layer, line, i->flag)) longjmp (i->env, 1); } return 0; } static int LOCtoPVarc_callback (const BoxType * b, void *cl) { ArcType *arc = (ArcType *) b; struct pv_info *i = (struct pv_info *) cl; if (!ViaIsOnLayerGroup (i->pv, GetLayerGroupNumberByNumber (i->layer))) return 0; if (!TEST_FLAG (i->flag, arc) && IS_PV_ON_ARC (i->pv, arc) && !TEST_FLAG (HOLEFLAG, i->pv)) { if (ADD_ARC_TO_LIST (i->layer, arc, i->flag)) longjmp (i->env, 1); } return 0; } static int LOCtoPVpad_callback (const BoxType * b, void *cl) { PadType *pad = (PadType *) b; struct pv_info *i = (struct pv_info *) cl; if (!ViaIsOnLayerGroup (i->pv, GetLayerGroupNumberBySide (TEST_FLAG (ONSOLDERFLAG, pad) ? BOTTOM_SIDE : TOP_SIDE))) return 0; if (!TEST_FLAG (i->flag, pad) && IS_PV_ON_PAD (i->pv, pad) && !TEST_FLAG (HOLEFLAG, i->pv) && ADD_PAD_TO_LIST (TEST_FLAG (ONSOLDERFLAG, pad) ? BOTTOM_SIDE : TOP_SIDE, pad, i->flag)) longjmp (i->env, 1); return 0; } static int LOCtoPVrat_callback (const BoxType * b, void *cl) { RatType *rat = (RatType *) b; struct pv_info *i = (struct pv_info *) cl; if (!TEST_FLAG (i->flag, rat) && IS_PV_ON_RAT (i->pv, rat) && ADD_RAT_TO_LIST (rat, i->flag)) longjmp (i->env, 1); return 0; } static int LOCtoPVpoly_callback (const BoxType * b, void *cl) { PolygonType *polygon = (PolygonType *) b; struct pv_info *i = (struct pv_info *) cl; if (!ViaIsOnLayerGroup (i->pv, GetLayerGroupNumberByNumber (i->layer))) return 0; /* if the pin doesn't have a therm and polygon is clearing * then it can't touch due to clearance, so skip the expensive * test. If it does have a therm, you still need to test * because it might not be inside the polygon, or it could * be on an edge such that it doesn't actually touch. */ if (!TEST_FLAG (i->flag, polygon) && !TEST_FLAG (HOLEFLAG, i->pv) && (TEST_THERM (i->layer, i->pv) || !TEST_FLAG (CLEARPOLYFLAG, polygon) || !i->pv->Clearance) && IsPinInPolygon(i->pv, polygon) && ADD_POLYGON_TO_LIST (i->layer, polygon, i->flag)) { longjmp (i->env, 1); } return 0; } /*! * \brief Checks if a PV is connected to LOs, if it is, the LO is added * to the appropriate list and the 'used' flag is set. */ static bool LookupLOConnectionsToPVList (int flag, bool AndRats) { Cardinal layer_no; struct pv_info info; info.flag = flag; /* loop over all PVs currently on list */ while (PVList.Location < PVList.Number) { BoxType search_box; /* get pointer to data */ info.pv = PVLIST_ENTRY (PVList.Location); search_box = expand_bounds (&info.pv->BoundingBox); /* Keep track of what item we started from for the drc. */ if (drc) SetThing(1, info.pv->Element ? PIN_TYPE : VIA_TYPE, /* type */ info.pv->Element ? info.pv->Element : info.pv, /* ptr1 */ info.pv, info.pv); /* ptr2, ptr3 */ /* check pads */ if (setjmp (info.env) == 0) r_search (PCB->Data->pad_tree, &search_box, NULL, LOCtoPVpad_callback, &info); else return true; /* now all lines, arcs and polygons of the several layers */ for (layer_no = 0; layer_no < max_copper_layer; layer_no++) { LayerType *layer = LAYER_PTR (layer_no); if (layer->no_drc) continue; info.layer = layer_no; /* add touching lines */ if (setjmp (info.env) == 0) r_search (layer->line_tree, &search_box, NULL, LOCtoPVline_callback, &info); else return true; /* add touching arcs */ if (setjmp (info.env) == 0) r_search (layer->arc_tree, &search_box, NULL, LOCtoPVarc_callback, &info); else return true; /* check all polygons */ if (setjmp (info.env) == 0) r_search (layer->polygon_tree, &search_box, NULL, LOCtoPVpoly_callback, &info); else return true; } /* Check for rat-lines that may intersect the PV */ if (AndRats) { if (setjmp (info.env) == 0) r_search (PCB->Data->rat_tree, &search_box, NULL, LOCtoPVrat_callback, &info); else return true; } PVList.Location++; } return false; } /*! * \brief Find all connections between LO at the current list position * and new LOs. */ static bool LookupLOConnectionsToLOList (int flag, bool AndRats) { bool done; Cardinal i, group, layer, ratposition, lineposition[MAX_LAYER], polyposition[MAX_LAYER], arcposition[MAX_LAYER], padposition[2]; /* copy the current LO list positions; the original data is changed * by 'LookupPVConnectionsToLOList()' which has to check the same * list entries plus the new ones */ for (i = 0; i < max_copper_layer; i++) { lineposition[i] = LineList[i].Location; polyposition[i] = PolygonList[i].Location; arcposition[i] = ArcList[i].Location; } for (i = 0; i < 2; i++) padposition[i] = PadList[i].Location; ratposition = RatList.Location; /* loop over all new LOs in the list; recurse until no * more new connections in the layergroup were found */ do { Cardinal *position; if (AndRats) { position = &ratposition; for (; *position < RatList.Number; (*position)++) { group = RATLIST_ENTRY (*position)->group1; if (LookupLOConnectionsToRatEnd (&(RATLIST_ENTRY (*position)->Point1), group, flag)) return (true); group = RATLIST_ENTRY (*position)->group2; if (LookupLOConnectionsToRatEnd (&(RATLIST_ENTRY (*position)->Point2), group, flag)) return (true); } } /* loop over all layergroups */ for (group = 0; group < max_group; group++) { Cardinal entry; for (entry = 0; entry < PCB->LayerGroups.Number[group]; entry++) { layer = PCB->LayerGroups.Entries[group][entry]; /* be aware that the layer number equal max_copper_layer * and max_copper_layer+1 have a special meaning for pads */ if (layer < max_copper_layer) { LayerType * pLayer = LAYER_PTR(layer); /* try all new lines */ position = &lineposition[layer]; for (; *position < LineList[layer].Number; (*position)++) { LineType * line = LINELIST_ENTRY (layer, *position); /* Keep track of what item we started from for the drc. */ if (drc) SetThing (1, LINE_TYPE, pLayer, line, line); if (LookupLOConnectionsToLine (line, group, flag, true, AndRats)) return (true); } /* try all new arcs */ position = &arcposition[layer]; for (; *position < ArcList[layer].Number; (*position)++) { ArcType * arc = ARCLIST_ENTRY(layer, *position); /* Keep track of what item we started from for the drc. */ if (drc) SetThing (1, ARC_TYPE, pLayer, arc, arc); if (LookupLOConnectionsToArc (arc, group, flag, AndRats)) return (true); } /* try all new polygons */ position = &polyposition[layer]; for (; *position < PolygonList[layer].Number; (*position)++) { PolygonType * poly = POLYGONLIST_ENTRY (layer, *position); /* Keep track of what item we started from for the drc. */ if (drc) SetThing (1, POLYGON_TYPE, pLayer, poly, poly); if (LookupLOConnectionsToPolygon (poly, group, flag, AndRats)) return (true); } } else { /* try all new pads */ layer -= max_copper_layer; if (layer > 1) { Message (_("bad layer number %d max_copper_layer=%d in find.c\n"), layer, max_copper_layer); return false; } position = &padposition[layer]; for (; *position < PadList[layer].Number; (*position)++) { PadType * pad = PADLIST_ENTRY (layer, *position); /* Keep track of what item we started from for the drc. */ if (drc) SetThing (1, PAD_TYPE, pad->Element, pad, pad); if (LookupLOConnectionsToPad (pad, group, flag, AndRats)) return (true); } } } } /* check if all lists are done; Later for-loops * may have changed the prior lists */ done = !AndRats || ratposition >= RatList.Number; done = done && padposition[0] >= PadList[0].Number && padposition[1] >= PadList[1].Number; for (layer = 0; layer < max_copper_layer; layer++) done = done && lineposition[layer] >= LineList[layer].Number && arcposition[layer] >= ArcList[layer].Number && polyposition[layer] >= PolygonList[layer].Number; } /* do */ while (!done); return (false); } /* * This function is an r_search callback. It's called to check if a pin or * via is overlapping with another pin or via. */ static int pv_pv_callback (const BoxType * b, void *cl) { /* Cast the object found by the r_search, it's known to be a pin */ PinType *pin = (PinType *) b; struct pv_info *i = (struct pv_info *) cl; bool pv_overlap = false; Cardinal l; /* If both vias are buried, check if the layers of the found via (pin) * overlap with the layers of the original via (i->pv). * * TODO: Why isn't PinPinIntersect called here? * TODO: Why aren't we checking the other flags, like we do below? */ if (VIA_IS_BURIED (pin) && VIA_IS_BURIED (i->pv)) { for (l = pin->BuriedFrom ; l <= pin->BuriedTo; l++) { if (ViaIsOnLayerGroup (i->pv, GetLayerGroupNumberByNumber (l))) { pv_overlap = true; break; } } if (!pv_overlap) return 0; } /* If either of the vias is a thru via, there is potential overlap. */ if (!TEST_FLAG (i->flag, pin) && PV_TOUCH_PV (i->pv, pin)) { /* If it's only a hole (no copper) then just issue a warning to the * log, and highlight the pin. It doesn't affect the netlist. */ if (TEST_FLAG (HOLEFLAG, pin) || TEST_FLAG (HOLEFLAG, i->pv)) { SET_FLAG (WARNFLAG, pin); Settings.RatWarn = true; if (pin->Element) Message (_("WARNING: Hole too close to pin.\n")); else Message (_("WARNING: Hole too close to via.\n")); } else if (ADD_PV_TO_LIST (pin, i->flag)) longjmp (i->env, 1); } return 0; } /*! * \brief Searches for new PVs that are connected to PVs on the list. */ static bool LookupPVConnectionsToPVList (int flag) { Cardinal save_place; struct pv_info info; info.flag = flag; /* loop over all PVs on list */ save_place = PVList.Location; while (PVList.Location < PVList.Number) { BoxType search_box; /* get pointer to data */ info.pv = PVLIST_ENTRY (PVList.Location); search_box = expand_bounds ((BoxType *)info.pv); /* Keep track of what item we started from for the drc. */ if (drc) SetThing(1, info.pv->Element ? PIN_TYPE : VIA_TYPE, /* type */ info.pv->Element ? info.pv->Element : info.pv, /* ptr1 */ info.pv, info.pv); /* ptr2, ptr3 */ if (setjmp (info.env) == 0) r_search (PCB->Data->via_tree, &search_box, NULL, pv_pv_callback, &info); else return true; if (setjmp (info.env) == 0) r_search (PCB->Data->pin_tree, &search_box, NULL, pv_pv_callback, &info); else return true; PVList.Location++; } PVList.Location = save_place; return (false); } struct lo_info { Cardinal layer; LineType *line; PadType *pad; ArcType *arc; PolygonType *polygon; RatType *rat; int flag; jmp_buf env; }; static int pv_line_callback (const BoxType * b, void *cl) { PinType *pv = (PinType *) b; struct lo_info *i = (struct lo_info *) cl; if (!ViaIsOnLayerGroup (pv, GetLayerGroupNumberByNumber (i->layer))) return 0; if (!TEST_FLAG (i->flag, pv) && PinLineIntersect (pv, i->line)) { if (TEST_FLAG (HOLEFLAG, pv)) { SET_FLAG (WARNFLAG, pv); Settings.RatWarn = true; Message (_("WARNING: Hole too close to line.\n")); } else if (ADD_PV_TO_LIST (pv, i->flag)) longjmp (i->env, 1); } return 0; } static int pv_pad_callback (const BoxType * b, void *cl) { PinType *pv = (PinType *) b; struct lo_info *i = (struct lo_info *) cl; if (!ViaIsOnLayerGroup (pv, GetLayerGroupNumberBySide (i->layer))) return 0; if (!TEST_FLAG (i->flag, pv) && IS_PV_ON_PAD (pv, i->pad)) { if (TEST_FLAG (HOLEFLAG, pv)) { SET_FLAG (WARNFLAG, pv); Settings.RatWarn = true; Message (_("WARNING: Hole too close to pad.\n")); } else if (ADD_PV_TO_LIST (pv, i->flag)) longjmp (i->env, 1); } return 0; } static int pv_arc_callback (const BoxType * b, void *cl) { PinType *pv = (PinType *) b; struct lo_info *i = (struct lo_info *) cl; if (!ViaIsOnLayerGroup (pv, GetLayerGroupNumberByNumber (i->layer))) return 0; if (!TEST_FLAG (i->flag, pv) && IS_PV_ON_ARC (pv, i->arc)) { if (TEST_FLAG (HOLEFLAG, pv)) { SET_FLAG (WARNFLAG, pv); Settings.RatWarn = true; Message (_("WARNING: Hole touches arc.\n")); } else if (ADD_PV_TO_LIST (pv, i->flag)) longjmp (i->env, 1); } return 0; } static int pv_poly_callback (const BoxType * b, void *cl) { PinType *pv = (PinType *) b; struct lo_info *i = (struct lo_info *) cl; if (!ViaIsOnLayerGroup (pv, GetLayerGroupNumberByNumber (i->layer))) return 0; /* note that holes in polygons are ok, so they don't generate warnings. */ if (!TEST_FLAG (i->flag, pv) && !TEST_FLAG (HOLEFLAG, pv) && (TEST_THERM (i->layer, pv) || !TEST_FLAG (CLEARPOLYFLAG, i->polygon) || !pv->Clearance)) { if (TEST_FLAG (SQUAREFLAG, pv)) { Coord x1, x2, y1, y2; x1 = pv->X - (PIN_SIZE (pv) + 1 + Bloat) / 2; x2 = pv->X + (PIN_SIZE (pv) + 1 + Bloat) / 2; y1 = pv->Y - (PIN_SIZE (pv) + 1 + Bloat) / 2; y2 = pv->Y + (PIN_SIZE (pv) + 1 + Bloat) / 2; if (IsRectangleInPolygon (x1, y1, x2, y2, i->polygon) && ADD_PV_TO_LIST (pv, i->flag)) longjmp (i->env, 1); } else if (TEST_FLAG (OCTAGONFLAG, pv)) { POLYAREA *oct = OctagonPoly (pv->X, pv->Y, PIN_SIZE (pv) / 2); if (isects (oct, i->polygon, true) && ADD_PV_TO_LIST (pv, i->flag)) longjmp (i->env, 1); } else { if (IsPointInPolygon (pv->X, pv->Y, PIN_SIZE (pv) * 0.5 + Bloat, i->polygon) && ADD_PV_TO_LIST (pv, i->flag)) longjmp (i->env, 1); } } return 0; } static int pv_rat_callback (const BoxType * b, void *cl) { PinType *pv = (PinType *) b; struct lo_info *i = (struct lo_info *) cl; /* rats can't cause DRC so there is no early exit */ if (!TEST_FLAG (i->flag, pv) && IS_PV_ON_RAT (pv, i->rat)) ADD_PV_TO_LIST (pv, i->flag); return 0; } /*! * \brief Searches for new PVs that are connected to NEW LOs on the list. * * This routine updates the position counter of the lists too. */ static bool LookupPVConnectionsToLOList (int flag, bool AndRats) { Cardinal layer_no; struct lo_info info; info.flag = flag; /* loop over all layers */ for (layer_no = 0; layer_no < max_copper_layer; layer_no++) { LayerType *layer = LAYER_PTR (layer_no); if (layer->no_drc) continue; /* do nothing if there are no PV's */ if (TotalP + TotalV == 0) { LineList[layer_no].Location = LineList[layer_no].Number; ArcList[layer_no].Location = ArcList[layer_no].Number; PolygonList[layer_no].Location = PolygonList[layer_no].Number; continue; } info.layer = layer_no; /* check all lines */ while (LineList[layer_no].Location < LineList[layer_no].Number) { BoxType search_box; info.line = LINELIST_ENTRY (layer_no, LineList[layer_no].Location); /* Keep track of what item we started from for the drc. */ if (drc) SetThing(1, LINE_TYPE, LAYER_PTR(layer_no), info.line, info.line); search_box = expand_bounds ((BoxType *)info.line); if (setjmp (info.env) == 0) r_search (PCB->Data->via_tree, &search_box, NULL, pv_line_callback, &info); else return true; if (setjmp (info.env) == 0) r_search (PCB->Data->pin_tree, &search_box, NULL, pv_line_callback, &info); else return true; LineList[layer_no].Location++; } /* check all arcs */ while (ArcList[layer_no].Location < ArcList[layer_no].Number) { BoxType search_box; info.arc = ARCLIST_ENTRY (layer_no, ArcList[layer_no].Location); /* Keep track of what item we started from for the drc. */ if (drc) SetThing(1, ARC_TYPE, LAYER_PTR(layer_no), info.arc, info.arc); search_box = expand_bounds ((BoxType *)info.arc); if (setjmp (info.env) == 0) r_search (PCB->Data->via_tree, &search_box, NULL, pv_arc_callback, &info); else return true; if (setjmp (info.env) == 0) r_search (PCB->Data->pin_tree, &search_box, NULL, pv_arc_callback, &info); else return true; ArcList[layer_no].Location++; } /* now all polygons */ info.layer = layer_no; while (PolygonList[layer_no].Location < PolygonList[layer_no].Number) { BoxType search_box; info.polygon = POLYGONLIST_ENTRY (layer_no, PolygonList[layer_no].Location); /* Keep track of what item we started from for the drc. */ if (drc) SetThing(1, POLYGON_TYPE, LAYER_PTR(layer_no), info.polygon, info.polygon); search_box = expand_bounds ((BoxType *)info.polygon); if (setjmp (info.env) == 0) r_search (PCB->Data->via_tree, &search_box, NULL, pv_poly_callback, &info); else return true; if (setjmp (info.env) == 0) r_search (PCB->Data->pin_tree, &search_box, NULL, pv_poly_callback, &info); else return true; PolygonList[layer_no].Location++; } } /* loop over all pad-layers */ for (layer_no = 0; layer_no < 2; layer_no++) { /* do nothing if there are no PV's */ if (TotalP + TotalV == 0) { PadList[layer_no].Location = PadList[layer_no].Number; continue; } /* check all pads; for a detailed description see * the handling of lines in this subroutine */ while (PadList[layer_no].Location < PadList[layer_no].Number) { BoxType search_box; info.layer = layer_no; info.pad = PADLIST_ENTRY (layer_no, PadList[layer_no].Location); /* Keep track of what item we started from for the drc. */ if (drc) SetThing(1, PAD_TYPE, info.pad->Element, info.pad, info.pad); search_box = expand_bounds ((BoxType *)info.pad); if (setjmp (info.env) == 0) r_search (PCB->Data->via_tree, &search_box, NULL, pv_pad_callback, &info); else return true; if (setjmp (info.env) == 0) r_search (PCB->Data->pin_tree, &search_box, NULL, pv_pad_callback, &info); else return true; PadList[layer_no].Location++; } } /* do nothing if there are no PV's */ if (TotalP + TotalV == 0) RatList.Location = RatList.Number; /* check all rat-lines */ if (AndRats) { while (RatList.Location < RatList.Number) { info.rat = RATLIST_ENTRY (RatList.Location); r_search_pt (PCB->Data->via_tree, & info.rat->Point1, 1, NULL, pv_rat_callback, &info); r_search_pt (PCB->Data->via_tree, & info.rat->Point2, 1, NULL, pv_rat_callback, &info); r_search_pt (PCB->Data->pin_tree, & info.rat->Point1, 1, NULL, pv_rat_callback, &info); r_search_pt (PCB->Data->pin_tree, & info.rat->Point2, 1, NULL, pv_rat_callback, &info); RatList.Location++; } } return (false); } static int LOCtoArcLine_callback (const BoxType * b, void *cl) { LineType *line = (LineType *) b; struct lo_info *i = (struct lo_info *) cl; if (!TEST_FLAG (i->flag, line) && LineArcIntersect (line, i->arc)) { if (ADD_LINE_TO_LIST (i->layer, line, i->flag)) longjmp (i->env, 1); } return 0; } static int LOCtoArcArc_callback (const BoxType * b, void *cl) { ArcType *arc = (ArcType *) b; struct lo_info *i = (struct lo_info *) cl; if (!arc->Thickness) return 0; if (!TEST_FLAG (i->flag, arc) && ArcArcIntersect (i->arc, arc)) { if (ADD_ARC_TO_LIST (i->layer, arc, i->flag)) longjmp (i->env, 1); } return 0; } static int LOCtoArcPad_callback (const BoxType * b, void *cl) { PadType *pad = (PadType *) b; struct lo_info *i = (struct lo_info *) cl; if (!TEST_FLAG (i->flag, pad) && i->layer == (TEST_FLAG (ONSOLDERFLAG, pad) ? BOTTOM_SIDE : TOP_SIDE) && ArcPadIntersect (i->arc, pad) && ADD_PAD_TO_LIST (i->layer, pad, i->flag)) longjmp (i->env, 1); return 0; } /*! * \brief Searches all LOs that are connected to the given arc on the * given layergroup. * * All found connections are added to the list. * * The notation that is used is:\n * Xij means Xj at arc i. */ static bool LookupLOConnectionsToArc (ArcType *Arc, Cardinal LayerGroup, int flag, bool AndRats) { Cardinal entry; struct lo_info info; BoxType search_box; info.flag = flag; info.arc = Arc; search_box = expand_bounds ((BoxType *)info.arc); /* loop over all layers of the group */ for (entry = 0; entry < PCB->LayerGroups.Number[LayerGroup]; entry++) { Cardinal layer_no; LayerType *layer; GList *i; layer_no = PCB->LayerGroups.Entries[LayerGroup][entry]; layer = LAYER_PTR (layer_no); /* handle normal layers */ if (layer_no < max_copper_layer) { info.layer = layer_no; /* add arcs */ if (setjmp (info.env) == 0) r_search (layer->line_tree, &search_box, NULL, LOCtoArcLine_callback, &info); else return true; if (setjmp (info.env) == 0) r_search (layer->arc_tree, &search_box, NULL, LOCtoArcArc_callback, &info); else return true; /* now check all polygons */ for (i = layer->Polygon; i != NULL; i = g_list_next (i)) { PolygonType *polygon = i->data; if (!TEST_FLAG (flag, polygon) && IsArcInPolygon (Arc, polygon) && ADD_POLYGON_TO_LIST (layer_no, polygon, flag)) return true; } } else { info.layer = layer_no - max_copper_layer; if (setjmp (info.env) == 0) r_search (PCB->Data->pad_tree, &search_box, NULL, LOCtoArcPad_callback, &info); else return true; } } return (false); } static int LOCtoLineLine_callback (const BoxType * b, void *cl) { LineType *line = (LineType *) b; struct lo_info *i = (struct lo_info *) cl; if (!TEST_FLAG (i->flag, line) && LineLineIntersect (i->line, line)) { if (ADD_LINE_TO_LIST (i->layer, line, i->flag)) longjmp (i->env, 1); } return 0; } static int LOCtoLineArc_callback (const BoxType * b, void *cl) { ArcType *arc = (ArcType *) b; struct lo_info *i = (struct lo_info *) cl; if (!arc->Thickness) return 0; if (!TEST_FLAG (i->flag, arc) && LineArcIntersect (i->line, arc)) { if (ADD_ARC_TO_LIST (i->layer, arc, i->flag)) longjmp (i->env, 1); } return 0; } static int LOCtoLineRat_callback (const BoxType * b, void *cl) { RatType *rat = (RatType *) b; struct lo_info *i = (struct lo_info *) cl; if (!TEST_FLAG (i->flag, rat)) { if ((rat->group1 == i->layer) && IsRatPointOnLineEnd (&rat->Point1, i->line)) { if (ADD_RAT_TO_LIST (rat, i->flag)) longjmp (i->env, 1); } else if ((rat->group2 == i->layer) && IsRatPointOnLineEnd (&rat->Point2, i->line)) { if (ADD_RAT_TO_LIST (rat, i->flag)) longjmp (i->env, 1); } } return 0; } static int LOCtoLinePad_callback (const BoxType * b, void *cl) { PadType *pad = (PadType *) b; struct lo_info *i = (struct lo_info *) cl; if (!TEST_FLAG (i->flag, pad) && i->layer == (TEST_FLAG (ONSOLDERFLAG, pad) ? BOTTOM_SIDE : TOP_SIDE) && LinePadIntersect (i->line, pad) && ADD_PAD_TO_LIST (i->layer, pad, i->flag)) longjmp (i->env, 1); return 0; } /*! * \brief Searches all LOs that are connected to the given line on the * given layergroup. * * All found connections are added to the list. * * The notation that is used is: * Xij means Xj at line i. */ static bool LookupLOConnectionsToLine (LineType *Line, Cardinal LayerGroup, int flag, bool PolysTo, bool AndRats) { Cardinal entry; struct lo_info info; BoxType search_box; info.flag = flag; info.layer = LayerGroup; info.line = Line; search_box = expand_bounds ((BoxType *)info.line); if (AndRats) { /* add the new rat lines */ if (setjmp (info.env) == 0) r_search (PCB->Data->rat_tree, &search_box, NULL, LOCtoLineRat_callback, &info); else return true; } /* loop over all layers of the group */ for (entry = 0; entry < PCB->LayerGroups.Number[LayerGroup]; entry++) { Cardinal layer_no; LayerType *layer; layer_no = PCB->LayerGroups.Entries[LayerGroup][entry]; layer = LAYER_PTR (layer_no); /* Note: for DRC, thing1 is set by the calling function, since this * function also handles pads with rounded ends. * */ /* handle normal layers */ if (layer_no < max_copper_layer) { info.layer = layer_no; /* add lines */ if (setjmp (info.env) == 0) r_search (layer->line_tree, &search_box, NULL, LOCtoLineLine_callback, &info); else return true; /* add arcs */ if (setjmp (info.env) == 0) r_search (layer->arc_tree, &search_box, NULL, LOCtoLineArc_callback, &info); else return true; /* now check all polygons */ if (PolysTo) { GList *i; for (i = layer->Polygon; i != NULL; i = g_list_next (i)) { PolygonType *polygon = i->data; if (!TEST_FLAG (flag, polygon) && IsLineInPolygon (Line, polygon) && ADD_POLYGON_TO_LIST (layer_no, polygon, flag)) return true; } } } else { /* handle special 'pad' layers */ info.layer = layer_no - max_copper_layer; if (setjmp (info.env) == 0) r_search (PCB->Data->pad_tree, &search_box, NULL, LOCtoLinePad_callback, &info); else return true; } } return (false); } struct rat_info { Cardinal layer; PointType *Point; int flag; jmp_buf env; }; static int LOCtoRat_callback (const BoxType * b, void *cl) { LineType *line = (LineType *) b; struct rat_info *i = (struct rat_info *) cl; if (!TEST_FLAG (i->flag, line) && ((line->Point1.X == i->Point->X && line->Point1.Y == i->Point->Y) || (line->Point2.X == i->Point->X && line->Point2.Y == i->Point->Y))) { if (ADD_LINE_TO_LIST (i->layer, line, i->flag)) longjmp (i->env, 1); } return 0; } static int PolygonToRat_callback (const BoxType * b, void *cl) { PolygonType *polygon = (PolygonType *) b; struct rat_info *i = (struct rat_info *) cl; if (!TEST_FLAG (i->flag, polygon) && polygon->Clipped && (i->Point->X == polygon->Clipped->contours->head.point[0]) && (i->Point->Y == polygon->Clipped->contours->head.point[1])) { if (ADD_POLYGON_TO_LIST (i->layer, polygon, i->flag)) longjmp (i->env, 1); } return 0; } static int LOCtoPad_callback (const BoxType * b, void *cl) { PadType *pad = (PadType *) b; struct rat_info *i = (struct rat_info *) cl; if (!TEST_FLAG (i->flag, pad) && i->layer == (TEST_FLAG (ONSOLDERFLAG, pad) ? BOTTOM_SIDE : TOP_SIDE) && ((pad->Point1.X == i->Point->X && pad->Point1.Y == i->Point->Y) || (pad->Point2.X == i->Point->X && pad->Point2.Y == i->Point->Y) || ((pad->Point1.X + pad->Point2.X) / 2 == i->Point->X && (pad->Point1.Y + pad->Point2.Y) / 2 == i->Point->Y)) && ADD_PAD_TO_LIST (i->layer, pad, i->flag)) longjmp (i->env, 1); return 0; } /*! * \brief Searches all LOs that are connected to the given rat-line on * the given layergroup. * * All found connections are added to the list. * * The notation that is used is: * Xij means Xj at line i. */ static bool LookupLOConnectionsToRatEnd (PointType *Point, Cardinal LayerGroup, int flag) { Cardinal entry; struct rat_info info; info.flag = flag; info.Point = Point; /* loop over all layers of this group */ for (entry = 0; entry < PCB->LayerGroups.Number[LayerGroup]; entry++) { Cardinal layer_no; LayerType *layer; layer_no = PCB->LayerGroups.Entries[LayerGroup][entry]; layer = LAYER_PTR (layer_no); /* handle normal layers rats don't ever touch arcs by definition */ if (layer_no < max_copper_layer) { info.layer = layer_no; if (setjmp (info.env) == 0) r_search_pt (layer->line_tree, Point, 1, NULL, LOCtoRat_callback, &info); else return true; if (setjmp (info.env) == 0) r_search_pt (layer->polygon_tree, Point, 1, NULL, PolygonToRat_callback, &info); } else { /* handle special 'pad' layers */ info.layer = layer_no - max_copper_layer; if (setjmp (info.env) == 0) r_search_pt (PCB->Data->pad_tree, Point, 1, NULL, LOCtoPad_callback, &info); else return true; } } return (false); } static int LOCtoPadLine_callback (const BoxType * b, void *cl) { LineType *line = (LineType *) b; struct lo_info *i = (struct lo_info *) cl; if (!TEST_FLAG (i->flag, line) && LinePadIntersect (line, i->pad)) { if (ADD_LINE_TO_LIST (i->layer, line, i->flag)) longjmp (i->env, 1); } return 0; } static int LOCtoPadArc_callback (const BoxType * b, void *cl) { ArcType *arc = (ArcType *) b; struct lo_info *i = (struct lo_info *) cl; if (!arc->Thickness) return 0; if (!TEST_FLAG (i->flag, arc) && ArcPadIntersect (arc, i->pad)) { if (ADD_ARC_TO_LIST (i->layer, arc, i->flag)) longjmp (i->env, 1); } return 0; } static int LOCtoPadPoly_callback (const BoxType * b, void *cl) { PolygonType *polygon = (PolygonType *) b; struct lo_info *i = (struct lo_info *) cl; if (!TEST_FLAG (i->flag, polygon) && (!TEST_FLAG (CLEARPOLYFLAG, polygon) || !i->pad->Clearance)) { if (IsPadInPolygon (i->pad, polygon) && ADD_POLYGON_TO_LIST (i->layer, polygon, i->flag)) longjmp (i->env, 1); } return 0; } static int LOCtoPadRat_callback (const BoxType * b, void *cl) { RatType *rat = (RatType *) b; struct lo_info *i = (struct lo_info *) cl; if (!TEST_FLAG (i->flag, rat)) { if (rat->group1 == i->layer && ((rat->Point1.X == i->pad->Point1.X && rat->Point1.Y == i->pad->Point1.Y) || (rat->Point1.X == i->pad->Point2.X && rat->Point1.Y == i->pad->Point2.Y) || (rat->Point1.X == (i->pad->Point1.X + i->pad->Point2.X) / 2 && rat->Point1.Y == (i->pad->Point1.Y + i->pad->Point2.Y) / 2))) { if (ADD_RAT_TO_LIST (rat, i->flag)) longjmp (i->env, 1); } else if (rat->group2 == i->layer && ((rat->Point2.X == i->pad->Point1.X && rat->Point2.Y == i->pad->Point1.Y) || (rat->Point2.X == i->pad->Point2.X && rat->Point2.Y == i->pad->Point2.Y) || (rat->Point2.X == (i->pad->Point1.X + i->pad->Point2.X) / 2 && rat->Point2.Y == (i->pad->Point1.Y + i->pad->Point2.Y) / 2))) { if (ADD_RAT_TO_LIST (rat, i->flag)) longjmp (i->env, 1); } } return 0; } static int LOCtoPadPad_callback (const BoxType * b, void *cl) { PadType *pad = (PadType *) b; struct lo_info *i = (struct lo_info *) cl; if (!TEST_FLAG (i->flag, pad) && i->layer == (TEST_FLAG (ONSOLDERFLAG, pad) ? BOTTOM_SIDE : TOP_SIDE) && PadPadIntersect (pad, i->pad) && ADD_PAD_TO_LIST (i->layer, pad, i->flag)) longjmp (i->env, 1); return 0; } /*! * \brief Searches all LOs that are connected to the given pad on the * given layergroup. * * All found connections are added to the list. */ static bool LookupLOConnectionsToPad (PadType *Pad, Cardinal LayerGroup, int flag, bool AndRats) { Cardinal entry; struct lo_info info; BoxType search_box; info.flag = flag; info.pad = Pad; if (!TEST_FLAG (SQUAREFLAG, Pad)) return (LookupLOConnectionsToLine ((LineType *) Pad, LayerGroup, flag, false, AndRats)); search_box = expand_bounds ((BoxType *)info.pad); /* add the new rat lines */ info.layer = LayerGroup; if (AndRats) { if (setjmp (info.env) == 0) r_search (PCB->Data->rat_tree, &search_box, NULL, LOCtoPadRat_callback, &info); else return true; } /* loop over all layers of the group */ for (entry = 0; entry < PCB->LayerGroups.Number[LayerGroup]; entry++) { Cardinal layer_no; LayerType *layer; layer_no = PCB->LayerGroups.Entries[LayerGroup][entry]; layer = LAYER_PTR (layer_no); /* handle normal layers */ if (layer_no < max_copper_layer) { info.layer = layer_no; /* add lines */ if (setjmp (info.env) == 0) r_search (layer->line_tree, &search_box, NULL, LOCtoPadLine_callback, &info); else return true; /* add arcs */ if (setjmp (info.env) == 0) r_search (layer->arc_tree, &search_box, NULL, LOCtoPadArc_callback, &info); else return true; /* add polygons */ if (setjmp (info.env) == 0) r_search (layer->polygon_tree, &search_box, NULL, LOCtoPadPoly_callback, &info); else return true; } else { /* handle special 'pad' layers */ info.layer = layer_no - max_copper_layer; if (setjmp (info.env) == 0) r_search (PCB->Data->pad_tree, &search_box, NULL, LOCtoPadPad_callback, &info); else return true; } } return (false); } static int LOCtoPolyLine_callback (const BoxType * b, void *cl) { LineType *line = (LineType *) b; struct lo_info *i = (struct lo_info *) cl; if (!TEST_FLAG (i->flag, line) && IsLineInPolygon (line, i->polygon)) { if (ADD_LINE_TO_LIST (i->layer, line, i->flag)) longjmp (i->env, 1); } return 0; } static int LOCtoPolyArc_callback (const BoxType * b, void *cl) { ArcType *arc = (ArcType *) b; struct lo_info *i = (struct lo_info *) cl; if (!arc->Thickness) return 0; if (!TEST_FLAG (i->flag, arc) && IsArcInPolygon (arc, i->polygon)) { if (ADD_ARC_TO_LIST (i->layer, arc, i->flag)) longjmp (i->env, 1); } return 0; } static int LOCtoPolyPad_callback (const BoxType * b, void *cl) { PadType *pad = (PadType *) b; struct lo_info *i = (struct lo_info *) cl; if (!TEST_FLAG (i->flag, pad) && i->layer == (TEST_FLAG (ONSOLDERFLAG, pad) ? BOTTOM_SIDE : TOP_SIDE) && IsPadInPolygon (pad, i->polygon)) { if (ADD_PAD_TO_LIST (i->layer, pad, i->flag)) longjmp (i->env, 1); } return 0; } static int LOCtoPolyRat_callback (const BoxType * b, void *cl) { RatType *rat = (RatType *) b; struct lo_info *i = (struct lo_info *) cl; if (!TEST_FLAG (i->flag, rat)) { if ((rat->Point1.X == (i->polygon->Clipped->contours->head.point[0]) && rat->Point1.Y == (i->polygon->Clipped->contours->head.point[1]) && rat->group1 == i->layer) || (rat->Point2.X == (i->polygon->Clipped->contours->head.point[0]) && rat->Point2.Y == (i->polygon->Clipped->contours->head.point[1]) && rat->group2 == i->layer)) if (ADD_RAT_TO_LIST (rat, i->flag)) longjmp (i->env, 1); } return 0; } /*! * \brief Looks up LOs that are connected to the given polygon on the * given layergroup. * * All found connections are added to the list. */ static bool LookupLOConnectionsToPolygon (PolygonType *Polygon, Cardinal LayerGroup, int flag, bool AndRats) { Cardinal entry; struct lo_info info; BoxType search_box; if (!Polygon->Clipped) return false; info.flag = flag; info.polygon = Polygon; search_box = expand_bounds ((BoxType *)info.polygon); info.layer = LayerGroup; /* check rats */ if (AndRats) { if (setjmp (info.env) == 0) r_search (PCB->Data->rat_tree, &search_box, NULL, LOCtoPolyRat_callback, &info); else return true; } /* loop over all layers of the group */ for (entry = 0; entry < PCB->LayerGroups.Number[LayerGroup]; entry++) { Cardinal layer_no; LayerType *layer; layer_no = PCB->LayerGroups.Entries[LayerGroup][entry]; layer = LAYER_PTR (layer_no); /* handle normal layers */ if (layer_no < max_copper_layer) { GList *i; /* check all polygons */ for (i = layer->Polygon; i != NULL; i = g_list_next (i)) { PolygonType *polygon = i->data; if (!TEST_FLAG (flag, polygon) && IsPolygonInPolygon (polygon, Polygon) && ADD_POLYGON_TO_LIST (layer_no, polygon, flag)) return true; } info.layer = layer_no; /* check all lines */ if (setjmp (info.env) == 0) r_search (layer->line_tree, &search_box, NULL, LOCtoPolyLine_callback, &info); else return true; /* check all arcs */ if (setjmp (info.env) == 0) r_search (layer->arc_tree, &search_box, NULL, LOCtoPolyArc_callback, &info); else return true; } else { info.layer = layer_no - max_copper_layer; if (setjmp (info.env) == 0) r_search (PCB->Data->pad_tree, &search_box, NULL, LOCtoPolyPad_callback, &info); else return true; } } return (false); } static void reassign_no_drc_flags (void) { int layer; for (layer = 0; layer < max_copper_layer; layer++) { LayerType *l = LAYER_PTR (layer); l->no_drc = AttributeGet (l, "PCB::skip-drc") != NULL; } } /*! * \brief Loops till no more connections are found. */ /*static*/ bool DoIt (int flag, Coord bloat, bool AndRats, bool AndDraw, bool is_drc) { bool newone = false; Bloat = bloat; drc = is_drc; reassign_no_drc_flags (); do { /* lookup connections; these are the steps (2) to (4) * from the description * * If anything is added to any of the lists, newone will be true. Any * new additions to the lists mean that there are potentially more things * to add to the list, things that might overlap with only the new * objects. */ newone = LookupPVConnectionsToPVList (flag) || LookupLOConnectionsToPVList (flag, AndRats) || LookupLOConnectionsToLOList (flag, AndRats) || LookupPVConnectionsToLOList (flag, AndRats); if (AndDraw) DrawNewConnections (); } /* Keep executing the lookup until no new objects are found. */ while (!newone && !ListsEmpty (AndRats)); if (AndDraw) Draw (); /* We should leave global state variables in a consistent state... */ Bloat = 0; return (newone); } /*! * \brief Resets some flags for looking up the next pin/pad. */ static bool PrepareNextLoop (FILE * FP) { Cardinal layer; /* reset found LOs for the next pin */ for (layer = 0; layer < max_copper_layer; layer++) { LineList[layer].Location = LineList[layer].Number = 0; ArcList[layer].Location = ArcList[layer].Number = 0; PolygonList[layer].Location = PolygonList[layer].Number = 0; } /* reset found pads */ for (layer = 0; layer < 2; layer++) PadList[layer].Location = PadList[layer].Number = 0; /* reset PVs */ PVList.Number = PVList.Location = 0; RatList.Number = RatList.Location = 0; return (false); } /* static */ void start_do_it_and_dump (int type, void *ptr1, void *ptr2, void *ptr3, int flag, bool AndDraw, Coord bloat, bool is_drc) { ListStart (type, ptr1, ptr2, ptr3, flag); DoIt (flag, bloat, true, AndDraw, is_drc); DumpList (); } /* ----------------------------------------------------------------------- * * * Ancillary Helper Functions * * ----------------------------------------------------------------------- */ /*! * \brief Writes the several names of an element to a file. */ static void PrintElementNameList (ElementType *Element, FILE * FP) { static DynamicStringType cname, pname, vname; CreateQuotedString (&cname, (char *)EMPTY (DESCRIPTION_NAME (Element))); CreateQuotedString (&pname, (char *)EMPTY (NAMEONPCB_NAME (Element))); CreateQuotedString (&vname, (char *)EMPTY (VALUE_NAME (Element))); fprintf (FP, "(%s %s %s)\n", cname.Data, pname.Data, vname.Data); } /*! * \brief Writes the several names of an element to a file. */ static void PrintConnectionElementName (ElementType *Element, FILE * FP) { fputs ("Element", FP); PrintElementNameList (Element, FP); fputs ("{\n", FP); } /*! * \brief Prints one {pin,pad,via}/element entry of connection lists. */ static void PrintConnectionListEntry (char *ObjName, ElementType *Element, bool FirstOne, FILE * FP) { static DynamicStringType oname; CreateQuotedString (&oname, ObjName); if (FirstOne) fprintf (FP, "\t%s\n\t{\n", oname.Data); else { fprintf (FP, "\t\t%s ", oname.Data); if (Element) PrintElementNameList (Element, FP); else fputs ("(__VIA__)\n", FP); } } /*! * \brief Prints all found connections of a pads to file FP * the connections are stacked in 'PadList'. */ static void PrintPadConnections (Cardinal Layer, FILE * FP, bool IsFirst) { Cardinal i; PadType *ptr; if (!PadList[Layer].Number) return; /* the starting pad */ if (IsFirst) { ptr = PADLIST_ENTRY (Layer, 0); if (ptr != NULL) PrintConnectionListEntry ((char *)UNKNOWN (ptr->Name), NULL, true, FP); else printf ("Skipping NULL ptr in 1st part of PrintPadConnections\n"); } /* we maybe have to start with i=1 if we are handling the * starting-pad itself */ for (i = IsFirst ? 1 : 0; i < PadList[Layer].Number; i++) { ptr = PADLIST_ENTRY (Layer, i); if (ptr != NULL) PrintConnectionListEntry ((char *)EMPTY (ptr->Name), (ElementType *)ptr->Element, false, FP); else printf ("Skipping NULL ptr in 2nd part of PrintPadConnections\n"); } } /*! * \brief Prints all found connections of a pin to file FP * the connections are stacked in 'PVList'. */ static void PrintPinConnections (FILE * FP, bool IsFirst) { Cardinal i; PinType *pv; if (!PVList.Number) return; if (IsFirst) { /* the starting pin */ pv = PVLIST_ENTRY (0); PrintConnectionListEntry ((char *)EMPTY (pv->Name), NULL, true, FP); } /* we maybe have to start with i=1 if we are handling the * starting-pin itself */ for (i = IsFirst ? 1 : 0; i < PVList.Number; i++) { /* get the elements name or assume that its a via */ pv = PVLIST_ENTRY (i); PrintConnectionListEntry ((char *)EMPTY (pv->Name), (ElementType *)pv->Element, false, FP); } } /*! * \brief Finds all connections to the pins of the passed element. * * The result is written to file FP. * * \return true if operation was aborted. */ static bool PrintElementConnections (ElementType *Element, FILE * FP, int flag, bool AndDraw) { PrintConnectionElementName (Element, FP); /* check all pins in element */ PIN_LOOP (Element); { /* pin might have been checked before, add to list if not */ if (TEST_FLAG (flag, pin)) { PrintConnectionListEntry ((char *)EMPTY (pin->Name), NULL, true, FP); fputs ("\t\t__CHECKED_BEFORE__\n\t}\n", FP); continue; } if (ADD_PV_TO_LIST (pin, flag)) return true; DoIt (flag, 0, true, AndDraw, false); /* printout all found connections */ PrintPinConnections (FP, true); PrintPadConnections (TOP_SIDE, FP, false); PrintPadConnections (BOTTOM_SIDE, FP, false); fputs ("\t}\n", FP); if (PrepareNextLoop (FP)) return (true); } END_LOOP; /* check all pads in element */ PAD_LOOP (Element); { Cardinal layer; /* pad might have been checked before, add to list if not */ if (TEST_FLAG (flag, pad)) { PrintConnectionListEntry ((char *)EMPTY (pad->Name), NULL, true, FP); fputs ("\t\t__CHECKED_BEFORE__\n\t}\n", FP); continue; } layer = TEST_FLAG (ONSOLDERFLAG, pad) ? BOTTOM_SIDE : TOP_SIDE; if (ADD_PAD_TO_LIST (layer, pad, flag)) return true; DoIt (flag, 0, true, AndDraw, false); /* print all found connections */ PrintPadConnections (layer, FP, true); PrintPadConnections (layer == (TOP_SIDE ? BOTTOM_SIDE : TOP_SIDE), FP, false); PrintPinConnections (FP, false); fputs ("\t}\n", FP); if (PrepareNextLoop (FP)) return (true); } END_LOOP; fputs ("}\n\n", FP); return (false); } /*! * \brief Draws all new connections which have been found since the * routine was called the last time. */ static void DrawNewConnections (void) { int i; Cardinal position; /* decrement 'i' to keep layerstack order */ for (i = max_copper_layer - 1; i != -1; i--) { Cardinal layer = LayerStack[i]; if (PCB->Data->Layer[layer].On) { /* draw all new lines */ position = LineList[layer].DrawLocation; for (; position < LineList[layer].Number; position++) DrawLine (LAYER_PTR (layer), LINELIST_ENTRY (layer, position)); LineList[layer].DrawLocation = LineList[layer].Number; /* draw all new arcs */ position = ArcList[layer].DrawLocation; for (; position < ArcList[layer].Number; position++) DrawArc (LAYER_PTR (layer), ARCLIST_ENTRY (layer, position)); ArcList[layer].DrawLocation = ArcList[layer].Number; /* draw all new polygons */ position = PolygonList[layer].DrawLocation; for (; position < PolygonList[layer].Number; position++) DrawPolygon (LAYER_PTR (layer), POLYGONLIST_ENTRY (layer, position)); PolygonList[layer].DrawLocation = PolygonList[layer].Number; } } /* draw all new pads */ if (PCB->PinOn) for (i = 0; i < 2; i++) { position = PadList[i].DrawLocation; for (; position < PadList[i].Number; position++) DrawPad (PADLIST_ENTRY (i, position)); PadList[i].DrawLocation = PadList[i].Number; } /* draw all new PVs; 'PVList' holds a list of pointers to the * sorted array pointers to PV data */ while (PVList.DrawLocation < PVList.Number) { PinType *pv = PVLIST_ENTRY (PVList.DrawLocation); if (TEST_FLAG (PINFLAG, pv)) { if (PCB->PinOn) DrawPin (pv); } else if (PCB->ViaOn) DrawVia (pv); PVList.DrawLocation++; } /* draw the new rat-lines */ if (PCB->RatOn) { position = RatList.DrawLocation; for (; position < RatList.Number; position++) DrawRat (RATLIST_ENTRY (position)); RatList.DrawLocation = RatList.Number; } } /* ----------------------------------------------------------------------- * * * Entry Points * * ----------------------------------------------------------------------- */ /*! * \brief Set the specified flag on all objects that touch the object at * the given coordinates. * * The objects are re-drawn if AndDraw is true. */ void LookupConnection (Coord X, Coord Y, bool AndDraw, Coord Range, int flag, bool AndRats) { void *ptr1, *ptr2, *ptr3; char *name; int type; /* check if there are any pins or pads at that position */ reassign_no_drc_flags (); /* LOOKUP_FIRST = PIN_TYPE | PAD_TYPE */ /* LOOKUP_MORE = Vias, lines, ratlines, polygons, arcs */ /* SILK_TYPE = lines, arcs, polygons */ type = SearchObjectByLocation (LOOKUP_FIRST, &ptr1, &ptr2, &ptr3, X, Y, Range); if (type == NO_TYPE) { type = SearchObjectByLocation ( LOOKUP_MORE & ~(AndRats ? 0 : RATLINE_TYPE), &ptr1, &ptr2, &ptr3, X, Y, Range); if (type == NO_TYPE) return; if (type & SILK_TYPE) { int laynum = GetLayerNumber (PCB->Data, (LayerType *) ptr1); /* don't mess with non-conducting objects! */ if (laynum >= max_copper_layer || ((LayerType *)ptr1)->no_drc) return; } } /* If the netlist window is open, this will highlight the entry * corresponding to net of the pin or pad we just found. It does not open * the window it is closed. */ name = ConnectionName (type, ptr1, ptr2); hid_actionl ("NetlistShow", name, NULL); InitConnectionLookup (); /* now add the object to the appropriate list and start scanning * This is step (1) from the description */ ListStart (type, ptr1, ptr2, ptr3, flag); DoIt (flag, 0, AndRats, AndDraw, false); /* we are done */ if (AndDraw) Draw (); if (AndDraw && Settings.RingBellWhenFinished) gui->beep (); FreeConnectionLookupMemory (); } void LookupConnectionByPin (int type, void *ptr1) { /* int TheFlag = FOUNDFLAG; */ LockUndo(); InitConnectionLookup (); ListStart (type, NULL, ptr1, NULL, FOUNDFLAG); DoIt (FOUNDFLAG, 0, true, false, false); FreeConnectionLookupMemory (); UnlockUndo(); } /*! * \brief Find connections for rats nesting. * * Assumes InitConnectionLookup() has already been done. */ void RatFindHook (int type, void *ptr1, void *ptr2, void *ptr3, bool undo, int flag, bool AndRats) { if(!undo) LockUndo(); DumpList (); ListStart (type, ptr1, ptr2, ptr3, flag); DoIt (flag, 0, AndRats, false, false); /* This is potentially problematic if there is a higher level function * that has locked the undo system. */ UnlockUndo(); } /*! * \brief Prints all unused pins of an element to file FP. */ static bool PrintAndSelectUnusedPinsAndPadsOfElement (ElementType *Element, FILE * FP, int flag) { bool first = true; Cardinal number; static DynamicStringType oname; /* check all pins in element */ PIN_LOOP (Element); { if (!TEST_FLAG (HOLEFLAG, pin)) { /* pin might have bee checked before, add to list if not */ if (!TEST_FLAG (flag, pin) && FP) { int i; if (ADD_PV_TO_LIST (pin, flag)) return true; DoIt (flag, 0, true, true, false); number = PadList[TOP_SIDE].Number + PadList[BOTTOM_SIDE].Number + PVList.Number; /* the pin has no connection if it's the only * list entry; don't count vias */ for (i = 0; i < PVList.Number; i++) if (!PVLIST_ENTRY (i)->Element) number--; if (number == 1) { /* output of element name if not already done */ if (first) { PrintConnectionElementName (Element, FP); first = false; } /* write name to list and draw selected object */ CreateQuotedString (&oname, (char *)EMPTY (pin->Name)); fprintf (FP, "\t%s\n", oname.Data); SET_FLAG (SELECTEDFLAG, pin); DrawPin (pin); } /* reset found objects for the next pin */ if (PrepareNextLoop (FP)) return (true); } } } END_LOOP; /* check all pads in element */ PAD_LOOP (Element); { /* lookup pad in list */ /* pad might has bee checked before, add to list if not */ if (!TEST_FLAG (flag, pad) && FP) { int i; if (ADD_PAD_TO_LIST (TEST_FLAG (ONSOLDERFLAG, pad) ? BOTTOM_SIDE : TOP_SIDE, pad, flag)) return true; DoIt (flag, 0, true, true, false); number = PadList[TOP_SIDE].Number + PadList[BOTTOM_SIDE].Number + PVList.Number; /* the pin has no connection if it's the only * list entry; don't count vias */ for (i = 0; i < PVList.Number; i++) if (!PVLIST_ENTRY (i)->Element) number--; if (number == 1) { /* output of element name if not already done */ if (first) { PrintConnectionElementName (Element, FP); first = false; } /* write name to list and draw selected object */ CreateQuotedString (&oname, (char *)EMPTY (pad->Name)); fprintf (FP, "\t%s\n", oname.Data); SET_FLAG (SELECTEDFLAG, pad); DrawPad (pad); } /* reset found objects for the next pin */ if (PrepareNextLoop (FP)) return (true); } } END_LOOP; /* print separator if element has unused pins or pads */ if (!first) { fputs ("}\n\n", FP); SEPARATE (FP); } return (false); } /*! * \brief Find all unused pins of all elements. */ void LookupUnusedPins (FILE * FP) { /* reset all currently marked connections */ ClearFlagOnAllObjects (FOUNDFLAG, true); InitConnectionLookup (); ELEMENT_LOOP (PCB->Data); { /* break if abort dialog returned true; * passing NULL as filedescriptor discards the normal output */ if (PrintAndSelectUnusedPinsAndPadsOfElement (element, FP, FOUNDFLAG)) break; } END_LOOP; if (Settings.RingBellWhenFinished) gui->beep (); FreeConnectionLookupMemory (); IncrementUndoSerialNumber (); Draw (); } /*! * \brief Find all connections to pins within one element. */ void LookupElementConnections (ElementType *Element, FILE * FP) { /* reset all currently marked connections */ ClearFlagOnAllObjects (FOUNDFLAG, true); InitConnectionLookup (); PrintElementConnections (Element, FP, FOUNDFLAG, true); SetChangedFlag (true); if (Settings.RingBellWhenFinished) gui->beep (); FreeConnectionLookupMemory (); IncrementUndoSerialNumber (); Draw (); } /*! * \brief Find all connections to pins of all element. * * This is called by an action to write out a list of all of the pins and * pads connected to each pin/pad of every element on the board. Kind of * an element oriented netlist. * * Since this runs to completion without any user interaction, and should * leave the database in the same state it was found, there's no reason to * add all of the overhead of making everything undo-able. */ void LookupConnectionsToAllElements (FILE * FP) { LockUndo(); /* reset all currently marked connections */ ClearFlagOnAllObjects (FOUNDFLAG, false); InitConnectionLookup (); ELEMENT_LOOP (PCB->Data); { /* break if abort dialog returned true */ if (PrintElementConnections (element, FP, FOUNDFLAG, false)) break; SEPARATE (FP); if (Settings.ResetAfterElement && n != 1) ClearFlagOnAllObjects (FOUNDFLAG, false); } END_LOOP; if (Settings.RingBellWhenFinished) gui->beep (); ClearFlagOnAllObjects (FOUNDFLAG, false); UnlockUndo(); FreeConnectionLookupMemory (); Redraw (); } pcb-4.3.0/src/strflags.h0000664000175000017500000000317013773431044012001 00000000000000/*! * \file src/strflags.h * * \brief Prototypes for strflags. * * The purpose of this interface is to make the file format able to * handle more than 32 flags, and to hide the internal details of * flags from the file format. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 2005 DJ Delorie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * * DJ Delorie, 334 North Road, Deerfield NH 03037-1110, USA * * dj@delorie.com */ #ifndef PCB_STRFLAGS_H #define PCB_STRFLAGS_H FlagType string_to_flags (const char *flagstring, int (*error) (const char *msg)); char *flags_to_string (FlagType flags, int object_type); FlagType string_to_pcbflags (const char *flagstring, int (*error) (const char *msg)); char *pcbflags_to_string (FlagType flags); void uninit_strflags_buf (void); void uninit_strflags_layerlist (void); #endif /* PCB_STRFLAGS_H */ pcb-4.3.0/src/renumber.c0000664000175000017500000001072613773431044011773 00000000000000/*! * \file renumber.c * * \brief Renumber refdesses on pcb or in the buffer. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 2006 DJ Delorie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include "config.h" #include "global.h" #include "data.h" #include "hid.h" #include "misc.h" #include "create.h" #include "rtree.h" #include "undo.h" #include "error.h" #include "change.h" /* %start-doc actions RenumberBlock The @code{RenumberBlocks()} action renumbers all selected refdesses on the pcb. Usage: RenumberBlock(oldnum,newnum) All selected elements are renumbered by adding (newnum-oldnum) to the existing number. To invoke it, use the command window, usually by typing ":". Example: @code{RenumberBlock(100,200)} will change R213 to R313. %end-doc */ static int renumber_block (int argc, char **argv, Coord x, Coord y) { char num_buf[15]; int old_base; int new_base; if (argc < 2) { Message("Usage: RenumberBlock oldnum newnum"); return 1; } old_base = atoi (argv[0]); new_base = atoi (argv[1]); SET_FLAG (NAMEONPCBFLAG, PCB); ELEMENT_LOOP (PCB->Data); { char *refdes_split; char *cp; char *old_ref; char *new_ref; int num; if (!TEST_FLAG (SELECTEDFLAG, element) || EMPTY_STRING_P(element->Name[1].TextString)) continue; old_ref = element->Name[1].TextString; for (refdes_split = cp = old_ref; *cp; cp++) if (!isdigit (*cp)) refdes_split = cp+1; num = atoi (refdes_split); num += (new_base - old_base); sprintf(num_buf, "%d" ,num); new_ref = (char *) malloc (refdes_split - old_ref + strlen (num_buf) + 1); memcpy (new_ref, old_ref, refdes_split - old_ref); strcpy (new_ref + (refdes_split - old_ref), num_buf); AddObjectToChangeNameUndoList (ELEMENT_TYPE, NULL, NULL, element, NAMEONPCB_NAME (element)); ChangeObjectName (ELEMENT_TYPE, element, NULL, NULL, new_ref); } END_LOOP; IncrementUndoSerialNumber (); return 0; } /* %start-doc actions RenumberBuffer The @code{RenumberBuffer()} action renumbers all selected refdesses in the paste buffer. Usage: RenumberBuffer(oldnum,newnum) All selected elements are renumbered by adding (newnum-oldnum) to the existing number. To invoke it, use the command window, usually by typing ":". Example: @code{RenumberBuffer(0,10)} will change R2 to R12. %end-doc */ static int renumber_buffer (int argc, char **argv, Coord x, Coord y) { char num_buf[15]; int old_base; int new_base; if (argc < 2) { Message("Usage: RenumberBuffer oldnum newnum"); return 1; } old_base = atoi (argv[0]); new_base = atoi (argv[1]); SET_FLAG (NAMEONPCBFLAG, PCB); ELEMENT_LOOP (PASTEBUFFER->Data); { char *refdes_split; char *cp; char *old_ref; char *new_ref; int num; if (EMPTY_STRING_P(element->Name[1].TextString)) continue; old_ref = element->Name[1].TextString; for (refdes_split=cp=old_ref; *cp; cp++) if (!isdigit(*cp)) refdes_split = cp+1; num = atoi (refdes_split); num += (new_base - old_base); sprintf (num_buf, "%d" ,num); new_ref = (char *) malloc (refdes_split - old_ref + strlen (num_buf) + 1); memcpy (new_ref, old_ref, refdes_split - old_ref); strcpy (new_ref + (refdes_split - old_ref), num_buf); ChangeObjectName (ELEMENT_TYPE, element, NULL, NULL, new_ref); } END_LOOP; return 0; } static HID_Action renumber_block_action_list[] = { {"RenumberBlock", NULL, renumber_block, NULL, NULL}, {"RenumberBuffer", NULL, renumber_buffer, NULL, NULL} }; REGISTER_ACTIONS (renumber_block_action_list) void hid_renumber_init() { register_renumber_block_action_list(); } pcb-4.3.0/src/error.c0000664000175000017500000001171513773431044011304 00000000000000/*! * \file src/error.c * * \brief Error and debug functions. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996, 2005 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * Thomas.Nau@rz.uni-ulm.de */ /* * getpid() needs a cast to (int) to get rid of compiler warnings * on several architectures */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include #include "global.h" #include "data.h" #include "error.h" #include "file.h" #include "misc.h" #ifdef HAVE_LIBDMALLOC #include #endif #define utf8_dup_string(a,b) *(a) = strdup(b) /* ---------------------------------------------------------------------- * some external identifiers */ #if !defined(HAVE_STRERROR) extern int sys_nerr; /*!< Number of messages available from array. */ #define USE_SYS_ERRLIST #endif /* the list is already defined for some OS */ #if !defined(__NetBSD__) && !defined(__FreeBSD__) && !defined(__linux__) && !defined(__DragonFly__) #ifdef USE_SYS_ERRLIST extern char *sys_errlist[]; /*!< Array of error messages. */ #endif #endif /*! * \brief Output of message in a dialog window or log window. */ void Message (const char *Format, ...) { va_list args; va_start (args, Format); gui->logv (Format, args); va_end (args); } /*! * \brief Print standard 'open error'. */ void OpenErrorMessage (char *Filename) { char *utf8 = NULL; utf8_dup_string (&utf8, Filename); #ifdef USE_SYS_ERRLIST Message (_("Can't open file\n" " '%s'\nfopen() returned: '%s'\n"), utf8, errno <= sys_nerr ? sys_errlist[errno] : "???"); #else Message (_("Can't open file\n" " '%s'\nfopen() returned: '%s'\n"), utf8, strerror (errno)); #endif free (utf8); } /*! * \brief Print standard 'popen error'. */ void PopenErrorMessage (char *Filename) { char *utf8 = NULL; utf8_dup_string (&utf8, Filename); #ifdef USE_SYS_ERRLIST Message (_("Can't execute command\n" " '%s'\npopen() returned: '%s'\n"), utf8, errno <= sys_nerr ? sys_errlist[errno] : "???"); #else Message (_("Can't execute command\n" " '%s'\npopen() returned: '%s'\n"), utf8, strerror (errno)); #endif free (utf8); } /*! * \brief Print standard 'opendir'. */ void OpendirErrorMessage (char *DirName) { char *utf8 = NULL; utf8_dup_string (&utf8, DirName); #ifdef USE_SYS_ERRLIST Message (_("Can't scan directory\n" " '%s'\nopendir() returned: '%s'\n"), utf8, errno <= sys_nerr ? sys_errlist[errno] : "???"); #else Message (_("Can't scan directory\n" " '%s'\nopendir() returned: '%s'\n"), utf8, strerror (errno)); #endif free (utf8); } /*! * \brief Print standard 'chdir error'. */ void ChdirErrorMessage (char *DirName) { char *utf8 = NULL; utf8_dup_string (&utf8, DirName); #ifdef USE_SYS_ERRLIST Message (_("Can't change working directory to\n" " '%s'\nchdir() returned: '%s'\n"), utf8, errno <= sys_nerr ? sys_errlist[errno] : "???"); #else Message (_("Can't change working directory to\n" " '%s'\nchdir() returned: '%s'\n"), utf8, strerror (errno)); #endif free (utf8); } /*! * \brief Output of fatal error message. */ void MyFatal (char *Format, ...) { va_list args; va_start (args, Format); /* try to save the layout and do some cleanup */ EmergencySave (); fprintf (stderr, "%s (%i): fatal, ", Progname, (int) getpid ()); vfprintf (stderr, Format, args); fflush (stderr); va_end (args); exit (1); } /*! * \brief Catches signals which abort the program. */ void CatchSignal (int Signal) { char *s; switch (Signal) { #ifdef SIGHUP case SIGHUP: s = "SIGHUP"; break; #endif case SIGINT: s = "SIGINT"; break; #ifdef SIGQUIT case SIGQUIT: s = "SIGQUIT"; break; #endif case SIGABRT: s = "SIGABRT"; break; case SIGTERM: s = "SIGTERM"; break; case SIGSEGV: s = "SIGSEGV"; break; default: s = "unknown"; break; } MyFatal ("aborted by %s signal\n", s); } pcb-4.3.0/src/strcasestr.c0000664000175000017500000000364013773431044012346 00000000000000/*! * \file src/strcasestr.c * * \brief Replacement for strcasestr on systems which need it * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 2017 Dan McMahill * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_STRING_H #include #endif #if !HAVE_STRCASESTR /* * strcasestr() is non-standard so provide a replacement * when missing */ char * strcasestr(const char *big, const char *little) { char *b, *l, *p; b = strdup(big); if(b == NULL ) { return NULL; } l = strdup(little); if(l == NULL ) { free(b); return NULL; } p = b; while(*p != '\0') { if (islower(*p)) { *p = (char) toupper( (int) *p); } p++; } p = l; while(*p != '\0') { if (islower(*p)) { *p = (char) toupper( (int) *p); } p++; } /* cheat and do this the easy. Convert to upper case, * use strstr, and then figure out an offset in *big */ p = strstr(b, l); if (p == NULL) { free(b); free(l); return NULL; } p = (char *) big + (p - b); free(b); free(l); return p; } #endif pcb-4.3.0/src/layerflags.c0000664000175000017500000001345513773431044012307 00000000000000/*! * \file src/layerflags.c * * \brief Functions for changing layer flags. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 2007 DJ Delorie * * Copyright (C) 2015 Markus "Traumflug" Hitter * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_STRING_H #include #endif #include "globalconst.h" #include "global.h" #include "compat.h" #include "data.h" #include "error.h" #include "hid.h" #include "strflags.h" #include "layerflags.h" /*! * \brief These are the names of all the Layertypes defined in hid.h. * * Order here has to match the order of typedef enum LayertypeType there. * They're used for parsing/writing layer types from/to the layout file. */ static char *layertype_name[LT_NUM_LAYERTYPES + 1] = { "copper", /* LT_COPPER */ "silk", /* LT_SILK */ "mask", /* LT_MASK */ "paste", /* LT_PASTE */ "outline", /* LT_OUTLINE */ "route", /* LT_ROUTE */ "keepout", /* LT_KEEPOUT */ "fab", /* LT_FAB */ "assy", /* LT_ASSY */ "notes", /* LT_NOTES */ "no_type" /* LT_NUM_LAYERTYPES */ }; LayertypeType string_to_layertype (const char *flagstring, int (*error) (const char *msg)) { LayertypeType type = 0; if (*flagstring == '"') flagstring++; while (flagstring > (char *)1 && strlen (flagstring) > 1) { for (type = 0; type < LT_NUM_LAYERTYPES; type++) { if (strcmp (flagstring, layertype_name[type]) == 0) break; } if (type == LT_NUM_LAYERTYPES) flagstring = strchr (flagstring, ',') + 1; else break; } return type; } const char * layertype_to_string (LayertypeType type) { const char *rv = ""; if (type < LT_NUM_LAYERTYPES) rv = layertype_name[type]; return rv; } /*! * \brief Given a layer without type, try to guess its type, mostly from * its name. * * This is used by parse_y.y for compatibility with old file formats and * _not_ used when such flags are already present in the file. */ LayertypeType guess_layertype (const char *name, int layer_number, DataType *data) { LayertypeType type; /* First try to find known (partial) matches. */ for (type = 0; type < LT_NUM_LAYERTYPES; type++) { if (strcasestr (name, layertype_name[type])) break; } /* Nothing found? Then it's likely copper. */ if (type == LT_NUM_LAYERTYPES) type = LT_COPPER; return type; } /* --------------------------------------------------------------------------- */ static const char listlayertypes_syntax[] = N_("ListLayertypes()"); static const char listlayertypes_help[] = N_("List all available layertypes.\n"); /* %start-doc actions ListLayertypes Lists all available layer types. These are the valid types for the second argument of @pxref{SetLayertype Action} or when editing the layout file with a text editor. %end-doc */ static int ActionListLayertypes (int argc, char **argv, Coord x, Coord y) { LayertypeType type; Message (N_("Available layer types:\n")); for (type = 0; type < LT_NUM_LAYERTYPES; type++) Message (" %s (%d)\n", layertype_name[type], type); return 0; } /* --------------------------------------------------------------------------- */ static const char setlayertype_syntax[] = N_("SetLayertype(layer, type)"); static const char setlayertype_help[] = N_("Sets the type of a layer. Type can be given by name or by number.\n" "For a list of available types, run ListLayertypes()."); /* %start-doc actions SetLayertype Layers can have various types, like @emph{copper}, @emph{silk} or @emph{outline}. Behaviour of GUI and exporters largely depend on these types. For example, searching for electrical connections searches only layers of type @emph{copper}, all other layers are ignored. For a list of available types see @pxref{ListLayertypes Action}. %end-doc */ int ActionSetLayertype (int argc, char **argv, Coord x, Coord y) { int index; LayertypeType type; if (argc != 2) AFAIL (setlayertype); /* layer array is zero-based, file format counts layers starting at 1. */ index = atoi (argv[0]) - 1; if (index < 0 || index >= max_copper_layer + SILK_LAYER) { Message (N_("Layer index %d out of range, must be 0 ... %d\n"), index + 1, max_copper_layer + SILK_LAYER); return 1; } if (isdigit (argv[1][0])) type = atoi (argv[1]); else type = string_to_layertype (argv[1], NULL); if (type < 0 || type >= LT_NUM_LAYERTYPES) { Message (N_("Invalid layer type (%d) requested. " "See ListLayertypes() for a list.\n"), type); return 1; } PCB->Data->Layer[index].Type = type; return 0; } HID_Action layerflags_action_list[] = { {"ListLayertypes", 0, ActionListLayertypes, listlayertypes_help, listlayertypes_syntax} , {"SetLayertype", 0, ActionSetLayertype, setlayertype_help, setlayertype_syntax} }; REGISTER_ACTIONS (layerflags_action_list) pcb-4.3.0/src/edif.h0000664000175000017500000004676513773432516011111 00000000000000/* A Bison parser, made by GNU Bison 3.5.1. */ /* Bison interface for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* Undocumented macros, especially those whose name start with YY_, are private implementation details. Do not rely on them. */ #ifndef YY_EDIF_EDIF_H_INCLUDED # define YY_EDIF_EDIF_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif #if YYDEBUG extern int edifdebug; #endif /* Token type. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE enum yytokentype { EDIF_TOK_IDENT = 258, EDIF_TOK_INT = 259, EDIF_TOK_KEYWORD = 260, EDIF_TOK_STR = 261, EDIF_TOK_ANGLE = 262, EDIF_TOK_BEHAVIOR = 263, EDIF_TOK_CALCULATED = 264, EDIF_TOK_CAPACITANCE = 265, EDIF_TOK_CENTERCENTER = 266, EDIF_TOK_CENTERLEFT = 267, EDIF_TOK_CENTERRIGHT = 268, EDIF_TOK_CHARGE = 269, EDIF_TOK_CONDUCTANCE = 270, EDIF_TOK_CURRENT = 271, EDIF_TOK_DISTANCE = 272, EDIF_TOK_DOCUMENT = 273, EDIF_TOK_ENERGY = 274, EDIF_TOK_EXTEND = 275, EDIF_TOK_FLUX = 276, EDIF_TOK_FREQUENCY = 277, EDIF_TOK_GENERIC = 278, EDIF_TOK_GRAPHIC = 279, EDIF_TOK_INDUCTANCE = 280, EDIF_TOK_INOUT = 281, EDIF_TOK_INPUT = 282, EDIF_TOK_LOGICMODEL = 283, EDIF_TOK_LOWERCENTER = 284, EDIF_TOK_LOWERLEFT = 285, EDIF_TOK_LOWERRIGHT = 286, EDIF_TOK_MASKLAYOUT = 287, EDIF_TOK_MASS = 288, EDIF_TOK_MEASURED = 289, EDIF_TOK_MX = 290, EDIF_TOK_MXR90 = 291, EDIF_TOK_MY = 292, EDIF_TOK_MYR90 = 293, EDIF_TOK_NETLIST = 294, EDIF_TOK_OUTPUT = 295, EDIF_TOK_PCBLAYOUT = 296, EDIF_TOK_POWER = 297, EDIF_TOK_R0 = 298, EDIF_TOK_R180 = 299, EDIF_TOK_R270 = 300, EDIF_TOK_R90 = 301, EDIF_TOK_REQUIRED = 302, EDIF_TOK_RESISTANCE = 303, EDIF_TOK_RIPPER = 304, EDIF_TOK_ROUND = 305, EDIF_TOK_SCHEMATIC = 306, EDIF_TOK_STRANGER = 307, EDIF_TOK_SYMBOLIC = 308, EDIF_TOK_TEMPERATURE = 309, EDIF_TOK_TIE = 310, EDIF_TOK_TIME = 311, EDIF_TOK_TRUNCATE = 312, EDIF_TOK_UPPERCENTER = 313, EDIF_TOK_UPPERLEFT = 314, EDIF_TOK_UPPERRIGHT = 315, EDIF_TOK_VOLTAGE = 316, EDIF_TOK_ACLOAD = 317, EDIF_TOK_AFTER = 318, EDIF_TOK_ANNOTATE = 319, EDIF_TOK_APPLY = 320, EDIF_TOK_ARC = 321, EDIF_TOK_ARRAY = 322, EDIF_TOK_ARRAYMACRO = 323, EDIF_TOK_ARRAYRELATEDINFO = 324, EDIF_TOK_ARRAYSITE = 325, EDIF_TOK_ATLEAST = 326, EDIF_TOK_ATMOST = 327, EDIF_TOK_AUTHOR = 328, EDIF_TOK_BASEARRAY = 329, EDIF_TOK_BECOMES = 330, EDIF_TOK_BETWEEN = 331, EDIF_TOK_BOOLEAN = 332, EDIF_TOK_BOOLEANDISPLAY = 333, EDIF_TOK_BOOLEANMAP = 334, EDIF_TOK_BORDERPATTERN = 335, EDIF_TOK_BORDERWIDTH = 336, EDIF_TOK_BOUNDINGBOX = 337, EDIF_TOK_CELL = 338, EDIF_TOK_CELLREF = 339, EDIF_TOK_CELLTYPE = 340, EDIF_TOK_CHANGE = 341, EDIF_TOK_CIRCLE = 342, EDIF_TOK_COLOR = 343, EDIF_TOK_COMMENT = 344, EDIF_TOK_COMMENTGRAPHICS = 345, EDIF_TOK_COMPOUND = 346, EDIF_TOK_CONNECTLOCATION = 347, EDIF_TOK_CONTENTS = 348, EDIF_TOK_CORNERTYPE = 349, EDIF_TOK_CRITICALITY = 350, EDIF_TOK_CURRENTMAP = 351, EDIF_TOK_CURVE = 352, EDIF_TOK_CYCLE = 353, EDIF_TOK_DATAORIGIN = 354, EDIF_TOK_DCFANINLOAD = 355, EDIF_TOK_DCFANOUTLOAD = 356, EDIF_TOK_DCMAXFANIN = 357, EDIF_TOK_DCMAXFANOUT = 358, EDIF_TOK_DELAY = 359, EDIF_TOK_DELTA = 360, EDIF_TOK_DERIVATION = 361, EDIF_TOK_DESIGN = 362, EDIF_TOK_DESIGNATOR = 363, EDIF_TOK_DIFFERENCE = 364, EDIF_TOK_DIRECTION = 365, EDIF_TOK_DISPLAY = 366, EDIF_TOK_DOMINATES = 367, EDIF_TOK_DOT = 368, EDIF_TOK_DURATION = 369, EDIF_TOK_E = 370, EDIF_TOK_EDIF = 371, EDIF_TOK_EDIFLEVEL = 372, EDIF_TOK_EDIFVERSION = 373, EDIF_TOK_ENCLOSUREDISTANCE = 374, EDIF_TOK_ENDTYPE = 375, EDIF_TOK_ENTRY = 376, EDIF_TOK_EVENT = 377, EDIF_TOK_EXACTLY = 378, EDIF_TOK_EXTERNAL = 379, EDIF_TOK_FABRICATE = 380, EDIF_TOK_FALSE = 381, EDIF_TOK_FIGURE = 382, EDIF_TOK_FIGUREAREA = 383, EDIF_TOK_FIGUREGROUP = 384, EDIF_TOK_FIGUREGROUPOBJECT = 385, EDIF_TOK_FIGUREGROUPOVERRIDE = 386, EDIF_TOK_FIGUREGROUPREF = 387, EDIF_TOK_FIGUREPERIMETER = 388, EDIF_TOK_FIGUREWIDTH = 389, EDIF_TOK_FILLPATTERN = 390, EDIF_TOK_FOLLOW = 391, EDIF_TOK_FORBIDDENEVENT = 392, EDIF_TOK_GLOBALPORTREF = 393, EDIF_TOK_GREATERTHAN = 394, EDIF_TOK_GRIDMAP = 395, EDIF_TOK_IGNORE = 396, EDIF_TOK_INCLUDEFIGUREGROUP = 397, EDIF_TOK_INITIAL = 398, EDIF_TOK_INSTANCE = 399, EDIF_TOK_INSTANCEBACKANNOTATE = 400, EDIF_TOK_INSTANCEGROUP = 401, EDIF_TOK_INSTANCEMAP = 402, EDIF_TOK_INSTANCEREF = 403, EDIF_TOK_INTEGER = 404, EDIF_TOK_INTEGERDISPLAY = 405, EDIF_TOK_INTERFACE = 406, EDIF_TOK_INTERFIGUREGROUPSPACING = 407, EDIF_TOK_INTERSECTION = 408, EDIF_TOK_INTRAFIGUREGROUPSPACING = 409, EDIF_TOK_INVERSE = 410, EDIF_TOK_ISOLATED = 411, EDIF_TOK_JOINED = 412, EDIF_TOK_JUSTIFY = 413, EDIF_TOK_KEYWORDDISPLAY = 414, EDIF_TOK_KEYWORDLEVEL = 415, EDIF_TOK_KEYWORDMAP = 416, EDIF_TOK_LESSTHAN = 417, EDIF_TOK_LIBRARY = 418, EDIF_TOK_LIBRARYREF = 419, EDIF_TOK_LISTOFNETS = 420, EDIF_TOK_LISTOFPORTS = 421, EDIF_TOK_LOADDELAY = 422, EDIF_TOK_LOGICASSIGN = 423, EDIF_TOK_LOGICINPUT = 424, EDIF_TOK_LOGICLIST = 425, EDIF_TOK_LOGICMAPINPUT = 426, EDIF_TOK_LOGICMAPOUTPUT = 427, EDIF_TOK_LOGICONEOF = 428, EDIF_TOK_LOGICOUTPUT = 429, EDIF_TOK_LOGICPORT = 430, EDIF_TOK_LOGICREF = 431, EDIF_TOK_LOGICVALUE = 432, EDIF_TOK_LOGICWAVEFORM = 433, EDIF_TOK_MAINTAIN = 434, EDIF_TOK_MATCH = 435, EDIF_TOK_MEMBER = 436, EDIF_TOK_MINOMAX = 437, EDIF_TOK_MINOMAXDISPLAY = 438, EDIF_TOK_MNM = 439, EDIF_TOK_MULTIPLEVALUESET = 440, EDIF_TOK_MUSTJOIN = 441, EDIF_TOK_NAME = 442, EDIF_TOK_NET = 443, EDIF_TOK_NETBACKANNOTATE = 444, EDIF_TOK_NETBUNDLE = 445, EDIF_TOK_NETDELAY = 446, EDIF_TOK_NETGROUP = 447, EDIF_TOK_NETMAP = 448, EDIF_TOK_NETREF = 449, EDIF_TOK_NOCHANGE = 450, EDIF_TOK_NONPERMUTABLE = 451, EDIF_TOK_NOTALLOWED = 452, EDIF_TOK_NOTCHSPACING = 453, EDIF_TOK_NUMBER = 454, EDIF_TOK_NUMBERDEFINITION = 455, EDIF_TOK_NUMBERDISPLAY = 456, EDIF_TOK_OFFPAGECONNECTOR = 457, EDIF_TOK_OFFSETEVENT = 458, EDIF_TOK_OPENSHAPE = 459, EDIF_TOK_ORIENTATION = 460, EDIF_TOK_ORIGIN = 461, EDIF_TOK_OVERHANGDISTANCE = 462, EDIF_TOK_OVERLAPDISTANCE = 463, EDIF_TOK_OVERSIZE = 464, EDIF_TOK_OWNER = 465, EDIF_TOK_PAGE = 466, EDIF_TOK_PAGESIZE = 467, EDIF_TOK_PARAMETER = 468, EDIF_TOK_PARAMETERASSIGN = 469, EDIF_TOK_PARAMETERDISPLAY = 470, EDIF_TOK_PATH = 471, EDIF_TOK_PATHDELAY = 472, EDIF_TOK_PATHWIDTH = 473, EDIF_TOK_PERMUTABLE = 474, EDIF_TOK_PHYSICALDESIGNRULE = 475, EDIF_TOK_PLUG = 476, EDIF_TOK_POINT = 477, EDIF_TOK_POINTDISPLAY = 478, EDIF_TOK_POINTLIST = 479, EDIF_TOK_POLYGON = 480, EDIF_TOK_PORT = 481, EDIF_TOK_PORTBACKANNOTATE = 482, EDIF_TOK_PORTBUNDLE = 483, EDIF_TOK_PORTDELAY = 484, EDIF_TOK_PORTGROUP = 485, EDIF_TOK_PORTIMPLEMENTATION = 486, EDIF_TOK_PORTINSTANCE = 487, EDIF_TOK_PORTLIST = 488, EDIF_TOK_PORTLISTALIAS = 489, EDIF_TOK_PORTMAP = 490, EDIF_TOK_PORTREF = 491, EDIF_TOK_PROGRAM = 492, EDIF_TOK_PROPERTY = 493, EDIF_TOK_PROPERTYDISPLAY = 494, EDIF_TOK_PROTECTIONFRAME = 495, EDIF_TOK_PT = 496, EDIF_TOK_RANGEVECTOR = 497, EDIF_TOK_RECTANGLE = 498, EDIF_TOK_RECTANGLESIZE = 499, EDIF_TOK_RENAME = 500, EDIF_TOK_RESOLVES = 501, EDIF_TOK_SCALE = 502, EDIF_TOK_SCALEX = 503, EDIF_TOK_SCALEY = 504, EDIF_TOK_SECTION = 505, EDIF_TOK_SHAPE = 506, EDIF_TOK_SIMULATE = 507, EDIF_TOK_SIMULATIONINFO = 508, EDIF_TOK_SINGLEVALUESET = 509, EDIF_TOK_SITE = 510, EDIF_TOK_SOCKET = 511, EDIF_TOK_SOCKETSET = 512, EDIF_TOK_STATUS = 513, EDIF_TOK_STEADY = 514, EDIF_TOK_STRING = 515, EDIF_TOK_STRINGDISPLAY = 516, EDIF_TOK_STRONG = 517, EDIF_TOK_SYMBOL = 518, EDIF_TOK_SYMMETRY = 519, EDIF_TOK_TABLE = 520, EDIF_TOK_TABLEDEFAULT = 521, EDIF_TOK_TECHNOLOGY = 522, EDIF_TOK_TEXTHEIGHT = 523, EDIF_TOK_TIMEINTERVAL = 524, EDIF_TOK_TIMESTAMP = 525, EDIF_TOK_TIMING = 526, EDIF_TOK_TRANSFORM = 527, EDIF_TOK_TRANSITION = 528, EDIF_TOK_TRIGGER = 529, EDIF_TOK_TRUE = 530, EDIF_TOK_UNCONSTRAINED = 531, EDIF_TOK_UNDEFINED = 532, EDIF_TOK_UNION = 533, EDIF_TOK_UNIT = 534, EDIF_TOK_UNUSED = 535, EDIF_TOK_USERDATA = 536, EDIF_TOK_VERSION = 537, EDIF_TOK_VIEW = 538, EDIF_TOK_VIEWLIST = 539, EDIF_TOK_VIEWMAP = 540, EDIF_TOK_VIEWREF = 541, EDIF_TOK_VIEWTYPE = 542, EDIF_TOK_VISIBLE = 543, EDIF_TOK_VOLTAGEMAP = 544, EDIF_TOK_WAVEVALUE = 545, EDIF_TOK_WEAK = 546, EDIF_TOK_WEAKJOINED = 547, EDIF_TOK_WHEN = 548, EDIF_TOK_WRITTEN = 549 }; #endif /* Tokens. */ #define EDIF_TOK_IDENT 258 #define EDIF_TOK_INT 259 #define EDIF_TOK_KEYWORD 260 #define EDIF_TOK_STR 261 #define EDIF_TOK_ANGLE 262 #define EDIF_TOK_BEHAVIOR 263 #define EDIF_TOK_CALCULATED 264 #define EDIF_TOK_CAPACITANCE 265 #define EDIF_TOK_CENTERCENTER 266 #define EDIF_TOK_CENTERLEFT 267 #define EDIF_TOK_CENTERRIGHT 268 #define EDIF_TOK_CHARGE 269 #define EDIF_TOK_CONDUCTANCE 270 #define EDIF_TOK_CURRENT 271 #define EDIF_TOK_DISTANCE 272 #define EDIF_TOK_DOCUMENT 273 #define EDIF_TOK_ENERGY 274 #define EDIF_TOK_EXTEND 275 #define EDIF_TOK_FLUX 276 #define EDIF_TOK_FREQUENCY 277 #define EDIF_TOK_GENERIC 278 #define EDIF_TOK_GRAPHIC 279 #define EDIF_TOK_INDUCTANCE 280 #define EDIF_TOK_INOUT 281 #define EDIF_TOK_INPUT 282 #define EDIF_TOK_LOGICMODEL 283 #define EDIF_TOK_LOWERCENTER 284 #define EDIF_TOK_LOWERLEFT 285 #define EDIF_TOK_LOWERRIGHT 286 #define EDIF_TOK_MASKLAYOUT 287 #define EDIF_TOK_MASS 288 #define EDIF_TOK_MEASURED 289 #define EDIF_TOK_MX 290 #define EDIF_TOK_MXR90 291 #define EDIF_TOK_MY 292 #define EDIF_TOK_MYR90 293 #define EDIF_TOK_NETLIST 294 #define EDIF_TOK_OUTPUT 295 #define EDIF_TOK_PCBLAYOUT 296 #define EDIF_TOK_POWER 297 #define EDIF_TOK_R0 298 #define EDIF_TOK_R180 299 #define EDIF_TOK_R270 300 #define EDIF_TOK_R90 301 #define EDIF_TOK_REQUIRED 302 #define EDIF_TOK_RESISTANCE 303 #define EDIF_TOK_RIPPER 304 #define EDIF_TOK_ROUND 305 #define EDIF_TOK_SCHEMATIC 306 #define EDIF_TOK_STRANGER 307 #define EDIF_TOK_SYMBOLIC 308 #define EDIF_TOK_TEMPERATURE 309 #define EDIF_TOK_TIE 310 #define EDIF_TOK_TIME 311 #define EDIF_TOK_TRUNCATE 312 #define EDIF_TOK_UPPERCENTER 313 #define EDIF_TOK_UPPERLEFT 314 #define EDIF_TOK_UPPERRIGHT 315 #define EDIF_TOK_VOLTAGE 316 #define EDIF_TOK_ACLOAD 317 #define EDIF_TOK_AFTER 318 #define EDIF_TOK_ANNOTATE 319 #define EDIF_TOK_APPLY 320 #define EDIF_TOK_ARC 321 #define EDIF_TOK_ARRAY 322 #define EDIF_TOK_ARRAYMACRO 323 #define EDIF_TOK_ARRAYRELATEDINFO 324 #define EDIF_TOK_ARRAYSITE 325 #define EDIF_TOK_ATLEAST 326 #define EDIF_TOK_ATMOST 327 #define EDIF_TOK_AUTHOR 328 #define EDIF_TOK_BASEARRAY 329 #define EDIF_TOK_BECOMES 330 #define EDIF_TOK_BETWEEN 331 #define EDIF_TOK_BOOLEAN 332 #define EDIF_TOK_BOOLEANDISPLAY 333 #define EDIF_TOK_BOOLEANMAP 334 #define EDIF_TOK_BORDERPATTERN 335 #define EDIF_TOK_BORDERWIDTH 336 #define EDIF_TOK_BOUNDINGBOX 337 #define EDIF_TOK_CELL 338 #define EDIF_TOK_CELLREF 339 #define EDIF_TOK_CELLTYPE 340 #define EDIF_TOK_CHANGE 341 #define EDIF_TOK_CIRCLE 342 #define EDIF_TOK_COLOR 343 #define EDIF_TOK_COMMENT 344 #define EDIF_TOK_COMMENTGRAPHICS 345 #define EDIF_TOK_COMPOUND 346 #define EDIF_TOK_CONNECTLOCATION 347 #define EDIF_TOK_CONTENTS 348 #define EDIF_TOK_CORNERTYPE 349 #define EDIF_TOK_CRITICALITY 350 #define EDIF_TOK_CURRENTMAP 351 #define EDIF_TOK_CURVE 352 #define EDIF_TOK_CYCLE 353 #define EDIF_TOK_DATAORIGIN 354 #define EDIF_TOK_DCFANINLOAD 355 #define EDIF_TOK_DCFANOUTLOAD 356 #define EDIF_TOK_DCMAXFANIN 357 #define EDIF_TOK_DCMAXFANOUT 358 #define EDIF_TOK_DELAY 359 #define EDIF_TOK_DELTA 360 #define EDIF_TOK_DERIVATION 361 #define EDIF_TOK_DESIGN 362 #define EDIF_TOK_DESIGNATOR 363 #define EDIF_TOK_DIFFERENCE 364 #define EDIF_TOK_DIRECTION 365 #define EDIF_TOK_DISPLAY 366 #define EDIF_TOK_DOMINATES 367 #define EDIF_TOK_DOT 368 #define EDIF_TOK_DURATION 369 #define EDIF_TOK_E 370 #define EDIF_TOK_EDIF 371 #define EDIF_TOK_EDIFLEVEL 372 #define EDIF_TOK_EDIFVERSION 373 #define EDIF_TOK_ENCLOSUREDISTANCE 374 #define EDIF_TOK_ENDTYPE 375 #define EDIF_TOK_ENTRY 376 #define EDIF_TOK_EVENT 377 #define EDIF_TOK_EXACTLY 378 #define EDIF_TOK_EXTERNAL 379 #define EDIF_TOK_FABRICATE 380 #define EDIF_TOK_FALSE 381 #define EDIF_TOK_FIGURE 382 #define EDIF_TOK_FIGUREAREA 383 #define EDIF_TOK_FIGUREGROUP 384 #define EDIF_TOK_FIGUREGROUPOBJECT 385 #define EDIF_TOK_FIGUREGROUPOVERRIDE 386 #define EDIF_TOK_FIGUREGROUPREF 387 #define EDIF_TOK_FIGUREPERIMETER 388 #define EDIF_TOK_FIGUREWIDTH 389 #define EDIF_TOK_FILLPATTERN 390 #define EDIF_TOK_FOLLOW 391 #define EDIF_TOK_FORBIDDENEVENT 392 #define EDIF_TOK_GLOBALPORTREF 393 #define EDIF_TOK_GREATERTHAN 394 #define EDIF_TOK_GRIDMAP 395 #define EDIF_TOK_IGNORE 396 #define EDIF_TOK_INCLUDEFIGUREGROUP 397 #define EDIF_TOK_INITIAL 398 #define EDIF_TOK_INSTANCE 399 #define EDIF_TOK_INSTANCEBACKANNOTATE 400 #define EDIF_TOK_INSTANCEGROUP 401 #define EDIF_TOK_INSTANCEMAP 402 #define EDIF_TOK_INSTANCEREF 403 #define EDIF_TOK_INTEGER 404 #define EDIF_TOK_INTEGERDISPLAY 405 #define EDIF_TOK_INTERFACE 406 #define EDIF_TOK_INTERFIGUREGROUPSPACING 407 #define EDIF_TOK_INTERSECTION 408 #define EDIF_TOK_INTRAFIGUREGROUPSPACING 409 #define EDIF_TOK_INVERSE 410 #define EDIF_TOK_ISOLATED 411 #define EDIF_TOK_JOINED 412 #define EDIF_TOK_JUSTIFY 413 #define EDIF_TOK_KEYWORDDISPLAY 414 #define EDIF_TOK_KEYWORDLEVEL 415 #define EDIF_TOK_KEYWORDMAP 416 #define EDIF_TOK_LESSTHAN 417 #define EDIF_TOK_LIBRARY 418 #define EDIF_TOK_LIBRARYREF 419 #define EDIF_TOK_LISTOFNETS 420 #define EDIF_TOK_LISTOFPORTS 421 #define EDIF_TOK_LOADDELAY 422 #define EDIF_TOK_LOGICASSIGN 423 #define EDIF_TOK_LOGICINPUT 424 #define EDIF_TOK_LOGICLIST 425 #define EDIF_TOK_LOGICMAPINPUT 426 #define EDIF_TOK_LOGICMAPOUTPUT 427 #define EDIF_TOK_LOGICONEOF 428 #define EDIF_TOK_LOGICOUTPUT 429 #define EDIF_TOK_LOGICPORT 430 #define EDIF_TOK_LOGICREF 431 #define EDIF_TOK_LOGICVALUE 432 #define EDIF_TOK_LOGICWAVEFORM 433 #define EDIF_TOK_MAINTAIN 434 #define EDIF_TOK_MATCH 435 #define EDIF_TOK_MEMBER 436 #define EDIF_TOK_MINOMAX 437 #define EDIF_TOK_MINOMAXDISPLAY 438 #define EDIF_TOK_MNM 439 #define EDIF_TOK_MULTIPLEVALUESET 440 #define EDIF_TOK_MUSTJOIN 441 #define EDIF_TOK_NAME 442 #define EDIF_TOK_NET 443 #define EDIF_TOK_NETBACKANNOTATE 444 #define EDIF_TOK_NETBUNDLE 445 #define EDIF_TOK_NETDELAY 446 #define EDIF_TOK_NETGROUP 447 #define EDIF_TOK_NETMAP 448 #define EDIF_TOK_NETREF 449 #define EDIF_TOK_NOCHANGE 450 #define EDIF_TOK_NONPERMUTABLE 451 #define EDIF_TOK_NOTALLOWED 452 #define EDIF_TOK_NOTCHSPACING 453 #define EDIF_TOK_NUMBER 454 #define EDIF_TOK_NUMBERDEFINITION 455 #define EDIF_TOK_NUMBERDISPLAY 456 #define EDIF_TOK_OFFPAGECONNECTOR 457 #define EDIF_TOK_OFFSETEVENT 458 #define EDIF_TOK_OPENSHAPE 459 #define EDIF_TOK_ORIENTATION 460 #define EDIF_TOK_ORIGIN 461 #define EDIF_TOK_OVERHANGDISTANCE 462 #define EDIF_TOK_OVERLAPDISTANCE 463 #define EDIF_TOK_OVERSIZE 464 #define EDIF_TOK_OWNER 465 #define EDIF_TOK_PAGE 466 #define EDIF_TOK_PAGESIZE 467 #define EDIF_TOK_PARAMETER 468 #define EDIF_TOK_PARAMETERASSIGN 469 #define EDIF_TOK_PARAMETERDISPLAY 470 #define EDIF_TOK_PATH 471 #define EDIF_TOK_PATHDELAY 472 #define EDIF_TOK_PATHWIDTH 473 #define EDIF_TOK_PERMUTABLE 474 #define EDIF_TOK_PHYSICALDESIGNRULE 475 #define EDIF_TOK_PLUG 476 #define EDIF_TOK_POINT 477 #define EDIF_TOK_POINTDISPLAY 478 #define EDIF_TOK_POINTLIST 479 #define EDIF_TOK_POLYGON 480 #define EDIF_TOK_PORT 481 #define EDIF_TOK_PORTBACKANNOTATE 482 #define EDIF_TOK_PORTBUNDLE 483 #define EDIF_TOK_PORTDELAY 484 #define EDIF_TOK_PORTGROUP 485 #define EDIF_TOK_PORTIMPLEMENTATION 486 #define EDIF_TOK_PORTINSTANCE 487 #define EDIF_TOK_PORTLIST 488 #define EDIF_TOK_PORTLISTALIAS 489 #define EDIF_TOK_PORTMAP 490 #define EDIF_TOK_PORTREF 491 #define EDIF_TOK_PROGRAM 492 #define EDIF_TOK_PROPERTY 493 #define EDIF_TOK_PROPERTYDISPLAY 494 #define EDIF_TOK_PROTECTIONFRAME 495 #define EDIF_TOK_PT 496 #define EDIF_TOK_RANGEVECTOR 497 #define EDIF_TOK_RECTANGLE 498 #define EDIF_TOK_RECTANGLESIZE 499 #define EDIF_TOK_RENAME 500 #define EDIF_TOK_RESOLVES 501 #define EDIF_TOK_SCALE 502 #define EDIF_TOK_SCALEX 503 #define EDIF_TOK_SCALEY 504 #define EDIF_TOK_SECTION 505 #define EDIF_TOK_SHAPE 506 #define EDIF_TOK_SIMULATE 507 #define EDIF_TOK_SIMULATIONINFO 508 #define EDIF_TOK_SINGLEVALUESET 509 #define EDIF_TOK_SITE 510 #define EDIF_TOK_SOCKET 511 #define EDIF_TOK_SOCKETSET 512 #define EDIF_TOK_STATUS 513 #define EDIF_TOK_STEADY 514 #define EDIF_TOK_STRING 515 #define EDIF_TOK_STRINGDISPLAY 516 #define EDIF_TOK_STRONG 517 #define EDIF_TOK_SYMBOL 518 #define EDIF_TOK_SYMMETRY 519 #define EDIF_TOK_TABLE 520 #define EDIF_TOK_TABLEDEFAULT 521 #define EDIF_TOK_TECHNOLOGY 522 #define EDIF_TOK_TEXTHEIGHT 523 #define EDIF_TOK_TIMEINTERVAL 524 #define EDIF_TOK_TIMESTAMP 525 #define EDIF_TOK_TIMING 526 #define EDIF_TOK_TRANSFORM 527 #define EDIF_TOK_TRANSITION 528 #define EDIF_TOK_TRIGGER 529 #define EDIF_TOK_TRUE 530 #define EDIF_TOK_UNCONSTRAINED 531 #define EDIF_TOK_UNDEFINED 532 #define EDIF_TOK_UNION 533 #define EDIF_TOK_UNIT 534 #define EDIF_TOK_UNUSED 535 #define EDIF_TOK_USERDATA 536 #define EDIF_TOK_VERSION 537 #define EDIF_TOK_VIEW 538 #define EDIF_TOK_VIEWLIST 539 #define EDIF_TOK_VIEWMAP 540 #define EDIF_TOK_VIEWREF 541 #define EDIF_TOK_VIEWTYPE 542 #define EDIF_TOK_VISIBLE 543 #define EDIF_TOK_VOLTAGEMAP 544 #define EDIF_TOK_WAVEVALUE 545 #define EDIF_TOK_WEAK 546 #define EDIF_TOK_WEAKJOINED 547 #define EDIF_TOK_WHEN 548 #define EDIF_TOK_WRITTEN 549 /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { #line 193 "edif.y" char* s; pair_list* pl; str_pair* ps; #line 651 "edif.h" }; typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif extern YYSTYPE ediflval; int edifparse (void); #endif /* !YY_EDIF_EDIF_H_INCLUDED */ pcb-4.3.0/src/gpcb-menu.res.h0000664000175000017500000006562714017001274012626 00000000000000# 56 "gpcb-menu.res" char *s = N_("File"); # 57 "gpcb-menu.res" char *s = N_("New"); # 57 "gpcb-menu.res" char *s = N_("Ctrl-N"); # 57 "gpcb-menu.res" char *s = N_("Ctrln"); # 58 "gpcb-menu.res" char *s = N_("Open..."); # 58 "gpcb-menu.res" char *s = N_("Load a layout from a file"); # 60 "gpcb-menu.res" char *s = N_("Save"); # 60 "gpcb-menu.res" char *s = N_("Saves current layout"); # 60 "gpcb-menu.res" char *s = N_("Ctrl-S"); # 60 "gpcb-menu.res" char *s = N_("Ctrls"); # 61 "gpcb-menu.res" char *s = N_("Save As..."); # 61 "gpcb-menu.res" char *s = N_("Saves current layout into a new file"); # 61 "gpcb-menu.res" char *s = N_("Shift Ctrl-S"); # 61 "gpcb-menu.res" char *s = N_("Shift Ctrls"); # 62 "gpcb-menu.res" char *s = N_("Revert"); # 62 "gpcb-menu.res" char *s = N_("Revert to the layout stored on disk"); # 64 "gpcb-menu.res" char *s = N_("Import Schematics"); # 65 "gpcb-menu.res" char *s = N_("gschem"); # 66 "gpcb-menu.res" char *s = N_("TinyCAD"); # 68 "gpcb-menu.res" char *s = N_("Load element to buffer"); # 69 "gpcb-menu.res" char *s = N_("Load layout to buffer"); # 70 "gpcb-menu.res" char *s = N_("Load netlist"); # 71 "gpcb-menu.res" char *s = N_("Load vendor resource file"); # 73 "gpcb-menu.res" char *s = N_("Save connection data of"); # 74 "gpcb-menu.res" char *s = N_(" a single element"); # 75 "gpcb-menu.res" char *s = N_(" all elements"); # 76 "gpcb-menu.res" char *s = N_(" unused pins"); # 78 "gpcb-menu.res" char *s = N_("Export..."); # 80 "gpcb-menu.res" char *s = N_("Calibrate Printer..."); # 81 "gpcb-menu.res" char *s = N_("Print..."); # 83 "gpcb-menu.res" char *s = N_("Preferences..."); # 85 "gpcb-menu.res" char *s = N_("Quit"); # 85 "gpcb-menu.res" char *s = N_("Ctrl-Q"); # 85 "gpcb-menu.res" char *s = N_("Ctrlq"); # 91 "gpcb-menu.res" char *s = N_("Edit"); # 92 "gpcb-menu.res" char *s = N_("Undo"); # 92 "gpcb-menu.res" char *s = N_("U"); # 92 "gpcb-menu.res" char *s = N_("u"); # 93 "gpcb-menu.res" char *s = N_("Redo"); # 93 "gpcb-menu.res" char *s = N_("Shift-R"); # 93 "gpcb-menu.res" char *s = N_("Shiftr"); # 94 "gpcb-menu.res" char *s = N_("Clear undo-buffer"); # 94 "gpcb-menu.res" char *s = N_("Shift-Ctrl-U"); # 94 "gpcb-menu.res" char *s = N_("Shift Ctrlu"); # 313 "gpcb-menu.res" char *s = N_("Cut to buffer"); # 98 "gpcb-menu.res" char *s = N_("Ctrl-X"); # 98 "gpcb-menu.res" char *s = N_("Ctrlx"); # 99 "gpcb-menu.res" char *s = N_("Copy to buffer"); # 101 "gpcb-menu.res" char *s = N_("Ctrl-C"); # 101 "gpcb-menu.res" char *s = N_("Ctrlc"); # 315 "gpcb-menu.res" char *s = N_("Paste buffer"); # 102 "gpcb-menu.res" char *s = N_("Ctrl-V"); # 102 "gpcb-menu.res" char *s = N_("Ctrlv"); # 251 "gpcb-menu.res" char *s = N_("Unselect all"); # 104 "gpcb-menu.res" char *s = N_("Shift-Ctrl-A"); # 104 "gpcb-menu.res" char *s = N_("Shift Ctrla"); # 246 "gpcb-menu.res" char *s = N_("Select all visible"); # 105 "gpcb-menu.res" char *s = N_("Ctrl-A"); # 105 "gpcb-menu.res" char *s = N_("Ctrla"); # 107 "gpcb-menu.res" char *s = N_("Edit name of"); # 108 "gpcb-menu.res" char *s = N_("text on layout"); # 108 "gpcb-menu.res" char *s = N_("N"); # 108 "gpcb-menu.res" char *s = N_("n"); # 109 "gpcb-menu.res" char *s = N_("layout"); # 110 "gpcb-menu.res" char *s = N_("active layer"); # 112 "gpcb-menu.res" char *s = N_("Edit attributes of"); # 113 "gpcb-menu.res" char *s = N_("Layout"); # 114 "gpcb-menu.res" char *s = N_("CurrentLayer"); # 115 "gpcb-menu.res" char *s = N_("Element"); # 118 "gpcb-menu.res" char *s = N_("Route Styles"); # 120 "gpcb-menu.res" char *s = N_("Edit..."); # 123 "gpcb-menu.res" char *s = N_("Via type"); # 303 "gpcb-menu.res" char *s = N_("Through-hole"); # 124 "gpcb-menu.res" char *s = N_("Xtrl-Shift-P"); # 228 "gpcb-menu.res" char *s = N_("Ctrl Shiftp"); # 125 "gpcb-menu.res" char *s = N_("Buried from"); # 125 "gpcb-menu.res" char *s = N_("Xtrl-Shift-F"); # 125 "gpcb-menu.res" char *s = N_("Ctrl Shiftf"); # 126 "gpcb-menu.res" char *s = N_("Buried to"); # 126 "gpcb-menu.res" char *s = N_("Xtrl-Shift-T"); # 126 "gpcb-menu.res" char *s = N_("Ctrl Shiftt"); # 133 "gpcb-menu.res" char *s = N_("View"); # 134 "gpcb-menu.res" char *s = N_("Enable visible grid"); # 135 "gpcb-menu.res" char *s = N_("Grid units"); # 136 "gpcb-menu.res" char *s = N_("mil"); # 137 "gpcb-menu.res" char *s = N_("mm"); # 139 "gpcb-menu.res" char *s = N_("Grid size"); # 140 "gpcb-menu.res" char *s = N_("No Grid"); # 142 "gpcb-menu.res" char *s = N_("0.1 mil"); # 143 "gpcb-menu.res" char *s = N_("1 mil"); # 144 "gpcb-menu.res" char *s = N_("5 mil"); # 145 "gpcb-menu.res" char *s = N_("10 mil"); # 146 "gpcb-menu.res" char *s = N_("25 mil"); # 147 "gpcb-menu.res" char *s = N_("50 mil"); # 148 "gpcb-menu.res" char *s = N_("100 mil"); # 150 "gpcb-menu.res" char *s = N_("0.01 mm"); # 151 "gpcb-menu.res" char *s = N_("0.05 mm"); # 152 "gpcb-menu.res" char *s = N_("0.1 mm"); # 153 "gpcb-menu.res" char *s = N_("0.25 mm"); # 154 "gpcb-menu.res" char *s = N_("0.5 mm"); # 155 "gpcb-menu.res" char *s = N_("1 mm"); # 157 "gpcb-menu.res" char *s = N_("Grid -"); # 157 "gpcb-menu.res" char *s = N_("Shift-G"); # 157 "gpcb-menu.res" char *s = N_("Shiftg"); # 158 "gpcb-menu.res" char *s = N_("Grid +"); # 158 "gpcb-menu.res" char *s = N_("G"); # 158 "gpcb-menu.res" char *s = N_("g"); # 160 "gpcb-menu.res" char *s = N_("Realign grid"); # 162 "gpcb-menu.res" char *s = N_("Displayed element name"); # 163 "gpcb-menu.res" char *s = N_("Description"); # 164 "gpcb-menu.res" char *s = N_("Reference Designator"); # 165 "gpcb-menu.res" char *s = N_("Value"); # 167 "gpcb-menu.res" char *s = N_("Enable Pinout shows number"); # 168 "gpcb-menu.res" char *s = N_("Pins/Via show Name/Number"); # 168 "gpcb-menu.res" char *s = N_("D"); # 168 "gpcb-menu.res" char *s = N_("d"); # 169 "gpcb-menu.res" /* xgettext:no-c-format */ char *s = N_("Zoom In 20%"); # 170 "gpcb-menu.res" char *s = N_("Z"); # 170 "gpcb-menu.res" char *s = N_("z"); # 170 "gpcb-menu.res" /* xgettext:no-c-format */ char *s = N_("Zoom Out 20%"); # 171 "gpcb-menu.res" char *s = N_("Shift-Z"); # 171 "gpcb-menu.res" char *s = N_("Shiftz"); # 172 "gpcb-menu.res" char *s = N_("More zooms and view changes"); # 173 "gpcb-menu.res" char *s = N_("Zoom Max"); # 173 "gpcb-menu.res" char *s = N_("V"); # 173 "gpcb-menu.res" char *s = N_("v"); # 174 "gpcb-menu.res" char *s = N_("Zoom In 2X"); # 175 "gpcb-menu.res" char *s = N_("Zoom Out 2X"); # 176 "gpcb-menu.res" char *s = N_("Zoom to 0.1mil/px"); # 177 "gpcb-menu.res" char *s = N_("Zoom to 0.01mm/px"); # 178 "gpcb-menu.res" char *s = N_("Zoom to 1mil/px"); # 179 "gpcb-menu.res" char *s = N_("Zoom to 0.05mm/px"); # 180 "gpcb-menu.res" char *s = N_("Zoom to 2.5mil/px"); # 181 "gpcb-menu.res" char *s = N_("Zoom to 0.1mm/px"); # 182 "gpcb-menu.res" char *s = N_("Zoom to 10mil/px"); # 182 "gpcb-menu.res" /* xgettext:no-c-format */ char *s = N_("Zoom In 20% and center"); # 183 "gpcb-menu.res" /* xgettext:no-c-format */ char *s = N_("Zoom Out 20% and center"); # 185 "gpcb-menu.res" char *s = N_("Flip up/down"); # 185 "gpcb-menu.res" char *s = N_("Tab"); # 185 "gpcb-menu.res" char *s = N_("Tab"); # 186 "gpcb-menu.res" char *s = N_("Flip left/right"); # 186 "gpcb-menu.res" char *s = N_("Shift-Tab"); # 186 "gpcb-menu.res" char *s = N_("ShiftTab"); # 187 "gpcb-menu.res" char *s = N_("Spin 180 degrees"); # 187 "gpcb-menu.res" char *s = N_("Ctrl-Tab"); # 187 "gpcb-menu.res" char *s = N_("CtrlTab"); # 188 "gpcb-menu.res" char *s = N_("Swap Sides"); # 188 "gpcb-menu.res" char *s = N_("Ctrl-Shift-Tab"); # 188 "gpcb-menu.res" char *s = N_("Ctrl ShiftTab"); # 189 "gpcb-menu.res" char *s = N_("Center cursor"); # 189 "gpcb-menu.res" char *s = N_("C"); # 189 "gpcb-menu.res" char *s = N_("c"); # 192 "gpcb-menu.res" char *s = N_("Shown Layers"); # 195 "gpcb-menu.res" char *s = N_("Edit Layer Groups"); # 197 "gpcb-menu.res" char *s = N_("Current Layer"); # 200 "gpcb-menu.res" char *s = N_("Delete current layer"); # 201 "gpcb-menu.res" char *s = N_("Add new layer"); # 202 "gpcb-menu.res" char *s = N_("Move current layer up"); # 203 "gpcb-menu.res" char *s = N_("Move current layer down"); # 210 "gpcb-menu.res" char *s = N_("Settings"); # 211 "gpcb-menu.res" char *s = N_("'All-direction' lines"); # 211 "gpcb-menu.res" char *s = N_("."); # 211 "gpcb-menu.res" char *s = N_("."); # 212 "gpcb-menu.res" char *s = N_("Auto swap line start angle"); # 213 "gpcb-menu.res" char *s = N_("Orthogonal moves"); # 214 "gpcb-menu.res" char *s = N_("Crosshair snaps to pins and pads"); # 215 "gpcb-menu.res" char *s = N_("Crosshair shows DRC clearance"); # 216 "gpcb-menu.res" char *s = N_("Auto enforce DRC clearance"); # 217 "gpcb-menu.res" char *s = N_("Lock Names"); # 218 "gpcb-menu.res" char *s = N_("Only Names"); # 219 "gpcb-menu.res" char *s = N_("Hide Names"); # 221 "gpcb-menu.res" char *s = N_("Rubber band mode"); # 222 "gpcb-menu.res" char *s = N_("Require unique element names"); # 223 "gpcb-menu.res" char *s = N_("Auto-zero delta measurements"); # 224 "gpcb-menu.res" char *s = N_("New lines, arcs clear polygons"); # 225 "gpcb-menu.res" char *s = N_("New polygons are full ones"); # 226 "gpcb-menu.res" char *s = N_("Show autorouter trials"); # 227 "gpcb-menu.res" char *s = N_("Thin draw"); # 227 "gpcb-menu.res" char *s = N_("|"); # 227 "gpcb-menu.res" char *s = N_("|"); # 228 "gpcb-menu.res" char *s = N_("Thin draw poly"); # 228 "gpcb-menu.res" char *s = N_("Ctrl-Shift-P"); # 229 "gpcb-menu.res" char *s = N_("Check polygons"); # 230 "gpcb-menu.res" char *s = N_("Auto buried vias"); # 232 "gpcb-menu.res" char *s = N_("Vendor drill mapping"); # 233 "gpcb-menu.res" char *s = N_("Import New Elements at"); # 234 "gpcb-menu.res" char *s = N_(" Center"); # 235 "gpcb-menu.res" char *s = N_(" Mark"); # 236 "gpcb-menu.res" char *s = N_(" Crosshair"); # 238 "gpcb-menu.res" char *s = N_("Set Dispersion"); # 245 "gpcb-menu.res" char *s = N_("Select"); # 247 "gpcb-menu.res" char *s = N_("Select all found"); # 248 "gpcb-menu.res" char *s = N_("Select all connected"); # 249 "gpcb-menu.res" char *s = N_("Select all buried vias"); # 252 "gpcb-menu.res" char *s = N_("Unselect all found"); # 253 "gpcb-menu.res" char *s = N_("Unselect all connected"); # 255 "gpcb-menu.res" char *s = N_("Select by name"); # 256 "gpcb-menu.res" char *s = N_("All objects"); # 298 "gpcb-menu.res" char *s = N_("Elements"); # 258 "gpcb-menu.res" char *s = N_("Pads"); # 299 "gpcb-menu.res" char *s = N_("Pins"); # 524 "gpcb-menu.res" char *s = N_("Text"); # 261 "gpcb-menu.res" char *s = N_("Vias"); # 264 "gpcb-menu.res" char *s = N_("Auto-place selected elements"); # 264 "gpcb-menu.res" char *s = N_("Ctrl-P"); # 264 "gpcb-menu.res" char *s = N_("Ctrlp"); # 265 "gpcb-menu.res" char *s = N_("Disperse all elements"); # 266 "gpcb-menu.res" char *s = N_("Disperse selected elements"); # 268 "gpcb-menu.res" char *s = N_("Move selected elements to other side"); # 268 "gpcb-menu.res" char *s = N_("Shift-B"); # 268 "gpcb-menu.res" char *s = N_("Shiftb"); # 269 "gpcb-menu.res" char *s = N_("Move selected to current layer"); # 269 "gpcb-menu.res" char *s = N_("Shift-M"); # 269 "gpcb-menu.res" char *s = N_("Shiftm"); # 493 "gpcb-menu.res" char *s = N_("Remove selected objects"); # 270 "gpcb-menu.res" char *s = N_("Shift-Delete"); # 270 "gpcb-menu.res" char *s = N_("ShiftDelete"); # 507 "gpcb-menu.res" char *s = N_("Convert selection to element"); # 273 "gpcb-menu.res" char *s = N_("Optimize selected rats"); # 351 "gpcb-menu.res" char *s = N_("Auto-route selected rats"); # 274 "gpcb-menu.res" char *s = N_("Alt-R"); # 274 "gpcb-menu.res" char *s = N_("Altr"); # 510 "gpcb-menu.res" char *s = N_("Rip up selected auto-routed tracks"); # 277 "gpcb-menu.res" char *s = N_("Change size of selected objects"); # 278 "gpcb-menu.res" char *s = N_("Lines -10 mil"); # 279 "gpcb-menu.res" char *s = N_("Lines +10 mil"); # 280 "gpcb-menu.res" char *s = N_("Pads -10 mil"); # 281 "gpcb-menu.res" char *s = N_("Pads +10 mil"); # 293 "gpcb-menu.res" char *s = N_("Pins -10 mil"); # 294 "gpcb-menu.res" char *s = N_("Pins +10 mil"); # 284 "gpcb-menu.res" char *s = N_("Texts -10 mil"); # 285 "gpcb-menu.res" char *s = N_("Texts +10 mil"); # 291 "gpcb-menu.res" char *s = N_("Vias -10 mil"); # 292 "gpcb-menu.res" char *s = N_("Vias +10 mil"); # 290 "gpcb-menu.res" char *s = N_("Change drilling hole of selected objects"); # 297 "gpcb-menu.res" char *s = N_("Change square-flag of selected objects"); # 302 "gpcb-menu.res" char *s = N_("Change type of selected vias"); # 304 "gpcb-menu.res" char *s = N_("Buried from current layer"); # 305 "gpcb-menu.res" char *s = N_("Buried to current layer"); # 528 "gpcb-menu.res" char *s = N_("Buffer"); # 317 "gpcb-menu.res" char *s = N_("Rotate buffer 90 deg CCW"); # 318 "gpcb-menu.res" char *s = N_("Shift-F7"); # 318 "gpcb-menu.res" char *s = N_("ShiftF7"); # 319 "gpcb-menu.res" char *s = N_("Rotate buffer 90 deg CW"); # 320 "gpcb-menu.res" char *s = N_("Arbitrarily Rotate Buffer"); # 321 "gpcb-menu.res" char *s = N_("Mirror buffer (up/down)"); # 322 "gpcb-menu.res" char *s = N_("Mirror buffer (left/right)"); # 325 "gpcb-menu.res" char *s = N_("Clear buffer"); # 326 "gpcb-menu.res" char *s = N_("Convert buffer to element"); # 327 "gpcb-menu.res" char *s = N_("Break buffer elements to pieces"); # 328 "gpcb-menu.res" char *s = N_("Save buffer elements to file"); # 330 "gpcb-menu.res" char *s = N_("Select Buffer #1"); # 330 "gpcb-menu.res" char *s = N_("Shift-1"); # 330 "gpcb-menu.res" char *s = N_("Shift1"); # 331 "gpcb-menu.res" char *s = N_("Select Buffer #2"); # 331 "gpcb-menu.res" char *s = N_("Shift-2"); # 331 "gpcb-menu.res" char *s = N_("Shift2"); # 332 "gpcb-menu.res" char *s = N_("Select Buffer #3"); # 332 "gpcb-menu.res" char *s = N_("Shift-3"); # 332 "gpcb-menu.res" char *s = N_("Shift3"); # 333 "gpcb-menu.res" char *s = N_("Select Buffer #4"); # 333 "gpcb-menu.res" char *s = N_("Shift-4"); # 333 "gpcb-menu.res" char *s = N_("Shift4"); # 334 "gpcb-menu.res" char *s = N_("Select Buffer #5"); # 334 "gpcb-menu.res" char *s = N_("Shift-5"); # 334 "gpcb-menu.res" char *s = N_("Shift5"); # 340 "gpcb-menu.res" char *s = N_("Connects"); # 341 "gpcb-menu.res" char *s = N_("Lookup connection"); # 341 "gpcb-menu.res" char *s = N_("Ctrl-F"); # 341 "gpcb-menu.res" char *s = N_("Ctrlf"); # 342 "gpcb-menu.res" char *s = N_("Reset scanned pads/pins/vias"); # 343 "gpcb-menu.res" char *s = N_("Reset scanned lines/polygons"); # 344 "gpcb-menu.res" char *s = N_("Reset all connections"); # 344 "gpcb-menu.res" char *s = N_("Shift-F"); # 344 "gpcb-menu.res" char *s = N_("Shiftf"); # 346 "gpcb-menu.res" char *s = N_("Optimize rats nest"); # 347 "gpcb-menu.res" char *s = N_("O"); # 347 "gpcb-menu.res" char *s = N_("o"); # 348 "gpcb-menu.res" char *s = N_("Erase rats nest"); # 348 "gpcb-menu.res" char *s = N_("E"); # 348 "gpcb-menu.res" char *s = N_("e"); # 349 "gpcb-menu.res" char *s = N_("Erase selected rats"); # 349 "gpcb-menu.res" char *s = N_("Shift-E"); # 349 "gpcb-menu.res" char *s = N_("Shifte"); # 352 "gpcb-menu.res" char *s = N_("Auto-route all rats"); # 353 "gpcb-menu.res" char *s = N_("Toporouter"); # 354 "gpcb-menu.res" char *s = N_("Rip up all auto-routed tracks"); # 356 "gpcb-menu.res" char *s = N_("Optimize routed tracks"); # 357 "gpcb-menu.res" char *s = N_("Auto-Optimize"); # 357 "gpcb-menu.res" char *s = N_("Shift-="); # 357 "gpcb-menu.res" char *s = N_("Shift="); # 358 "gpcb-menu.res" char *s = N_("Debumpify"); # 359 "gpcb-menu.res" char *s = N_("Unjaggy"); # 360 "gpcb-menu.res" char *s = N_("Vianudge"); # 361 "gpcb-menu.res" char *s = N_("Viatrim"); # 362 "gpcb-menu.res" char *s = N_("Ortho pull"); # 363 "gpcb-menu.res" char *s = N_("Simple optimization"); # 363 "gpcb-menu.res" char *s = N_("="); # 363 "gpcb-menu.res" char *s = N_("="); # 364 "gpcb-menu.res" char *s = N_("Miter"); # 365 "gpcb-menu.res" char *s = N_("Puller"); # 365 "gpcb-menu.res" char *s = N_("Y"); # 365 "gpcb-menu.res" char *s = N_("y"); # 366 "gpcb-menu.res" char *s = N_("Global Puller"); # 367 "gpcb-menu.res" char *s = N_("Selected"); # 368 "gpcb-menu.res" char *s = N_("Found"); # 369 "gpcb-menu.res" char *s = N_("All"); # 372 "gpcb-menu.res" char *s = N_("Only autorouted nets"); # 375 "gpcb-menu.res" char *s = N_("Design Rule Checker"); # 377 "gpcb-menu.res" char *s = N_("Apply vendor drill mapping"); # 383 "gpcb-menu.res" char *s = N_("Info"); # 513 "gpcb-menu.res" char *s = N_("Generate object report"); # 384 "gpcb-menu.res" char *s = N_("Ctrl-R"); # 384 "gpcb-menu.res" char *s = N_("Ctrlr"); # 385 "gpcb-menu.res" char *s = N_("Generate drill summary"); # 386 "gpcb-menu.res" char *s = N_("Report found pins/pads"); # 387 "gpcb-menu.res" char *s = N_("Report net length"); # 387 "gpcb-menu.res" char *s = N_("R"); # 387 "gpcb-menu.res" char *s = N_("r"); # 388 "gpcb-menu.res" char *s = N_("Key Bindings"); # 529 "gpcb-menu.res" char *s = N_("Remove"); # 389 "gpcb-menu.res" char *s = N_("Delete"); # 389 "gpcb-menu.res" char *s = N_("Delete"); # 395 "gpcb-menu.res" char *s = N_("Remove Selected"); # 395 "gpcb-menu.res" char *s = N_("Backspace"); # 395 "gpcb-menu.res" char *s = N_("BackSpace"); # 398 "gpcb-menu.res" char *s = N_("Remove Connected"); # 398 "gpcb-menu.res" char *s = N_("Shift-Backspace"); # 398 "gpcb-menu.res" char *s = N_("ShiftBackSpace"); # 415 "gpcb-menu.res" char *s = N_("Set Same"); # 415 "gpcb-menu.res" char *s = N_("A"); # 415 "gpcb-menu.res" char *s = N_("a"); # 416 "gpcb-menu.res" char *s = N_("Flip Object"); # 416 "gpcb-menu.res" char *s = N_("B"); # 416 "gpcb-menu.res" char *s = N_("b"); # 417 "gpcb-menu.res" char *s = N_("Find Connections"); # 417 "gpcb-menu.res" char *s = N_("F"); # 417 "gpcb-menu.res" char *s = N_("f"); # 418 "gpcb-menu.res" char *s = N_("ToggleHideName Object"); # 418 "gpcb-menu.res" char *s = N_("H"); # 418 "gpcb-menu.res" char *s = N_("h"); # 419 "gpcb-menu.res" char *s = N_("ToggleHideName SelectedElement"); # 419 "gpcb-menu.res" char *s = N_("Shift-H"); # 419 "gpcb-menu.res" char *s = N_("Shifth"); # 420 "gpcb-menu.res" char *s = N_("ChangeHole Object"); # 420 "gpcb-menu.res" char *s = N_("Ctrl-H"); # 420 "gpcb-menu.res" char *s = N_("Ctrlh"); # 421 "gpcb-menu.res" char *s = N_("ChangeJoin Object"); # 421 "gpcb-menu.res" char *s = N_("J"); # 421 "gpcb-menu.res" char *s = N_("j"); # 422 "gpcb-menu.res" char *s = N_("ChangeJoin SelectedObject"); # 422 "gpcb-menu.res" char *s = N_("Shift-J"); # 422 "gpcb-menu.res" char *s = N_("Shiftj"); # 423 "gpcb-menu.res" char *s = N_("Clear Object +"); # 423 "gpcb-menu.res" char *s = N_("K"); # 423 "gpcb-menu.res" char *s = N_("k"); # 424 "gpcb-menu.res" char *s = N_("Clear Object -"); # 424 "gpcb-menu.res" char *s = N_("Shift-K"); # 424 "gpcb-menu.res" char *s = N_("Shiftk"); # 425 "gpcb-menu.res" char *s = N_("Clear Selected +"); # 425 "gpcb-menu.res" char *s = N_("Ctrl-K"); # 425 "gpcb-menu.res" char *s = N_("Ctrlk"); # 426 "gpcb-menu.res" char *s = N_("Clear Selected -"); # 426 "gpcb-menu.res" char *s = N_("Shift-Ctrl-K"); # 426 "gpcb-menu.res" char *s = N_("Shift Ctrlk"); # 427 "gpcb-menu.res" char *s = N_("Line Tool size +"); # 427 "gpcb-menu.res" char *s = N_("L"); # 427 "gpcb-menu.res" char *s = N_("l"); # 428 "gpcb-menu.res" char *s = N_("Line Tool size -"); # 428 "gpcb-menu.res" char *s = N_("Shift-L"); # 428 "gpcb-menu.res" char *s = N_("Shiftl"); # 429 "gpcb-menu.res" char *s = N_("Move Object to current layer"); # 429 "gpcb-menu.res" char *s = N_("M"); # 429 "gpcb-menu.res" char *s = N_("m"); # 430 "gpcb-menu.res" char *s = N_("MarkCrosshair"); # 430 "gpcb-menu.res" char *s = N_("Ctrl-M"); # 430 "gpcb-menu.res" char *s = N_("Ctrlm"); # 431 "gpcb-menu.res" char *s = N_("Select shortest rat"); # 431 "gpcb-menu.res" char *s = N_("Shift-N"); # 431 "gpcb-menu.res" char *s = N_("Shiftn"); # 432 "gpcb-menu.res" char *s = N_("AddRats to selected pins"); # 432 "gpcb-menu.res" char *s = N_("Shift-O"); # 432 "gpcb-menu.res" char *s = N_("Shifto"); # 438 "gpcb-menu.res" char *s = N_("ChangeOctagon Object"); # 438 "gpcb-menu.res" char *s = N_("Ctrl-O"); # 438 "gpcb-menu.res" char *s = N_("Ctrlo"); # 439 "gpcb-menu.res" char *s = N_("Polygon PreviousPoint"); # 439 "gpcb-menu.res" char *s = N_("P"); # 439 "gpcb-menu.res" char *s = N_("p"); # 440 "gpcb-menu.res" char *s = N_("Polygon Close"); # 440 "gpcb-menu.res" char *s = N_("Shift-P"); # 440 "gpcb-menu.res" char *s = N_("Shiftp"); # 441 "gpcb-menu.res" char *s = N_("ChangeSquare Object"); # 441 "gpcb-menu.res" char *s = N_("Q"); # 441 "gpcb-menu.res" char *s = N_("q"); # 442 "gpcb-menu.res" char *s = N_("ChangeSize +"); # 442 "gpcb-menu.res" char *s = N_("S"); # 442 "gpcb-menu.res" char *s = N_("s"); # 443 "gpcb-menu.res" char *s = N_("ChangeSize -"); # 443 "gpcb-menu.res" char *s = N_("Shift-S"); # 443 "gpcb-menu.res" char *s = N_("Shifts"); # 444 "gpcb-menu.res" char *s = N_("ChangeDrill +5 mil"); # 444 "gpcb-menu.res" char *s = N_("Ctrl-D"); # 444 "gpcb-menu.res" char *s = N_("Ctrld"); # 445 "gpcb-menu.res" char *s = N_("ChangeDrill -5 mil"); # 445 "gpcb-menu.res" char *s = N_("Ctrl-Shift-D"); # 445 "gpcb-menu.res" char *s = N_("Ctrl Shiftd"); # 446 "gpcb-menu.res" char *s = N_("Text Tool scale +10 mil"); # 446 "gpcb-menu.res" char *s = N_("T"); # 446 "gpcb-menu.res" char *s = N_("t"); # 447 "gpcb-menu.res" char *s = N_("Text Tool scale -10 mil"); # 447 "gpcb-menu.res" char *s = N_("Shift-T"); # 447 "gpcb-menu.res" char *s = N_("Shiftt"); # 448 "gpcb-menu.res" char *s = N_("Via Tool size +5 mil"); # 448 "gpcb-menu.res" char *s = N_("Shift-V"); # 448 "gpcb-menu.res" char *s = N_("Shiftv"); # 449 "gpcb-menu.res" char *s = N_("Via Tool size -5 mil"); # 449 "gpcb-menu.res" char *s = N_("Shift-Ctrl-V"); # 449 "gpcb-menu.res" char *s = N_("Shift Ctrlv"); # 450 "gpcb-menu.res" char *s = N_("Via Tool drill +5 mil"); # 450 "gpcb-menu.res" char *s = N_("Ctrl-L"); # 450 "gpcb-menu.res" char *s = N_("Ctrll"); # 451 "gpcb-menu.res" char *s = N_("Via Tool drill -5 mil"); # 451 "gpcb-menu.res" char *s = N_("Ctrl-Shift-L"); # 451 "gpcb-menu.res" char *s = N_("Ctrl Shiftl"); # 452 "gpcb-menu.res" char *s = N_("AddRats Selected"); # 452 "gpcb-menu.res" char *s = N_("Shift-W"); # 452 "gpcb-menu.res" char *s = N_("Shiftw"); # 453 "gpcb-menu.res" char *s = N_("Add All Rats"); # 453 "gpcb-menu.res" char *s = N_("W"); # 453 "gpcb-menu.res" char *s = N_("w"); # 454 "gpcb-menu.res" char *s = N_("Cycle Clip"); # 454 "gpcb-menu.res" char *s = N_("/"); # 454 "gpcb-menu.res" char *s = N_("/"); # 455 "gpcb-menu.res" char *s = N_("Arrow Mode"); # 455 "gpcb-menu.res" char *s = N_("Space"); # 455 "gpcb-menu.res" char *s = N_("space"); # 456 "gpcb-menu.res" char *s = N_("Temp Arrow ON"); # 456 "gpcb-menu.res" char *s = N_("["); # 456 "gpcb-menu.res" char *s = N_("["); # 457 "gpcb-menu.res" char *s = N_("Temp Arrow OFF"); # 457 "gpcb-menu.res" char *s = N_("]"); # 457 "gpcb-menu.res" char *s = N_("]"); # 459 "gpcb-menu.res" char *s = N_("Step Up"); # 463 "gpcb-menu.res" char *s = N_("Up"); # 459 "gpcb-menu.res" char *s = N_("Up"); # 460 "gpcb-menu.res" char *s = N_("Step Down"); # 464 "gpcb-menu.res" char *s = N_("Down"); # 460 "gpcb-menu.res" char *s = N_("Down"); # 461 "gpcb-menu.res" char *s = N_("Step Left"); # 465 "gpcb-menu.res" char *s = N_("Left"); # 461 "gpcb-menu.res" char *s = N_("Left"); # 462 "gpcb-menu.res" char *s = N_("Step Right"); # 466 "gpcb-menu.res" char *s = N_("Right"); # 462 "gpcb-menu.res" char *s = N_("Right"); # 463 "gpcb-menu.res" char *s = N_("Step +Up"); # 463 "gpcb-menu.res" char *s = N_("ShiftUp"); # 464 "gpcb-menu.res" char *s = N_("Step +Down"); # 464 "gpcb-menu.res" char *s = N_("ShiftDown"); # 465 "gpcb-menu.res" char *s = N_("Step +Left"); # 465 "gpcb-menu.res" char *s = N_("ShiftLeft"); # 466 "gpcb-menu.res" char *s = N_("Step +Right"); # 466 "gpcb-menu.res" char *s = N_("ShiftRight"); # 467 "gpcb-menu.res" char *s = N_("Click"); # 467 "gpcb-menu.res" char *s = N_("Enter"); # 467 "gpcb-menu.res" char *s = N_("Enter"); # 475 "gpcb-menu.res" char *s = N_("Window"); # 476 "gpcb-menu.res" char *s = N_("Library"); # 476 "gpcb-menu.res" char *s = N_("i"); # 476 "gpcb-menu.res" char *s = N_("i"); # 477 "gpcb-menu.res" char *s = N_("Message Log"); # 478 "gpcb-menu.res" char *s = N_("DRC Check"); # 479 "gpcb-menu.res" char *s = N_("Netlist"); # 480 "gpcb-menu.res" char *s = N_("Command Entry"); # 480 "gpcb-menu.res" char *s = N_(":"); # 480 "gpcb-menu.res" char *s = N_(":"); # 481 "gpcb-menu.res" char *s = N_("Pinout"); # 481 "gpcb-menu.res" char *s = N_("Shift-D"); # 481 "gpcb-menu.res" char *s = N_("Shiftd"); # 483 "gpcb-menu.res" char *s = N_("About..."); # 491 "gpcb-menu.res" char *s = N_("Operations on selections"); # 492 "gpcb-menu.res" char *s = N_("Unselect all objects"); # 494 "gpcb-menu.res" char *s = N_("Copy selection to buffer"); # 500 "gpcb-menu.res" char *s = N_("Cut selection to buffer"); # 508 "gpcb-menu.res" char *s = N_("Auto place selected elements"); # 509 "gpcb-menu.res" char *s = N_("Autoroute selected elements"); # 512 "gpcb-menu.res" char *s = N_("Operations on this location"); # 516 "gpcb-menu.res" char *s = N_("Undo last operation"); # 517 "gpcb-menu.res" char *s = N_("Redo last undone operation"); # 520 "gpcb-menu.res" char *s = N_("None"); # 521 "gpcb-menu.res" char *s = N_("Via"); # 521 "gpcb-menu.res" char *s = N_("F1"); # 521 "gpcb-menu.res" char *s = N_("F1"); # 522 "gpcb-menu.res" char *s = N_("Line"); # 522 "gpcb-menu.res" char *s = N_("F2"); # 522 "gpcb-menu.res" char *s = N_("F2"); # 523 "gpcb-menu.res" char *s = N_("Arc"); # 523 "gpcb-menu.res" char *s = N_("F3"); # 523 "gpcb-menu.res" char *s = N_("F3"); # 524 "gpcb-menu.res" char *s = N_("F4"); # 524 "gpcb-menu.res" char *s = N_("F4"); # 525 "gpcb-menu.res" char *s = N_("Rectangle"); # 525 "gpcb-menu.res" char *s = N_("F5"); # 525 "gpcb-menu.res" char *s = N_("F5"); # 526 "gpcb-menu.res" char *s = N_("Polygon"); # 526 "gpcb-menu.res" char *s = N_("F6"); # 526 "gpcb-menu.res" char *s = N_("F6"); # 527 "gpcb-menu.res" char *s = N_("Polygon Hole"); # 528 "gpcb-menu.res" char *s = N_("F7"); # 528 "gpcb-menu.res" char *s = N_("F7"); # 529 "gpcb-menu.res" char *s = N_("F8"); # 529 "gpcb-menu.res" char *s = N_("F8"); # 530 "gpcb-menu.res" char *s = N_("Rotate"); # 530 "gpcb-menu.res" char *s = N_("F9"); # 530 "gpcb-menu.res" char *s = N_("F9"); # 531 "gpcb-menu.res" char *s = N_("Thermal"); # 531 "gpcb-menu.res" char *s = N_("F10"); # 531 "gpcb-menu.res" char *s = N_("F10"); # 532 "gpcb-menu.res" char *s = N_("Arrow"); # 532 "gpcb-menu.res" char *s = N_("F11"); # 532 "gpcb-menu.res" char *s = N_("F11"); # 533 "gpcb-menu.res" char *s = N_("Insert Point"); # 533 "gpcb-menu.res" char *s = N_("Insert"); # 533 "gpcb-menu.res" char *s = N_("Insert"); # 534 "gpcb-menu.res" char *s = N_("Move"); # 535 "gpcb-menu.res" char *s = N_("Copy"); # 536 "gpcb-menu.res" char *s = N_("Lock"); # 536 "gpcb-menu.res" char *s = N_("F12"); # 536 "gpcb-menu.res" char *s = N_("F12"); # 537 "gpcb-menu.res" char *s = N_("Cancel"); # 537 "gpcb-menu.res" char *s = N_("Esc"); # 537 "gpcb-menu.res" char *s = N_("Escape"); pcb-4.3.0/src/dbus.c0000664000175000017500000002524013773431044011106 00000000000000/*! * \file src/dbus.c * * \brief D-Bus IPC logic * * D-Bus code originally derrived from example-service.c in the * dbus-glib bindings. * * PCB, an interactive printed circuit board editor * * Copyright (C) 2006 University of Cambridge * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #define DBUS_API_SUBJECT_TO_CHANGE #include #include #include "dbus.h" #include "dbus-pcbmain.h" #include "dbus-introspect.h" #include "global.h" #include "data.h" /* For lrealpath */ #include "lrealpath.h" #define PCB_DBUS_CANONICAL_NAME "org.seul.geda.pcb" #define PCB_DBUS_OBJECT_PATH "/org/seul/geda/pcb" #define PCB_DBUS_INTERFACE "org.seul.geda.pcb" #define PCB_DBUS_ACTIONS_INTERFACE "org.seul.geda.pcb.actions" static DBusConnection *pcb_dbus_conn; static DBusHandlerResult handle_get_filename (DBusConnection * connection, DBusMessage * message, void *data) { DBusMessage *reply; DBusMessageIter iter; DBusHandlerResult result; char *filename; result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; // TODO: Should check the message signature matches what we expect? reply = dbus_message_new_method_return (message); if (reply == NULL) { fprintf (stderr, "pcb_dbus: Couldn't create reply message\n"); return result; } dbus_message_iter_init_append (reply, &iter); if (PCB->Filename) filename = lrealpath (PCB->Filename); else filename = NULL; if (filename == NULL) { #ifdef DEBUG fprintf (stderr, "pcb_dbus: DEBUG: Couldn't get working filename, assuming none\n"); #endif filename = strdup (""); if (filename == NULL) { fprintf (stderr, "pcb_dbus: Couldn't strdup( \"\" ) for the filename\n"); goto out; } } if (!dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &filename)) { fprintf (stderr, "pcb_dbus: Couldn't append return filename string to message reply, Out Of Memory!\n"); free (filename); goto out; } free (filename); if (!dbus_connection_send (connection, reply, NULL)) { fprintf (stderr, "pcb_dbus: Couldn't send message, Out Of Memory!\n"); goto out; } result = DBUS_HANDLER_RESULT_HANDLED; out: dbus_message_unref (reply); return result; } static DBusHandlerResult handle_exec_action (DBusConnection * connection, DBusMessage * message, void *data) { DBusMessage *reply; DBusMessageIter iter; DBusHandlerResult result; DBusError err; dbus_uint32_t retval; char *action_name; char **argv; int argc; #ifdef DEBUG int i; #endif result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; // TODO: Should check the message signature matches what we expect? // initialise the error struct dbus_error_init (&err); /* DON'T FREE action_name, as it belongs to DBUS, * DO FREE argv, using dbus_free_string_array() */ argv = NULL; if (!dbus_message_get_args (message, &err, DBUS_TYPE_STRING, &action_name, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &argv, &argc, DBUS_TYPE_INVALID)) { fprintf (stderr, "Failed to read method arguments\n"); if (argv) dbus_free_string_array (argv); return result; } #ifdef DEBUG fprintf (stderr, "pcb_dbus: DEBUG: Executing action: %s(", action_name); if (argc > 0) fprintf (stderr, " \"%s\"", argv[0]); for (i = 1; i < argc; i++) fprintf (stderr, ", \"%s\"", argv[i]); fprintf (stderr, " )\n"); #endif // TODO: Proper return value from actions hid_actionv (action_name, argc, argv); retval = 0; dbus_free_string_array (argv); reply = dbus_message_new_method_return (message); if (reply == NULL) { fprintf (stderr, "pcb_dbus: Couldn't create reply message\n"); return result; } dbus_message_iter_init_append (reply, &iter); if (!dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &retval)) { fprintf (stderr, "pcb_dbus: Couldn't sent message, Out Of Memory!\n"); goto out; } if (!dbus_connection_send (connection, reply, NULL)) { fprintf (stderr, "pcb_dbus: Couldn't send message, Out Of Memory!\n"); goto out; } result = DBUS_HANDLER_RESULT_HANDLED; out: dbus_message_unref (reply); return result; } static DBusHandlerResult handle_introspect (DBusConnection * connection, DBusMessage * message, void *data) { DBusMessage *reply; DBusMessageIter iter; DBusHandlerResult result; result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; reply = dbus_message_new_method_return (message); if (reply == NULL) { fprintf (stderr, "pcb_dbus: Couldn't create reply message\n"); return result; } dbus_message_iter_init_append (reply, &iter); if (!dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &pcb_dbus_introspect_xml)) { fprintf (stderr, "pcb_dbus: Couldn't add introspect XML to message return\n"); goto out; } if (!dbus_connection_send (pcb_dbus_conn, reply, NULL)) { fprintf (stderr, "pcb_dbus: Couldn't queue reply message for sending\n"); goto out; } result = DBUS_HANDLER_RESULT_HANDLED; out: dbus_message_unref (reply); return result; } static void unregister_dbus_handler (DBusConnection * connection, void *data) { } static DBusHandlerResult handle_dbus_message (DBusConnection * connection, DBusMessage * message, void *data) { int msg_type; msg_type = dbus_message_get_type (message); switch (msg_type) { case DBUS_MESSAGE_TYPE_METHOD_CALL: { const char *method_name; const char *interface_name; method_name = dbus_message_get_member (message); if (method_name == NULL) { fprintf (stderr, "pcb_dbus: Method had no name specified\n"); break; } interface_name = dbus_message_get_interface (message); if (interface_name == NULL) { fprintf (stderr, "pcb_dbus: Method had no interface specified\n"); break; } if (strcmp (interface_name, PCB_DBUS_INTERFACE) == 0) { if (strcmp (method_name, "GetFilename") == 0) { return handle_get_filename (connection, message, data); } fprintf (stderr, "pcb_dbus: Interface '%s' has no method '%s'\n", interface_name, method_name); break; } else if (strcmp (interface_name, PCB_DBUS_ACTIONS_INTERFACE) == 0) { if (strcmp (method_name, "ExecAction") == 0) { return handle_exec_action (connection, message, data); } fprintf (stderr, "pcb_dbus: Interface '%s' has no method '%s'\n", interface_name, method_name); break; } else if (strcmp (interface_name, DBUS_INTERFACE_INTROSPECTABLE) == 0) { if (strcmp (method_name, "Introspect") == 0) { return handle_introspect (connection, message, data); } fprintf (stderr, "pcb_dbus: Interface '%s' has no method '%s'\n", interface_name, method_name); break; } else { fprintf (stderr, "pcb_dbus: Interface '%s' was not recognised\n", interface_name); break; } } break; case DBUS_MESSAGE_TYPE_METHOD_RETURN: fprintf (stderr, "pcb_dbus: DBUG: Method return message\n"); // WON'T ACTUALLY BE ANY UNLESS WE MAKE AN ASYNCRONOUS CALL? break; case DBUS_MESSAGE_TYPE_ERROR: fprintf (stderr, "pcb_dbus: DEBUG: Error message\n"); // HOPE NOT! break; case DBUS_MESSAGE_TYPE_SIGNAL: fprintf (stderr, "pcb_dbus: DEBUG: Signal message\n"); // NONE AT PRESENT break; default: fprintf (stderr, "pcb_dbus: DEBUG: Message type wasn't one we know about!\n"); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } /*! * \brief Carry out all actions to setup the D-Bus and register * appropriate callbacks. */ void pcb_dbus_setup (void) { DBusError err; int ret; const DBusObjectPathVTable object_vtable = { unregister_dbus_handler, handle_dbus_message, NULL, NULL, NULL, NULL }; // Initialise the error variable dbus_error_init (&err); // Connect to the bus pcb_dbus_conn = dbus_bus_get_private (DBUS_BUS_SESSION, &err); if (dbus_error_is_set (&err)) { fprintf (stderr, "pcb_dbus: DBus connection Error (%s)\n", err.message); dbus_error_free (&err); } if (pcb_dbus_conn == NULL) return; // Request the canonical name for PCB on the bus ret = dbus_bus_request_name (pcb_dbus_conn, PCB_DBUS_CANONICAL_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING, &err); if (dbus_error_is_set (&err)) { fprintf (stderr, "pcb_dbus: DBus name error (%s)\n", err.message); dbus_error_free (&err); } if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER && ret != DBUS_REQUEST_NAME_REPLY_IN_QUEUE) { fprintf (stderr, "pcb_dbus: Couldn't gain ownership or queued ownership of the canonical DBus name\n"); return; } if (!dbus_connection_register_object_path (pcb_dbus_conn, PCB_DBUS_OBJECT_PATH, &object_vtable, NULL // void * user_data )) { fprintf (stderr, "pcb_dbus: Couldn't register DBUS handler for %s\n", PCB_DBUS_OBJECT_PATH); return; } // Setup intergration with the pcb mainloop pcb_dbus_connection_setup_with_mainloop (pcb_dbus_conn); // dbus_error_free(&err); return; } /*! * \brief Carry out all actions to finalise the D-Bus connection. */ void pcb_dbus_finish (void) { DBusError err; // Initialise the error variable dbus_error_init (&err); // TODO: Could emit a "goodbye" signal here? dbus_connection_flush (pcb_dbus_conn); dbus_connection_unregister_object_path (pcb_dbus_conn, PCB_DBUS_OBJECT_PATH); dbus_bus_release_name (pcb_dbus_conn, PCB_DBUS_CANONICAL_NAME, &err); dbus_error_free (&err); pcb_dbus_connection_finish_with_mainloop (pcb_dbus_conn); dbus_connection_close (pcb_dbus_conn); dbus_connection_unref (pcb_dbus_conn); // Call DBus shutdown. This doesn't work with shared connections, // only private ones (like we took out earlier). // If any future module / plugin to PCB wants to use DBus too, // we must remove this call. DBus will get shut-down when the app exits. dbus_shutdown (); } pcb-4.3.0/src/data.c0000664000175000017500000000342513773431044011063 00000000000000/*! * \file src/data.c * * \brief Just defines common identifiers. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * Thomas.Nau@rz.uni-ulm.de */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "data.h" #ifdef HAVE_LIBDMALLOC #include #endif /* --------------------------------------------------------------------------- * some shared identifiers */ CrosshairType Crosshair; /*!< information about cursor settings. */ MarkType Marked; /*!< a cross-hair mark. */ OutputType Output; /*!< some widgets ... used for drawing. */ PCBType *PCB; /*!< pointer to layout struct. */ char *Progname; SettingType Settings; int LayerStack[MAX_LAYER]; /*!< determines the layer draw order. */ BufferType Buffers[MAX_BUFFER]; /*!< my buffers. */ LibraryType Library; /*!< the library. */ bool Bumped; /*!< if the undo serial number has changed. */ int addedLines; pcb-4.3.0/src/edif.y0000664000175000017500000034327013773431044011114 00000000000000%{ /* * PCB Edif parser based heavily on: * * Header: edif.y,v 1.18 87/12/07 19:59:49 roger Locked */ /************************************************************************ * * * edif.y * * * * EDIF 2.0.0 parser, Level 0 * * * * You are free to copy, distribute, use it, abuse it, make it * * write bad tracks all over the disk ... or anything else. * * * * Your friendly neighborhood Rogue Monster - roger@mips.com * * * ************************************************************************/ #include /* for malloc, free, atoi */ #include /* for strcpy */ #include #include #include "global.h" #include "data.h" /* from mymem.h, not include because of the malloc junk */ LibraryMenuType * GetLibraryMenuMemory (LibraryType *); LibraryEntryType * GetLibraryEntryMemory (LibraryMenuType *); /* * Local definitions. */ #define IDENT_LENGTH 255 #define Malloc(s) malloc(s) #define Free(p) free(p) #define Getc(s) getc(s) #define Ungetc(c) ungetc(c,Input) typedef struct _str_pair { char* str1; char* str2; struct _str_pair* next; } str_pair; typedef struct _pair_list { char* name; str_pair* list; } pair_list; str_pair* new_str_pair(char* s1, char* s2) { str_pair* ps = (str_pair *)malloc(sizeof(str_pair)); ps->str1 = s1; ps->str2 = s2; ps->next = NULL; return ps; } pair_list* new_pair_list(str_pair* ps) { pair_list* pl = (pair_list *)malloc(sizeof(pair_list)); pl->list = ps; pl->name = NULL; return pl; } void str_pair_free(str_pair* ps) { str_pair* node; while ( ps ) { free(ps->str1); free(ps->str2); node = ps; ps = ps->next; free(node); } } void pair_list_free(pair_list* pl) { str_pair_free(pl->list); free(pl->name); free(pl); } void define_pcb_net(str_pair* name, pair_list* nodes) { int tl; str_pair* done_node; str_pair* node; char* buf; char* p; LibraryEntryType *entry; LibraryMenuType *menu = GetLibraryMenuMemory (&PCB->NetlistLib); if ( !name->str1 ) { /* no net name given, stop now */ /* if renamed str2 also exists and must be freed */ if ( name->str2 ) free(name->str2); free(name); pair_list_free(nodes); return; } menu->Name = strdup (name->str1); free(name->str1); /* if renamed str2 also exists and must be freed */ if ( name->str2 ) free(name->str2); free(name); buf = (char *)malloc(256); if ( !buf ) { /* no memory */ pair_list_free(nodes); return; } node = nodes->list; free(nodes->name); free(nodes); while ( node ) { /* check for node with no instance */ if ( !node->str1 ) { /* toss it and move on */ free(node->str2); done_node = node; node = node->next; free(done_node); continue; } tl = strlen(node->str1) + strlen(node->str2); if ( tl + 3 > 256 ) { free(buf); buf = (char *)malloc(tl+3); if ( !buf ) { /* no memory */ str_pair_free(node); return; } } strcpy(buf,node->str1); /* make all upper case, because of PCB funky behaviour */ p=buf; while ( *p ) { *p = toupper( (int) *p); p++; } /* add dash separating designator from node */ *(buf+strlen(node->str1)) = '-'; /* check for the edif number prefix */ if ( node->str2[0] == '&' ) { /* skip number prefix */ strcpy(buf+strlen(node->str1)+1,node->str2 +1); } else { strcpy(buf+strlen(node->str1)+1,node->str2); } /* free the strings */ free(node->str1); free(node->str2); entry = GetLibraryEntryMemory (menu); entry->ListEntry = strdup(buf); done_node = node; node = node->next; free(done_node); } } /* forward function declarations */ static int yylex(void); static void yyerror(const char *); static void PopC(void); %} %name-prefix "edif" %union { char* s; pair_list* pl; str_pair* ps; } %type Int Ident Str Keyword Name _Name %type PortRef _PortRef NetNameDef NameDef %type Rename _Joined %type __Rename _Rename NameRef %type InstanceRef InstNameRef Member PortNameRef %type Net _Net Joined %token EDIF_TOK_IDENT %token EDIF_TOK_INT %token EDIF_TOK_KEYWORD %token EDIF_TOK_STR %token EDIF_TOK_ANGLE %token EDIF_TOK_BEHAVIOR %token EDIF_TOK_CALCULATED %token EDIF_TOK_CAPACITANCE %token EDIF_TOK_CENTERCENTER %token EDIF_TOK_CENTERLEFT %token EDIF_TOK_CENTERRIGHT %token EDIF_TOK_CHARGE %token EDIF_TOK_CONDUCTANCE %token EDIF_TOK_CURRENT %token EDIF_TOK_DISTANCE %token EDIF_TOK_DOCUMENT %token EDIF_TOK_ENERGY %token EDIF_TOK_EXTEND %token EDIF_TOK_FLUX %token EDIF_TOK_FREQUENCY %token EDIF_TOK_GENERIC %token EDIF_TOK_GRAPHIC %token EDIF_TOK_INDUCTANCE %token EDIF_TOK_INOUT %token EDIF_TOK_INPUT %token EDIF_TOK_LOGICMODEL %token EDIF_TOK_LOWERCENTER %token EDIF_TOK_LOWERLEFT %token EDIF_TOK_LOWERRIGHT %token EDIF_TOK_MASKLAYOUT %token EDIF_TOK_MASS %token EDIF_TOK_MEASURED %token EDIF_TOK_MX %token EDIF_TOK_MXR90 %token EDIF_TOK_MY %token EDIF_TOK_MYR90 %token EDIF_TOK_NETLIST %token EDIF_TOK_OUTPUT %token EDIF_TOK_PCBLAYOUT %token EDIF_TOK_POWER %token EDIF_TOK_R0 %token EDIF_TOK_R180 %token EDIF_TOK_R270 %token EDIF_TOK_R90 %token EDIF_TOK_REQUIRED %token EDIF_TOK_RESISTANCE %token EDIF_TOK_RIPPER %token EDIF_TOK_ROUND %token EDIF_TOK_SCHEMATIC %token EDIF_TOK_STRANGER %token EDIF_TOK_SYMBOLIC %token EDIF_TOK_TEMPERATURE %token EDIF_TOK_TIE %token EDIF_TOK_TIME %token EDIF_TOK_TRUNCATE %token EDIF_TOK_UPPERCENTER %token EDIF_TOK_UPPERLEFT %token EDIF_TOK_UPPERRIGHT %token EDIF_TOK_VOLTAGE %token EDIF_TOK_ACLOAD %token EDIF_TOK_AFTER %token EDIF_TOK_ANNOTATE %token EDIF_TOK_APPLY %token EDIF_TOK_ARC %token EDIF_TOK_ARRAY %token EDIF_TOK_ARRAYMACRO %token EDIF_TOK_ARRAYRELATEDINFO %token EDIF_TOK_ARRAYSITE %token EDIF_TOK_ATLEAST %token EDIF_TOK_ATMOST %token EDIF_TOK_AUTHOR %token EDIF_TOK_BASEARRAY %token EDIF_TOK_BECOMES %token EDIF_TOK_BETWEEN %token EDIF_TOK_BOOLEAN %token EDIF_TOK_BOOLEANDISPLAY %token EDIF_TOK_BOOLEANMAP %token EDIF_TOK_BORDERPATTERN %token EDIF_TOK_BORDERWIDTH %token EDIF_TOK_BOUNDINGBOX %token EDIF_TOK_CELL %token EDIF_TOK_CELLREF %token EDIF_TOK_CELLTYPE %token EDIF_TOK_CHANGE %token EDIF_TOK_CIRCLE %token EDIF_TOK_COLOR %token EDIF_TOK_COMMENT %token EDIF_TOK_COMMENTGRAPHICS %token EDIF_TOK_COMPOUND %token EDIF_TOK_CONNECTLOCATION %token EDIF_TOK_CONTENTS %token EDIF_TOK_CORNERTYPE %token EDIF_TOK_CRITICALITY %token EDIF_TOK_CURRENTMAP %token EDIF_TOK_CURVE %token EDIF_TOK_CYCLE %token EDIF_TOK_DATAORIGIN %token EDIF_TOK_DCFANINLOAD %token EDIF_TOK_DCFANOUTLOAD %token EDIF_TOK_DCMAXFANIN %token EDIF_TOK_DCMAXFANOUT %token EDIF_TOK_DELAY %token EDIF_TOK_DELTA %token EDIF_TOK_DERIVATION %token EDIF_TOK_DESIGN %token EDIF_TOK_DESIGNATOR %token EDIF_TOK_DIFFERENCE %token EDIF_TOK_DIRECTION %token EDIF_TOK_DISPLAY %token EDIF_TOK_DOMINATES %token EDIF_TOK_DOT %token EDIF_TOK_DURATION %token EDIF_TOK_E %token EDIF_TOK_EDIF %token EDIF_TOK_EDIFLEVEL %token EDIF_TOK_EDIFVERSION %token EDIF_TOK_ENCLOSUREDISTANCE %token EDIF_TOK_ENDTYPE %token EDIF_TOK_ENTRY %token EDIF_TOK_EVENT %token EDIF_TOK_EXACTLY %token EDIF_TOK_EXTERNAL %token EDIF_TOK_FABRICATE %token EDIF_TOK_FALSE %token EDIF_TOK_FIGURE %token EDIF_TOK_FIGUREAREA %token EDIF_TOK_FIGUREGROUP %token EDIF_TOK_FIGUREGROUPOBJECT %token EDIF_TOK_FIGUREGROUPOVERRIDE %token EDIF_TOK_FIGUREGROUPREF %token EDIF_TOK_FIGUREPERIMETER %token EDIF_TOK_FIGUREWIDTH %token EDIF_TOK_FILLPATTERN %token EDIF_TOK_FOLLOW %token EDIF_TOK_FORBIDDENEVENT %token EDIF_TOK_GLOBALPORTREF %token EDIF_TOK_GREATERTHAN %token EDIF_TOK_GRIDMAP %token EDIF_TOK_IGNORE %token EDIF_TOK_INCLUDEFIGUREGROUP %token EDIF_TOK_INITIAL %token EDIF_TOK_INSTANCE %token EDIF_TOK_INSTANCEBACKANNOTATE %token EDIF_TOK_INSTANCEGROUP %token EDIF_TOK_INSTANCEMAP %token EDIF_TOK_INSTANCEREF %token EDIF_TOK_INTEGER %token EDIF_TOK_INTEGERDISPLAY %token EDIF_TOK_INTERFACE %token EDIF_TOK_INTERFIGUREGROUPSPACING %token EDIF_TOK_INTERSECTION %token EDIF_TOK_INTRAFIGUREGROUPSPACING %token EDIF_TOK_INVERSE %token EDIF_TOK_ISOLATED %token EDIF_TOK_JOINED %token EDIF_TOK_JUSTIFY %token EDIF_TOK_KEYWORDDISPLAY %token EDIF_TOK_KEYWORDLEVEL %token EDIF_TOK_KEYWORDMAP %token EDIF_TOK_LESSTHAN %token EDIF_TOK_LIBRARY %token EDIF_TOK_LIBRARYREF %token EDIF_TOK_LISTOFNETS %token EDIF_TOK_LISTOFPORTS %token EDIF_TOK_LOADDELAY %token EDIF_TOK_LOGICASSIGN %token EDIF_TOK_LOGICINPUT %token EDIF_TOK_LOGICLIST %token EDIF_TOK_LOGICMAPINPUT %token EDIF_TOK_LOGICMAPOUTPUT %token EDIF_TOK_LOGICONEOF %token EDIF_TOK_LOGICOUTPUT %token EDIF_TOK_LOGICPORT %token EDIF_TOK_LOGICREF %token EDIF_TOK_LOGICVALUE %token EDIF_TOK_LOGICWAVEFORM %token EDIF_TOK_MAINTAIN %token EDIF_TOK_MATCH %token EDIF_TOK_MEMBER %token EDIF_TOK_MINOMAX %token EDIF_TOK_MINOMAXDISPLAY %token EDIF_TOK_MNM %token EDIF_TOK_MULTIPLEVALUESET %token EDIF_TOK_MUSTJOIN %token EDIF_TOK_NAME %token EDIF_TOK_NET %token EDIF_TOK_NETBACKANNOTATE %token EDIF_TOK_NETBUNDLE %token EDIF_TOK_NETDELAY %token EDIF_TOK_NETGROUP %token EDIF_TOK_NETMAP %token EDIF_TOK_NETREF %token EDIF_TOK_NOCHANGE %token EDIF_TOK_NONPERMUTABLE %token EDIF_TOK_NOTALLOWED %token EDIF_TOK_NOTCHSPACING %token EDIF_TOK_NUMBER %token EDIF_TOK_NUMBERDEFINITION %token EDIF_TOK_NUMBERDISPLAY %token EDIF_TOK_OFFPAGECONNECTOR %token EDIF_TOK_OFFSETEVENT %token EDIF_TOK_OPENSHAPE %token EDIF_TOK_ORIENTATION %token EDIF_TOK_ORIGIN %token EDIF_TOK_OVERHANGDISTANCE %token EDIF_TOK_OVERLAPDISTANCE %token EDIF_TOK_OVERSIZE %token EDIF_TOK_OWNER %token EDIF_TOK_PAGE %token EDIF_TOK_PAGESIZE %token EDIF_TOK_PARAMETER %token EDIF_TOK_PARAMETERASSIGN %token EDIF_TOK_PARAMETERDISPLAY %token EDIF_TOK_PATH %token EDIF_TOK_PATHDELAY %token EDIF_TOK_PATHWIDTH %token EDIF_TOK_PERMUTABLE %token EDIF_TOK_PHYSICALDESIGNRULE %token EDIF_TOK_PLUG %token EDIF_TOK_POINT %token EDIF_TOK_POINTDISPLAY %token EDIF_TOK_POINTLIST %token EDIF_TOK_POLYGON %token EDIF_TOK_PORT %token EDIF_TOK_PORTBACKANNOTATE %token EDIF_TOK_PORTBUNDLE %token EDIF_TOK_PORTDELAY %token EDIF_TOK_PORTGROUP %token EDIF_TOK_PORTIMPLEMENTATION %token EDIF_TOK_PORTINSTANCE %token EDIF_TOK_PORTLIST %token EDIF_TOK_PORTLISTALIAS %token EDIF_TOK_PORTMAP %token EDIF_TOK_PORTREF %token EDIF_TOK_PROGRAM %token EDIF_TOK_PROPERTY %token EDIF_TOK_PROPERTYDISPLAY %token EDIF_TOK_PROTECTIONFRAME %token EDIF_TOK_PT %token EDIF_TOK_RANGEVECTOR %token EDIF_TOK_RECTANGLE %token EDIF_TOK_RECTANGLESIZE %token EDIF_TOK_RENAME %token EDIF_TOK_RESOLVES %token EDIF_TOK_SCALE %token EDIF_TOK_SCALEX %token EDIF_TOK_SCALEY %token EDIF_TOK_SECTION %token EDIF_TOK_SHAPE %token EDIF_TOK_SIMULATE %token EDIF_TOK_SIMULATIONINFO %token EDIF_TOK_SINGLEVALUESET %token EDIF_TOK_SITE %token EDIF_TOK_SOCKET %token EDIF_TOK_SOCKETSET %token EDIF_TOK_STATUS %token EDIF_TOK_STEADY %token EDIF_TOK_STRING %token EDIF_TOK_STRINGDISPLAY %token EDIF_TOK_STRONG %token EDIF_TOK_SYMBOL %token EDIF_TOK_SYMMETRY %token EDIF_TOK_TABLE %token EDIF_TOK_TABLEDEFAULT %token EDIF_TOK_TECHNOLOGY %token EDIF_TOK_TEXTHEIGHT %token EDIF_TOK_TIMEINTERVAL %token EDIF_TOK_TIMESTAMP %token EDIF_TOK_TIMING %token EDIF_TOK_TRANSFORM %token EDIF_TOK_TRANSITION %token EDIF_TOK_TRIGGER %token EDIF_TOK_TRUE %token EDIF_TOK_UNCONSTRAINED %token EDIF_TOK_UNDEFINED %token EDIF_TOK_UNION %token EDIF_TOK_UNIT %token EDIF_TOK_UNUSED %token EDIF_TOK_USERDATA %token EDIF_TOK_VERSION %token EDIF_TOK_VIEW %token EDIF_TOK_VIEWLIST %token EDIF_TOK_VIEWMAP %token EDIF_TOK_VIEWREF %token EDIF_TOK_VIEWTYPE %token EDIF_TOK_VISIBLE %token EDIF_TOK_VOLTAGEMAP %token EDIF_TOK_WAVEVALUE %token EDIF_TOK_WEAK %token EDIF_TOK_WEAKJOINED %token EDIF_TOK_WHEN %token EDIF_TOK_WRITTEN %start Edif %% PopC : ')' { PopC(); } ; Edif : EDIF_TOK_EDIF EdifFileName EdifVersion EdifLevel KeywordMap _Edif PopC ; _Edif : | _Edif Status | _Edif External | _Edif Library | _Edif Design | _Edif Comment | _Edif UserData ; EdifFileName : NameDef { str_pair_free($1); } ; EdifLevel : EDIF_TOK_EDIFLEVEL Int PopC { free($2); } ; EdifVersion : EDIF_TOK_EDIFVERSION Int Int Int PopC { free($2); free($3); free($4); } ; AcLoad : EDIF_TOK_ACLOAD _AcLoad PopC ; _AcLoad : MiNoMaValue | MiNoMaDisp ; After : EDIF_TOK_AFTER _After PopC ; _After : MiNoMaValue | _After Follow | _After Maintain | _After LogicAssn | _After Comment | _After UserData ; Annotate : EDIF_TOK_ANNOTATE _Annotate PopC ; _Annotate : Str { free($1); } | StrDisplay ; Apply : EDIF_TOK_APPLY _Apply PopC ; _Apply : Cycle | _Apply LogicIn | _Apply LogicOut | _Apply Comment | _Apply UserData ; Arc : EDIF_TOK_ARC PointValue PointValue PointValue PopC ; Array : EDIF_TOK_ARRAY NameDef Int _Array PopC { str_pair_free($2); free($3); } ; _Array : | Int { free($1); } ; ArrayMacro : EDIF_TOK_ARRAYMACRO Plug PopC ; ArrayRelInfo : EDIF_TOK_ARRAYRELATEDINFO _ArrayRelInfo PopC ; _ArrayRelInfo : BaseArray | ArraySite | ArrayMacro | _ArrayRelInfo Comment | _ArrayRelInfo UserData ; ArraySite : EDIF_TOK_ARRAYSITE Socket PopC ; AtLeast : EDIF_TOK_ATLEAST ScaledInt PopC ; AtMost : EDIF_TOK_ATMOST ScaledInt PopC ; Author : EDIF_TOK_AUTHOR Str PopC { free($2); } ; BaseArray : EDIF_TOK_BASEARRAY PopC ; Becomes : EDIF_TOK_BECOMES _Becomes PopC ; _Becomes : LogicNameRef | LogicList | LogicOneOf ; Between : EDIF_TOK_BETWEEN __Between _Between PopC ; __Between : AtLeast | GreaterThan ; _Between : AtMost | LessThan ; Boolean : EDIF_TOK_BOOLEAN _Boolean PopC ; _Boolean : | _Boolean BooleanValue | _Boolean BooleanDisp | _Boolean Boolean ; BooleanDisp : EDIF_TOK_BOOLEANDISPLAY _BooleanDisp PopC ; _BooleanDisp : BooleanValue | _BooleanDisp Display ; BooleanMap : EDIF_TOK_BOOLEANMAP BooleanValue PopC ; BooleanValue : True | False ; BorderPat : EDIF_TOK_BORDERPATTERN Int Int Boolean PopC { free($2); free($3); } ; BorderWidth : EDIF_TOK_BORDERWIDTH Int PopC { free($2); } ; BoundBox : EDIF_TOK_BOUNDINGBOX Rectangle PopC ; Cell : EDIF_TOK_CELL CellNameDef _Cell PopC ; _Cell : CellType | _Cell Status | _Cell ViewMap | _Cell View | _Cell Comment | _Cell UserData | _Cell Property ; CellNameDef : NameDef { str_pair_free($1); } ; CellRef : EDIF_TOK_CELLREF CellNameRef _CellRef PopC ; _CellRef : | LibraryRef ; CellNameRef : NameRef { free($1); } ; CellType : EDIF_TOK_CELLTYPE _CellType PopC ; _CellType : EDIF_TOK_TIE | EDIF_TOK_RIPPER | EDIF_TOK_GENERIC ; Change : EDIF_TOK_CHANGE __Change _Change PopC ; __Change : PortNameRef | PortRef { str_pair_free($1); } | PortList ; _Change : | Becomes | Transition ; Circle : EDIF_TOK_CIRCLE PointValue PointValue _Circle PopC ; _Circle : | _Circle Property ; Color : EDIF_TOK_COLOR ScaledInt ScaledInt ScaledInt PopC ; Comment : EDIF_TOK_COMMENT _Comment PopC ; _Comment : | _Comment Str { free($2); } ; CommGraph : EDIF_TOK_COMMENTGRAPHICS _CommGraph PopC ; _CommGraph : | _CommGraph Annotate | _CommGraph Figure | _CommGraph Instance | _CommGraph BoundBox | _CommGraph Property | _CommGraph Comment | _CommGraph UserData ; Compound : EDIF_TOK_COMPOUND LogicNameRef PopC ; Contents : EDIF_TOK_CONTENTS _Contents PopC ; _Contents : | _Contents Instance | _Contents OffPageConn | _Contents Figure | _Contents Section | _Contents Net | _Contents NetBundle | _Contents Page | _Contents CommGraph | _Contents PortImpl | _Contents Timing | _Contents Simulate | _Contents When | _Contents Follow | _Contents LogicPort | _Contents BoundBox | _Contents Comment | _Contents UserData ; ConnectLoc : EDIF_TOK_CONNECTLOCATION _ConnectLoc PopC ; _ConnectLoc : | Figure ; CornerType : EDIF_TOK_CORNERTYPE _CornerType PopC ; _CornerType : EDIF_TOK_EXTEND | EDIF_TOK_ROUND | EDIF_TOK_TRUNCATE ; Criticality : EDIF_TOK_CRITICALITY _Criticality PopC ; _Criticality : Int { free($1); } | IntDisplay ; CurrentMap : EDIF_TOK_CURRENTMAP MiNoMaValue PopC ; Curve : EDIF_TOK_CURVE _Curve PopC ; _Curve : | _Curve Arc | _Curve PointValue ; Cycle : EDIF_TOK_CYCLE Int _Cycle PopC { free($2); } ; _Cycle : | Duration ; DataOrigin : EDIF_TOK_DATAORIGIN Str _DataOrigin PopC { free($2); } ; _DataOrigin : | Version ; DcFanInLoad : EDIF_TOK_DCFANINLOAD _DcFanInLoad PopC ; _DcFanInLoad : ScaledInt | NumbDisplay ; DcFanOutLoad : EDIF_TOK_DCFANOUTLOAD _DcFanOutLoad PopC ; _DcFanOutLoad : ScaledInt | NumbDisplay ; DcMaxFanIn : EDIF_TOK_DCMAXFANIN _DcMaxFanIn PopC ; _DcMaxFanIn : ScaledInt | NumbDisplay ; DcMaxFanOut : EDIF_TOK_DCMAXFANOUT _DcMaxFanOut PopC ; _DcMaxFanOut : ScaledInt | NumbDisplay ; Delay : EDIF_TOK_DELAY _Delay PopC ; _Delay : MiNoMaValue | MiNoMaDisp ; Delta : EDIF_TOK_DELTA _Delta PopC ; _Delta : | _Delta PointValue ; Derivation : EDIF_TOK_DERIVATION _Derivation PopC ; _Derivation : EDIF_TOK_CALCULATED | EDIF_TOK_MEASURED | EDIF_TOK_REQUIRED ; Design : EDIF_TOK_DESIGN DesignNameDef _Design PopC ; _Design : CellRef | _Design Status | _Design Comment | _Design Property | _Design UserData ; Designator : EDIF_TOK_DESIGNATOR _Designator PopC ; _Designator : Str { free($1); } | StrDisplay ; DesignNameDef : NameDef { str_pair_free($1); } ; DesignRule : EDIF_TOK_PHYSICALDESIGNRULE _DesignRule PopC ; _DesignRule : | _DesignRule FigureWidth | _DesignRule FigureArea | _DesignRule RectSize | _DesignRule FigurePerim | _DesignRule OverlapDist | _DesignRule OverhngDist | _DesignRule EncloseDist | _DesignRule InterFigGrp | _DesignRule IntraFigGrp | _DesignRule NotchSpace | _DesignRule NotAllowed | _DesignRule FigGrp | _DesignRule Comment | _DesignRule UserData ; Difference : EDIF_TOK_DIFFERENCE _Difference PopC ; _Difference : FigGrpRef | FigureOp | _Difference FigGrpRef | _Difference FigureOp ; Direction : EDIF_TOK_DIRECTION _Direction PopC ; _Direction : EDIF_TOK_INOUT | EDIF_TOK_INPUT | EDIF_TOK_OUTPUT ; Display : EDIF_TOK_DISPLAY _Display _DisplayJust _DisplayOrien _DisplayOrg PopC ; _Display : FigGrpNameRef | FigGrpOver ; _DisplayJust : | Justify ; _DisplayOrien : | Orientation ; _DisplayOrg : | Origin ; Dominates : EDIF_TOK_DOMINATES _Dominates PopC ; _Dominates : | _Dominates LogicNameRef ; Dot : EDIF_TOK_DOT _Dot PopC ; _Dot : PointValue | _Dot Property ; Duration : EDIF_TOK_DURATION ScaledInt PopC ; EncloseDist : EDIF_TOK_ENCLOSUREDISTANCE RuleNameDef FigGrpObj FigGrpObj _EncloseDist PopC ; _EncloseDist : Range | SingleValSet | _EncloseDist Comment | _EncloseDist UserData ; EndType : EDIF_TOK_ENDTYPE _EndType PopC ; _EndType : EDIF_TOK_EXTEND | EDIF_TOK_ROUND | EDIF_TOK_TRUNCATE ; Entry : EDIF_TOK_ENTRY ___Entry __Entry _Entry PopC ; ___Entry : Match | Change | Steady ; __Entry : LogicRef | PortRef { str_pair_free($1); } | NoChange | Table ; _Entry : | Delay | LoadDelay ; Event : EDIF_TOK_EVENT _Event PopC ; _Event : PortRef { str_pair_free($1); } | PortList | PortGroup | NetRef | NetGroup | _Event Transition | _Event Becomes ; Exactly : EDIF_TOK_EXACTLY ScaledInt PopC ; External : EDIF_TOK_EXTERNAL LibNameDef EdifLevel _External PopC ; _External : Technology | _External Status | _External Cell | _External Comment | _External UserData ; Fabricate : EDIF_TOK_FABRICATE LayerNameDef FigGrpNameRef PopC ; False : EDIF_TOK_FALSE PopC ; FigGrp : EDIF_TOK_FIGUREGROUP _FigGrp PopC ; _FigGrp : FigGrpNameDef | _FigGrp CornerType | _FigGrp EndType | _FigGrp PathWidth | _FigGrp BorderWidth | _FigGrp Color | _FigGrp FillPattern | _FigGrp BorderPat | _FigGrp TextHeight | _FigGrp Visible | _FigGrp Comment | _FigGrp Property | _FigGrp UserData | _FigGrp IncFigGrp ; FigGrpNameDef : NameDef { str_pair_free($1); } ; FigGrpNameRef : NameRef { free($1); } ; FigGrpObj : EDIF_TOK_FIGUREGROUPOBJECT _FigGrpObj PopC ; _FigGrpObj : FigGrpNameRef | FigGrpRef | FigureOp ; FigGrpOver : EDIF_TOK_FIGUREGROUPOVERRIDE _FigGrpOver PopC ; _FigGrpOver : FigGrpNameRef | _FigGrpOver CornerType | _FigGrpOver EndType | _FigGrpOver PathWidth | _FigGrpOver BorderWidth | _FigGrpOver Color | _FigGrpOver FillPattern | _FigGrpOver BorderPat | _FigGrpOver TextHeight | _FigGrpOver Visible | _FigGrpOver Comment | _FigGrpOver Property | _FigGrpOver UserData ; FigGrpRef : EDIF_TOK_FIGUREGROUPREF FigGrpNameRef _FigGrpRef PopC ; _FigGrpRef : | LibraryRef ; Figure : EDIF_TOK_FIGURE _Figure PopC ; _Figure : FigGrpNameDef | FigGrpOver | _Figure Circle | _Figure Dot | _Figure OpenShape | _Figure Path | _Figure Polygon | _Figure Rectangle | _Figure Shape | _Figure Comment | _Figure UserData ; FigureArea : EDIF_TOK_FIGUREAREA RuleNameDef FigGrpObj _FigureArea PopC ; _FigureArea : Range | SingleValSet | _FigureArea Comment | _FigureArea UserData ; FigureOp : Intersection | Union | Difference | Inverse | Oversize ; FigurePerim : EDIF_TOK_FIGUREPERIMETER RuleNameDef FigGrpObj _FigurePerim PopC ; _FigurePerim : Range | SingleValSet | _FigurePerim Comment | _FigurePerim UserData ; FigureWidth : EDIF_TOK_FIGUREWIDTH RuleNameDef FigGrpObj _FigureWidth PopC ; _FigureWidth : Range | SingleValSet | _FigureWidth Comment | _FigureWidth UserData ; FillPattern : EDIF_TOK_FILLPATTERN Int Int Boolean PopC { free($2); free($3); } ; Follow : EDIF_TOK_FOLLOW __Follow _Follow PopC ; __Follow : PortNameRef | PortRef { str_pair_free($1); } ; _Follow : PortRef { str_pair_free($1); } | Table | _Follow Delay | _Follow LoadDelay ; Forbidden : EDIF_TOK_FORBIDDENEVENT _Forbidden PopC ; _Forbidden : TimeIntval | _Forbidden Event ; Form : Keyword _Form ')' { free($1); } ; _Form : | _Form Int { free($2); } | _Form Str { free($2); } | _Form Ident { free($2); } | _Form Form ; GlobPortRef : EDIF_TOK_GLOBALPORTREF PortNameRef PopC ; GreaterThan : EDIF_TOK_GREATERTHAN ScaledInt PopC ; GridMap : EDIF_TOK_GRIDMAP ScaledInt ScaledInt PopC ; Ignore : EDIF_TOK_IGNORE PopC ; IncFigGrp : EDIF_TOK_INCLUDEFIGUREGROUP _IncFigGrp PopC ; _IncFigGrp : FigGrpRef | FigureOp ; Initial : EDIF_TOK_INITIAL PopC ; Instance : EDIF_TOK_INSTANCE InstNameDef _Instance PopC ; _Instance : ViewRef | ViewList | _Instance Transform | _Instance ParamAssign | _Instance PortInst | _Instance Timing | _Instance Designator | _Instance Property | _Instance Comment | _Instance UserData ; InstanceRef : EDIF_TOK_INSTANCEREF InstNameRef _InstanceRef PopC { $$=$2; } ; _InstanceRef : | InstanceRef { free($1); } | ViewRef ; InstBackAn : EDIF_TOK_INSTANCEBACKANNOTATE _InstBackAn PopC ; _InstBackAn : InstanceRef { free($1); } | _InstBackAn Designator | _InstBackAn Timing | _InstBackAn Property | _InstBackAn Comment ; InstGroup : EDIF_TOK_INSTANCEGROUP _InstGroup PopC ; _InstGroup : | _InstGroup InstanceRef { free($2); } ; InstMap : EDIF_TOK_INSTANCEMAP _InstMap PopC ; _InstMap : | _InstMap InstanceRef { free($2); } | _InstMap InstGroup | _InstMap Comment | _InstMap UserData ; InstNameDef : NameDef { str_pair_free($1); } | Array ; InstNameRef : NameRef { $$=$1; } | Member ; IntDisplay : EDIF_TOK_INTEGERDISPLAY _IntDisplay PopC ; _IntDisplay : Int { free($1); } | _IntDisplay Display ; Integer : EDIF_TOK_INTEGER _Integer PopC ; _Integer : | _Integer Int { free($2); } | _Integer IntDisplay | _Integer Integer ; Interface : EDIF_TOK_INTERFACE _Interface PopC ; _Interface : | _Interface Port | _Interface PortBundle | _Interface Symbol | _Interface ProtectFrame | _Interface ArrayRelInfo | _Interface Parameter | _Interface Joined { pair_list_free($2); } | _Interface MustJoin | _Interface WeakJoined | _Interface Permutable | _Interface Timing | _Interface Simulate | _Interface Designator | _Interface Property | _Interface Comment | _Interface UserData ; InterFigGrp : EDIF_TOK_INTERFIGUREGROUPSPACING RuleNameDef FigGrpObj FigGrpObj _InterFigGrp PopC ; _InterFigGrp : Range | SingleValSet | _InterFigGrp Comment | _InterFigGrp UserData ; Intersection : EDIF_TOK_INTERSECTION _Intersection PopC ; _Intersection : FigGrpRef | FigureOp | _Intersection FigGrpRef | _Intersection FigureOp ; IntraFigGrp : EDIF_TOK_INTRAFIGUREGROUPSPACING RuleNameDef FigGrpObj _IntraFigGrp PopC ; _IntraFigGrp : Range | SingleValSet | _IntraFigGrp Comment | _IntraFigGrp UserData ; Inverse : EDIF_TOK_INVERSE _Inverse PopC ; _Inverse : FigGrpRef | FigureOp ; Isolated : EDIF_TOK_ISOLATED PopC ; Joined : EDIF_TOK_JOINED _Joined PopC { $$ = new_pair_list($2); } ; _Joined : { $$=NULL; } | _Joined PortRef { $2->next = $1; $$ = $2; } | _Joined PortList | _Joined GlobPortRef ; Justify : EDIF_TOK_JUSTIFY _Justify PopC ; _Justify : EDIF_TOK_CENTERCENTER | EDIF_TOK_CENTERLEFT | EDIF_TOK_CENTERRIGHT | EDIF_TOK_LOWERCENTER | EDIF_TOK_LOWERLEFT | EDIF_TOK_LOWERRIGHT | EDIF_TOK_UPPERCENTER | EDIF_TOK_UPPERLEFT | EDIF_TOK_UPPERRIGHT ; KeywordDisp : EDIF_TOK_KEYWORDDISPLAY _KeywordDisp PopC ; _KeywordDisp : KeywordName | _KeywordDisp Display ; KeywordLevel : EDIF_TOK_KEYWORDLEVEL Int PopC { free($2); } ; KeywordMap : EDIF_TOK_KEYWORDMAP _KeywordMap PopC ; _KeywordMap : KeywordLevel | _KeywordMap Comment ; KeywordName : Ident { free($1); } ; LayerNameDef : NameDef { str_pair_free($1); } ; LessThan : EDIF_TOK_LESSTHAN ScaledInt PopC ; LibNameDef : NameDef { str_pair_free($1); } ; LibNameRef : NameRef { free($1); } ; Library : EDIF_TOK_LIBRARY LibNameDef EdifLevel _Library PopC ; _Library : Technology | _Library Status | _Library Cell | _Library Comment | _Library UserData ; LibraryRef : EDIF_TOK_LIBRARYREF LibNameRef PopC ; ListOfNets : EDIF_TOK_LISTOFNETS _ListOfNets PopC ; _ListOfNets : | _ListOfNets Net ; ListOfPorts : EDIF_TOK_LISTOFPORTS _ListOfPorts PopC ; _ListOfPorts : | _ListOfPorts Port | _ListOfPorts PortBundle ; LoadDelay : EDIF_TOK_LOADDELAY _LoadDelay _LoadDelay PopC ; _LoadDelay : MiNoMaValue | MiNoMaDisp ; LogicAssn : EDIF_TOK_LOGICASSIGN ___LogicAssn __LogicAssn _LogicAssn PopC ; ___LogicAssn : PortNameRef | PortRef { str_pair_free($1); } ; __LogicAssn : PortRef { str_pair_free($1); } | LogicRef | Table ; _LogicAssn : | Delay | LoadDelay ; LogicIn : EDIF_TOK_LOGICINPUT _LogicIn PopC ; _LogicIn : PortList | PortRef { str_pair_free($1); } | PortNameRef | _LogicIn LogicWave ; LogicList : EDIF_TOK_LOGICLIST _LogicList PopC ; _LogicList : | _LogicList LogicNameRef | _LogicList LogicOneOf | _LogicList Ignore ; LogicMapIn : EDIF_TOK_LOGICMAPINPUT _LogicMapIn PopC ; _LogicMapIn : | _LogicMapIn LogicNameRef ; LogicMapOut : EDIF_TOK_LOGICMAPOUTPUT _LogicMapOut PopC ; _LogicMapOut : | _LogicMapOut LogicNameRef ; LogicNameDef : NameDef { str_pair_free($1); } ; LogicNameRef : NameRef { free($1); } ; LogicOneOf : EDIF_TOK_LOGICONEOF _LogicOneOf PopC ; _LogicOneOf : | _LogicOneOf LogicNameRef | _LogicOneOf LogicList ; LogicOut : EDIF_TOK_LOGICOUTPUT _LogicOut PopC ; _LogicOut : PortList | PortRef { str_pair_free($1); } | PortNameRef | _LogicOut LogicWave ; LogicPort : EDIF_TOK_LOGICPORT _LogicPort PopC ; _LogicPort : PortNameDef | _LogicPort Property | _LogicPort Comment | _LogicPort UserData ; LogicRef : EDIF_TOK_LOGICREF LogicNameRef _LogicRef PopC ; _LogicRef : | LibraryRef ; LogicValue : EDIF_TOK_LOGICVALUE _LogicValue PopC ; _LogicValue : LogicNameDef | _LogicValue VoltageMap | _LogicValue CurrentMap | _LogicValue BooleanMap | _LogicValue Compound | _LogicValue Weak | _LogicValue Strong | _LogicValue Dominates | _LogicValue LogicMapOut | _LogicValue LogicMapIn | _LogicValue Isolated | _LogicValue Resolves | _LogicValue Property | _LogicValue Comment | _LogicValue UserData ; LogicWave : EDIF_TOK_LOGICWAVEFORM _LogicWave PopC ; _LogicWave : | _LogicWave LogicNameRef | _LogicWave LogicList | _LogicWave LogicOneOf | _LogicWave Ignore ; Maintain : EDIF_TOK_MAINTAIN __Maintain _Maintain PopC ; __Maintain : PortNameRef | PortRef { str_pair_free($1); } ; _Maintain : | Delay | LoadDelay ; Match : EDIF_TOK_MATCH __Match _Match PopC ; __Match : PortNameRef | PortRef { str_pair_free($1); } | PortList ; _Match : LogicNameRef | LogicList | LogicOneOf ; Member : EDIF_TOK_MEMBER NameRef _Member PopC { free($2); } ; _Member : Int { free($1); } | _Member Int { free($2); } ; MiNoMa : EDIF_TOK_MINOMAX _MiNoMa PopC ; _MiNoMa : | _MiNoMa MiNoMaValue | _MiNoMa MiNoMaDisp | _MiNoMa MiNoMa ; MiNoMaDisp : EDIF_TOK_MINOMAXDISPLAY _MiNoMaDisp PopC ; _MiNoMaDisp : MiNoMaValue | _MiNoMaDisp Display ; MiNoMaValue : Mnm | ScaledInt ; Mnm : EDIF_TOK_MNM _Mnm _Mnm _Mnm PopC ; _Mnm : ScaledInt | Undefined | Unconstrained ; MultValSet : EDIF_TOK_MULTIPLEVALUESET _MultValSet PopC ; _MultValSet : | _MultValSet RangeVector ; MustJoin : EDIF_TOK_MUSTJOIN _MustJoin PopC ; _MustJoin : | _MustJoin PortRef { str_pair_free($2); } | _MustJoin PortList | _MustJoin WeakJoined | _MustJoin Joined { pair_list_free($2); } ; Name : EDIF_TOK_NAME _Name PopC { $$=$2; } ; _Name : Ident { $$=$1; } | _Name Display ; NameDef : Ident { $$ = new_str_pair($1,NULL); } | Name { $$ = new_str_pair($1,NULL); } | Rename { $$=$1; } ; NameRef : Ident { $$=$1; } | Name { $$=$1; } ; Net : EDIF_TOK_NET NetNameDef _Net PopC { define_pcb_net($2, $3); } ; _Net : Joined { $$=$1; } | _Net Criticality | _Net NetDelay | _Net Figure | _Net Net | _Net Instance | _Net CommGraph | _Net Property | _Net Comment | _Net UserData ; NetBackAn : EDIF_TOK_NETBACKANNOTATE _NetBackAn PopC ; _NetBackAn : NetRef | _NetBackAn NetDelay | _NetBackAn Criticality | _NetBackAn Property | _NetBackAn Comment ; NetBundle : EDIF_TOK_NETBUNDLE NetNameDef _NetBundle PopC { str_pair_free($2); } ; _NetBundle : ListOfNets | _NetBundle Figure | _NetBundle CommGraph | _NetBundle Property | _NetBundle Comment | _NetBundle UserData ; NetDelay : EDIF_TOK_NETDELAY Derivation _NetDelay PopC ; _NetDelay : Delay | _NetDelay Transition | _NetDelay Becomes ; NetGroup : EDIF_TOK_NETGROUP _NetGroup PopC ; _NetGroup : | _NetGroup NetNameRef | _NetGroup NetRef ; NetMap : EDIF_TOK_NETMAP _NetMap PopC ; _NetMap : | _NetMap NetRef | _NetMap NetGroup | _NetMap Comment | _NetMap UserData ; NetNameDef : NameDef { $$=$1; } | Array { $$=NULL; } ; NetNameRef : NameRef { free($1); } | Member ; NetRef : EDIF_TOK_NETREF NetNameRef _NetRef PopC ; _NetRef : | NetRef | InstanceRef { free($1); } | ViewRef ; NoChange : EDIF_TOK_NOCHANGE PopC ; NonPermut : EDIF_TOK_NONPERMUTABLE _NonPermut PopC ; _NonPermut : | _NonPermut PortRef { str_pair_free($2); } | _NonPermut Permutable ; NotAllowed : EDIF_TOK_NOTALLOWED RuleNameDef _NotAllowed PopC ; _NotAllowed : FigGrpObj | _NotAllowed Comment | _NotAllowed UserData ; NotchSpace : EDIF_TOK_NOTCHSPACING RuleNameDef FigGrpObj _NotchSpace PopC ; _NotchSpace : Range | SingleValSet | _NotchSpace Comment | _NotchSpace UserData ; Number : EDIF_TOK_NUMBER _Number PopC ; _Number : | _Number ScaledInt | _Number NumbDisplay | _Number Number ; NumbDisplay : EDIF_TOK_NUMBERDISPLAY _NumbDisplay PopC ; _NumbDisplay : ScaledInt | _NumbDisplay Display ; NumberDefn : EDIF_TOK_NUMBERDEFINITION _NumberDefn PopC ; _NumberDefn : | _NumberDefn Scale | _NumberDefn GridMap | _NumberDefn Comment ; OffPageConn : EDIF_TOK_OFFPAGECONNECTOR _OffPageConn PopC ; _OffPageConn : PortNameDef | _OffPageConn Unused | _OffPageConn Property | _OffPageConn Comment | _OffPageConn UserData ; OffsetEvent : EDIF_TOK_OFFSETEVENT Event ScaledInt PopC ; OpenShape : EDIF_TOK_OPENSHAPE _OpenShape PopC ; _OpenShape : Curve | _OpenShape Property ; Orientation : EDIF_TOK_ORIENTATION _Orientation PopC ; _Orientation : EDIF_TOK_R0 | EDIF_TOK_R90 | EDIF_TOK_R180 | EDIF_TOK_R270 | EDIF_TOK_MX | EDIF_TOK_MY | EDIF_TOK_MYR90 | EDIF_TOK_MXR90 ; Origin : EDIF_TOK_ORIGIN PointValue PopC ; OverhngDist : EDIF_TOK_OVERHANGDISTANCE RuleNameDef FigGrpObj FigGrpObj _OverhngDist PopC ; _OverhngDist : Range | SingleValSet | _OverhngDist Comment | _OverhngDist UserData ; OverlapDist : EDIF_TOK_OVERLAPDISTANCE RuleNameDef FigGrpObj FigGrpObj _OverlapDist PopC ; _OverlapDist : Range | SingleValSet | _OverlapDist Comment | _OverlapDist UserData ; Oversize : EDIF_TOK_OVERSIZE Int _Oversize CornerType PopC { free($2); } ; _Oversize : FigGrpRef | FigureOp ; Owner : EDIF_TOK_OWNER Str PopC { free($2); } ; Page : EDIF_TOK_PAGE _Page PopC ; _Page : InstNameDef | _Page Instance | _Page Net | _Page NetBundle | _Page CommGraph | _Page PortImpl | _Page PageSize | _Page BoundBox | _Page Comment | _Page UserData ; PageSize : EDIF_TOK_PAGESIZE Rectangle PopC ; ParamDisp : EDIF_TOK_PARAMETERDISPLAY _ParamDisp PopC ; _ParamDisp : ValueNameRef | _ParamDisp Display ; Parameter : EDIF_TOK_PARAMETER ValueNameDef TypedValue _Parameter PopC ; _Parameter : | Unit ; ParamAssign : EDIF_TOK_PARAMETERASSIGN ValueNameRef TypedValue PopC ; Path : EDIF_TOK_PATH _Path PopC ; _Path : PointList | _Path Property ; PathDelay : EDIF_TOK_PATHDELAY _PathDelay PopC ; _PathDelay : Delay | _PathDelay Event ; PathWidth : EDIF_TOK_PATHWIDTH Int PopC { free($2); } ; Permutable : EDIF_TOK_PERMUTABLE _Permutable PopC ; _Permutable : | _Permutable PortRef { str_pair_free($2); } | _Permutable Permutable | _Permutable NonPermut ; Plug : EDIF_TOK_PLUG _Plug PopC ; _Plug : | _Plug SocketSet ; Point : EDIF_TOK_POINT _Point PopC ; _Point : | _Point PointValue | _Point PointDisp | _Point Point ; PointDisp : EDIF_TOK_POINTDISPLAY _PointDisp PopC ; _PointDisp : PointValue | _PointDisp Display ; PointList : EDIF_TOK_POINTLIST _PointList PopC ; _PointList : | _PointList PointValue ; PointValue : EDIF_TOK_PT Int Int PopC { free($2); free($3); } ; Polygon : EDIF_TOK_POLYGON _Polygon PopC ; _Polygon : PointList | _Polygon Property ; Port : EDIF_TOK_PORT _Port PopC ; _Port : PortNameDef | _Port Direction | _Port Unused | _Port PortDelay | _Port Designator | _Port DcFanInLoad | _Port DcFanOutLoad | _Port DcMaxFanIn | _Port DcMaxFanOut | _Port AcLoad | _Port Property | _Port Comment | _Port UserData ; PortBackAn : EDIF_TOK_PORTBACKANNOTATE _PortBackAn PopC ; _PortBackAn : PortRef { str_pair_free($1); } | _PortBackAn Designator | _PortBackAn PortDelay | _PortBackAn DcFanInLoad | _PortBackAn DcFanOutLoad | _PortBackAn DcMaxFanIn | _PortBackAn DcMaxFanOut | _PortBackAn AcLoad | _PortBackAn Property | _PortBackAn Comment ; PortBundle : EDIF_TOK_PORTBUNDLE PortNameDef _PortBundle PopC ; _PortBundle : ListOfPorts | _PortBundle Property | _PortBundle Comment | _PortBundle UserData ; PortDelay : EDIF_TOK_PORTDELAY Derivation _PortDelay PopC ; _PortDelay : Delay | LoadDelay | _PortDelay Transition | _PortDelay Becomes ; PortGroup : EDIF_TOK_PORTGROUP _PortGroup PopC ; _PortGroup : | _PortGroup PortNameRef | _PortGroup PortRef { str_pair_free($2); } ; PortImpl : EDIF_TOK_PORTIMPLEMENTATION _PortImpl PopC ; _PortImpl : PortRef { str_pair_free($1); } | PortNameRef | _PortImpl ConnectLoc | _PortImpl Figure | _PortImpl Instance | _PortImpl CommGraph | _PortImpl PropDisplay | _PortImpl KeywordDisp | _PortImpl Property | _PortImpl UserData | _PortImpl Comment ; PortInst : EDIF_TOK_PORTINSTANCE _PortInst PopC ; _PortInst : PortRef { str_pair_free($1); } | PortNameRef | _PortInst Unused | _PortInst PortDelay | _PortInst Designator | _PortInst DcFanInLoad | _PortInst DcFanOutLoad | _PortInst DcMaxFanIn | _PortInst DcMaxFanOut | _PortInst AcLoad | _PortInst Property | _PortInst Comment | _PortInst UserData ; PortList : EDIF_TOK_PORTLIST _PortList PopC ; _PortList : | _PortList PortRef { str_pair_free($2); } | _PortList PortNameRef ; PortListAls : EDIF_TOK_PORTLISTALIAS PortNameDef PortList PopC ; PortMap : EDIF_TOK_PORTMAP _PortMap PopC ; _PortMap : | _PortMap PortRef { str_pair_free($2); } | _PortMap PortGroup | _PortMap Comment | _PortMap UserData ; PortNameDef : NameDef { str_pair_free($1); } | Array ; PortNameRef : NameRef { $$=$1; } | Member ; PortRef : EDIF_TOK_PORTREF PortNameRef _PortRef PopC { if ($3) { $$ = new_str_pair($3->str1,$2); free($3); } else { /* handle port with no instance by passing up the chain */ $$ = new_str_pair(NULL,$2); } } ; _PortRef : { $$=NULL; } | PortRef { $$=$1; } | InstanceRef { $$ = new_str_pair($1,NULL); } | ViewRef { $$=NULL; } ; Program : EDIF_TOK_PROGRAM Str _Program PopC ; _Program : | Version ; PropDisplay : EDIF_TOK_PROPERTYDISPLAY _PropDisplay PopC ; _PropDisplay : PropNameRef | _PropDisplay Display ; Property : EDIF_TOK_PROPERTY PropNameDef _Property PopC ; _Property : TypedValue | _Property Owner | _Property Unit | _Property Property | _Property Comment ; PropNameDef : NameDef { str_pair_free($1); } ; PropNameRef : NameRef { free($1); } ; ProtectFrame : EDIF_TOK_PROTECTIONFRAME _ProtectFrame PopC ; _ProtectFrame : | _ProtectFrame PortImpl | _ProtectFrame Figure | _ProtectFrame Instance | _ProtectFrame CommGraph | _ProtectFrame BoundBox | _ProtectFrame PropDisplay | _ProtectFrame KeywordDisp | _ProtectFrame ParamDisp | _ProtectFrame Property | _ProtectFrame Comment | _ProtectFrame UserData ; Range : LessThan | GreaterThan | AtMost | AtLeast | Exactly | Between ; RangeVector : EDIF_TOK_RANGEVECTOR _RangeVector PopC ; _RangeVector : | _RangeVector Range | _RangeVector SingleValSet ; Rectangle : EDIF_TOK_RECTANGLE PointValue _Rectangle PopC ; _Rectangle : PointValue | _Rectangle Property ; RectSize : EDIF_TOK_RECTANGLESIZE RuleNameDef FigGrpObj _RectSize PopC ; _RectSize : RangeVector | MultValSet | _RectSize Comment | _RectSize UserData ; Rename : EDIF_TOK_RENAME __Rename _Rename PopC { $$ = new_str_pair($2,$3); } ; __Rename : Ident { $$=$1; } | Name { $$=$1; } ; _Rename : Str { $$=$1; } | StrDisplay { $$=NULL; } ; Resolves : EDIF_TOK_RESOLVES _Resolves PopC ; _Resolves : | _Resolves LogicNameRef ; RuleNameDef : NameDef { str_pair_free($1); } ; Scale : EDIF_TOK_SCALE ScaledInt ScaledInt Unit PopC ; ScaledInt : Int { free($1); } | EDIF_TOK_E Int Int PopC { free($2); free($3); } ; ScaleX : EDIF_TOK_SCALEX Int Int PopC { free($2); free($3); } ; ScaleY : EDIF_TOK_SCALEY Int Int PopC { free($2); free($3); } ; Section : EDIF_TOK_SECTION _Section PopC ; _Section : Str { free($1); } | _Section Section | _Section Str { free($2); } | _Section Instance ; Shape : EDIF_TOK_SHAPE _Shape PopC ; _Shape : Curve | _Shape Property ; SimNameDef : NameDef { str_pair_free($1); } ; Simulate : EDIF_TOK_SIMULATE _Simulate PopC ; _Simulate : SimNameDef | _Simulate PortListAls | _Simulate WaveValue | _Simulate Apply | _Simulate Comment | _Simulate UserData ; SimulInfo : EDIF_TOK_SIMULATIONINFO _SimulInfo PopC ; _SimulInfo : | _SimulInfo LogicValue | _SimulInfo Comment | _SimulInfo UserData ; SingleValSet : EDIF_TOK_SINGLEVALUESET _SingleValSet PopC ; _SingleValSet : | Range ; Site : EDIF_TOK_SITE ViewRef _Site PopC ; _Site : | Transform ; Socket : EDIF_TOK_SOCKET _Socket PopC ; _Socket : | Symmetry ; SocketSet : EDIF_TOK_SOCKETSET _SocketSet PopC ; _SocketSet : Symmetry | _SocketSet Site ; Status : EDIF_TOK_STATUS _Status PopC ; _Status : | _Status Written | _Status Comment | _Status UserData ; Steady : EDIF_TOK_STEADY __Steady _Steady PopC ; __Steady : PortNameRef | PortRef { str_pair_free($1); } | PortList ; _Steady : Duration | _Steady Transition | _Steady Becomes ; StrDisplay : EDIF_TOK_STRINGDISPLAY _StrDisplay PopC ; String : EDIF_TOK_STRING _String PopC ; _String : | _String Str { free($2); } | _String StrDisplay | _String String ; _StrDisplay : Str { free($1); } | _StrDisplay Display ; Strong : EDIF_TOK_STRONG LogicNameRef PopC ; Symbol : EDIF_TOK_SYMBOL _Symbol PopC ; _Symbol : | _Symbol PortImpl | _Symbol Figure | _Symbol Instance | _Symbol CommGraph | _Symbol Annotate | _Symbol PageSize | _Symbol BoundBox | _Symbol PropDisplay | _Symbol KeywordDisp | _Symbol ParamDisp | _Symbol Property | _Symbol Comment | _Symbol UserData ; Symmetry : EDIF_TOK_SYMMETRY _Symmetry PopC ; _Symmetry : | _Symmetry Transform ; Table : EDIF_TOK_TABLE _Table PopC ; _Table : | _Table Entry | _Table TableDeflt ; TableDeflt : EDIF_TOK_TABLEDEFAULT __TableDeflt _TableDeflt PopC ; __TableDeflt : LogicRef | PortRef { str_pair_free($1); } | NoChange | Table ; _TableDeflt : | Delay | LoadDelay ; Technology : EDIF_TOK_TECHNOLOGY _Technology PopC ; _Technology : NumberDefn | _Technology FigGrp | _Technology Fabricate | _Technology SimulInfo | _Technology DesignRule | _Technology Comment | _Technology UserData ; TextHeight : EDIF_TOK_TEXTHEIGHT Int PopC { free($2); } ; TimeIntval : EDIF_TOK_TIMEINTERVAL __TimeIntval _TimeIntval PopC ; __TimeIntval : Event | OffsetEvent ; _TimeIntval : Event | OffsetEvent | Duration ; TimeStamp : EDIF_TOK_TIMESTAMP Int Int Int Int Int Int PopC { free($2); free($3); free($4); free($5); free($6); free($7); } ; Timing : EDIF_TOK_TIMING _Timing PopC ; _Timing : Derivation | _Timing PathDelay | _Timing Forbidden | _Timing Comment | _Timing UserData ; Transform : EDIF_TOK_TRANSFORM _TransX _TransY _TransDelta _TransOrien _TransOrg PopC ; _TransX : | ScaleX ; _TransY : | ScaleY ; _TransDelta : | Delta ; _TransOrien : | Orientation ; _TransOrg : | Origin ; Transition : EDIF_TOK_TRANSITION _Transition _Transition PopC ; _Transition : LogicNameRef | LogicList | LogicOneOf ; Trigger : EDIF_TOK_TRIGGER _Trigger PopC ; _Trigger : | _Trigger Change | _Trigger Steady | _Trigger Initial ; True : EDIF_TOK_TRUE PopC ; TypedValue : Boolean | Integer | MiNoMa | Number | Point | String ; Unconstrained : EDIF_TOK_UNCONSTRAINED PopC ; Undefined : EDIF_TOK_UNDEFINED PopC ; Union : EDIF_TOK_UNION _Union PopC ; _Union : FigGrpRef | FigureOp | _Union FigGrpRef | _Union FigureOp ; Unit : EDIF_TOK_UNIT _Unit PopC ; _Unit : EDIF_TOK_DISTANCE | EDIF_TOK_CAPACITANCE | EDIF_TOK_CURRENT | EDIF_TOK_RESISTANCE | EDIF_TOK_TEMPERATURE | EDIF_TOK_TIME | EDIF_TOK_VOLTAGE | EDIF_TOK_MASS | EDIF_TOK_FREQUENCY | EDIF_TOK_INDUCTANCE | EDIF_TOK_ENERGY | EDIF_TOK_POWER | EDIF_TOK_CHARGE | EDIF_TOK_CONDUCTANCE | EDIF_TOK_FLUX | EDIF_TOK_ANGLE ; Unused : EDIF_TOK_UNUSED PopC ; UserData : EDIF_TOK_USERDATA _UserData PopC ; _UserData : Ident { free($1); } | _UserData Int { free($2); } | _UserData Str { free($2); } | _UserData Ident { free($2); } | _UserData Form ; ValueNameDef : NameDef { str_pair_free($1); } | Array ; ValueNameRef : NameRef { free($1); } | Member ; Version : EDIF_TOK_VERSION Str PopC { free($2); } ; View : EDIF_TOK_VIEW ViewNameDef ViewType _View PopC ; _View : Interface | _View Status | _View Contents | _View Comment | _View Property | _View UserData ; ViewList : EDIF_TOK_VIEWLIST _ViewList PopC ; _ViewList : | _ViewList ViewRef | _ViewList ViewList ; ViewMap : EDIF_TOK_VIEWMAP _ViewMap PopC ; _ViewMap : | _ViewMap PortMap | _ViewMap PortBackAn | _ViewMap InstMap | _ViewMap InstBackAn | _ViewMap NetMap | _ViewMap NetBackAn | _ViewMap Comment | _ViewMap UserData ; ViewNameDef : NameDef { str_pair_free($1); } ; ViewNameRef : NameRef { free($1); } ; ViewRef : EDIF_TOK_VIEWREF ViewNameRef _ViewRef PopC ; _ViewRef : | CellRef ; ViewType : EDIF_TOK_VIEWTYPE _ViewType PopC ; _ViewType : EDIF_TOK_MASKLAYOUT | EDIF_TOK_PCBLAYOUT | EDIF_TOK_NETLIST | EDIF_TOK_SCHEMATIC | EDIF_TOK_SYMBOLIC | EDIF_TOK_BEHAVIOR | EDIF_TOK_LOGICMODEL | EDIF_TOK_DOCUMENT | EDIF_TOK_GRAPHIC | EDIF_TOK_STRANGER ; Visible : EDIF_TOK_VISIBLE BooleanValue PopC ; VoltageMap : EDIF_TOK_VOLTAGEMAP MiNoMaValue PopC ; WaveValue : EDIF_TOK_WAVEVALUE LogicNameDef ScaledInt LogicWave PopC ; Weak : EDIF_TOK_WEAK LogicNameRef PopC ; WeakJoined : EDIF_TOK_WEAKJOINED _WeakJoined PopC ; _WeakJoined : | _WeakJoined PortRef { str_pair_free($2); } | _WeakJoined PortList | _WeakJoined Joined { pair_list_free($2); } ; When : EDIF_TOK_WHEN _When PopC ; _When : Trigger | _When After | _When Follow | _When Maintain | _When LogicAssn | _When Comment | _When UserData ; Written : EDIF_TOK_WRITTEN _Written PopC ; _Written : TimeStamp | _Written Author | _Written Program | _Written DataOrigin | _Written Property | _Written Comment | _Written UserData ; Ident : EDIF_TOK_IDENT { $$=$1; } ; Str : EDIF_TOK_STR { $$=$1; } ; Int : EDIF_TOK_INT { $$=$1; } ; Keyword : EDIF_TOK_KEYWORD { $$=$1; } ; %% /* * xmalloc: * * Garbage function for 'alloca()'. */ char *xmalloc(int siz) { return ((char *)Malloc(siz)); } /* * Token & context carriers: * * These are the linkage pointers for threading this context garbage * for converting identifiers into parser tokens. */ typedef struct TokenCar { struct TokenCar *Next; /* pointer to next carrier */ struct Token *Token; /* associated token */ } TokenCar; typedef struct UsedCar { struct UsedCar *Next; /* pointer to next carrier */ short Code; /* used '%token' value */ } UsedCar; typedef struct ContextCar { struct ContextCar *Next; /* pointer to next carrier */ struct Context *Context; /* associated context */ union { int Single; /* single usage flag (context tree) */ struct UsedCar *Used; /* single used list (context stack) */ } u; } ContextCar; /* * Token definitions: * * This associates the '%token' codings with strings which are to * be free standing tokens. Doesn't have to be in sorted order but the * strings must be in lower case. */ typedef struct Token { char *Name; /* token name */ int Code; /* '%token' value */ struct Token *Next; /* hash table linkage */ } Token; static Token TokenDef[] = { {"angle", EDIF_TOK_ANGLE}, {"behavior", EDIF_TOK_BEHAVIOR}, {"calculated", EDIF_TOK_CALCULATED}, {"capacitance", EDIF_TOK_CAPACITANCE}, {"centercenter", EDIF_TOK_CENTERCENTER}, {"centerleft", EDIF_TOK_CENTERLEFT}, {"centerright", EDIF_TOK_CENTERRIGHT}, {"charge", EDIF_TOK_CHARGE}, {"conductance", EDIF_TOK_CONDUCTANCE}, {"current", EDIF_TOK_CURRENT}, {"distance", EDIF_TOK_DISTANCE}, {"document", EDIF_TOK_DOCUMENT}, {"energy", EDIF_TOK_ENERGY}, {"extend", EDIF_TOK_EXTEND}, {"flux", EDIF_TOK_FLUX}, {"frequency", EDIF_TOK_FREQUENCY}, {"generic", EDIF_TOK_GENERIC}, {"graphic", EDIF_TOK_GRAPHIC}, {"inductance", EDIF_TOK_INDUCTANCE}, {"inout", EDIF_TOK_INOUT}, {"input", EDIF_TOK_INPUT}, {"logicmodel", EDIF_TOK_LOGICMODEL}, {"lowercenter", EDIF_TOK_LOWERCENTER}, {"lowerleft", EDIF_TOK_LOWERLEFT}, {"lowerright", EDIF_TOK_LOWERRIGHT}, {"masklayout", EDIF_TOK_MASKLAYOUT}, {"mass", EDIF_TOK_MASS}, {"measured", EDIF_TOK_MEASURED}, {"mx", EDIF_TOK_MX}, {"mxr90", EDIF_TOK_MXR90}, {"my", EDIF_TOK_MY}, {"myr90", EDIF_TOK_MYR90}, {"netlist", EDIF_TOK_NETLIST}, {"output", EDIF_TOK_OUTPUT}, {"pcblayout", EDIF_TOK_PCBLAYOUT}, {"power", EDIF_TOK_POWER}, {"r0", EDIF_TOK_R0}, {"r180", EDIF_TOK_R180}, {"r270", EDIF_TOK_R270}, {"r90", EDIF_TOK_R90}, {"required", EDIF_TOK_REQUIRED}, {"resistance", EDIF_TOK_RESISTANCE}, {"ripper", EDIF_TOK_RIPPER}, {"round", EDIF_TOK_ROUND}, {"schematic", EDIF_TOK_SCHEMATIC}, {"stranger", EDIF_TOK_STRANGER}, {"symbolic", EDIF_TOK_SYMBOLIC}, {"temperature", EDIF_TOK_TEMPERATURE}, {"tie", EDIF_TOK_TIE}, {"time", EDIF_TOK_TIME}, {"truncate", EDIF_TOK_TRUNCATE}, {"uppercenter", EDIF_TOK_UPPERCENTER}, {"upperleft", EDIF_TOK_UPPERLEFT}, {"upperright", EDIF_TOK_UPPERRIGHT}, {"voltage", EDIF_TOK_VOLTAGE} }; static int TokenDefSize = sizeof(TokenDef) / sizeof(Token); /* * Token enable definitions: * * There is one array for each set of tokens enabled by a * particular context (barf). Another array is used to bind * these arrays to a context. */ static short e_CellType[] = {EDIF_TOK_TIE, EDIF_TOK_RIPPER, EDIF_TOK_GENERIC}; static short e_CornerType[] = {EDIF_TOK_EXTEND, EDIF_TOK_TRUNCATE, EDIF_TOK_ROUND}; static short e_Derivation[] = {EDIF_TOK_CALCULATED, EDIF_TOK_MEASURED, EDIF_TOK_REQUIRED}; static short e_Direction[] = {EDIF_TOK_INPUT, EDIF_TOK_OUTPUT, EDIF_TOK_INOUT}; static short e_EndType[] = {EDIF_TOK_EXTEND, EDIF_TOK_TRUNCATE, EDIF_TOK_ROUND}; static short e_Justify[] = {EDIF_TOK_CENTERCENTER, EDIF_TOK_CENTERLEFT, EDIF_TOK_CENTERRIGHT, EDIF_TOK_LOWERCENTER, EDIF_TOK_LOWERLEFT, EDIF_TOK_LOWERRIGHT, EDIF_TOK_UPPERCENTER, EDIF_TOK_UPPERLEFT, EDIF_TOK_UPPERRIGHT}; static short e_Orientation[] = {EDIF_TOK_R0, EDIF_TOK_R90, EDIF_TOK_R180, EDIF_TOK_R270, EDIF_TOK_MX, EDIF_TOK_MY, EDIF_TOK_MXR90, EDIF_TOK_MYR90}; static short e_Unit[] = {EDIF_TOK_DISTANCE, EDIF_TOK_CAPACITANCE, EDIF_TOK_CURRENT, EDIF_TOK_RESISTANCE, EDIF_TOK_TEMPERATURE, EDIF_TOK_TIME, EDIF_TOK_VOLTAGE, EDIF_TOK_MASS, EDIF_TOK_FREQUENCY, EDIF_TOK_INDUCTANCE, EDIF_TOK_ENERGY, EDIF_TOK_POWER, EDIF_TOK_CHARGE, EDIF_TOK_CONDUCTANCE, EDIF_TOK_FLUX, EDIF_TOK_ANGLE}; static short e_ViewType[] = {EDIF_TOK_MASKLAYOUT, EDIF_TOK_PCBLAYOUT, EDIF_TOK_NETLIST, EDIF_TOK_SCHEMATIC, EDIF_TOK_SYMBOLIC, EDIF_TOK_BEHAVIOR, EDIF_TOK_LOGICMODEL, EDIF_TOK_DOCUMENT, EDIF_TOK_GRAPHIC, EDIF_TOK_STRANGER}; /* * Token tying table: * * This binds enabled tokens to a context. */ typedef struct Tie { short *Enable; /* pointer to enable array */ short Origin; /* '%token' value of context */ short EnableSize; /* size of enabled array */ } Tie; #define TE(e,o) {e,o,sizeof(e)/sizeof(short)} static Tie TieDef[] = { TE(e_CellType, EDIF_TOK_CELLTYPE), TE(e_CornerType, EDIF_TOK_CORNERTYPE), TE(e_Derivation, EDIF_TOK_DERIVATION), TE(e_Direction, EDIF_TOK_DIRECTION), TE(e_EndType, EDIF_TOK_ENDTYPE), TE(e_Justify, EDIF_TOK_JUSTIFY), TE(e_Orientation, EDIF_TOK_ORIENTATION), TE(e_Unit, EDIF_TOK_UNIT), TE(e_ViewType, EDIF_TOK_VIEWTYPE) }; static int TieDefSize = sizeof(TieDef) / sizeof(Tie); /* * Context definitions: * * This associates keyword strings with '%token' values. It * also creates a pretty much empty header for later building of * the context tree. Again they needn't be sorted, but strings * must be lower case. */ typedef struct Context { char *Name; /* keyword name */ short Code; /* '%token' value */ short Flags; /* special operation flags */ struct ContextCar *Context; /* contexts which can be moved to */ struct TokenCar *Token; /* active tokens */ struct Context *Next; /* hash table linkage */ } Context; static Context ContextDef[] = { {"", 0}, /* start context */ {"acload", EDIF_TOK_ACLOAD}, {"after", EDIF_TOK_AFTER}, {"annotate", EDIF_TOK_ANNOTATE}, {"apply", EDIF_TOK_APPLY}, {"arc", EDIF_TOK_ARC}, {"array", EDIF_TOK_ARRAY}, {"arraymacro", EDIF_TOK_ARRAYMACRO}, {"arrayrelatedinfo", EDIF_TOK_ARRAYRELATEDINFO}, {"arraysite", EDIF_TOK_ARRAYSITE}, {"atleast", EDIF_TOK_ATLEAST}, {"atmost", EDIF_TOK_ATMOST}, {"author", EDIF_TOK_AUTHOR}, {"basearray", EDIF_TOK_BASEARRAY}, {"becomes", EDIF_TOK_BECOMES}, {"between", EDIF_TOK_BETWEEN}, {"boolean", EDIF_TOK_BOOLEAN}, {"booleandisplay", EDIF_TOK_BOOLEANDISPLAY}, {"booleanmap", EDIF_TOK_BOOLEANMAP}, {"borderpattern", EDIF_TOK_BORDERPATTERN}, {"borderwidth", EDIF_TOK_BORDERWIDTH}, {"boundingbox", EDIF_TOK_BOUNDINGBOX}, {"cell", EDIF_TOK_CELL}, {"cellref", EDIF_TOK_CELLREF}, {"celltype", EDIF_TOK_CELLTYPE}, {"change", EDIF_TOK_CHANGE}, {"circle", EDIF_TOK_CIRCLE}, {"color", EDIF_TOK_COLOR}, {"comment", EDIF_TOK_COMMENT}, {"commentgraphics", EDIF_TOK_COMMENTGRAPHICS}, {"compound", EDIF_TOK_COMPOUND}, {"connectlocation", EDIF_TOK_CONNECTLOCATION}, {"contents", EDIF_TOK_CONTENTS}, {"cornertype", EDIF_TOK_CORNERTYPE}, {"criticality", EDIF_TOK_CRITICALITY}, {"currentmap", EDIF_TOK_CURRENTMAP}, {"curve", EDIF_TOK_CURVE}, {"cycle", EDIF_TOK_CYCLE}, {"dataorigin", EDIF_TOK_DATAORIGIN}, {"dcfaninload", EDIF_TOK_DCFANINLOAD}, {"dcfanoutload", EDIF_TOK_DCFANOUTLOAD}, {"dcmaxfanin", EDIF_TOK_DCMAXFANIN}, {"dcmaxfanout", EDIF_TOK_DCMAXFANOUT}, {"delay", EDIF_TOK_DELAY}, {"delta", EDIF_TOK_DELTA}, {"derivation", EDIF_TOK_DERIVATION}, {"design", EDIF_TOK_DESIGN}, {"designator", EDIF_TOK_DESIGNATOR}, {"difference", EDIF_TOK_DIFFERENCE}, {"direction", EDIF_TOK_DIRECTION}, {"display", EDIF_TOK_DISPLAY}, {"dominates", EDIF_TOK_DOMINATES}, {"dot", EDIF_TOK_DOT}, {"duration", EDIF_TOK_DURATION}, {"e", EDIF_TOK_E}, {"edif", EDIF_TOK_EDIF}, {"ediflevel", EDIF_TOK_EDIFLEVEL}, {"edifversion", EDIF_TOK_EDIFVERSION}, {"enclosuredistance", EDIF_TOK_ENCLOSUREDISTANCE}, {"endtype", EDIF_TOK_ENDTYPE}, {"entry", EDIF_TOK_ENTRY}, {"exactly", EDIF_TOK_EXACTLY}, {"external", EDIF_TOK_EXTERNAL}, {"fabricate", EDIF_TOK_FABRICATE}, {"false", EDIF_TOK_FALSE}, {"figure", EDIF_TOK_FIGURE}, {"figurearea", EDIF_TOK_FIGUREAREA}, {"figuregroup", EDIF_TOK_FIGUREGROUP}, {"figuregroupobject", EDIF_TOK_FIGUREGROUPOBJECT}, {"figuregroupoverride", EDIF_TOK_FIGUREGROUPOVERRIDE}, {"figuregroupref", EDIF_TOK_FIGUREGROUPREF}, {"figureperimeter", EDIF_TOK_FIGUREPERIMETER}, {"figurewidth", EDIF_TOK_FIGUREWIDTH}, {"fillpattern", EDIF_TOK_FILLPATTERN}, {"follow", EDIF_TOK_FOLLOW}, {"forbiddenevent", EDIF_TOK_FORBIDDENEVENT}, {"globalportref", EDIF_TOK_GLOBALPORTREF}, {"greaterthan", EDIF_TOK_GREATERTHAN}, {"gridmap", EDIF_TOK_GRIDMAP}, {"ignore", EDIF_TOK_IGNORE}, {"includefiguregroup", EDIF_TOK_INCLUDEFIGUREGROUP}, {"initial", EDIF_TOK_INITIAL}, {"instance", EDIF_TOK_INSTANCE}, {"instancebackannotate", EDIF_TOK_INSTANCEBACKANNOTATE}, {"instancegroup", EDIF_TOK_INSTANCEGROUP}, {"instancemap", EDIF_TOK_INSTANCEMAP}, {"instanceref", EDIF_TOK_INSTANCEREF}, {"integer", EDIF_TOK_INTEGER}, {"integerdisplay", EDIF_TOK_INTEGERDISPLAY}, {"interface", EDIF_TOK_INTERFACE}, {"interfiguregroupspacing", EDIF_TOK_INTERFIGUREGROUPSPACING}, {"intersection", EDIF_TOK_INTERSECTION}, {"intrafiguregroupspacing", EDIF_TOK_INTRAFIGUREGROUPSPACING}, {"inverse", EDIF_TOK_INVERSE}, {"isolated", EDIF_TOK_ISOLATED}, {"joined", EDIF_TOK_JOINED}, {"justify", EDIF_TOK_JUSTIFY}, {"keyworddisplay", EDIF_TOK_KEYWORDDISPLAY}, {"keywordlevel", EDIF_TOK_KEYWORDLEVEL}, {"keywordmap", EDIF_TOK_KEYWORDMAP}, {"lessthan", EDIF_TOK_LESSTHAN}, {"library", EDIF_TOK_LIBRARY}, {"libraryref", EDIF_TOK_LIBRARYREF}, {"listofnets", EDIF_TOK_LISTOFNETS}, {"listofports", EDIF_TOK_LISTOFPORTS}, {"loaddelay", EDIF_TOK_LOADDELAY}, {"logicassign", EDIF_TOK_LOGICASSIGN}, {"logicinput", EDIF_TOK_LOGICINPUT}, {"logiclist", EDIF_TOK_LOGICLIST}, {"logicmapinput", EDIF_TOK_LOGICMAPINPUT}, {"logicmapoutput", EDIF_TOK_LOGICMAPOUTPUT}, {"logiconeof", EDIF_TOK_LOGICONEOF}, {"logicoutput", EDIF_TOK_LOGICOUTPUT}, {"logicport", EDIF_TOK_LOGICPORT}, {"logicref", EDIF_TOK_LOGICREF}, {"logicvalue", EDIF_TOK_LOGICVALUE}, {"logicwaveform", EDIF_TOK_LOGICWAVEFORM}, {"maintain", EDIF_TOK_MAINTAIN}, {"match", EDIF_TOK_MATCH}, {"member", EDIF_TOK_MEMBER}, {"minomax", EDIF_TOK_MINOMAX}, {"minomaxdisplay", EDIF_TOK_MINOMAXDISPLAY}, {"mnm", EDIF_TOK_MNM}, {"multiplevalueset", EDIF_TOK_MULTIPLEVALUESET}, {"mustjoin", EDIF_TOK_MUSTJOIN}, {"name", EDIF_TOK_NAME}, {"net", EDIF_TOK_NET}, {"netbackannotate", EDIF_TOK_NETBACKANNOTATE}, {"netbundle", EDIF_TOK_NETBUNDLE}, {"netdelay", EDIF_TOK_NETDELAY}, {"netgroup", EDIF_TOK_NETGROUP}, {"netmap", EDIF_TOK_NETMAP}, {"netref", EDIF_TOK_NETREF}, {"nochange", EDIF_TOK_NOCHANGE}, {"nonpermutable", EDIF_TOK_NONPERMUTABLE}, {"notallowed", EDIF_TOK_NOTALLOWED}, {"notchspacing", EDIF_TOK_NOTCHSPACING}, {"number", EDIF_TOK_NUMBER}, {"numberdefinition", EDIF_TOK_NUMBERDEFINITION}, {"numberdisplay", EDIF_TOK_NUMBERDISPLAY}, {"offpageconnector", EDIF_TOK_OFFPAGECONNECTOR}, {"offsetevent", EDIF_TOK_OFFSETEVENT}, {"openshape", EDIF_TOK_OPENSHAPE}, {"orientation", EDIF_TOK_ORIENTATION}, {"origin", EDIF_TOK_ORIGIN}, {"overhangdistance", EDIF_TOK_OVERHANGDISTANCE}, {"overlapdistance", EDIF_TOK_OVERLAPDISTANCE}, {"oversize", EDIF_TOK_OVERSIZE}, {"owner", EDIF_TOK_OWNER}, {"page", EDIF_TOK_PAGE}, {"pagesize", EDIF_TOK_PAGESIZE}, {"parameter", EDIF_TOK_PARAMETER}, {"parameterassign", EDIF_TOK_PARAMETERASSIGN}, {"parameterdisplay", EDIF_TOK_PARAMETERDISPLAY}, {"path", EDIF_TOK_PATH}, {"pathdelay", EDIF_TOK_PATHDELAY}, {"pathwidth", EDIF_TOK_PATHWIDTH}, {"permutable", EDIF_TOK_PERMUTABLE}, {"physicaldesignrule", EDIF_TOK_PHYSICALDESIGNRULE}, {"plug", EDIF_TOK_PLUG}, {"point", EDIF_TOK_POINT}, {"pointdisplay", EDIF_TOK_POINTDISPLAY}, {"pointlist", EDIF_TOK_POINTLIST}, {"polygon", EDIF_TOK_POLYGON}, {"port", EDIF_TOK_PORT}, {"portbackannotate", EDIF_TOK_PORTBACKANNOTATE}, {"portbundle", EDIF_TOK_PORTBUNDLE}, {"portdelay", EDIF_TOK_PORTDELAY}, {"portgroup", EDIF_TOK_PORTGROUP}, {"portimplementation", EDIF_TOK_PORTIMPLEMENTATION}, {"portinstance", EDIF_TOK_PORTINSTANCE}, {"portlist", EDIF_TOK_PORTLIST}, {"portlistalias", EDIF_TOK_PORTLISTALIAS}, {"portmap", EDIF_TOK_PORTMAP}, {"portref", EDIF_TOK_PORTREF}, {"program", EDIF_TOK_PROGRAM}, {"property", EDIF_TOK_PROPERTY}, {"propertydisplay", EDIF_TOK_PROPERTYDISPLAY}, {"protectionframe", EDIF_TOK_PROTECTIONFRAME}, {"pt", EDIF_TOK_PT}, {"rangevector", EDIF_TOK_RANGEVECTOR}, {"rectangle", EDIF_TOK_RECTANGLE}, {"rectanglesize", EDIF_TOK_RECTANGLESIZE}, {"rename", EDIF_TOK_RENAME}, {"resolves", EDIF_TOK_RESOLVES}, {"scale", EDIF_TOK_SCALE}, {"scalex", EDIF_TOK_SCALEX}, {"scaley", EDIF_TOK_SCALEY}, {"section", EDIF_TOK_SECTION}, {"shape", EDIF_TOK_SHAPE}, {"simulate", EDIF_TOK_SIMULATE}, {"simulationinfo", EDIF_TOK_SIMULATIONINFO}, {"singlevalueset", EDIF_TOK_SINGLEVALUESET}, {"site", EDIF_TOK_SITE}, {"socket", EDIF_TOK_SOCKET}, {"socketset", EDIF_TOK_SOCKETSET}, {"status", EDIF_TOK_STATUS}, {"steady", EDIF_TOK_STEADY}, {"string", EDIF_TOK_STRING}, {"stringdisplay", EDIF_TOK_STRINGDISPLAY}, {"strong", EDIF_TOK_STRONG}, {"symbol", EDIF_TOK_SYMBOL}, {"symmetry", EDIF_TOK_SYMMETRY}, {"table", EDIF_TOK_TABLE}, {"tabledefault", EDIF_TOK_TABLEDEFAULT}, {"technology", EDIF_TOK_TECHNOLOGY}, {"textheight", EDIF_TOK_TEXTHEIGHT}, {"timeinterval", EDIF_TOK_TIMEINTERVAL}, {"timestamp", EDIF_TOK_TIMESTAMP}, {"timing", EDIF_TOK_TIMING}, {"transform", EDIF_TOK_TRANSFORM}, {"transition", EDIF_TOK_TRANSITION}, {"trigger", EDIF_TOK_TRIGGER}, {"true", EDIF_TOK_TRUE}, {"unconstrained", EDIF_TOK_UNCONSTRAINED}, {"undefined", EDIF_TOK_UNDEFINED}, {"union", EDIF_TOK_UNION}, {"unit", EDIF_TOK_UNIT}, {"unused", EDIF_TOK_UNUSED}, {"userdata", EDIF_TOK_USERDATA}, {"version", EDIF_TOK_VERSION}, {"view", EDIF_TOK_VIEW}, {"viewlist", EDIF_TOK_VIEWLIST}, {"viewmap", EDIF_TOK_VIEWMAP}, {"viewref", EDIF_TOK_VIEWREF}, {"viewtype", EDIF_TOK_VIEWTYPE}, {"visible", EDIF_TOK_VISIBLE}, {"voltagemap", EDIF_TOK_VOLTAGEMAP}, {"wavevalue", EDIF_TOK_WAVEVALUE}, {"weak", EDIF_TOK_WEAK}, {"weakjoined", EDIF_TOK_WEAKJOINED}, {"when", EDIF_TOK_WHEN}, {"written", EDIF_TOK_WRITTEN} }; static int ContextDefSize = sizeof(ContextDef) / sizeof(Context); /* * Context follower tables: * * This is pretty ugly, an array is defined for each context * which has following context levels. Yet another table is used * to bind these arrays to the originating contexts. * Arrays are declared as: * * static short f_[] = { ... }; * * The array entries are the '%token' values for all keywords which * can be reached from the context. Like I said, ugly, * but it works. * A negative entry means that the follow can only occur once within * the specified context. */ static short f_NULL[] = {EDIF_TOK_EDIF}; static short f_Edif[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_EDIFVERSION, EDIF_TOK_EDIFLEVEL, EDIF_TOK_KEYWORDMAP, -EDIF_TOK_STATUS, EDIF_TOK_EXTERNAL, EDIF_TOK_LIBRARY, EDIF_TOK_DESIGN, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_AcLoad[] = {EDIF_TOK_MNM, EDIF_TOK_E, EDIF_TOK_MINOMAXDISPLAY}; static short f_After[] = {EDIF_TOK_MNM, EDIF_TOK_E, EDIF_TOK_FOLLOW, EDIF_TOK_MAINTAIN, EDIF_TOK_LOGICASSIGN, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Annotate[] = {EDIF_TOK_STRINGDISPLAY}; static short f_Apply[] = {EDIF_TOK_CYCLE, EDIF_TOK_LOGICINPUT, EDIF_TOK_LOGICOUTPUT, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Arc[] = {EDIF_TOK_PT}; static short f_Array[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME}; static short f_ArrayMacro[] = {EDIF_TOK_PLUG}; static short f_ArrayRelatedInfo[] = {EDIF_TOK_BASEARRAY, EDIF_TOK_ARRAYSITE, EDIF_TOK_ARRAYMACRO, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_ArraySite[] = {EDIF_TOK_SOCKET}; static short f_AtLeast[] = {EDIF_TOK_E}; static short f_AtMost[] = {EDIF_TOK_E}; static short f_Becomes[] = {EDIF_TOK_NAME, EDIF_TOK_LOGICLIST, EDIF_TOK_LOGICONEOF}; /* static short f_Between[] = {EDIF_TOK_ATLEAST, EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, EDIF_TOK_LESSTHAN}; */ static short f_Boolean[] = {EDIF_TOK_FALSE, EDIF_TOK_TRUE, EDIF_TOK_BOOLEANDISPLAY, EDIF_TOK_BOOLEAN}; static short f_BooleanDisplay[] = {EDIF_TOK_FALSE, EDIF_TOK_TRUE, EDIF_TOK_DISPLAY}; static short f_BooleanMap[] = {EDIF_TOK_FALSE, EDIF_TOK_TRUE}; static short f_BorderPattern[] = {EDIF_TOK_BOOLEAN}; static short f_BoundingBox[] = {EDIF_TOK_RECTANGLE}; static short f_Cell[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_CELLTYPE, -EDIF_TOK_STATUS, -EDIF_TOK_VIEWMAP, EDIF_TOK_VIEW, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA, EDIF_TOK_PROPERTY}; static short f_CellRef[] = {EDIF_TOK_NAME, EDIF_TOK_LIBRARYREF}; static short f_Change[] = {EDIF_TOK_NAME, EDIF_TOK_PORTREF, EDIF_TOK_PORTLIST, EDIF_TOK_BECOMES, EDIF_TOK_TRANSITION}; static short f_Circle[] = {EDIF_TOK_PT, EDIF_TOK_PROPERTY}; static short f_Color[] = {EDIF_TOK_E}; static short f_CommentGraphics[] = {EDIF_TOK_ANNOTATE, EDIF_TOK_FIGURE, EDIF_TOK_INSTANCE, -EDIF_TOK_BOUNDINGBOX, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Compound[] = {EDIF_TOK_NAME}; static short f_ConnectLocation[] = {EDIF_TOK_FIGURE}; static short f_Contents[] = {EDIF_TOK_INSTANCE, EDIF_TOK_OFFPAGECONNECTOR, EDIF_TOK_FIGURE, EDIF_TOK_SECTION, EDIF_TOK_NET, EDIF_TOK_NETBUNDLE, EDIF_TOK_PAGE, EDIF_TOK_COMMENTGRAPHICS, EDIF_TOK_PORTIMPLEMENTATION, EDIF_TOK_TIMING, EDIF_TOK_SIMULATE, EDIF_TOK_WHEN, EDIF_TOK_FOLLOW, EDIF_TOK_LOGICPORT, -EDIF_TOK_BOUNDINGBOX, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Criticality[] = {EDIF_TOK_INTEGERDISPLAY}; static short f_CurrentMap[] = {EDIF_TOK_MNM, EDIF_TOK_E}; static short f_Curve[] = {EDIF_TOK_ARC, EDIF_TOK_PT}; static short f_Cycle[] = {EDIF_TOK_DURATION}; static short f_DataOrigin[] = {EDIF_TOK_VERSION}; static short f_DcFanInLoad[] = {EDIF_TOK_E, EDIF_TOK_NUMBERDISPLAY}; static short f_DcFanOutLoad[] = {EDIF_TOK_E, EDIF_TOK_NUMBERDISPLAY}; static short f_DcMaxFanIn[] = {EDIF_TOK_E, EDIF_TOK_NUMBERDISPLAY}; static short f_DcMaxFanOut[] = {EDIF_TOK_E, EDIF_TOK_NUMBERDISPLAY}; static short f_Delay[] = {EDIF_TOK_MNM, EDIF_TOK_E}; static short f_Delta[] = {EDIF_TOK_PT}; static short f_Design[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_CELLREF, EDIF_TOK_STATUS, EDIF_TOK_COMMENT, EDIF_TOK_PROPERTY, EDIF_TOK_USERDATA}; static short f_Designator[] = {EDIF_TOK_STRINGDISPLAY}; static short f_Difference[] = {EDIF_TOK_FIGUREGROUPREF, EDIF_TOK_INTERSECTION, EDIF_TOK_UNION, EDIF_TOK_DIFFERENCE, EDIF_TOK_INVERSE, EDIF_TOK_OVERSIZE}; static short f_Display[] = {EDIF_TOK_NAME, EDIF_TOK_FIGUREGROUPOVERRIDE, EDIF_TOK_JUSTIFY, EDIF_TOK_ORIENTATION, EDIF_TOK_ORIGIN}; static short f_Dominates[] = {EDIF_TOK_NAME}; static short f_Dot[] = {EDIF_TOK_PT, EDIF_TOK_PROPERTY}; static short f_Duration[] = {EDIF_TOK_E}; static short f_EnclosureDistance[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_LESSTHAN, EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN, EDIF_TOK_SINGLEVALUESET, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Entry[] = {EDIF_TOK_MATCH, EDIF_TOK_CHANGE, EDIF_TOK_STEADY, EDIF_TOK_LOGICREF, EDIF_TOK_PORTREF, EDIF_TOK_NOCHANGE, EDIF_TOK_TABLE, EDIF_TOK_DELAY, EDIF_TOK_LOADDELAY}; static short f_Exactly[] = {EDIF_TOK_E}; static short f_External[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_EDIFLEVEL, EDIF_TOK_TECHNOLOGY, -EDIF_TOK_STATUS, EDIF_TOK_CELL, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Fabricate[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME}; static short f_Figure[] = {EDIF_TOK_NAME, EDIF_TOK_FIGUREGROUPOVERRIDE, EDIF_TOK_CIRCLE, EDIF_TOK_DOT, EDIF_TOK_OPENSHAPE, EDIF_TOK_PATH, EDIF_TOK_POLYGON, EDIF_TOK_RECTANGLE, EDIF_TOK_SHAPE, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_FigureArea[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_LESSTHAN, EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN, EDIF_TOK_SINGLEVALUESET, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_FigureGroup[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, -EDIF_TOK_CORNERTYPE, -EDIF_TOK_ENDTYPE, -EDIF_TOK_PATHWIDTH, -EDIF_TOK_BORDERWIDTH, -EDIF_TOK_COLOR, -EDIF_TOK_FILLPATTERN, -EDIF_TOK_BORDERPATTERN, -EDIF_TOK_TEXTHEIGHT, -EDIF_TOK_VISIBLE, EDIF_TOK_INCLUDEFIGUREGROUP, EDIF_TOK_COMMENT, EDIF_TOK_PROPERTY, EDIF_TOK_USERDATA}; static short f_FigureGroupObject[] = {EDIF_TOK_NAME, EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_INTERSECTION, EDIF_TOK_UNION, EDIF_TOK_DIFFERENCE, EDIF_TOK_INVERSE, EDIF_TOK_OVERSIZE}; static short f_FigureGroupOverride[] = {EDIF_TOK_NAME, -EDIF_TOK_CORNERTYPE, -EDIF_TOK_ENDTYPE, -EDIF_TOK_PATHWIDTH, -EDIF_TOK_BORDERWIDTH, -EDIF_TOK_COLOR, -EDIF_TOK_FILLPATTERN, -EDIF_TOK_TEXTHEIGHT, -EDIF_TOK_BORDERPATTERN, EDIF_TOK_VISIBLE, EDIF_TOK_COMMENT, EDIF_TOK_PROPERTY, EDIF_TOK_USERDATA}; static short f_FigureGroupRef[] = {EDIF_TOK_NAME, EDIF_TOK_LIBRARYREF}; static short f_FigurePerimeter[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_LESSTHAN, EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN, EDIF_TOK_SINGLEVALUESET, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_FigureWidth[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_LESSTHAN, EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN, EDIF_TOK_SINGLEVALUESET, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_FillPattern[] = {EDIF_TOK_BOOLEAN}; static short f_Follow[] = {EDIF_TOK_NAME, EDIF_TOK_PORTREF, EDIF_TOK_TABLE, EDIF_TOK_DELAY, EDIF_TOK_LOADDELAY}; static short f_ForbiddenEvent[] = {EDIF_TOK_TIMEINTERVAL, EDIF_TOK_EVENT}; static short f_GlobalPortRef[] = {EDIF_TOK_NAME}; static short f_GreaterThan[] = {EDIF_TOK_E}; static short f_GridMap[] = {EDIF_TOK_E}; static short f_IncludeFigureGroup[] = {EDIF_TOK_FIGUREGROUPREF, EDIF_TOK_INTERSECTION, EDIF_TOK_UNION, EDIF_TOK_DIFFERENCE, EDIF_TOK_INVERSE, EDIF_TOK_OVERSIZE}; static short f_Instance[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_ARRAY, EDIF_TOK_VIEWREF, EDIF_TOK_VIEWLIST, -EDIF_TOK_TRANSFORM, EDIF_TOK_PARAMETERASSIGN, EDIF_TOK_PORTINSTANCE, EDIF_TOK_TIMING, -EDIF_TOK_DESIGNATOR, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_InstanceBackAnnotate[] = {EDIF_TOK_INSTANCEREF, -EDIF_TOK_DESIGNATOR, EDIF_TOK_TIMING, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT}; static short f_InstanceGroup[] = {EDIF_TOK_INSTANCEREF}; static short f_InstanceMap[] = {EDIF_TOK_INSTANCEREF, EDIF_TOK_INSTANCEGROUP, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_InstanceRef[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, EDIF_TOK_INSTANCEREF, EDIF_TOK_VIEWREF}; static short f_Integer[] = {EDIF_TOK_INTEGERDISPLAY, EDIF_TOK_INTEGER}; static short f_IntegerDisplay[] = {EDIF_TOK_DISPLAY}; static short f_Interface[] = {EDIF_TOK_PORT, EDIF_TOK_PORTBUNDLE, -EDIF_TOK_SYMBOL, -EDIF_TOK_PROTECTIONFRAME, -EDIF_TOK_ARRAYRELATEDINFO, EDIF_TOK_PARAMETER, EDIF_TOK_JOINED, EDIF_TOK_MUSTJOIN, EDIF_TOK_WEAKJOINED, EDIF_TOK_PERMUTABLE, EDIF_TOK_TIMING, EDIF_TOK_SIMULATE, -EDIF_TOK_DESIGNATOR, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_InterFigureGroupSpacing[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_LESSTHAN, EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN, EDIF_TOK_SINGLEVALUESET, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Intersection[] = {EDIF_TOK_FIGUREGROUPREF, EDIF_TOK_INTERSECTION, EDIF_TOK_UNION, EDIF_TOK_DIFFERENCE, EDIF_TOK_INVERSE, EDIF_TOK_OVERSIZE}; static short f_IntraFigureGroupSpacing[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_LESSTHAN, EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN, EDIF_TOK_SINGLEVALUESET, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Inverse[] = {EDIF_TOK_FIGUREGROUPREF, EDIF_TOK_INTERSECTION, EDIF_TOK_UNION, EDIF_TOK_DIFFERENCE, EDIF_TOK_INVERSE, EDIF_TOK_OVERSIZE}; static short f_Joined[] = {EDIF_TOK_PORTREF, EDIF_TOK_PORTLIST, EDIF_TOK_GLOBALPORTREF}; static short f_KeywordDisplay[] = {EDIF_TOK_DISPLAY}; static short f_KeywordMap[] = {EDIF_TOK_KEYWORDLEVEL, EDIF_TOK_COMMENT}; static short f_LessThan[] = {EDIF_TOK_E}; static short f_Library[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_EDIFLEVEL, EDIF_TOK_TECHNOLOGY, -EDIF_TOK_STATUS, EDIF_TOK_CELL, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_LibraryRef[] = {EDIF_TOK_NAME}; static short f_ListOfNets[] = {EDIF_TOK_NET}; static short f_ListOfPorts[] = {EDIF_TOK_PORT, EDIF_TOK_PORTBUNDLE}; static short f_LoadDelay[] = {EDIF_TOK_MNM, EDIF_TOK_E, EDIF_TOK_MINOMAXDISPLAY}; static short f_LogicAssign[] = {EDIF_TOK_NAME, EDIF_TOK_PORTREF, EDIF_TOK_LOGICREF, EDIF_TOK_TABLE, EDIF_TOK_DELAY, EDIF_TOK_LOADDELAY}; static short f_LogicInput[] = {EDIF_TOK_PORTLIST, EDIF_TOK_PORTREF, EDIF_TOK_NAME, EDIF_TOK_LOGICWAVEFORM}; static short f_LogicList[] = {EDIF_TOK_NAME, EDIF_TOK_LOGICONEOF, EDIF_TOK_IGNORE}; static short f_LogicMapInput[] = {EDIF_TOK_LOGICREF}; static short f_LogicMapOutput[] = {EDIF_TOK_LOGICREF}; static short f_LogicOneOf[] = {EDIF_TOK_NAME, EDIF_TOK_LOGICLIST}; static short f_LogicOutput[] = {EDIF_TOK_PORTLIST, EDIF_TOK_PORTREF, EDIF_TOK_NAME, EDIF_TOK_LOGICWAVEFORM}; static short f_LogicPort[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_LogicRef[] = {EDIF_TOK_NAME, EDIF_TOK_LIBRARYREF}; static short f_LogicValue[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, -EDIF_TOK_VOLTAGEMAP, -EDIF_TOK_CURRENTMAP, -EDIF_TOK_BOOLEANMAP, -EDIF_TOK_COMPOUND, -EDIF_TOK_WEAK ,-EDIF_TOK_STRONG, -EDIF_TOK_DOMINATES, -EDIF_TOK_LOGICMAPOUTPUT, -EDIF_TOK_LOGICMAPINPUT, -EDIF_TOK_ISOLATED, EDIF_TOK_RESOLVES, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_LogicWaveform[] = {EDIF_TOK_NAME, EDIF_TOK_LOGICLIST, EDIF_TOK_LOGICONEOF, EDIF_TOK_IGNORE}; static short f_Maintain[] = {EDIF_TOK_NAME, EDIF_TOK_PORTREF, EDIF_TOK_DELAY, EDIF_TOK_LOADDELAY}; static short f_Match[] = {EDIF_TOK_NAME, EDIF_TOK_PORTREF, EDIF_TOK_PORTLIST, EDIF_TOK_LOGICLIST, EDIF_TOK_LOGICONEOF}; static short f_Member[] = {EDIF_TOK_NAME}; static short f_MiNoMax[] = {EDIF_TOK_MNM, EDIF_TOK_E, EDIF_TOK_MINOMAXDISPLAY, EDIF_TOK_MINOMAX}; static short f_MiNoMaxDisplay[] = {EDIF_TOK_MNM, EDIF_TOK_E, EDIF_TOK_DISPLAY}; static short f_Mnm[] = {EDIF_TOK_E, EDIF_TOK_UNDEFINED, EDIF_TOK_UNCONSTRAINED}; static short f_MultipleValueSet[] = {EDIF_TOK_RANGEVECTOR}; static short f_MustJoin[] = {EDIF_TOK_PORTREF, EDIF_TOK_PORTLIST, EDIF_TOK_WEAKJOINED, EDIF_TOK_JOINED}; static short f_Name[] = {EDIF_TOK_DISPLAY}; static short f_Net[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, -EDIF_TOK_CRITICALITY, EDIF_TOK_NETDELAY, EDIF_TOK_FIGURE, EDIF_TOK_NET, EDIF_TOK_INSTANCE, EDIF_TOK_COMMENTGRAPHICS, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA, EDIF_TOK_JOINED, EDIF_TOK_ARRAY}; static short f_NetBackAnnotate[] = {EDIF_TOK_NETREF, EDIF_TOK_NETDELAY, -EDIF_TOK_CRITICALITY, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT}; static short f_NetBundle[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_ARRAY, EDIF_TOK_LISTOFNETS, EDIF_TOK_FIGURE, EDIF_TOK_COMMENTGRAPHICS, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_NetDelay[] = {EDIF_TOK_DERIVATION, EDIF_TOK_DELAY, EDIF_TOK_TRANSITION, EDIF_TOK_BECOMES}; static short f_NetGroup[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, EDIF_TOK_NETREF}; static short f_NetMap[] = {EDIF_TOK_NETREF, EDIF_TOK_NETGROUP, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_NetRef[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, EDIF_TOK_NETREF, EDIF_TOK_INSTANCEREF, EDIF_TOK_VIEWREF}; static short f_NonPermutable[] = {EDIF_TOK_PORTREF, EDIF_TOK_PERMUTABLE}; static short f_NotAllowed[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_NotchSpacing[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_LESSTHAN, EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN, EDIF_TOK_SINGLEVALUESET, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Number[] = {EDIF_TOK_E, EDIF_TOK_NUMBERDISPLAY, EDIF_TOK_NUMBER}; static short f_NumberDefinition[] = {EDIF_TOK_SCALE, -EDIF_TOK_GRIDMAP, EDIF_TOK_COMMENT}; static short f_NumberDisplay[] = {EDIF_TOK_E, EDIF_TOK_DISPLAY}; static short f_OffPageConnector[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, -EDIF_TOK_UNUSED, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_OffsetEvent[] = {EDIF_TOK_EVENT, EDIF_TOK_E}; static short f_OpenShape[] = {EDIF_TOK_CURVE, EDIF_TOK_PROPERTY}; static short f_Origin[] = {EDIF_TOK_PT}; static short f_OverhangDistance[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_LESSTHAN, EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN, EDIF_TOK_SINGLEVALUESET, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_OverlapDistance[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_LESSTHAN, EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN, EDIF_TOK_SINGLEVALUESET, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Oversize[] = {EDIF_TOK_FIGUREGROUPREF, EDIF_TOK_INTERSECTION, EDIF_TOK_UNION, EDIF_TOK_DIFFERENCE, EDIF_TOK_INVERSE, EDIF_TOK_OVERSIZE, EDIF_TOK_CORNERTYPE}; static short f_Page[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_ARRAY, EDIF_TOK_INSTANCE, EDIF_TOK_NET, EDIF_TOK_NETBUNDLE, EDIF_TOK_COMMENTGRAPHICS, EDIF_TOK_PORTIMPLEMENTATION, -EDIF_TOK_PAGESIZE, -EDIF_TOK_BOUNDINGBOX, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_PageSize[] = {EDIF_TOK_RECTANGLE}; static short f_Parameter[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_ARRAY, EDIF_TOK_BOOLEAN, EDIF_TOK_INTEGER, EDIF_TOK_MINOMAX, EDIF_TOK_NUMBER, EDIF_TOK_POINT, EDIF_TOK_STRING}; static short f_ParameterAssign[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, EDIF_TOK_BOOLEAN, EDIF_TOK_INTEGER, EDIF_TOK_MINOMAX, EDIF_TOK_NUMBER, EDIF_TOK_POINT, EDIF_TOK_STRING}; static short f_ParameterDisplay[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, EDIF_TOK_DISPLAY}; static short f_Path[] = {EDIF_TOK_POINTLIST, EDIF_TOK_PROPERTY}; static short f_PathDelay[] = {EDIF_TOK_DELAY, EDIF_TOK_EVENT}; static short f_Permutable[] = {EDIF_TOK_PORTREF, EDIF_TOK_PERMUTABLE, EDIF_TOK_NONPERMUTABLE}; static short f_PhysicalDesignRule[] = {EDIF_TOK_FIGUREWIDTH, EDIF_TOK_FIGUREAREA, EDIF_TOK_RECTANGLESIZE, EDIF_TOK_FIGUREPERIMETER, EDIF_TOK_OVERLAPDISTANCE, EDIF_TOK_OVERHANGDISTANCE, EDIF_TOK_ENCLOSUREDISTANCE, EDIF_TOK_INTERFIGUREGROUPSPACING, EDIF_TOK_NOTCHSPACING, EDIF_TOK_INTRAFIGUREGROUPSPACING, EDIF_TOK_NOTALLOWED, EDIF_TOK_FIGUREGROUP, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Plug[] = {EDIF_TOK_SOCKETSET}; static short f_Point[] = {EDIF_TOK_PT, EDIF_TOK_POINTDISPLAY, EDIF_TOK_POINT}; static short f_PointDisplay[] = {EDIF_TOK_PT, EDIF_TOK_DISPLAY}; static short f_PointList[] = {EDIF_TOK_PT}; static short f_Polygon[] = {EDIF_TOK_POINTLIST, EDIF_TOK_PROPERTY}; static short f_Port[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_ARRAY, -EDIF_TOK_DIRECTION, -EDIF_TOK_UNUSED, EDIF_TOK_PORTDELAY, -EDIF_TOK_DESIGNATOR, -EDIF_TOK_DCFANINLOAD, -EDIF_TOK_DCFANOUTLOAD, -EDIF_TOK_DCMAXFANIN, -EDIF_TOK_DCMAXFANOUT, -EDIF_TOK_ACLOAD, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_PortBackAnnotate[] = {EDIF_TOK_PORTREF, -EDIF_TOK_DESIGNATOR, EDIF_TOK_PORTDELAY, -EDIF_TOK_DCFANINLOAD, -EDIF_TOK_DCFANOUTLOAD, -EDIF_TOK_DCMAXFANIN, -EDIF_TOK_DCMAXFANOUT, -EDIF_TOK_ACLOAD, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT}; static short f_PortBundle[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_ARRAY, EDIF_TOK_LISTOFPORTS, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_PortDelay[] = {EDIF_TOK_DERIVATION, EDIF_TOK_DELAY, EDIF_TOK_LOADDELAY, EDIF_TOK_TRANSITION, EDIF_TOK_BECOMES}; static short f_PortGroup[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, EDIF_TOK_PORTREF}; static short f_PortImplementation[] = {EDIF_TOK_PORTREF, EDIF_TOK_NAME, EDIF_TOK_MEMBER, -EDIF_TOK_CONNECTLOCATION, EDIF_TOK_FIGURE, EDIF_TOK_INSTANCE, EDIF_TOK_COMMENTGRAPHICS, EDIF_TOK_PROPERTYDISPLAY, EDIF_TOK_KEYWORDDISPLAY, EDIF_TOK_PROPERTY, EDIF_TOK_USERDATA, EDIF_TOK_COMMENT}; static short f_PortInstance[] = {EDIF_TOK_PORTREF, EDIF_TOK_NAME, EDIF_TOK_MEMBER, -EDIF_TOK_UNUSED, EDIF_TOK_PORTDELAY, -EDIF_TOK_DESIGNATOR, -EDIF_TOK_DCFANINLOAD, -EDIF_TOK_DCFANOUTLOAD, -EDIF_TOK_DCMAXFANIN, -EDIF_TOK_DCMAXFANOUT, -EDIF_TOK_ACLOAD, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_PortList[] = {EDIF_TOK_PORTREF, EDIF_TOK_NAME, EDIF_TOK_MEMBER}; static short f_PortListAlias[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_ARRAY, EDIF_TOK_PORTLIST}; static short f_PortMap[] = {EDIF_TOK_PORTREF, EDIF_TOK_PORTGROUP, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_PortRef[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, EDIF_TOK_PORTREF, EDIF_TOK_INSTANCEREF, EDIF_TOK_VIEWREF}; static short f_Program[] = {EDIF_TOK_VERSION}; static short f_Property[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_BOOLEAN, EDIF_TOK_INTEGER, EDIF_TOK_MINOMAX, EDIF_TOK_NUMBER, EDIF_TOK_POINT, EDIF_TOK_STRING, -EDIF_TOK_OWNER, -EDIF_TOK_UNIT, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT}; static short f_PropertyDisplay[] = {EDIF_TOK_NAME, EDIF_TOK_DISPLAY}; static short f_ProtectionFrame[] = {EDIF_TOK_PORTIMPLEMENTATION, EDIF_TOK_FIGURE, EDIF_TOK_INSTANCE, EDIF_TOK_COMMENTGRAPHICS, -EDIF_TOK_BOUNDINGBOX, EDIF_TOK_PROPERTYDISPLAY, EDIF_TOK_KEYWORDDISPLAY, EDIF_TOK_PARAMETERDISPLAY, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_RangeVector[] = {EDIF_TOK_LESSTHAN, EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN, EDIF_TOK_SINGLEVALUESET}; static short f_Rectangle[] = {EDIF_TOK_PT, EDIF_TOK_PROPERTY}; static short f_RectangleSize[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_RANGEVECTOR, EDIF_TOK_MULTIPLEVALUESET,EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Rename[] = {EDIF_TOK_NAME, EDIF_TOK_STRINGDISPLAY}; static short f_Resolves[] = {EDIF_TOK_NAME}; static short f_Scale[] = {EDIF_TOK_E, EDIF_TOK_UNIT}; static short f_Section[] = {EDIF_TOK_SECTION, EDIF_TOK_INSTANCE}; static short f_Shape[] = {EDIF_TOK_CURVE, EDIF_TOK_PROPERTY}; static short f_Simulate[] = {EDIF_TOK_NAME, EDIF_TOK_PORTLISTALIAS, EDIF_TOK_WAVEVALUE, EDIF_TOK_APPLY, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_SimulationInfo[] = {EDIF_TOK_LOGICVALUE, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_SingleValueSet[] = {EDIF_TOK_LESSTHAN, EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN}; static short f_Site[] = {EDIF_TOK_VIEWREF, EDIF_TOK_TRANSFORM}; static short f_Socket[] = {EDIF_TOK_SYMMETRY}; static short f_SocketSet[] = {EDIF_TOK_SYMMETRY, EDIF_TOK_SITE}; static short f_Status[] = {EDIF_TOK_WRITTEN, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Steady[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, EDIF_TOK_PORTREF, EDIF_TOK_PORTLIST, EDIF_TOK_DURATION, EDIF_TOK_TRANSITION, EDIF_TOK_BECOMES}; static short f_String[] = {EDIF_TOK_STRINGDISPLAY, EDIF_TOK_STRING}; static short f_StringDisplay[] = {EDIF_TOK_DISPLAY}; static short f_Strong[] = {EDIF_TOK_NAME}; static short f_Symbol[] = {EDIF_TOK_PORTIMPLEMENTATION, EDIF_TOK_FIGURE, EDIF_TOK_INSTANCE, EDIF_TOK_COMMENTGRAPHICS, EDIF_TOK_ANNOTATE, -EDIF_TOK_PAGESIZE, -EDIF_TOK_BOUNDINGBOX, EDIF_TOK_PROPERTYDISPLAY, EDIF_TOK_KEYWORDDISPLAY, EDIF_TOK_PARAMETERDISPLAY, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Symmetry[] = {EDIF_TOK_TRANSFORM}; static short f_Table[] = {EDIF_TOK_ENTRY, EDIF_TOK_TABLEDEFAULT}; static short f_TableDefault[] = {EDIF_TOK_LOGICREF, EDIF_TOK_PORTREF, EDIF_TOK_NOCHANGE, EDIF_TOK_TABLE, EDIF_TOK_DELAY, EDIF_TOK_LOADDELAY}; static short f_Technology[] = {EDIF_TOK_NUMBERDEFINITION, EDIF_TOK_FIGUREGROUP, EDIF_TOK_FABRICATE, -EDIF_TOK_SIMULATIONINFO, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA, -EDIF_TOK_PHYSICALDESIGNRULE}; static short f_TimeInterval[] = {EDIF_TOK_EVENT, EDIF_TOK_OFFSETEVENT, EDIF_TOK_DURATION}; static short f_Timing[] = {EDIF_TOK_DERIVATION, EDIF_TOK_PATHDELAY, EDIF_TOK_FORBIDDENEVENT, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Transform[] = {EDIF_TOK_SCALEX, EDIF_TOK_SCALEY, EDIF_TOK_DELTA, EDIF_TOK_ORIENTATION, EDIF_TOK_ORIGIN}; static short f_Transition[] = {EDIF_TOK_NAME, EDIF_TOK_LOGICLIST, EDIF_TOK_LOGICONEOF}; static short f_Trigger[] = {EDIF_TOK_CHANGE, EDIF_TOK_STEADY, EDIF_TOK_INITIAL}; static short f_Union[] = {EDIF_TOK_FIGUREGROUPREF, EDIF_TOK_INTERSECTION, EDIF_TOK_UNION, EDIF_TOK_DIFFERENCE, EDIF_TOK_INVERSE, EDIF_TOK_OVERSIZE}; static short f_View[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_VIEWTYPE, EDIF_TOK_INTERFACE, -EDIF_TOK_STATUS, -EDIF_TOK_CONTENTS, EDIF_TOK_COMMENT, EDIF_TOK_PROPERTY, EDIF_TOK_USERDATA}; static short f_ViewList[] = {EDIF_TOK_VIEWREF, EDIF_TOK_VIEWLIST}; static short f_ViewMap[] = {EDIF_TOK_PORTMAP, EDIF_TOK_PORTBACKANNOTATE, EDIF_TOK_INSTANCEMAP, EDIF_TOK_INSTANCEBACKANNOTATE, EDIF_TOK_NETMAP, EDIF_TOK_NETBACKANNOTATE, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_ViewRef[] = {EDIF_TOK_NAME, EDIF_TOK_CELLREF}; static short f_Visible[] = {EDIF_TOK_FALSE, EDIF_TOK_TRUE}; static short f_VoltageMap[] = {EDIF_TOK_MNM, EDIF_TOK_E}; static short f_WaveValue[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_E, EDIF_TOK_LOGICWAVEFORM}; static short f_Weak[] = {EDIF_TOK_NAME}; static short f_WeakJoined[] = {EDIF_TOK_PORTREF, EDIF_TOK_PORTLIST, EDIF_TOK_JOINED}; static short f_When[] = {EDIF_TOK_TRIGGER, EDIF_TOK_AFTER, EDIF_TOK_FOLLOW, EDIF_TOK_MAINTAIN, EDIF_TOK_LOGICASSIGN, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; static short f_Written[] = {EDIF_TOK_TIMESTAMP, EDIF_TOK_AUTHOR, EDIF_TOK_PROGRAM, EDIF_TOK_DATAORIGIN, EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; /* * Context binding table: * * This binds context follower arrays to their originating context. */ typedef struct Binder { short *Follower; /* pointer to follower array */ short Origin; /* '%token' value of origin */ short FollowerSize; /* size of follower array */ } Binder; #define BE(f,o) {f,o,sizeof(f)/sizeof(short)} static Binder BinderDef[] = { BE(f_NULL, 0), BE(f_Edif, EDIF_TOK_EDIF), BE(f_AcLoad, EDIF_TOK_ACLOAD), BE(f_After, EDIF_TOK_AFTER), BE(f_Annotate, EDIF_TOK_ANNOTATE), BE(f_Apply, EDIF_TOK_APPLY), BE(f_Arc, EDIF_TOK_ARC), BE(f_Array, EDIF_TOK_ARRAY), BE(f_ArrayMacro, EDIF_TOK_ARRAYMACRO), BE(f_ArrayRelatedInfo, EDIF_TOK_ARRAYRELATEDINFO), BE(f_ArraySite, EDIF_TOK_ARRAYSITE), BE(f_AtLeast, EDIF_TOK_ATLEAST), BE(f_AtMost, EDIF_TOK_ATMOST), BE(f_Becomes, EDIF_TOK_BECOMES), BE(f_Boolean, EDIF_TOK_BOOLEAN), BE(f_BooleanDisplay, EDIF_TOK_BOOLEANDISPLAY), BE(f_BooleanMap, EDIF_TOK_BOOLEANMAP), BE(f_BorderPattern, EDIF_TOK_BORDERPATTERN), BE(f_BoundingBox, EDIF_TOK_BOUNDINGBOX), BE(f_Cell, EDIF_TOK_CELL), BE(f_CellRef, EDIF_TOK_CELLREF), BE(f_Change, EDIF_TOK_CHANGE), BE(f_Circle, EDIF_TOK_CIRCLE), BE(f_Color, EDIF_TOK_COLOR), BE(f_CommentGraphics, EDIF_TOK_COMMENTGRAPHICS), BE(f_Compound, EDIF_TOK_COMPOUND), BE(f_ConnectLocation, EDIF_TOK_CONNECTLOCATION), BE(f_Contents, EDIF_TOK_CONTENTS), BE(f_Criticality, EDIF_TOK_CRITICALITY), BE(f_CurrentMap, EDIF_TOK_CURRENTMAP), BE(f_Curve, EDIF_TOK_CURVE), BE(f_Cycle, EDIF_TOK_CYCLE), BE(f_DataOrigin, EDIF_TOK_DATAORIGIN), BE(f_DcFanInLoad, EDIF_TOK_DCFANINLOAD), BE(f_DcFanOutLoad, EDIF_TOK_DCFANOUTLOAD), BE(f_DcMaxFanIn, EDIF_TOK_DCMAXFANIN), BE(f_DcMaxFanOut, EDIF_TOK_DCMAXFANOUT), BE(f_Delay, EDIF_TOK_DELAY), BE(f_Delta, EDIF_TOK_DELTA), BE(f_Design, EDIF_TOK_DESIGN), BE(f_Designator, EDIF_TOK_DESIGNATOR), BE(f_Difference, EDIF_TOK_DIFFERENCE), BE(f_Display, EDIF_TOK_DISPLAY), BE(f_Dominates, EDIF_TOK_DOMINATES), BE(f_Dot, EDIF_TOK_DOT), BE(f_Duration, EDIF_TOK_DURATION), BE(f_EnclosureDistance, EDIF_TOK_ENCLOSUREDISTANCE), BE(f_Entry, EDIF_TOK_ENTRY), BE(f_Exactly, EDIF_TOK_EXACTLY), BE(f_External, EDIF_TOK_EXTERNAL), BE(f_Fabricate, EDIF_TOK_FABRICATE), BE(f_Figure, EDIF_TOK_FIGURE), BE(f_FigureArea, EDIF_TOK_FIGUREAREA), BE(f_FigureGroup, EDIF_TOK_FIGUREGROUP), BE(f_FigureGroupObject, EDIF_TOK_FIGUREGROUPOBJECT), BE(f_FigureGroupOverride, EDIF_TOK_FIGUREGROUPOVERRIDE), BE(f_FigureGroupRef, EDIF_TOK_FIGUREGROUPREF), BE(f_FigurePerimeter, EDIF_TOK_FIGUREPERIMETER), BE(f_FigureWidth, EDIF_TOK_FIGUREWIDTH), BE(f_FillPattern, EDIF_TOK_FILLPATTERN), BE(f_Follow, EDIF_TOK_FOLLOW), BE(f_ForbiddenEvent, EDIF_TOK_FORBIDDENEVENT), BE(f_GlobalPortRef, EDIF_TOK_GLOBALPORTREF), BE(f_GreaterThan, EDIF_TOK_GREATERTHAN), BE(f_GridMap, EDIF_TOK_GRIDMAP), BE(f_IncludeFigureGroup, EDIF_TOK_INCLUDEFIGUREGROUP), BE(f_Instance, EDIF_TOK_INSTANCE), BE(f_InstanceBackAnnotate, EDIF_TOK_INSTANCEBACKANNOTATE), BE(f_InstanceGroup, EDIF_TOK_INSTANCEGROUP), BE(f_InstanceMap, EDIF_TOK_INSTANCEMAP), BE(f_InstanceRef, EDIF_TOK_INSTANCEREF), BE(f_Integer, EDIF_TOK_INTEGER), BE(f_IntegerDisplay, EDIF_TOK_INTEGERDISPLAY), BE(f_InterFigureGroupSpacing, EDIF_TOK_INTERFIGUREGROUPSPACING), BE(f_Interface, EDIF_TOK_INTERFACE), BE(f_Intersection, EDIF_TOK_INTERSECTION), BE(f_IntraFigureGroupSpacing, EDIF_TOK_INTRAFIGUREGROUPSPACING), BE(f_Inverse, EDIF_TOK_INVERSE), BE(f_Joined, EDIF_TOK_JOINED), BE(f_KeywordDisplay, EDIF_TOK_KEYWORDDISPLAY), BE(f_KeywordMap, EDIF_TOK_KEYWORDMAP), BE(f_LessThan, EDIF_TOK_LESSTHAN), BE(f_Library, EDIF_TOK_LIBRARY), BE(f_LibraryRef, EDIF_TOK_LIBRARYREF), BE(f_ListOfNets, EDIF_TOK_LISTOFNETS), BE(f_ListOfPorts, EDIF_TOK_LISTOFPORTS), BE(f_LoadDelay, EDIF_TOK_LOADDELAY), BE(f_LogicAssign, EDIF_TOK_LOGICASSIGN), BE(f_LogicInput, EDIF_TOK_LOGICINPUT), BE(f_LogicList, EDIF_TOK_LOGICLIST), BE(f_LogicMapInput, EDIF_TOK_LOGICMAPINPUT), BE(f_LogicMapOutput, EDIF_TOK_LOGICMAPOUTPUT), BE(f_LogicOneOf, EDIF_TOK_LOGICONEOF), BE(f_LogicOutput, EDIF_TOK_LOGICOUTPUT), BE(f_LogicPort, EDIF_TOK_LOGICPORT), BE(f_LogicRef, EDIF_TOK_LOGICREF), BE(f_LogicValue, EDIF_TOK_LOGICVALUE), BE(f_LogicWaveform, EDIF_TOK_LOGICWAVEFORM), BE(f_Maintain, EDIF_TOK_MAINTAIN), BE(f_Match, EDIF_TOK_MATCH), BE(f_Member, EDIF_TOK_MEMBER), BE(f_MiNoMax, EDIF_TOK_MINOMAX), BE(f_MiNoMaxDisplay, EDIF_TOK_MINOMAXDISPLAY), BE(f_Mnm, EDIF_TOK_MNM), BE(f_MultipleValueSet, EDIF_TOK_MULTIPLEVALUESET), BE(f_MustJoin, EDIF_TOK_MUSTJOIN), BE(f_Name, EDIF_TOK_NAME), BE(f_Net, EDIF_TOK_NET), BE(f_NetBackAnnotate, EDIF_TOK_NETBACKANNOTATE), BE(f_NetBundle, EDIF_TOK_NETBUNDLE), BE(f_NetDelay, EDIF_TOK_NETDELAY), BE(f_NetGroup, EDIF_TOK_NETGROUP), BE(f_NetMap, EDIF_TOK_NETMAP), BE(f_NetRef, EDIF_TOK_NETREF), BE(f_NonPermutable, EDIF_TOK_NONPERMUTABLE), BE(f_NotAllowed, EDIF_TOK_NOTALLOWED), BE(f_NotchSpacing, EDIF_TOK_NOTCHSPACING), BE(f_Number, EDIF_TOK_NUMBER), BE(f_NumberDefinition, EDIF_TOK_NUMBERDEFINITION), BE(f_NumberDisplay, EDIF_TOK_NUMBERDISPLAY), BE(f_OffPageConnector, EDIF_TOK_OFFPAGECONNECTOR), BE(f_OffsetEvent, EDIF_TOK_OFFSETEVENT), BE(f_OpenShape, EDIF_TOK_OPENSHAPE), BE(f_Origin, EDIF_TOK_ORIGIN), BE(f_OverhangDistance, EDIF_TOK_OVERHANGDISTANCE), BE(f_OverlapDistance, EDIF_TOK_OVERLAPDISTANCE), BE(f_Oversize, EDIF_TOK_OVERSIZE), BE(f_Page, EDIF_TOK_PAGE), BE(f_PageSize, EDIF_TOK_PAGESIZE), BE(f_Parameter, EDIF_TOK_PARAMETER), BE(f_ParameterAssign, EDIF_TOK_PARAMETERASSIGN), BE(f_ParameterDisplay, EDIF_TOK_PARAMETERDISPLAY), BE(f_Path, EDIF_TOK_PATH), BE(f_PathDelay, EDIF_TOK_PATHDELAY), BE(f_Permutable, EDIF_TOK_PERMUTABLE), BE(f_PhysicalDesignRule, EDIF_TOK_PHYSICALDESIGNRULE), BE(f_Plug, EDIF_TOK_PLUG), BE(f_Point, EDIF_TOK_POINT), BE(f_PointDisplay, EDIF_TOK_POINTDISPLAY), BE(f_PointList, EDIF_TOK_POINTLIST), BE(f_Polygon, EDIF_TOK_POLYGON), BE(f_Port, EDIF_TOK_PORT), BE(f_PortBackAnnotate, EDIF_TOK_PORTBACKANNOTATE), BE(f_PortBundle, EDIF_TOK_PORTBUNDLE), BE(f_PortDelay, EDIF_TOK_PORTDELAY), BE(f_PortGroup, EDIF_TOK_PORTGROUP), BE(f_PortImplementation, EDIF_TOK_PORTIMPLEMENTATION), BE(f_PortInstance, EDIF_TOK_PORTINSTANCE), BE(f_PortList, EDIF_TOK_PORTLIST), BE(f_PortListAlias, EDIF_TOK_PORTLISTALIAS), BE(f_PortMap, EDIF_TOK_PORTMAP), BE(f_PortRef, EDIF_TOK_PORTREF), BE(f_Program, EDIF_TOK_PROGRAM), BE(f_Property, EDIF_TOK_PROPERTY), BE(f_PropertyDisplay, EDIF_TOK_PROPERTYDISPLAY), BE(f_ProtectionFrame, EDIF_TOK_PROTECTIONFRAME), BE(f_RangeVector, EDIF_TOK_RANGEVECTOR), BE(f_Rectangle, EDIF_TOK_RECTANGLE), BE(f_RectangleSize, EDIF_TOK_RECTANGLESIZE), BE(f_Rename, EDIF_TOK_RENAME), BE(f_Resolves, EDIF_TOK_RESOLVES), BE(f_Scale, EDIF_TOK_SCALE), BE(f_Section, EDIF_TOK_SECTION), BE(f_Shape, EDIF_TOK_SHAPE), BE(f_Simulate, EDIF_TOK_SIMULATE), BE(f_SimulationInfo, EDIF_TOK_SIMULATIONINFO), BE(f_SingleValueSet, EDIF_TOK_SINGLEVALUESET), BE(f_Site, EDIF_TOK_SITE), BE(f_Socket, EDIF_TOK_SOCKET), BE(f_SocketSet, EDIF_TOK_SOCKETSET), BE(f_Status, EDIF_TOK_STATUS), BE(f_Steady, EDIF_TOK_STEADY), BE(f_String, EDIF_TOK_STRING), BE(f_StringDisplay, EDIF_TOK_STRINGDISPLAY), BE(f_Strong, EDIF_TOK_STRONG), BE(f_Symbol, EDIF_TOK_SYMBOL), BE(f_Symmetry, EDIF_TOK_SYMMETRY), BE(f_Table, EDIF_TOK_TABLE), BE(f_TableDefault, EDIF_TOK_TABLEDEFAULT), BE(f_Technology, EDIF_TOK_TECHNOLOGY), BE(f_TimeInterval, EDIF_TOK_TIMEINTERVAL), BE(f_Timing, EDIF_TOK_TIMING), BE(f_Transform, EDIF_TOK_TRANSFORM), BE(f_Transition, EDIF_TOK_TRANSITION), BE(f_Trigger, EDIF_TOK_TRIGGER), BE(f_Union, EDIF_TOK_UNION), BE(f_View, EDIF_TOK_VIEW), BE(f_ViewList, EDIF_TOK_VIEWLIST), BE(f_ViewMap, EDIF_TOK_VIEWMAP), BE(f_ViewRef, EDIF_TOK_VIEWREF), BE(f_Visible, EDIF_TOK_VISIBLE), BE(f_VoltageMap, EDIF_TOK_VOLTAGEMAP), BE(f_WaveValue, EDIF_TOK_WAVEVALUE), BE(f_Weak, EDIF_TOK_WEAK), BE(f_WeakJoined, EDIF_TOK_WEAKJOINED), BE(f_When, EDIF_TOK_WHEN), BE(f_Written, EDIF_TOK_WRITTEN) }; static int BinderDefSize = sizeof(BinderDef) / sizeof(Binder); /* * Keyword table: * * This hash table holds all strings which may have to be matched * to. WARNING: it is assumed that there is no overlap of the 'token' * and 'context' strings. */ typedef struct Keyword { struct Keyword *Next; /* pointer to next entry */ char *String; /* pointer to associated string */ } Keyword; #define KEYWORD_HASH 127 /* hash table size */ static Keyword *KeywordTable[KEYWORD_HASH]; /* * Enter keyword: * * The passed string is entered into the keyword hash table. */ static void EnterKeyword(char * str) { /* * Locals. */ register Keyword *key; register unsigned int hsh; register char *cp; /* * Create the hash code, and add an entry to the table. */ for (hsh = 0, cp = str; *cp; hsh += hsh + *cp++); hsh %= KEYWORD_HASH; key = (Keyword *) Malloc(sizeof(Keyword)); key->Next = KeywordTable[hsh]; (KeywordTable[hsh] = key)->String = str; } /* * Find keyword: * * The passed string is located within the keyword table. If an * entry exists, then the value of the keyword string is returned. This * is real useful for doing string comparisons by pointer value later. * If there is no match, a NULL is returned. */ static char *FindKeyword(char * str) { /* * Locals. */ register Keyword *wlk,*owk; register unsigned int hsh; register char *cp; char lower[IDENT_LENGTH + 1]; /* * Create a lower case copy of the string. */ for (cp = lower; *str;) if (isupper( (int) *str)) *cp++ = tolower( (int) *str++); else *cp++ = *str++; *cp = '\0'; /* * Search the hash table for a match. */ for (hsh = 0, cp = lower; *cp; hsh += hsh + *cp++); hsh %= KEYWORD_HASH; for (owk = NULL, wlk = KeywordTable[hsh]; wlk; wlk = (owk = wlk)->Next) if (!strcmp(wlk->String,lower)){ /* * Readjust the LRU. */ if (owk){ owk->Next = wlk->Next; wlk->Next = KeywordTable[hsh]; KeywordTable[hsh] = wlk; } return (wlk->String); } return (NULL); } /* * Token hash table. */ #define TOKEN_HASH 51 static Token *TokenHash[TOKEN_HASH]; /* * Find token: * * A pointer to the token of the passed code is returned. If * no such beastie is present a NULL is returned instead. */ static Token *FindToken(register int cod) { /* * Locals. */ register Token *wlk,*owk; register unsigned int hsh; /* * Search the hash table for a matching token. */ hsh = cod % TOKEN_HASH; for (owk = NULL, wlk = TokenHash[hsh]; wlk; wlk = (owk = wlk)->Next) if (cod == wlk->Code){ if (owk){ owk->Next = wlk->Next; wlk->Next = TokenHash[hsh]; TokenHash[hsh] = wlk; } break; } return (wlk); } /* * Context hash table. */ #define CONTEXT_HASH 127 static Context *ContextHash[CONTEXT_HASH]; /* * Find context: * * A pointer to the context of the passed code is returned. If * no such beastie is present a NULL is returned instead. */ static Context *FindContext(register int cod) { /* * Locals. */ register Context *wlk,*owk; register unsigned int hsh; /* * Search the hash table for a matching context. */ hsh = cod % CONTEXT_HASH; for (owk = NULL, wlk = ContextHash[hsh]; wlk; wlk = (owk = wlk)->Next) if (cod == wlk->Code){ if (owk){ owk->Next = wlk->Next; wlk->Next = ContextHash[hsh]; ContextHash[hsh] = wlk; } break; } return (wlk); } /* * Parser state variables. */ static FILE *Input = NULL; /* input stream */ static FILE *Error = NULL; /* error stream */ static char *InFile; /* file name on the input stream */ static long LineNumber; /* current input line number */ static ContextCar *CSP = NULL; /* top of context stack */ static char yytext[IDENT_LENGTH + 1]; /* token buffer */ static char CharBuf[IDENT_LENGTH + 1]; /* garbage buffer */ /* * Token stacking variables. */ #ifdef DEBUG #define TS_DEPTH 8 #define TS_MASK (TS_DEPTH - 1) static unsigned int TSP = 0; /* token stack pointer */ static char *TokenStack[TS_DEPTH]; /* token name strings */ static short TokenType[TS_DEPTH]; /* token types */ /* * Stack: * * Add a token to the debug stack. The passed string and type are * what is to be pushed. */ static int Stack(char * str, int typ) { /* * Free any previous string, then push. */ if (TokenStack[TSP & TS_MASK]) Free(TokenStack[TSP & TS_MASK]); TokenStack[TSP & TS_MASK] = strcpy((char *)Malloc(strlen(str) + 1),str); TokenType[TSP & TS_MASK] = typ; TSP += 1; return 0; } /* * Dump stack: * * This displays the last set of accumulated tokens. */ static int DumpStack() { /* * Locals. */ register int i; register Context *cxt; register Token *tok; register char *nam; /* * Run through the list displaying the oldest first. */ fprintf(Error,"\n\n"); for (i = 0; i < TS_DEPTH; i += 1) if (TokenStack[(TSP + i) & TS_MASK]){ /* * Get the type name string. */ if ((cxt = FindContext(TokenType[(TSP + i) & TS_MASK]))) nam = cxt->Name; else if ((tok = FindToken(TokenType[(TSP + i) & TS_MASK]))) nam = tok->Name; else switch (TokenType[(TSP + i) & TS_MASK]){ case EDIF_TOK_IDENT: nam = "IDENT"; break; case EDIF_TOK_INT: nam = "INT"; break; case EDIF_TOK_KEYWORD: nam = "KEYWORD"; break; case EDIF_TOK_STR: nam = "STR"; break; default: nam = "?"; break; } /* * Now print the token state. */ fprintf(Error,"%2d %-16.16s '%s'\n",TS_DEPTH - i,nam, TokenStack[(TSP + i) & TS_MASK]); } fprintf(Error,"\n"); return 0; } #else #define Stack(s,t) #endif /* DEBUG */ /* * yyerror: * * Standard error reporter, it prints out the passed string * preceeded by the current filename and line number. */ static void yyerror(const char *ers) { #ifdef DEBUG DumpStack(); #endif /* DEBUG */ fprintf(Error,"%s, line %ld: %s\n",InFile,LineNumber,ers); } /* * String bucket definitions. */ #define BUCKET_SIZE 64 typedef struct Bucket { struct Bucket *Next; /* pointer to next bucket */ int Index; /* pointer to next free slot */ char Data[BUCKET_SIZE]; /* string data */ } Bucket; static Bucket *CurrentBucket = NULL; /* string bucket list */ static int StringSize = 0; /* current string length */ /* * Push string: * * This adds the passed charater to the current string bucket. */ static void PushString(char chr) { /* * Locals. */ register Bucket *bck; /* * Make sure there is room for the push. */ if ((bck = CurrentBucket)->Index >= BUCKET_SIZE){ bck = (Bucket *) Malloc(sizeof(Bucket)); bck->Next = CurrentBucket; (CurrentBucket = bck)->Index = 0; } /* * Push the character. */ bck->Data[bck->Index++] = chr; StringSize += 1; } /* * Form string: * * This converts the current string bucket into a real live string, * whose pointer is returned. */ static char *FormString() { /* * Locals. */ register Bucket *bck; register char *cp; /* * Allocate space for the string, set the pointer at the end. */ cp = (char *) Malloc(StringSize + 1); cp += StringSize; *cp-- = '\0'; /* * Yank characters out of the bucket. */ for (bck = CurrentBucket; bck->Index || bck->Next;){ if (!bck->Index){ CurrentBucket = bck->Next; Free(bck); bck = CurrentBucket; } *cp-- = bck->Data[--bck->Index]; } /* reset buffer size to zero */ StringSize =0; return (cp + 1); } /* * Parse EDIF: * * This builds the context tree and then calls the real parser. * It is passed two file streams, the first is where the input comes * from; the second is where error messages get printed. */ void ParseEDIF(char* filename,FILE* err) { /* * Locals. */ register int i; static int ContextDefined = 1; /* * Set up the file state to something useful. */ InFile = filename; Input = fopen(filename,"r"); Error = err; LineNumber = 1; /* * Define both the enabled token and context strings. */ if (ContextDefined){ for (i = TokenDefSize; i--; EnterKeyword(TokenDef[i].Name)){ register unsigned int hsh; hsh = TokenDef[i].Code % TOKEN_HASH; TokenDef[i].Next = TokenHash[hsh]; TokenHash[hsh] = &TokenDef[i]; } for (i = ContextDefSize; i--; EnterKeyword(ContextDef[i].Name)){ register unsigned int hsh; hsh = ContextDef[i].Code % CONTEXT_HASH; ContextDef[i].Next = ContextHash[hsh]; ContextHash[hsh] = &ContextDef[i]; } /* * Build the context tree. */ for (i = BinderDefSize; i--;){ register Context *cxt; register int j; /* * Define the current context to have carriers bound to it. */ cxt = FindContext(BinderDef[i].Origin); for (j = BinderDef[i].FollowerSize; j--;){ register ContextCar *cc; /* * Add carriers to the current context. */ cc = (ContextCar *) Malloc(sizeof(ContextCar)); cc->Next = cxt->Context; (cxt->Context = cc)->Context = FindContext(ABS(BinderDef[i].Follower[j])); cc->u.Single = BinderDef[i].Follower[j] < 0; } } /* * Build the token tree. */ for (i = TieDefSize; i--;){ register Context *cxt; register int j; /* * Define the current context to have carriers bound to it. */ cxt = FindContext(TieDef[i].Origin); for (j = TieDef[i].EnableSize; j--;){ register TokenCar *tc; /* * Add carriers to the current context. */ tc = (TokenCar *) Malloc(sizeof(TokenCar)); tc->Next = cxt->Token; (cxt->Token = tc)->Token = FindToken(TieDef[i].Enable[j]); } } /* * Put a bogus context on the stack which has 'EDIF' as its * follower. */ CSP = (ContextCar *) Malloc(sizeof(ContextCar)); CSP->Next = NULL; CSP->Context = FindContext(0); CSP->u.Used = NULL; ContextDefined = 0; } /* * Create an initial, empty string bucket. */ CurrentBucket = (Bucket *) Malloc(sizeof(Bucket)); CurrentBucket->Next = 0; CurrentBucket->Index = 0; /* * Fill the token stack with NULLs if debugging is enabled. */ #ifdef DEBUG for (i = TS_DEPTH; i--; TokenStack[i] = NULL) if (TokenStack[i]) Free(TokenStack[i]); TSP = 0; #endif /* DEBUG */ /* * Go parse things! */ edifparse(); } /* * Match token: * * The passed string is looked up in the current context's token * list to see if it is enabled. If so the token value is returned, * if not then zero. */ static int MatchToken(register char * str) { /* * Locals. */ register TokenCar *wlk,*owk; /* * Convert the string to the proper form, then search the token * carrier list for a match. */ str = FindKeyword(str); for (owk = NULL, wlk = CSP->Context->Token; wlk; wlk = (owk = wlk)->Next) if (str == wlk->Token->Name){ if (owk){ owk->Next = wlk->Next; wlk->Next = CSP->Context->Token; CSP->Context->Token = wlk; } return (wlk->Token->Code); } return (0); } /* * Match context: * * If the passed keyword string is within the current context, the * new context is pushed and token value is returned. A zero otherwise. */ static int MatchContext(register char * str) { /* * Locals. */ register ContextCar *wlk,*owk; /* * See if the context is present. */ str = FindKeyword(str); for (owk = NULL, wlk = CSP->Context->Context; wlk; wlk = (owk = wlk)->Next) if (str == wlk->Context->Name){ if (owk){ owk->Next = wlk->Next; wlk->Next = CSP->Context->Context; CSP->Context->Context = wlk; } /* * If a single context, make sure it isn't already used. */ if (wlk->u.Single){ register UsedCar *usc; for (usc = CSP->u.Used; usc; usc = usc->Next) if (usc->Code == wlk->Context->Code) break; if (usc){ sprintf(CharBuf,"'%s' is used more than once within '%s'", str,CSP->Context->Name); yyerror(CharBuf); } else { usc = (UsedCar *) Malloc(sizeof(UsedCar)); usc->Next = CSP->u.Used; (CSP->u.Used = usc)->Code = wlk->Context->Code; } } /* * Push the new context. */ owk = (ContextCar *) Malloc(sizeof(ContextCar)); owk->Next = CSP; (CSP = owk)->Context = wlk->Context; owk->u.Used = NULL; return (wlk->Context->Code); } return (0); } /* * PopC: * * This pops the current context. */ static void PopC() { /* * Locals. */ register UsedCar *usc; register ContextCar *csp; /* * Release single markers and pop context. */ while ( (usc = CSP->u.Used) ){ CSP->u.Used = usc->Next; Free(usc); } csp = CSP->Next; Free(CSP); CSP = csp; } /* * Lexical analyzer states. */ #define L_START 0 #define L_INT 1 #define L_IDENT 2 #define L_KEYWORD 3 #define L_STRING 4 #define L_KEYWORD2 5 #define L_ASCIICHAR 6 #define L_ASCIICHAR2 7 /* * yylex: * * This is the lexical analyzer called by the YACC/BISON parser. * It returns a pretty restricted set of token types and does the * context movement when acceptable keywords are found. The token * value returned is a NULL terminated string to allocated storage * (ie - it should get released some time) with some restrictions. * The token value for integers is strips a leading '+' if present. * String token values have the leading and trailing '"'-s stripped. * '%' conversion characters in string values are passed converted. * The '(' and ')' characters do not have a token value. */ static int yylex() { /* * Locals. */ register int c,s,l; /* * Keep on sucking up characters until we find something which * explicitly forces us out of this function. */ for (s = L_START, l = 0; 1;){ yytext[l++] = c = Getc(Input); switch (s){ /* * Starting state, look for something resembling a token. */ case L_START: if (isdigit(c) || c == '-') s = L_INT; else if (isalpha(c) || c == '&') s = L_IDENT; else if (isspace(c)){ if (c == '\n') LineNumber += 1; l = 0; } else if (c == '('){ l = 0; s = L_KEYWORD; } else if (c == '"') s = L_STRING; else if (c == '+'){ l = 0; /* strip '+' */ s = L_INT; } else if (c == EOF) return ('\0'); else { yytext[1] = '\0'; Stack(yytext,c); return (c); } break; /* * Suck up the integer digits. */ case L_INT: if (isdigit(c)) break; Ungetc(c); yytext[--l] = '\0'; yylval.s = strcpy((char *)Malloc(l + 1),yytext); Stack(yytext,EDIF_TOK_INT); return (EDIF_TOK_INT); /* * Grab an identifier, see if the current context enables * it with a specific token value. */ case L_IDENT: if (isalpha(c) || isdigit(c) || c == '_') break; Ungetc(c); yytext[--l] = '\0'; if (CSP->Context->Token && (c = MatchToken(yytext))){ Stack(yytext,c); return (c); } yylval.s = strcpy((char *)Malloc(l + 1),yytext); Stack(yytext, EDIF_TOK_IDENT); return (EDIF_TOK_IDENT); /* * Scan until you find the start of an identifier, discard * any whitespace found. On no identifier, return a '('. */ case L_KEYWORD: if (isalpha(c) || c == '&'){ s = L_KEYWORD2; break; } else if (isspace(c)){ l = 0; break; } Ungetc(c); Stack("(",'('); return ('('); /* * Suck up the keyword identifier, if it matches the set of * allowable contexts then return its token value and push * the context, otherwise just return the identifier string. */ case L_KEYWORD2: if (isalpha(c) || isdigit(c) || c == '_') break; Ungetc(c); yytext[--l] = '\0'; if ( (c = MatchContext(yytext)) ){ Stack(yytext,c); return (c); } yylval.s = strcpy((char *)Malloc(l + 1),yytext); Stack(yytext, EDIF_TOK_KEYWORD); return (EDIF_TOK_KEYWORD); /* * Suck up string characters but once resolved they should * be deposited in the string bucket because they can be * arbitrarily long. */ case L_STRING: if (c == '\n') LineNumber += 1; else if (c == '\r') ; else if (c == '"' || c == EOF){ yylval.s = FormString(); Stack(yylval.s, EDIF_TOK_STR); return (EDIF_TOK_STR); } else if (c == '%') s = L_ASCIICHAR; else PushString(c); l = 0; break; /* * Skip white space and look for integers to be pushed * as characters. */ case L_ASCIICHAR: if (isdigit(c)){ s = L_ASCIICHAR2; break; } else if (c == '%' || c == EOF) s = L_STRING; else if (c == '\n') LineNumber += 1; l = 0; break; /* * Convert the accumulated integer into a char and push. */ case L_ASCIICHAR2: if (isdigit(c)) break; Ungetc(c); yytext[--l] = '\0'; PushString(atoi(yytext)); s = L_ASCIICHAR; l = 0; break; } } } pcb-4.3.0/src/thermal.c0000664000175000017500000004102113773431044011600 00000000000000/*! * \file src/thermal.c * * \brief Negative thermal finger polygons. * * Thermals are normal lines on the layout * * The only thing unique about them is that they have the USETHERMALFLAG * set so that they can be identified as thermals. * * It is handy for pcb to automatically make adjustments to the thermals * when the user performs certain operations, and the functions in * thermal.h help implement that. * * \author This file, thermal.c was written by and is * (C) Copyright 2006, harry eaton * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996,2004,2006 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * * Thomas.Nau@rz.uni-ulm.de */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #ifdef HAVE_STRING_H #include #endif #include #include #include #include #include #include #include #include #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_PWD_H #include #endif #include "global.h" #include "create.h" #include "data.h" #include "draw.h" #include "error.h" #include "misc.h" #include "move.h" #include "polygon.h" #include "rtree.h" #include "thermal.h" #include "undo.h" #ifdef HAVE_LIBDMALLOC #include #endif static PCBType *pcb; struct cent { Coord x, y; Coord s, c; char style; POLYAREA *p; }; static POLYAREA * diag_line (Coord X, Coord Y, Coord l, Coord w, bool rt) { PLINE *c; Vector v; Coord x1, x2, y1, y2; if (rt) { x1 = (l - w) * M_SQRT1_2; x2 = (l + w) * M_SQRT1_2; y1 = x1; y2 = x2; } else { x2 = -(l - w) * M_SQRT1_2; x1 = -(l + w) * M_SQRT1_2; y1 = -x1; y2 = -x2; } v[0] = X + x1; v[1] = Y + y2; if ((c = poly_NewContour (v)) == NULL) return NULL; v[0] = X - x2; v[1] = Y - y1; poly_InclVertex (c->head.prev, poly_CreateNode (v)); v[0] = X - x1; v[1] = Y - y2; poly_InclVertex (c->head.prev, poly_CreateNode (v)); v[0] = X + x2; v[1] = Y + y1; poly_InclVertex (c->head.prev, poly_CreateNode (v)); return ContourToPoly (c); } static POLYAREA * square_therm (PinType *pin, Cardinal style) { POLYAREA *p, *p2; PLINE *c; Vector v; Coord d, in, out; switch (style) { case 1: /* This is the style where the thermals come out of the corners of the * square. We create this by removing four trapezoids from the polygon. * * The d variable is the offset from the corner of the pad/cutout required * to produce the diagonal line of the appropriate thickness. If you draw * a hypotenuse of length (clearance * thermscale) in the corner of the * square, you create a 1:1:sqrt(2) triangle. The length of the "1" sides * is the width of the line divided by the sqrt(2). * */ d = pcb->ThermScale * pin->Clearance * M_SQRT1_2; out = (pin->Thickness + pin->Clearance) / 2; in = pin->Thickness / 2; /* top (actually bottom since +y is down) */ v[0] = pin->X - in + d; v[1] = pin->Y + in; if ((c = poly_NewContour (v)) == NULL) return NULL; v[0] = pin->X + in - d; poly_InclVertex (c->head.prev, poly_CreateNode (v)); v[0] = pin->X + out - d; v[1] = pin->Y + out; poly_InclVertex (c->head.prev, poly_CreateNode (v)); v[0] = pin->X - out + d; poly_InclVertex (c->head.prev, poly_CreateNode (v)); p = ContourToPoly (c); /* right */ v[0] = pin->X + in; v[1] = pin->Y + in - d; if ((c = poly_NewContour (v)) == NULL) return NULL; v[1] = pin->Y - in + d; poly_InclVertex (c->head.prev, poly_CreateNode (v)); v[0] = pin->X + out; v[1] = pin->Y - out + d; poly_InclVertex (c->head.prev, poly_CreateNode (v)); v[1] = pin->Y + out - d; poly_InclVertex (c->head.prev, poly_CreateNode (v)); p2 = ContourToPoly (c); p->f = p2; p2->b = p; /* left */ v[0] = pin->X - in; v[1] = pin->Y - in + d; if ((c = poly_NewContour (v)) == NULL) return NULL; v[1] = pin->Y + in - d; poly_InclVertex (c->head.prev, poly_CreateNode (v)); v[0] = pin->X - out; v[1] = pin->Y + out - d; poly_InclVertex (c->head.prev, poly_CreateNode (v)); v[1] = pin->Y - out + d; poly_InclVertex (c->head.prev, poly_CreateNode (v)); p2 = ContourToPoly (c); p->f->f = p2; p2->b = p->f; /* bottom (actually top since +y is down) */ v[0] = pin->X + in - d; v[1] = pin->Y - in; if ((c = poly_NewContour (v)) == NULL) return NULL; v[0] = pin->X - in + d; poly_InclVertex (c->head.prev, poly_CreateNode (v)); v[0] = pin->X - out + d; v[1] = pin->Y - out; poly_InclVertex (c->head.prev, poly_CreateNode (v)); v[0] = pin->X + out - d; poly_InclVertex (c->head.prev, poly_CreateNode (v)); p2 = ContourToPoly (c); p->f->f->f = p2; p2->f = p; p2->b = p->f->f; p->b = p2; return p; case 4: { /* This version has four lines coming out of the corners, but the edges * are all rounded. It's created by subtracting four lines from the * polygon that run along the edge pin. * */ LineType l; l.Flags = NoFlags (); d = pin->Thickness / 2 - pcb->ThermScale * pin->Clearance; out = pin->Thickness / 2 + pin->Clearance / 4; in = pin->Clearance / 2; /* top */ l.Point1.X = pin->X - d; l.Point2.Y = l.Point1.Y = pin->Y + out; l.Point2.X = pin->X + d; p = LinePoly (&l, in); /* right */ l.Point1.X = l.Point2.X = pin->X + out; l.Point1.Y = pin->Y - d; l.Point2.Y = pin->Y + d; p2 = LinePoly (&l, in); p->f = p2; p2->b = p; /* bottom */ l.Point1.X = pin->X - d; l.Point2.Y = l.Point1.Y = pin->Y - out; l.Point2.X = pin->X + d; p2 = LinePoly (&l, in); p->f->f = p2; p2->b = p->f; /* left */ l.Point1.X = l.Point2.X = pin->X - out; l.Point1.Y = pin->Y - d; l.Point2.Y = pin->Y + d; p2 = LinePoly (&l, in); p->f->f->f = p2; p2->b = p->f->f; p->b = p2; p2->f = p; return p; } default: /* style 2 and 5 */ /* These styles have the fingers coming out the top, bottom and sides. We * create these by carving out contours around the corners. If we're doing * style 5, the corners are square, and if we're doing style 2, the * corners are round. * */ d = 0.5 * pcb->ThermScale * pin->Clearance; if (style == 5) d += d; out = (pin->Thickness + pin->Clearance) / 2; in = pin->Thickness / 2; /* "top" right */ /* Start at the lower right hand corner of the pin. */ v[0] = pin->X + in; v[1] = pin->Y + in; if ((c = poly_NewContour (v)) == NULL) return NULL; /* Move up to the point where the bottom of the right finger meets the * pin. If we're doing round corners, d is bigger to account for the arc * */ v[1] = pin->Y + d; poly_InclVertex (c->head.prev, poly_CreateNode (v)); /* Either go straight or arc over to the point where the lower edge of the * right finger meets the bulk of the polygon. * */ if (style == 2) { v[0] = pin->X + out; poly_InclVertex (c->head.prev, poly_CreateNode (v)); } else frac_circle (c, v[0] + pin->Clearance / 4, v[1], v, 2); /* Move to the bottom right corner. Both styles use arcs around the outer * corners, so, arc around to the bottom edge. */ v[1] = pin->Y + in; poly_InclVertex (c->head.prev, poly_CreateNode (v)); /* pivot 1/4 circle to next point */ frac_circle (c, pin->X + in, pin->Y + in, v, 4); /* The corner where the right side of the bottom finger meets the bulk of * the polygon. If we're doing the rounded style, this has already been * adjusted for the raidus of the arc. * */ v[0] = pin->X + d; poly_InclVertex (c->head.prev, poly_CreateNode (v)); /* Either straight, or arc to the point where the right side of the bottom * finger meets the pad. * */ if (style == 2) { poly_InclVertex (c->head.prev, poly_CreateNode (v)); v[1] = pin->Y + in; poly_InclVertex (c->head.prev, poly_CreateNode (v)); } else frac_circle (c, v[0], v[1] - pin->Clearance / 4, v, 2); /* We don't have to add the starting vertext a second time, so, we're * done! */ p = ContourToPoly (c); /* Now do the other three corners... */ /* "bottom" right */ v[0] = pin->X + in; v[1] = pin->Y - d; if ((c = poly_NewContour (v)) == NULL) return NULL; v[1] = pin->Y - in; poly_InclVertex (c->head.prev, poly_CreateNode (v)); v[0] = pin->X + d; poly_InclVertex (c->head.prev, poly_CreateNode (v)); if (style == 2) { v[1] = pin->Y - out; poly_InclVertex (c->head.prev, poly_CreateNode (v)); } else frac_circle (c, v[0], v[1] - pin->Clearance / 4, v, 2); v[0] = pin->X + in; poly_InclVertex (c->head.prev, poly_CreateNode (v)); /* pivot 1/4 circle to next point */ frac_circle (c, pin->X + in, pin->Y - in, v, 4); v[1] = pin->Y - d; poly_InclVertex (c->head.prev, poly_CreateNode (v)); if (style == 5) frac_circle (c, v[0] - pin->Clearance / 4, v[1], v, 2); p2 = ContourToPoly (c); p->f = p2; p2->b = p; /* "bottom" left */ v[0] = pin->X - d; v[1] = pin->Y - in; if ((c = poly_NewContour (v)) == NULL) return NULL; v[0] = pin->X - in; poly_InclVertex (c->head.prev, poly_CreateNode (v)); v[1] = pin->Y - d; poly_InclVertex (c->head.prev, poly_CreateNode (v)); if (style == 2) { v[0] = pin->X - out; poly_InclVertex (c->head.prev, poly_CreateNode (v)); } else frac_circle (c, v[0] - pin->Clearance / 4, v[1], v, 2); v[1] = pin->Y - in; poly_InclVertex (c->head.prev, poly_CreateNode (v)); /* pivot 1/4 circle to next point */ frac_circle (c, pin->X - in, pin->Y - in, v, 4); v[0] = pin->X - d; poly_InclVertex (c->head.prev, poly_CreateNode (v)); if (style == 5) frac_circle (c, v[0], v[1] + pin->Clearance / 4, v, 2); p2 = ContourToPoly (c); p->f->f = p2; p2->b = p->f; /* "top" left */ v[0] = pin->X - d; v[1] = pin->Y + out; if ((c = poly_NewContour (v)) == NULL) return NULL; v[0] = pin->X - in; poly_InclVertex (c->head.prev, poly_CreateNode (v)); /* pivot 1/4 circle to next point (x-out, y+in) */ frac_circle (c, pin->X - in, pin->Y + in, v, 4); v[1] = pin->Y + d; poly_InclVertex (c->head.prev, poly_CreateNode (v)); if (style == 2) { v[0] = pin->X - in; poly_InclVertex (c->head.prev, poly_CreateNode (v)); } else frac_circle (c, v[0] + pin->Clearance / 4, v[1], v, 2); v[1] = pin->Y + in; poly_InclVertex (c->head.prev, poly_CreateNode (v)); v[0] = pin->X - d; poly_InclVertex (c->head.prev, poly_CreateNode (v)); if (style == 5) frac_circle (c, v[0], v[1] + pin->Clearance / 4, v, 2); p2 = ContourToPoly (c); p->f->f->f = p2; p2->f = p; p2->b = p->f->f; p->b = p2; return p; } } static POLYAREA * oct_therm (PinType *pin, Cardinal style) { POLYAREA *p, *p2, *m; Coord t = 0.5 * pcb->ThermScale * pin->Clearance; Coord w = pin->Thickness + pin->Clearance; p = OctagonPoly (pin->X, pin->Y, w); p2 = OctagonPoly (pin->X, pin->Y, pin->Thickness); /* make full clearance ring */ poly_Boolean_free (p, p2, &m, PBO_SUB); switch (style) { default: case 1: p = diag_line (pin->X, pin->Y, w, t, true); poly_Boolean_free (m, p, &p2, PBO_SUB); p = diag_line (pin->X, pin->Y, w, t, false); poly_Boolean_free (p2, p, &m, PBO_SUB); return m; case 2: p = RectPoly (pin->X - t, pin->X + t, pin->Y - w, pin->Y + w); poly_Boolean_free (m, p, &p2, PBO_SUB); p = RectPoly (pin->X - w, pin->X + w, pin->Y - t, pin->Y + t); poly_Boolean_free (p2, p, &m, PBO_SUB); return m; /* fix me add thermal style 4 */ case 5: { Coord t = pin->Thickness / 2; POLYAREA *q; /* cheat by using the square therm's rounded parts */ p = square_therm (pin, style); q = RectPoly (pin->X - t, pin->X + t, pin->Y - t, pin->Y + t); poly_Boolean_free (p, q, &p2, PBO_UNITE); poly_Boolean_free (m, p2, &p, PBO_ISECT); return p; } } } /*! * \brief . * * \return ThermPoly returns a POLYAREA having all of the clearance that * when subtracted from the plane create the desired thermal fingers. * Usually this is 4 disjoint regions. */ POLYAREA * ThermPoly (PCBType *p, PinType *pin, Cardinal laynum) { ArcType a; POLYAREA *pa, *arc; Cardinal style = GET_THERM (laynum, pin); if (style == 3) return NULL; /* solid connection no clearance */ pcb = p; if (TEST_FLAG (SQUAREFLAG, pin)) return square_therm (pin, style); if (TEST_FLAG (OCTAGONFLAG, pin)) return oct_therm (pin, style); /* must be circular */ switch (style) { case 1: case 2: { POLYAREA *m; Coord t = (pin->Thickness + pin->Clearance) / 2; Coord w = 0.5 * pcb->ThermScale * pin->Clearance; pa = CirclePoly (pin->X, pin->Y, t); arc = CirclePoly (pin->X, pin->Y, pin->Thickness / 2); /* create a thin ring */ poly_Boolean_free (pa, arc, &m, PBO_SUB); /* fix me needs error checking */ if (style == 2) { /* t is the theoretically required length, but we use twice that * to avoid descritisation errors in our circle approximation. */ pa = RectPoly (pin->X - t * 2, pin->X + t * 2, pin->Y - w, pin->Y + w); poly_Boolean_free (m, pa, &arc, PBO_SUB); pa = RectPoly (pin->X - w, pin->X + w, pin->Y - t * 2, pin->Y + t * 2); } else { /* t is the theoretically required length, but we use twice that * to avoid descritisation errors in our circle approximation. */ pa = diag_line (pin->X, pin->Y, t * 2, w, true); poly_Boolean_free (m, pa, &arc, PBO_SUB); pa = diag_line (pin->X, pin->Y, t * 2, w, false); } poly_Boolean_free (arc, pa, &m, PBO_SUB); return m; } default: a.X = pin->X; a.Y = pin->Y; a.Height = a.Width = pin->Thickness / 2 + pin->Clearance / 4; a.Thickness = 1; a.Clearance = pin->Clearance / 2; a.Flags = NoFlags (); a.Delta = 90 - (a.Clearance * (1. + 2. * pcb->ThermScale) * 180) / (M_PI * a.Width); a.StartAngle = 90 - a.Delta / 2 + (style == 4 ? 0 : 45); pa = ArcPoly (&a, a.Clearance); if (!pa) return NULL; a.StartAngle += 90; arc = ArcPoly (&a, a.Clearance); if (!arc) return NULL; pa->f = arc; arc->b = pa; a.StartAngle += 90; arc = ArcPoly (&a, a.Clearance); if (!arc) return NULL; pa->f->f = arc; arc->b = pa->f; a.StartAngle += 90; arc = ArcPoly (&a, a.Clearance); if (!arc) return NULL; pa->b = arc; pa->f->f->f = arc; arc->b = pa->f->f; arc->f = pa; pa->b = arc; return pa; } } pcb-4.3.0/src/free_atexit.h0000664000175000017500000000164013773431044012453 00000000000000/*! * \file src/free_atexit.c * * \brief . * * This tiny library is to assist cleaning up harmless memory leaks * caused by (growing) buffers allocated in static variables in * functions.\n * The library provides leaky_ prefixed variants of the common * allocation routines.\n * These wrappers will remember all pointers they return and can free * all memory used, at the end of the application. */ #include #ifdef NDEBUG #define leaky_init() #define leaky_uninit() #define leaky_malloc(size) malloc(size) #define leaky_calloc(nmemb, size) calloc(nmemb, size) #define leaky_realloc(old_memory, size) realloc(old_memory, size) #define leaky_strdup(str) strdup(str) #else void leaky_init (void); void leaky_uninit (void); void *leaky_malloc (size_t size); void *leaky_calloc (size_t nmemb, size_t size); void *leaky_realloc (void* old_memory, size_t size); char *leaky_strdup (const char *src); #endif pcb-4.3.0/src/compat.c0000664000175000017500000000416713773431044011441 00000000000000/*! * \file src/compat.c * * \brief . * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 2004, 2006 Dan McMahill * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "compat.h" #include "global.h" #ifdef HAVE_LIBDMALLOC #include #endif #ifndef HAVE_EXPF float expf (float x) { return (float) exp ((double) x); } #endif #ifndef HAVE_LOGF float logf (float x) { return (float) log ((double) x); } #endif #ifndef HAVE_RANDOM long random (void) { return (long) rand (); } #endif #if !defined(HAVE_DLFCN_H) && defined(WIN32) #define WIN32_LEAN_AND_MEAN #include void * dlopen (const char * f, int ATTRIBUTE_UNUSED flag) { return LoadLibrary (f); } void dlclose (void * h) { FreeLibrary ((HINSTANCE) h); } char * dlerror () { static LPVOID lpMsgBuf = NULL; DWORD dw; /* free the error message buffer */ if (lpMsgBuf) LocalFree (lpMsgBuf); /* get the error code */ dw = GetLastError(); /* get the corresponding error message */ FormatMessage ( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); return (char *) lpMsgBuf; } void * dlsym (void *handle, const char *symbol) { return (void *) GetProcAddress((HMODULE) handle, symbol); } #endif pcb-4.3.0/src/polygon.c0000664000175000017500000015201013773431044011634 00000000000000/*! * \file src/polygon.c * * \brief Special polygon editing routines. * * Here's a brief tour of the data and life of a polygon, courtesy of * Ben Jackson: * * A PCB PolygonType contains an array of points outlining the polygon. * This is what is manipulated by the UI and stored in the saved PCB. * * A PolygonType also contains a POLYAREA called 'Clipped' which is * computed dynamically by InitClip every time a board is loaded. * The point array is coverted to a POLYAREA by original_poly and then * holes are cut in it by clearPoly. * After that it is maintained dynamically as parts are added, moved or * removed (this is why sometimes bugs can be fixed by just re-loading * the board). * * A POLYAREA consists of a linked list of PLINE structures. * The head of that list is POLYAREA.contours. * The first contour is an outline of a filled region. * All of the subsequent PLINEs are holes cut out of that first contour. * POLYAREAs are in a doubly-linked list and each member of the list is * an independent (non-overlapping) area with its own outline and holes. * The function biggest() finds the largest POLYAREA so that * PolygonType.Clipped points to that shape. * The rest of the polygon still exists, it's just ignored when turning * the polygon into copper. * * The first POLYAREA in PolygonType.Clipped is what is used for the * vast majority of Polygon related tests. * The basic logic for an intersection is "is the target shape inside * POLYAREA.contours and NOT fully enclosed in any of * POLYAREA.contours.next... (the holes)". * * The polygon dicer (NoHolesPolygonDicer and r_NoHolesPolygonDicer) * emits a series of "simple" PLINE shapes. * That is, the PLINE isn't linked to any other "holes" oulines. * That's the meaning of the first test in r_NoHolesPolygonDicer. * It is testing to see if the PLINE contour (the first, making it a * solid outline) has a valid next pointer (which would point to one or * more holes). * The dicer works by recursively chopping the polygon in half through * the first hole it sees (which is guaranteed to eliminate at least * that one hole). * The dicer output is used for HIDs which cannot render things with * holes (which would require erasure). * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996,2010 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * * Thomas.Nau@rz.uni-ulm.de */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "global.h" #include "box.h" #include "create.h" #include "crosshair.h" #include "data.h" #include "draw.h" #include "error.h" #include "find.h" #include "misc.h" #include "move.h" #include "pcb-printf.h" #include "polygon.h" #include "remove.h" #include "rtree.h" #include "search.h" #include "set.h" #include "thermal.h" #include "undo.h" #ifdef HAVE_LIBDMALLOC #include #endif #define ROUND(x) ((long)(((x) >= 0 ? (x) + 0.5 : (x) - 0.5))) #define UNSUBTRACT_BLOAT 10 #define SUBTRACT_PIN_VIA_BATCH_SIZE 100 #define SUBTRACT_LINE_BATCH_SIZE 20 static double rotate_circle_seg[4]; void polygon_init (void) { double cos_ang = cos (2.0 * M_PI / POLY_CIRC_SEGS_F); double sin_ang = sin (2.0 * M_PI / POLY_CIRC_SEGS_F); rotate_circle_seg[0] = cos_ang; rotate_circle_seg[1] = -sin_ang; rotate_circle_seg[2] = sin_ang; rotate_circle_seg[3] = cos_ang; } Cardinal polygon_point_idx (PolygonType *polygon, PointType *point) { assert (point >= polygon->Points); assert (point <= polygon->Points + polygon->PointN); return ((char *)point - (char *)polygon->Points) / sizeof (PointType); } /*! * \brief Find contour number. * * 0 for outer, * * 1 for first hole etc.. */ Cardinal polygon_point_contour (PolygonType *polygon, Cardinal point) { Cardinal i; Cardinal contour = 0; for (i = 0; i < polygon->HoleIndexN; i++) if (point >= polygon->HoleIndex[i]) contour = i + 1; return contour; } Cardinal next_contour_point (PolygonType *polygon, Cardinal point) { Cardinal contour; Cardinal this_contour_start; Cardinal next_contour_start; contour = polygon_point_contour (polygon, point); this_contour_start = (contour == 0) ? 0 : polygon->HoleIndex[contour - 1]; next_contour_start = (contour == polygon->HoleIndexN) ? polygon->PointN : polygon->HoleIndex[contour]; /* Wrap back to the start of the contour we're in if we pass the end */ if (++point == next_contour_start) point = this_contour_start; return point; } Cardinal prev_contour_point (PolygonType *polygon, Cardinal point) { Cardinal contour; Cardinal prev_contour_end; Cardinal this_contour_end; contour = polygon_point_contour (polygon, point); prev_contour_end = (contour == 0) ? 0 : polygon->HoleIndex[contour - 1]; this_contour_end = (contour == polygon->HoleIndexN) ? polygon->PointN - 1: polygon->HoleIndex[contour] - 1; /* Wrap back to the start of the contour we're in if we pass the end */ if (point == prev_contour_end) point = this_contour_end; else point--; return point; } static void add_noholes_polyarea (PLINE *pline, void *user_data) { PolygonType *poly = (PolygonType *)user_data; /* Prepend the pline into the NoHoles linked list */ pline->next = poly->NoHoles; poly->NoHoles = pline; } void ComputeNoHoles (PolygonType *poly) { poly_FreeContours (&poly->NoHoles); if (poly->Clipped) NoHolesPolygonDicer (poly, NULL, add_noholes_polyarea, poly); else printf ("Compute_noholes caught poly->Clipped = NULL\n"); poly->NoHolesValid = 1; } static POLYAREA * biggest (POLYAREA * p) { POLYAREA *n, *top = NULL; PLINE *pl; rtree_t *tree; double big = -1; if (!p) return NULL; n = p; do { #if 0 if (n->contours->area < PCB->IsleArea) { n->b->f = n->f; n->f->b = n->b; poly_DelContour (&n->contours); if (n == p) p = n->f; n = n->f; if (!n->contours) { free (n); return NULL; } } #endif if (n->contours->area > big) { top = n; big = n->contours->area; } } while ((n = n->f) != p); assert (top); if (top == p) return p; pl = top->contours; tree = top->contour_tree; top->contours = p->contours; top->contour_tree = p->contour_tree; p->contours = pl; p->contour_tree = tree; assert (pl); assert (p->f); assert (p->b); return p; } POLYAREA * ContourToPoly (PLINE * contour) { POLYAREA *p; poly_PreContour (contour, TRUE); assert (contour->Flags.orient == PLF_DIR); if (!(p = poly_Create ())) return NULL; poly_InclContour (p, contour); assert (poly_Valid (p)); return p; } /*! * \brief Generate the basic polygon shape. * * This includes the perimeter of the polygon with any holes removed, but no * areas cleared by objects. * */ POLYAREA * original_poly (PolygonType * p) { PLINE *contour = NULL; POLYAREA *np = NULL; Cardinal n; Vector v; int hole = 0; /* If we can't create the structures, we can't do anything. */ if ((np = poly_Create ()) == NULL) return NULL; /* Iterate over every point in the array. Note that this includes both the * perimeter points and the points that define holes contours in the * polygon. The indices at which the points of each hole start are * recorded in the HoleIndex array. */ for (n = 0; n < p->PointN; n++) { /* No current contour? Make a new one starting at point */ /* (or) Add point to existing contour */ v[0] = p->Points[n].X; v[1] = p->Points[n].Y; if (contour == NULL) { /* This is the first VNODE in the contour, we need to initialize * the contour. * */ if ((contour = poly_NewContour (v)) == NULL) return NULL; /* Couldn't allocate memory*/ } else { /* Create a new VNODE at v, and insert it after head.prev */ poly_InclVertex (contour->head.prev, poly_CreateNode (v)); } /* Is current point last in contour (perimeter or hole)? * If so process it. * */ if (n == p->PointN - 1 /* last perimeter point */ /* or, last point of a hole contour.*/ || (hole < p->HoleIndexN && n == p->HoleIndex[hole] - 1)) { /* Process the contour */ poly_PreContour (contour, TRUE); /* make sure it is a positive contour (outer) or negative (hole) */ if (contour->Flags.orient != (hole ? PLF_INV : PLF_DIR)) poly_InvContour (contour); assert (contour->Flags.orient == (hole ? PLF_INV : PLF_DIR)); /* Insert the contour in the POLYAREA PLINE chain */ poly_InclContour (np, contour); assert (poly_Valid (np)); /* advance to the next hole contour and start over */ hole++; contour = NULL; } } return biggest (np); } POLYAREA * PolygonToPoly (PolygonType *p) { return original_poly (p); } POLYAREA * RectPoly (Coord x1, Coord x2, Coord y1, Coord y2) { PLINE *contour = NULL; Vector v; /* Return NULL for zero or negatively sized rectangles */ if (x2 <= x1 || y2 <= y1) return NULL; v[0] = x1; v[1] = y1; if ((contour = poly_NewContour (v)) == NULL) return NULL; v[0] = x2; v[1] = y1; poly_InclVertex (contour->head.prev, poly_CreateNode (v)); v[0] = x2; v[1] = y2; poly_InclVertex (contour->head.prev, poly_CreateNode (v)); v[0] = x1; v[1] = y2; poly_InclVertex (contour->head.prev, poly_CreateNode (v)); return ContourToPoly (contour); } POLYAREA * OctagonPoly (Coord x, Coord y, Coord radius) { PLINE *contour = NULL; Vector v; v[0] = x + ROUND (radius * 0.5); v[1] = y + ROUND (radius * TAN_22_5_DEGREE_2); if ((contour = poly_NewContour (v)) == NULL) return NULL; v[0] = x + ROUND (radius * TAN_22_5_DEGREE_2); v[1] = y + ROUND (radius * 0.5); poly_InclVertex (contour->head.prev, poly_CreateNode (v)); v[0] = x - (v[0] - x); poly_InclVertex (contour->head.prev, poly_CreateNode (v)); v[0] = x - ROUND (radius * 0.5); v[1] = y + ROUND (radius * TAN_22_5_DEGREE_2); poly_InclVertex (contour->head.prev, poly_CreateNode (v)); v[1] = y - (v[1] - y); poly_InclVertex (contour->head.prev, poly_CreateNode (v)); v[0] = x - ROUND (radius * TAN_22_5_DEGREE_2); v[1] = y - ROUND (radius * 0.5); poly_InclVertex (contour->head.prev, poly_CreateNode (v)); v[0] = x - (v[0] - x); poly_InclVertex (contour->head.prev, poly_CreateNode (v)); v[0] = x + ROUND (radius * 0.5); v[1] = y - ROUND (radius * TAN_22_5_DEGREE_2); poly_InclVertex (contour->head.prev, poly_CreateNode (v)); return ContourToPoly (contour); } /*! * \brief Add vertices in a fractional-circle starting from v * centered at X, Y and going counter-clockwise. * * Does not include the first point. * last argument is 1 for a full circle. * 2 for a half circle. * or 4 for a quarter circle. */ void frac_circle (PLINE * c, Coord X, Coord Y, Vector v, int fraction) { double e1, e2, t1; int i, range; poly_InclVertex (c->head.prev, poly_CreateNode (v)); /* move vector to origin */ e1 = (v[0] - X) * POLY_CIRC_RADIUS_ADJ; e2 = (v[1] - Y) * POLY_CIRC_RADIUS_ADJ; /* NB: the caller adds the last vertex, hence the -1 */ range = POLY_CIRC_SEGS / fraction - 1; for (i = 0; i < range; i++) { /* rotate the vector */ t1 = rotate_circle_seg[0] * e1 + rotate_circle_seg[1] * e2; e2 = rotate_circle_seg[2] * e1 + rotate_circle_seg[3] * e2; e1 = t1; v[0] = X + ROUND (e1); v[1] = Y + ROUND (e2); poly_InclVertex (c->head.prev, poly_CreateNode (v)); } } /*! * \brief Create a circle approximation from lines. */ POLYAREA * CirclePoly (Coord x, Coord y, Coord radius) { PLINE *contour; Vector v; if (radius <= 0) return NULL; v[0] = x + radius; v[1] = y; if ((contour = poly_NewContour (v)) == NULL) return NULL; frac_circle (contour, x, y, v, 1); contour->is_round = TRUE; contour->cx = x; contour->cy = y; contour->radius = radius; return ContourToPoly (contour); } /*! * \brief Make a rounded-corner rectangle with radius t beyond * x1,x2,y1,y2 rectangle. */ POLYAREA * RoundRect (Coord x1, Coord x2, Coord y1, Coord y2, Coord t) { PLINE *contour = NULL; Vector v; assert (x2 > x1); assert (y2 > y1); v[0] = x1 - t; v[1] = y1; if ((contour = poly_NewContour (v)) == NULL) return NULL; frac_circle (contour, x1, y1, v, 4); v[0] = x2; v[1] = y1 - t; poly_InclVertex (contour->head.prev, poly_CreateNode (v)); frac_circle (contour, x2, y1, v, 4); v[0] = x2 + t; v[1] = y2; poly_InclVertex (contour->head.prev, poly_CreateNode (v)); frac_circle (contour, x2, y2, v, 4); v[0] = x1; v[1] = y2 + t; poly_InclVertex (contour->head.prev, poly_CreateNode (v)); frac_circle (contour, x1, y2, v, 4); return ContourToPoly (contour); } #define ARC_ANGLE 5 static POLYAREA * ArcPolyNoIntersect (ArcType * a, Coord thick) { PLINE *contour = NULL; POLYAREA *np = NULL; Vector v; BoxType *ends; int i, segs; double ang, da, rx, ry; long half; double radius_adj; if (thick <= 0) return NULL; if (a->Delta < 0) { a->StartAngle += a->Delta; a->Delta = -a->Delta; } half = (thick + 1) / 2; ends = GetArcEnds (a); /* start with inner radius */ rx = MAX (a->Width - half, 0); ry = MAX (a->Height - half, 0); segs = 1; if(thick > 0) segs = MAX (segs, a->Delta * M_PI / 360 * sqrt (hypot (rx, ry) / POLY_ARC_MAX_DEVIATION / 2 / thick)); segs = MAX(segs, a->Delta / ARC_ANGLE); ang = a->StartAngle; da = (1.0 * a->Delta) / segs; radius_adj = (M_PI*da/360)*(M_PI*da/360)/2; v[0] = a->X - rx * cos (ang * M180); v[1] = a->Y + ry * sin (ang * M180); if ((contour = poly_NewContour (v)) == NULL) return 0; for (i = 0; i < segs - 1; i++) { ang += da; v[0] = a->X - rx * cos (ang * M180); v[1] = a->Y + ry * sin (ang * M180); poly_InclVertex (contour->head.prev, poly_CreateNode (v)); } /* find last point */ ang = a->StartAngle + a->Delta; v[0] = a->X - rx * cos (ang * M180) * (1 - radius_adj); v[1] = a->Y + ry * sin (ang * M180) * (1 - radius_adj); /* add the round cap at the end */ frac_circle (contour, ends->X2, ends->Y2, v, 2); /* and now do the outer arc (going backwards) */ rx = (a->Width + half) * (1+radius_adj); ry = (a->Width + half) * (1+radius_adj); da = -da; for (i = 0; i < segs; i++) { v[0] = a->X - rx * cos (ang * M180); v[1] = a->Y + ry * sin (ang * M180); poly_InclVertex (contour->head.prev, poly_CreateNode (v)); ang += da; } /* now add other round cap */ ang = a->StartAngle; v[0] = a->X - rx * cos (ang * M180) * (1 - radius_adj); v[1] = a->Y + ry * sin (ang * M180) * (1 - radius_adj); frac_circle (contour, ends->X1, ends->Y1, v, 2); /* now we have the whole contour */ if (!(np = ContourToPoly (contour))) return NULL; return np; } #define MIN_CLEARANCE_BEFORE_BISECT 10. POLYAREA * ArcPoly (ArcType * a, Coord thick) { double delta; ArcType seg1, seg2; POLYAREA *tmp1, *tmp2, *res; delta = (a->Delta < 0) ? -a->Delta : a->Delta; /* If the arc segment would self-intersect, we need to construct it as the union of two non-intersecting segments */ if (2 * M_PI * a->Width * (1. - (double)delta / 360.) - thick < MIN_CLEARANCE_BEFORE_BISECT) { int half_delta = a->Delta / 2; seg1 = seg2 = *a; seg1.Delta = half_delta; seg2.Delta -= half_delta; seg2.StartAngle += half_delta; tmp1 = ArcPolyNoIntersect (&seg1, thick); tmp2 = ArcPolyNoIntersect (&seg2, thick); poly_Boolean_free (tmp1, tmp2, &res, PBO_UNITE); return res; } return ArcPolyNoIntersect (a, thick); } POLYAREA * LinePoly (LineType * L, Coord thick) { PLINE *contour = NULL; POLYAREA *np = NULL; Vector v; double d, dx, dy; long half;LineType _l=*L,*l=&_l; if (thick <= 0) return NULL; half = (thick + 1) / 2; d = hypot (l->Point1.X - l->Point2.X, l->Point1.Y - l->Point2.Y); if (!TEST_FLAG (SQUAREFLAG,l)) if (d == 0) /* line is a point */ return CirclePoly (l->Point1.X, l->Point1.Y, half); if (d != 0) { d = half / d; dx = (l->Point1.Y - l->Point2.Y) * d; dy = (l->Point2.X - l->Point1.X) * d; } else { dx = half; dy = 0; } if (TEST_FLAG (SQUAREFLAG,l))/* take into account the ends */ { l->Point1.X -= dy; l->Point1.Y += dx; l->Point2.X += dy; l->Point2.Y -= dx; } v[0] = l->Point1.X - dx; v[1] = l->Point1.Y - dy; if ((contour = poly_NewContour (v)) == NULL) return 0; v[0] = l->Point2.X - dx; v[1] = l->Point2.Y - dy; if (TEST_FLAG (SQUAREFLAG,l)) poly_InclVertex (contour->head.prev, poly_CreateNode (v)); else frac_circle (contour, l->Point2.X, l->Point2.Y, v, 2); v[0] = l->Point2.X + dx; v[1] = l->Point2.Y + dy; poly_InclVertex (contour->head.prev, poly_CreateNode (v)); v[0] = l->Point1.X + dx; v[1] = l->Point1.Y + dy; if (TEST_FLAG (SQUAREFLAG,l)) poly_InclVertex (contour->head.prev, poly_CreateNode (v)); else frac_circle (contour, l->Point1.X, l->Point1.Y, v, 2); /* now we have the line contour */ if (!(np = ContourToPoly (contour))) return NULL; return np; } /*! * \brief Make a rounded-corner rectangle. */ POLYAREA * SquarePadPoly (PadType * pad, Coord clear) { PLINE *contour = NULL; POLYAREA *np = NULL; Vector v; double d; double tx, ty; double cx, cy; PadType _t=*pad,*t=&_t; PadType _c=*pad,*c=&_c; int halfthick = (pad->Thickness + 1) / 2; int halfclear = (clear + 1) / 2; d = hypot (pad->Point1.X - pad->Point2.X, pad->Point1.Y - pad->Point2.Y); if (d != 0) { double a = halfthick / d; tx = (t->Point1.Y - t->Point2.Y) * a; ty = (t->Point2.X - t->Point1.X) * a; a = halfclear / d; cx = (c->Point1.Y - c->Point2.Y) * a; cy = (c->Point2.X - c->Point1.X) * a; t->Point1.X -= ty; t->Point1.Y += tx; t->Point2.X += ty; t->Point2.Y -= tx; c->Point1.X -= cy; c->Point1.Y += cx; c->Point2.X += cy; c->Point2.Y -= cx; } else { tx = halfthick; ty = 0; cx = halfclear; cy = 0; t->Point1.Y += tx; t->Point2.Y -= tx; c->Point1.Y += cx; c->Point2.Y -= cx; } v[0] = c->Point1.X - tx; v[1] = c->Point1.Y - ty; if ((contour = poly_NewContour (v)) == NULL) return 0; frac_circle (contour, (t->Point1.X - tx), (t->Point1.Y - ty), v, 4); v[0] = t->Point2.X - cx; v[1] = t->Point2.Y - cy; poly_InclVertex (contour->head.prev, poly_CreateNode (v)); frac_circle (contour, (t->Point2.X - tx), (t->Point2.Y - ty), v, 4); v[0] = c->Point2.X + tx; v[1] = c->Point2.Y + ty; poly_InclVertex (contour->head.prev, poly_CreateNode (v)); frac_circle (contour, (t->Point2.X + tx), (t->Point2.Y + ty), v, 4); v[0] = t->Point1.X + cx; v[1] = t->Point1.Y + cy; poly_InclVertex (contour->head.prev, poly_CreateNode (v)); frac_circle (contour, (t->Point1.X + tx), (t->Point1.Y + ty), v, 4); /* now we have the line contour */ if (!(np = ContourToPoly (contour))) return NULL; return np; } /*! * \brief Clear np1 from the polygon. */ static int Subtract (POLYAREA * np1, PolygonType * p, bool fnp) { POLYAREA *merged = NULL, *np = np1; int x; assert (np); assert (p); if (!p->Clipped) /* polygon has no poly area, nothing to subtract from */ { if (fnp) poly_Free (&np); return 1; } assert (poly_Valid (p->Clipped)); assert (poly_Valid (np)); /* subtract the polyarea, using a boolean subtraction operation */ if (fnp) x = poly_Boolean_free (p->Clipped, np, &merged, PBO_SUB); else { x = poly_Boolean (p->Clipped, np, &merged, PBO_SUB); poly_Free (&p->Clipped); } assert (!merged || poly_Valid (merged)); if (x != err_ok) { fprintf (stderr, "Error while clipping PBO_SUB: %d\n", x); poly_Free (&merged); p->Clipped = NULL; if (p->NoHoles) printf ("Just leaked in Subtract\n"); p->NoHoles = NULL; return -1; } p->Clipped = biggest (merged); assert (!p->Clipped || poly_Valid (p->Clipped)); if (!p->Clipped) Message ("Polygon cleared out of existence near (%d, %d)\n", (p->BoundingBox.X1 + p->BoundingBox.X2) / 2, (p->BoundingBox.Y1 + p->BoundingBox.Y2) / 2); return 1; } /*! * \brief Create a polygon of the pin clearance. */ POLYAREA * PinPoly (PinType * pin, Coord thick, Coord clear) { int size; if (TEST_FLAG (SQUAREFLAG, pin)) { size = (thick + 1) / 2; return RoundRect (pin->X - size, pin->X + size, pin->Y - size, pin->Y + size, (clear + 1) / 2); } else { size = (thick + clear + 1) / 2; if (TEST_FLAG (OCTAGONFLAG, pin)) { return OctagonPoly (pin->X, pin->Y, size + size); } } return CirclePoly (pin->X, pin->Y, size); } POLYAREA * BoxPolyBloated (BoxType *box, Coord bloat) { return RectPoly (box->X1 - bloat, box->X2 + bloat, box->Y1 - bloat, box->Y2 + bloat); } /*! * \brief Remove the pin clearance from the polygon. */ static int SubtractPin (DataType * d, PinType * pin, LayerType * l, PolygonType * p) { POLYAREA *np; Cardinal i; if (pin->Clearance == 0) return 0; i = GetLayerNumber (d, l); if (TEST_THERM (i, pin)) { np = ThermPoly ((PCBType *) (d->pcb), pin, i); if (!np) return 0; } else { np = PinPoly (pin, PIN_SIZE (pin), pin->Clearance); if (!np) return -1; } return Subtract (np, p, TRUE); } static int SubtractLine (LineType * line, PolygonType * p) { POLYAREA *np; if (!TEST_FLAG (CLEARLINEFLAG, line)) return 0; if (!(np = LinePoly (line, line->Thickness + line->Clearance))) return -1; return Subtract (np, p, true); } static int SubtractArc (ArcType * arc, PolygonType * p) { POLYAREA *np; if (!TEST_FLAG (CLEARLINEFLAG, arc)) return 0; if (!(np = ArcPoly (arc, arc->Thickness + arc->Clearance))) return -1; return Subtract (np, p, true); } static int SubtractText (TextType * text, PolygonType * p) { POLYAREA *np; const BoxType *b = &text->BoundingBox; if (!TEST_FLAG (CLEARLINEFLAG, text)) return 0; if (!(np = RoundRect (b->X1 + PCB->Bloat, b->X2 - PCB->Bloat, b->Y1 + PCB->Bloat, b->Y2 - PCB->Bloat, PCB->Bloat))) return -1; return Subtract (np, p, true); } static int SubtractPad (PadType * pad, PolygonType * p) { POLYAREA *np = NULL; if (pad->Clearance == 0) return 0; if (TEST_FLAG (SQUAREFLAG, pad)) { if (! (np = SquarePadPoly (pad, pad->Thickness + pad->Clearance))) return -1; } else { if (! (np = LinePoly ((LineType *) pad, pad->Thickness + pad->Clearance))) return -1; } return Subtract (np, p, true); } struct cpInfo { const BoxType *other; DataType *data; LayerType *layer; PolygonType *polygon; bool bottom; POLYAREA *accumulate; int batch_size; jmp_buf env; }; static void subtract_accumulated (struct cpInfo *info, PolygonType *polygon) { if (info->accumulate == NULL) return; Subtract (info->accumulate, polygon, true); info->accumulate = NULL; info->batch_size = 0; } static int pin_sub_callback (const BoxType * b, void *cl) { PinType *pin = (PinType *) b; struct cpInfo *info = (struct cpInfo *) cl; PolygonType *polygon; POLYAREA *np; POLYAREA *merged; Cardinal i; /* don't subtract the object that was put back! */ if (b == info->other) return 0; polygon = info->polygon; i = GetLayerNumber (info->data, info->layer); if (VIA_IS_BURIED (pin) && (!VIA_ON_LAYER (pin, i))) return 0; if (pin->Clearance == 0) return 0; if (TEST_THERM (i, pin)) { np = ThermPoly ((PCBType *) (info->data->pcb), pin, i); if (!np) return 1; } else { np = PinPoly (pin, PIN_SIZE (pin), pin->Clearance); if (!np) longjmp (info->env, 1); } poly_Boolean_free (info->accumulate, np, &merged, PBO_UNITE); info->accumulate = merged; info->batch_size ++; if (info->batch_size == SUBTRACT_PIN_VIA_BATCH_SIZE) subtract_accumulated (info, polygon); return 1; } static int arc_sub_callback (const BoxType * b, void *cl) { ArcType *arc = (ArcType *) b; struct cpInfo *info = (struct cpInfo *) cl; PolygonType *polygon; /* don't subtract the object that was put back! */ if (b == info->other) return 0; if (!TEST_FLAG (CLEARLINEFLAG, arc)) return 0; polygon = info->polygon; if (SubtractArc (arc, polygon) < 0) longjmp (info->env, 1); return 1; } static int pad_sub_callback (const BoxType * b, void *cl) { PadType *pad = (PadType *) b; struct cpInfo *info = (struct cpInfo *) cl; PolygonType *polygon; /* don't subtract the object that was put back! */ if (b == info->other) return 0; if (pad->Clearance == 0) return 0; polygon = info->polygon; if (XOR (TEST_FLAG (ONSOLDERFLAG, pad), !info->bottom)) { if (SubtractPad (pad, polygon) < 0) longjmp (info->env, 1); return 1; } return 0; } static int line_sub_callback (const BoxType * b, void *cl) { LineType *line = (LineType *) b; struct cpInfo *info = (struct cpInfo *) cl; PolygonType *polygon; POLYAREA *np; POLYAREA *merged; /* don't subtract the object that was put back! */ if (b == info->other) return 0; if (!TEST_FLAG (CLEARLINEFLAG, line)) return 0; polygon = info->polygon; if (!(np = LinePoly (line, line->Thickness + line->Clearance))) longjmp (info->env, 1); poly_Boolean_free (info->accumulate, np, &merged, PBO_UNITE); info->accumulate = merged; info->batch_size ++; if (info->batch_size == SUBTRACT_LINE_BATCH_SIZE) subtract_accumulated (info, polygon); return 1; } static int text_sub_callback (const BoxType * b, void *cl) { TextType *text = (TextType *) b; struct cpInfo *info = (struct cpInfo *) cl; PolygonType *polygon; /* don't subtract the object that was put back! */ if (b == info->other) return 0; if (!TEST_FLAG (CLEARLINEFLAG, text)) return 0; polygon = info->polygon; if (SubtractText (text, polygon) < 0) longjmp (info->env, 1); return 1; } static int Group (DataType *Data, Cardinal layer) { Cardinal i, j; for (i = 0; i < max_group; i++) for (j = 0; j < ((PCBType *) (Data->pcb))->LayerGroups.Number[i]; j++) if (layer == ((PCBType *) (Data->pcb))->LayerGroups.Entries[i][j]) return i; return i; } static int clearPoly (DataType *Data, LayerType *Layer, PolygonType * polygon, const BoxType * here, Coord expand) { int r = 0; BoxType region; struct cpInfo info; Cardinal group; if (!TEST_FLAG (CLEARPOLYFLAG, polygon) || GetLayerNumber (Data, Layer) >= max_copper_layer) return 0; group = Group (Data, GetLayerNumber (Data, Layer)); info.bottom = (group == Group (Data, bottom_silk_layer)); info.data = Data; info.other = here; info.layer = Layer; info.polygon = polygon; if (here) region = clip_box (here, &polygon->BoundingBox); else region = polygon->BoundingBox; region = bloat_box (®ion, expand); if (setjmp (info.env) == 0) { r = 0; info.accumulate = NULL; info.batch_size = 0; if (info.bottom || group == Group (Data, top_silk_layer)) r += r_search (Data->pad_tree, ®ion, NULL, pad_sub_callback, &info); GROUP_LOOP (Data, group); { r += r_search (layer->line_tree, ®ion, NULL, line_sub_callback, &info); subtract_accumulated (&info, polygon); r += r_search (layer->arc_tree, ®ion, NULL, arc_sub_callback, &info); r += r_search (layer->text_tree, ®ion, NULL, text_sub_callback, &info); } END_LOOP; r += r_search (Data->via_tree, ®ion, NULL, pin_sub_callback, &info); r += r_search (Data->pin_tree, ®ion, NULL, pin_sub_callback, &info); subtract_accumulated (&info, polygon); } polygon->NoHolesValid = 0; return r; } static int Unsubtract (POLYAREA * np1, PolygonType * p) { POLYAREA *merged = NULL, *np = np1; POLYAREA *orig_poly, *clipped_np; int x; assert (np); assert (p && p->Clipped); orig_poly = original_poly (p); x = poly_Boolean_free (np, orig_poly, &clipped_np, PBO_ISECT); if (x != err_ok) { fprintf (stderr, "Error while clipping PBO_ISECT: %d\n", x); poly_Free (&clipped_np); goto fail; } x = poly_Boolean_free (p->Clipped, clipped_np, &merged, PBO_UNITE); if (x != err_ok) { fprintf (stderr, "Error while clipping PBO_UNITE: %d\n", x); poly_Free (&merged); goto fail; } p->Clipped = biggest (merged); assert (!p->Clipped || poly_Valid (p->Clipped)); return 1; fail: p->Clipped = NULL; if (p->NoHoles) printf ("Just leaked in Unsubtract\n"); p->NoHoles = NULL; return 0; } static int UnsubtractPin (PinType * pin, LayerType * l, PolygonType * p) { POLYAREA *np; /* overlap a bit to prevent gaps from rounding errors */ np = BoxPolyBloated (&pin->BoundingBox, UNSUBTRACT_BLOAT); if (!np) return 0; if (!Unsubtract (np, p)) return 0; clearPoly (PCB->Data, l, p, (const BoxType *) pin, 2 * UNSUBTRACT_BLOAT); return 1; } static int UnsubtractArc (ArcType * arc, LayerType * l, PolygonType * p) { POLYAREA *np; if (!TEST_FLAG (CLEARLINEFLAG, arc)) return 0; /* overlap a bit to prevent gaps from rounding errors */ np = BoxPolyBloated (&arc->BoundingBox, UNSUBTRACT_BLOAT); if (!np) return 0; if (!Unsubtract (np, p)) return 0; clearPoly (PCB->Data, l, p, (const BoxType *) arc, 2 * UNSUBTRACT_BLOAT); return 1; } static int UnsubtractLine (LineType * line, LayerType * l, PolygonType * p) { POLYAREA *np; if (!TEST_FLAG (CLEARLINEFLAG, line)) return 0; /* overlap a bit to prevent notches from rounding errors */ np = BoxPolyBloated (&line->BoundingBox, UNSUBTRACT_BLOAT); if (!np) return 0; if (!Unsubtract (np, p)) return 0; clearPoly (PCB->Data, l, p, (const BoxType *) line, 2 * UNSUBTRACT_BLOAT); return 1; } static int UnsubtractText (TextType * text, LayerType * l, PolygonType * p) { POLYAREA *np; if (!TEST_FLAG (CLEARLINEFLAG, text)) return 0; /* overlap a bit to prevent notches from rounding errors */ np = BoxPolyBloated (&text->BoundingBox, UNSUBTRACT_BLOAT); if (!np) return -1; if (!Unsubtract (np, p)) return 0; clearPoly (PCB->Data, l, p, (const BoxType *) text, 2 * UNSUBTRACT_BLOAT); return 1; } static int UnsubtractPad (PadType * pad, LayerType * l, PolygonType * p) { POLYAREA *np; /* overlap a bit to prevent notches from rounding errors */ np = BoxPolyBloated (&pad->BoundingBox, UNSUBTRACT_BLOAT); if (!np) return 0; if (!Unsubtract (np, p)) return 0; clearPoly (PCB->Data, l, p, (const BoxType *) pad, 2 * UNSUBTRACT_BLOAT); return 1; } static bool inhibit = false; /*! * \brief Initialize low level polygon data structures. * */ int InitClip (DataType *Data, LayerType *layer, PolygonType * p) { if (inhibit) return 0; /* Clear any existing data. */ if (p->Clipped) poly_Free (&p->Clipped); /* Compute the perimeter of the polygon */ p->Clipped = original_poly (p); /* NoHoles is a version of the polygon broken into pieces so that it is * hole free. If we have one, we need to clear it. */ poly_FreeContours (&p->NoHoles); if (!p->Clipped) return 0; assert (poly_Valid (p->Clipped)); /* If the polygon is clearing, we need to add all of the object cutouts. */ if (TEST_FLAG (CLEARPOLYFLAG, p)) clearPoly (Data, layer, p, NULL, 0); else p->NoHolesValid = 0; return 1; } /*! * \brief Remove redundant polygon points. * * Any point that lies on the straight line between the points on either * side of it is redundant. * * \return True if any points are removed. */ bool RemoveExcessPolygonPoints (LayerType *Layer, PolygonType *Polygon) { PointType *p; Cardinal n, prev, next; LineType line; bool changed = false; if (Undoing ()) return (false); for (n = 0; n < Polygon->PointN; n++) { prev = prev_contour_point (Polygon, n); next = next_contour_point (Polygon, n); p = &Polygon->Points[n]; line.Point1 = Polygon->Points[prev]; line.Point2 = Polygon->Points[next]; line.Thickness = 0; if (IsPointOnLine (p->X, p->Y, 0.0, &line)) { RemoveObject (POLYGONPOINT_TYPE, Layer, Polygon, p); changed = true; } } return (changed); } /*! * \brief . * * \return The index of the polygon point which is the end point of the * segment with the lowest distance to the passed coordinates. */ Cardinal GetLowestDistancePolygonPoint (PolygonType *Polygon, Coord X, Coord Y) { double mindistance = (double) MAX_COORD * MAX_COORD; PointType *ptr1, *ptr2; Cardinal n, result = 0; /* we calculate the distance to each segment and choose the * shortest distance. If the closest approach between the * given point and the projected line (i.e. the segment extended) * is not on the segment, then the distance is the distance * to the segment end point. */ for (n = 0; n < Polygon->PointN; n++) { double u, dx, dy; ptr1 = &Polygon->Points[prev_contour_point (Polygon, n)]; ptr2 = &Polygon->Points[n]; dx = ptr2->X - ptr1->X; dy = ptr2->Y - ptr1->Y; if (dx != 0.0 || dy != 0.0) { /* projected intersection is at P1 + u(P2 - P1) */ u = ((X - ptr1->X) * dx + (Y - ptr1->Y) * dy) / (dx * dx + dy * dy); if (u < 0.0) { /* ptr1 is closest point */ u = SQUARE (X - ptr1->X) + SQUARE (Y - ptr1->Y); } else if (u > 1.0) { /* ptr2 is closest point */ u = SQUARE (X - ptr2->X) + SQUARE (Y - ptr2->Y); } else { /* projected intersection is closest point */ u = SQUARE (X - ptr1->X * (1.0 - u) - u * ptr2->X) + SQUARE (Y - ptr1->Y * (1.0 - u) - u * ptr2->Y); } if (u < mindistance) { mindistance = u; result = n; } } } return (result); } /*! * \brief Go back to the previous point of the polygon. */ void GoToPreviousPoint (void) { switch (Crosshair.AttachedPolygon.PointN) { /* do nothing if mode has just been entered */ case 0: break; /* reset number of points and 'LINE_MODE' state */ case 1: Crosshair.AttachedPolygon.PointN = 0; Crosshair.AttachedLine.State = STATE_FIRST; addedLines = 0; break; /* back-up one point */ default: { PointType *points = Crosshair.AttachedPolygon.Points; Cardinal n = Crosshair.AttachedPolygon.PointN - 2; Crosshair.AttachedPolygon.PointN--; Crosshair.AttachedLine.Point1.X = points[n].X; Crosshair.AttachedLine.Point1.Y = points[n].Y; break; } } } /*! * \brief Close polygon if possible. */ void ClosePolygon (void) { Cardinal n = Crosshair.AttachedPolygon.PointN; /* check number of points */ if (n >= 3) { /* if 45 degree lines are what we want do a quick check * if closing the polygon makes sense */ if (!TEST_FLAG (ALLDIRECTIONFLAG, PCB)) { Coord dx, dy; dx = abs (Crosshair.AttachedPolygon.Points[n - 1].X - Crosshair.AttachedPolygon.Points[0].X); dy = abs (Crosshair.AttachedPolygon.Points[n - 1].Y - Crosshair.AttachedPolygon.Points[0].Y); if (!(dx == 0 || dy == 0 || dx == dy)) { Message (_ ("Cannot close polygon because 45 degree lines are requested.\n")); return; } } CopyAttachedPolygonToLayer (); Draw (); } else Message (_("A polygon has to have at least 3 points\n")); } /*! * \brief Moves the data of the attached (new) polygon to the current * layer. */ void CopyAttachedPolygonToLayer (void) { PolygonType *polygon; int saveID; /* move data to layer and clear attached struct */ polygon = CreateNewPolygon (CURRENT, NoFlags ()); saveID = polygon->ID; *polygon = Crosshair.AttachedPolygon; polygon->ID = saveID; SET_FLAG (CLEARPOLYFLAG, polygon); if (TEST_FLAG (NEWFULLPOLYFLAG, PCB)) SET_FLAG (FULLPOLYFLAG, polygon); memset (&Crosshair.AttachedPolygon, 0, sizeof (PolygonType)); SetPolygonBoundingBox (polygon); if (!CURRENT->polygon_tree) CURRENT->polygon_tree = r_create_tree (NULL, 0, 0); r_insert_entry (CURRENT->polygon_tree, (BoxType *) polygon, 0); InitClip (PCB->Data, CURRENT, polygon); DrawPolygon (CURRENT, polygon); SetChangedFlag (true); /* reset state of attached line */ Crosshair.AttachedLine.State = STATE_FIRST; addedLines = 0; /* add to undo list */ AddObjectToCreateUndoList (POLYGON_TYPE, CURRENT, polygon, polygon); IncrementUndoSerialNumber (); } /*! * \brief Find polygon holes in range, then call the callback function * for each hole. * * If the callback returns non-zero, stop the search. */ int PolygonHoles (PolygonType *polygon, const BoxType *range, int (*callback) (PLINE *contour, void *user_data), void *user_data) { POLYAREA *pa = polygon->Clipped; PLINE *pl; /* If this hole is so big the polygon doesn't exist, then it's not * really a hole. */ if (!pa) return 0; for (pl = pa->contours->next; pl; pl = pl->next) { if (range != NULL && (pl->xmin > range->X2 || pl->xmax < range->X1 || pl->ymin > range->Y2 || pl->ymax < range->Y1)) continue; if (callback (pl, user_data)) { return 1; } } return 0; } struct plow_info { int type; void *ptr1, *ptr2; LayerType *layer; DataType *data; int (*callback) (DataType *, LayerType *, PolygonType *, int, void *, void *, void *); void *userdata; }; static int subtract_plow (DataType *Data, LayerType *Layer, PolygonType *Polygon, int type, void *ptr1, void *ptr2, void *userdata) { PinType *via; int layer_n = GetLayerNumber (Data, Layer); if (!Polygon->Clipped) return 0; switch (type) { case PIN_TYPE: SubtractPin (Data, (PinType *) ptr2, Layer, Polygon); Polygon->NoHolesValid = 0; return 1; case VIA_TYPE: via = (PinType *) ptr2; if (!VIA_IS_BURIED (via) || VIA_ON_LAYER (via, layer_n)) { SubtractPin (Data, via, Layer, Polygon); Polygon->NoHolesValid = 0; return 1; } break; case LINE_TYPE: SubtractLine ((LineType *) ptr2, Polygon); Polygon->NoHolesValid = 0; return 1; case ARC_TYPE: SubtractArc ((ArcType *) ptr2, Polygon); Polygon->NoHolesValid = 0; return 1; case PAD_TYPE: SubtractPad ((PadType *) ptr2, Polygon); Polygon->NoHolesValid = 0; return 1; case TEXT_TYPE: SubtractText ((TextType *) ptr2, Polygon); Polygon->NoHolesValid = 0; return 1; } return 0; } static int add_plow (DataType *Data, LayerType *Layer, PolygonType *Polygon, int type, void *ptr1, void *ptr2, void *userdata) { PinType *via; int layer_n = GetLayerNumber (Data, Layer); switch (type) { case PIN_TYPE: UnsubtractPin ((PinType *) ptr2, Layer, Polygon); return 1; case VIA_TYPE: via = (PinType *) ptr2; if (!VIA_IS_BURIED (via) || VIA_ON_LAYER (via, layer_n)) { UnsubtractPin ((PinType *) ptr2, Layer, Polygon); return 1; } break; case LINE_TYPE: UnsubtractLine ((LineType *) ptr2, Layer, Polygon); return 1; case ARC_TYPE: UnsubtractArc ((ArcType *) ptr2, Layer, Polygon); return 1; case PAD_TYPE: UnsubtractPad ((PadType *) ptr2, Layer, Polygon); return 1; case TEXT_TYPE: UnsubtractText ((TextType *) ptr2, Layer, Polygon); return 1; } return 0; } static int plow_callback (const BoxType * b, void *cl) { struct plow_info *plow = (struct plow_info *) cl; PolygonType *polygon = (PolygonType *) b; if (TEST_FLAG (CLEARPOLYFLAG, polygon)) return plow->callback (plow->data, plow->layer, polygon, plow->type, plow->ptr1, plow->ptr2, plow->userdata); return 0; } int PlowsPolygon (DataType * Data, int type, void *ptr1, void *ptr2, int (*call_back) (DataType *data, LayerType *lay, PolygonType *poly, int type, void *ptr1, void *ptr2, void *userdata), void *userdata) { BoxType sb = ((PinType *) ptr2)->BoundingBox; int r = 0; struct plow_info info; info.type = type; info.ptr1 = ptr1; info.ptr2 = ptr2; info.data = Data; info.callback = call_back; info.userdata = userdata; switch (type) { case PIN_TYPE: case VIA_TYPE: if (type == PIN_TYPE || ptr1 == ptr2 || ptr1 == NULL) { LAYER_LOOP (Data, max_copper_layer); { info.layer = layer; r += r_search (layer->polygon_tree, &sb, NULL, plow_callback, &info); } END_LOOP; } else { GROUP_LOOP (Data, GetLayerGroupNumberByNumber (GetLayerNumber (Data, ((LayerType *) ptr1)))); { info.layer = layer; r += r_search (layer->polygon_tree, &sb, NULL, plow_callback, &info); } END_LOOP; } break; case LINE_TYPE: case ARC_TYPE: case TEXT_TYPE: /* Don't test clearlineflag here because the DRC still needs to check * such objects. */ /* silk doesn't plow */ if (GetLayerNumber (Data, (LayerType *)ptr1) >= max_copper_layer) return 0; GROUP_LOOP (Data, GetLayerGroupNumberByNumber (GetLayerNumber (Data, ((LayerType *) ptr1)))); { info.layer = layer; r += r_search (layer->polygon_tree, &sb, NULL, plow_callback, &info); } END_LOOP; break; case PAD_TYPE: { Cardinal group = GetLayerGroupNumberByNumber ( TEST_FLAG (ONSOLDERFLAG, (PadType *) ptr2) ? bottom_silk_layer : top_silk_layer); GROUP_LOOP (Data, group); { info.layer = layer; r += r_search (layer->polygon_tree, &sb, NULL, plow_callback, &info); } END_LOOP; } break; case ELEMENT_TYPE: { PIN_LOOP ((ElementType *) ptr1); { PlowsPolygon (Data, PIN_TYPE, ptr1, pin, call_back, userdata); } END_LOOP; PAD_LOOP ((ElementType *) ptr1); { PlowsPolygon (Data, PAD_TYPE, ptr1, pad, call_back, userdata); } END_LOOP; } break; } return r; } void RestoreToPolygon (DataType * Data, int type, void *ptr1, void *ptr2) { if (!Data->polyClip) return; if (type == POLYGON_TYPE) InitClip (PCB->Data, (LayerType *) ptr1, (PolygonType *) ptr2); else PlowsPolygon (Data, type, ptr1, ptr2, add_plow, NULL); } void ClearFromPolygon (DataType * Data, int type, void *ptr1, void *ptr2) { if (!Data->polyClip) return; if (type == POLYGON_TYPE) InitClip (PCB->Data, (LayerType *) ptr1, (PolygonType *) ptr2); else PlowsPolygon (Data, type, ptr1, ptr2, subtract_plow, NULL); } /*! * \brief Determine if a POLYAREA touches a polygon. * * if the third argument is true, this function will free the POLYAREA when * finished. * */ bool isects (POLYAREA * a, PolygonType *p, bool fr) { POLYAREA *x; bool ans; ans = Touching (a, p->Clipped); /* argument may be register, so we must copy it */ x = a; if (fr) poly_Free (&x); return ans; } /*! * \brief Determine if a point of radius r is inside a polygon. * */ bool IsPointInPolygon (Coord X, Coord Y, Coord r, PolygonType *p) { POLYAREA *c; Vector v; v[0] = X; v[1] = Y; /* If the center point is inside, then some part of the point must be too. */ if (poly_CheckInside (p->Clipped, v)) return true; /* if the center isn't inside, then the point has to have a non-zero * radius. * */ if (r < 1) return false; /* Create a circular POLYAREA of radius r, and see if it intersects. */ if (!(c = CirclePoly (X, Y, r))) return false; /* failed to create POLYAREA */ return isects (c, p, true); } bool IsPointInPolygonIgnoreHoles (Coord X, Coord Y, PolygonType *p) { Vector v; v[0] = X; v[1] = Y; return poly_InsideContour (p->Clipped->contours, v); } bool IsRectangleInPolygon (Coord X1, Coord Y1, Coord X2, Coord Y2, PolygonType *p) { POLYAREA *s; if (! (s = RectPoly (min (X1, X2), max (X1, X2), min (Y1, Y2), max (Y1, Y2)))) return false; return isects (s, p, true); } /*! * \brief . * * \note This function will free the passed POLYAREA. * It must only be passed a single POLYAREA (pa->f == pa->b == pa). */ static void r_NoHolesPolygonDicer (POLYAREA * pa, void (*emit) (PLINE *, void *), void *user_data) { PLINE *p = pa->contours; if (!pa->contours->next) /* no holes */ { pa->contours = NULL; /* The callback now owns the contour */ /* Don't bother removing it from the POLYAREA's rtree since we're going to free the POLYAREA below anyway */ emit (p, user_data); poly_Free (&pa); return; } else { POLYAREA *poly2, *left, *right; /* make a rectangle of the left region slicing through the middle of the first hole */ poly2 = RectPoly (p->xmin, (p->next->xmin + p->next->xmax) / 2, p->ymin, p->ymax); poly_AndSubtract_free (pa, poly2, &left, &right); if (left) { POLYAREA *cur, *next; cur = left; do { next = cur->f; cur->f = cur->b = cur; /* Detach this polygon piece */ r_NoHolesPolygonDicer (cur, emit, user_data); /* NB: The POLYAREA was freed by its use in the recursive dicer */ } while ((cur = next) != left); } if (right) { POLYAREA *cur, *next; cur = right; do { next = cur->f; cur->f = cur->b = cur; /* Detach this polygon piece */ r_NoHolesPolygonDicer (cur, emit, user_data); /* NB: The POLYAREA was freed by its use in the recursive dicer */ } while ((cur = next) != right); } } } void NoHolesPolygonDicer (PolygonType *p, const BoxType * clip, void (*emit) (PLINE *, void *), void *user_data) { POLYAREA *main_contour, *cur, *next; main_contour = poly_Create (); /* copy the main poly only */ poly_Copy1 (main_contour, p->Clipped); /* clip to the bounding box */ if (clip) { POLYAREA *cbox = RectPoly (clip->X1, clip->X2, clip->Y1, clip->Y2); poly_Boolean_free (main_contour, cbox, &main_contour, PBO_ISECT); } if (main_contour == NULL) return; /* Now dice it up. * NB: Could be more than one piece (because of the clip above) */ cur = main_contour; do { next = cur->f; cur->f = cur->b = cur; /* Detach this polygon piece */ r_NoHolesPolygonDicer (cur, emit, user_data); /* NB: The POLYAREA was freed by its use in the recursive dicer */ } while ((cur = next) != main_contour); } /*! * \brief Make a polygon split into multiple parts into multiple * polygons. */ bool MorphPolygon (LayerType *layer, PolygonType *poly) { POLYAREA *p, *start; bool many = false; FlagType flags; if (!poly->Clipped || TEST_FLAG (LOCKFLAG, poly)) return false; if (poly->Clipped->f == poly->Clipped) return false; ErasePolygon (poly); start = p = poly->Clipped; /* This is ugly. The creation of the new polygons can cause * all of the polygon pointers (including the one we're called * with to change if there is a realloc in GetPolygonMemory(). * That will invalidate our original "poly" argument, potentially * inside the loop. We need to steal the Clipped pointer and * hide it from the Remove call so that it still exists while * we do this dirty work. */ poly->Clipped = NULL; if (poly->NoHoles) printf ("Just leaked in MorpyPolygon\n"); poly->NoHoles = NULL; flags = poly->Flags; RemovePolygon (layer, poly); inhibit = true; do { VNODE *v; PolygonType *newone; if (p->contours->area > PCB->IsleArea) { newone = CreateNewPolygon (layer, flags); if (!newone) return false; many = true; v = &p->contours->head; CreateNewPointInPolygon (newone, v->point[0], v->point[1]); for (v = v->next; v != &p->contours->head; v = v->next) CreateNewPointInPolygon (newone, v->point[0], v->point[1]); newone->BoundingBox.X1 = p->contours->xmin; newone->BoundingBox.X2 = p->contours->xmax + 1; newone->BoundingBox.Y1 = p->contours->ymin; newone->BoundingBox.Y2 = p->contours->ymax + 1; AddObjectToCreateUndoList (POLYGON_TYPE, layer, newone, newone); newone->Clipped = p; p = p->f; /* go to next pline */ newone->Clipped->b = newone->Clipped->f = newone->Clipped; /* unlink from others */ r_insert_entry (layer->polygon_tree, (BoxType *) newone, 0); DrawPolygon (layer, newone); } else { POLYAREA *t = p; p = p->f; poly_DelContour (&t->contours); free (t); } } while (p != start); inhibit = false; IncrementUndoSerialNumber (); return many; } void debug_pline (PLINE *pl) { VNODE *v; pcb_fprintf (stderr, "\txmin %#mS xmax %#mS ymin %#mS ymax %#mS\n", pl->xmin, pl->xmax, pl->ymin, pl->ymax); v = &pl->head; while (v) { pcb_fprintf(stderr, "\t\tvnode: %#mD\n", v->point[0], v->point[1]); v = v->next; if (v == &pl->head) break; } } void debug_polyarea (POLYAREA *p) { PLINE *pl; fprintf (stderr, "POLYAREA %p\n", p); for (pl=p->contours; pl; pl=pl->next) debug_pline (pl); } void debug_polygon (PolygonType *p) { Cardinal i; POLYAREA *pa; fprintf (stderr, "POLYGON %p %d pts\n", p, p->PointN); for (i=0; iPointN; i++) pcb_fprintf(stderr, "\t%d: %#mD\n", i, p->Points[i].X, p->Points[i].Y); if (p->HoleIndexN) { fprintf (stderr, "%d holes, starting at indices\n", p->HoleIndexN); for (i=0; iHoleIndexN; i++) fprintf(stderr, "\t%d: %d\n", i, p->HoleIndex[i]); } else fprintf (stderr, "it has no holes\n"); pa = p->Clipped; while (pa) { debug_polyarea (pa); pa = pa->f; if (pa == p->Clipped) break; } } /*! * \brief Convert a POLYAREA (and all linked POLYAREA) to raw PCB * polygons on the given layer. */ void PolyToPolygonsOnLayer (DataType *Destination, LayerType *Layer, POLYAREA *Input, FlagType Flags) { PolygonType *Polygon; POLYAREA *pa; PLINE *pline; VNODE *node; bool outer; if (Input == NULL) return; pa = Input; do { Polygon = CreateNewPolygon (Layer, Flags); pline = pa->contours; outer = true; do { if (!outer) CreateNewHoleInPolygon (Polygon); outer = false; node = &pline->head; do { CreateNewPointInPolygon (Polygon, node->point[0], node->point[1]); } while ((node = node->next) != &pline->head); } while ((pline = pline->next) != NULL); InitClip (Destination, Layer, Polygon); SetPolygonBoundingBox (Polygon); if (!Layer->polygon_tree) Layer->polygon_tree = r_create_tree (NULL, 0, 0); r_insert_entry (Layer->polygon_tree, (BoxType *) Polygon, 0); DrawPolygon (Layer, Polygon); /* add to undo list */ AddObjectToCreateUndoList (POLYGON_TYPE, Layer, Polygon, Polygon); } while ((pa = pa->f) != Input); SetChangedFlag (true); } pcb-4.3.0/src/remove.c0000664000175000017500000003600713773431044011451 00000000000000/*! * \file src/remove.c * * \brief Functions used to remove vias, pins ... * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design. * * Copyright (C) 1994,1995,1996 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * * Thomas.Nau@rz.uni-ulm.de */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "global.h" #include "data.h" #include "draw.h" #include "error.h" #include "misc.h" #include "move.h" #include "mymem.h" #include "polygon.h" #include "rats.h" #include "remove.h" #include "rtree.h" #include "search.h" #include "select.h" #include "set.h" #include "undo.h" #ifdef HAVE_LIBDMALLOC #include #endif /* --------------------------------------------------------------------------- * some local prototypes */ static void *DestroyVia (PinType *); static void *DestroyRat (RatType *); static void *DestroyLine (LayerType *, LineType *); static void *DestroyArc (LayerType *, ArcType *); static void *DestroyText (LayerType *, TextType *); static void *DestroyPolygon (LayerType *, PolygonType *); static void *DestroyElement (ElementType *); static void *RemoveVia (PinType *); static void *RemoveRat (RatType *); static void *DestroyPolygonPoint (LayerType *, PolygonType *, PointType *); static void *RemovePolygonContour (LayerType *, PolygonType *, Cardinal); static void *RemovePolygonPoint (LayerType *, PolygonType *, PointType *); static void *RemoveLinePoint (LayerType *, LineType *, PointType *); /* --------------------------------------------------------------------------- * some local types */ static ObjectFunctionType RemoveFunctions = { RemoveLine, RemoveText, RemovePolygon, RemoveVia, RemoveElement, NULL, NULL, NULL, RemoveLinePoint, RemovePolygonPoint, RemoveArc, RemoveRat }; static ObjectFunctionType DestroyFunctions = { DestroyLine, DestroyText, DestroyPolygon, DestroyVia, DestroyElement, NULL, NULL, NULL, NULL, DestroyPolygonPoint, DestroyArc, DestroyRat }; static DataType *DestroyTarget; static bool Bulk = false; /*! * \brief Remove PCB. */ void RemovePCB (PCBType *Ptr) { ClearUndoList (true); FreePCBMemory (Ptr); free (Ptr); } /*! * \brief Destroys a via. */ static void * DestroyVia (PinType *Via) { r_delete_entry (DestroyTarget->via_tree, (BoxType *) Via); free (Via->Name); DestroyTarget->Via = g_list_remove (DestroyTarget->Via, Via); DestroyTarget->ViaN --; g_slice_free (PinType, Via); return NULL; } /*! * \brief Destroys a line from a layer. */ static void * DestroyLine (LayerType *Layer, LineType *Line) { r_delete_entry (Layer->line_tree, (BoxType *) Line); free (Line->Number); Layer->Line = g_list_remove (Layer->Line, Line); Layer->LineN --; g_slice_free (LineType, Line); return NULL; } /*! * \brief Destroys an arc from a layer. */ static void * DestroyArc (LayerType *Layer, ArcType *Arc) { r_delete_entry (Layer->arc_tree, (BoxType *) Arc); Layer->Arc = g_list_remove (Layer->Arc, Arc); Layer->ArcN --; g_slice_free (ArcType, Arc); return NULL; } /*! * \brief Destroys a polygon from a layer. */ static void * DestroyPolygon (LayerType *Layer, PolygonType *Polygon) { r_delete_entry (Layer->polygon_tree, (BoxType *) Polygon); FreePolygonMemory (Polygon); Layer->Polygon = g_list_remove (Layer->Polygon, Polygon); Layer->PolygonN --; g_slice_free (PolygonType, Polygon); return NULL; } /*! * \brief Removes a polygon-point from a polygon and destroys the data. */ static void * DestroyPolygonPoint (LayerType *Layer, PolygonType *Polygon, PointType *Point) { Cardinal point_idx; Cardinal i; Cardinal contour; Cardinal contour_start, contour_end, contour_points; point_idx = polygon_point_idx (Polygon, Point); contour = polygon_point_contour (Polygon, point_idx); contour_start = (contour == 0) ? 0 : Polygon->HoleIndex[contour - 1]; contour_end = (contour == Polygon->HoleIndexN) ? Polygon->PointN : Polygon->HoleIndex[contour]; contour_points = contour_end - contour_start; if (contour_points <= 3) return RemovePolygonContour (Layer, Polygon, contour); r_delete_entry (Layer->polygon_tree, (BoxType *) Polygon); /* remove point from list, keep point order */ for (i = point_idx; i < Polygon->PointN - 1; i++) Polygon->Points[i] = Polygon->Points[i + 1]; Polygon->PointN--; /* Shift down indices of any holes */ for (i = 0; i < Polygon->HoleIndexN; i++) if (Polygon->HoleIndex[i] > point_idx) Polygon->HoleIndex[i]--; SetPolygonBoundingBox (Polygon); r_insert_entry (Layer->polygon_tree, (BoxType *) Polygon, 0); InitClip (PCB->Data, Layer, Polygon); return (Polygon); } /*! * \brief Destroys a text from a layer. */ static void * DestroyText (LayerType *Layer, TextType *Text) { free (Text->TextString); r_delete_entry (Layer->text_tree, (BoxType *) Text); Layer->Text = g_list_remove (Layer->Text, Text); Layer->TextN --; g_slice_free (TextType, Text); return NULL; } /* --------------------------------------------------------------------------- * destroys a element */ static void * DestroyElement (ElementType *Element) { if (DestroyTarget->element_tree) r_delete_entry (DestroyTarget->element_tree, (BoxType *) Element); if (DestroyTarget->pin_tree) { PIN_LOOP (Element); { r_delete_entry (DestroyTarget->pin_tree, (BoxType *) pin); } END_LOOP; } if (DestroyTarget->pad_tree) { PAD_LOOP (Element); { r_delete_entry (DestroyTarget->pad_tree, (BoxType *) pad); } END_LOOP; } ELEMENTTEXT_LOOP (Element); { if (DestroyTarget->name_tree[n]) r_delete_entry (DestroyTarget->name_tree[n], (BoxType *) text); } END_LOOP; FreeElementMemory (Element); DestroyTarget->Element = g_list_remove (DestroyTarget->Element, Element); DestroyTarget->ElementN --; g_slice_free (ElementType, Element); return NULL; } /*! * \brief Destroys a rat. */ static void * DestroyRat (RatType *Rat) { if (DestroyTarget->rat_tree) r_delete_entry (DestroyTarget->rat_tree, &Rat->BoundingBox); DestroyTarget->Rat = g_list_remove (DestroyTarget->Rat, Rat); DestroyTarget->RatN --; g_slice_free (RatType, Rat); return NULL; } /*! * \brief Removes a via. */ static void * RemoveVia (PinType *Via) { /* erase from screen and memory */ if (PCB->ViaOn) { EraseVia (Via); if (!Bulk) Draw (); } MoveObjectToRemoveUndoList (VIA_TYPE, Via, Via, Via); return NULL; } /*! * \brief Removes a rat. */ static void * RemoveRat (RatType *Rat) { /* erase from screen and memory */ if (PCB->RatOn) { EraseRat (Rat); if (!Bulk) Draw (); } MoveObjectToRemoveUndoList (RATLINE_TYPE, Rat, Rat, Rat); return NULL; } struct rlp_info { jmp_buf env; LineType *line; PointType *point; }; static int remove_point (const BoxType * b, void *cl) { LineType *line = (LineType *) b; struct rlp_info *info = (struct rlp_info *) cl; if (line == info->line) return 0; if ((line->Point1.X == info->point->X) && (line->Point1.Y == info->point->Y)) { info->line = line; info->point = &line->Point1; longjmp (info->env, 1); } else if ((line->Point2.X == info->point->X) && (line->Point2.Y == info->point->Y)) { info->line = line; info->point = &line->Point2; longjmp (info->env, 1); } return 0; } /*! * \brief Removes a line point, or a line if the selected point is the * end. */ static void * RemoveLinePoint (LayerType *Layer, LineType *Line, PointType *Point) { PointType other; struct rlp_info info; if (&Line->Point1 == Point) other = Line->Point2; else other = Line->Point1; info.line = Line; info.point = Point; if (setjmp (info.env) == 0) { r_search (Layer->line_tree, (const BoxType *) Point, NULL, remove_point, &info); return RemoveLine (Layer, Line); } MoveObject (LINEPOINT_TYPE, Layer, info.line, info.point, other.X - Point->X, other.Y - Point->Y); return (RemoveLine (Layer, Line)); } /*! * \brief Removes a line from a layer. */ void * RemoveLine (LayerType *Layer, LineType *Line) { /* erase from screen */ if (Layer->On) { EraseLine (Line); if (!Bulk) Draw (); } MoveObjectToRemoveUndoList (LINE_TYPE, Layer, Line, Line); return NULL; } /*! * \brief Removes an arc from a layer. */ void * RemoveArc (LayerType *Layer, ArcType *Arc) { /* erase from screen */ if (Layer->On) { EraseArc (Arc); if (!Bulk) Draw (); } MoveObjectToRemoveUndoList (ARC_TYPE, Layer, Arc, Arc); return NULL; } /*! * \brief Removes a text from a layer. */ void * RemoveText (LayerType *Layer, TextType *Text) { /* erase from screen */ if (Layer->On) { EraseText (Layer, Text); r_delete_entry (Layer->text_tree, (BoxType *) Text); if (!Bulk) Draw (); } MoveObjectToRemoveUndoList (TEXT_TYPE, Layer, Text, Text); return NULL; } /*! * \brief Removes a polygon from a layer. */ void * RemovePolygon (LayerType *Layer, PolygonType *Polygon) { /* erase from screen */ if (Layer->On) { ErasePolygon (Polygon); if (!Bulk) Draw (); } MoveObjectToRemoveUndoList (POLYGON_TYPE, Layer, Polygon, Polygon); return NULL; } /*! * \brief Removes a contour from a polygon. * * If removing the outer contour, it removes the whole polygon. */ static void * RemovePolygonContour (LayerType *Layer, PolygonType *Polygon, Cardinal contour) { Cardinal contour_start, contour_end, contour_points; Cardinal i; if (contour == 0) return RemovePolygon (Layer, Polygon); if (Layer->On) { ErasePolygon (Polygon); if (!Bulk) Draw (); } /* Copy the polygon to the undo list */ AddObjectToRemoveContourUndoList (POLYGON_TYPE, Layer, Polygon); contour_start = (contour == 0) ? 0 : Polygon->HoleIndex[contour - 1]; contour_end = (contour == Polygon->HoleIndexN) ? Polygon->PointN : Polygon->HoleIndex[contour]; contour_points = contour_end - contour_start; /* remove points from list, keep point order */ for (i = contour_start; i < Polygon->PointN - contour_points; i++) Polygon->Points[i] = Polygon->Points[i + contour_points]; Polygon->PointN -= contour_points; /* remove hole from list and shift down remaining indices */ for (i = contour; i < Polygon->HoleIndexN; i++) Polygon->HoleIndex[i - 1] = Polygon->HoleIndex[i] - contour_points; Polygon->HoleIndexN--; InitClip (PCB->Data, Layer, Polygon); /* redraw polygon if necessary */ if (Layer->On) { DrawPolygon (Layer, Polygon); if (!Bulk) Draw (); } return NULL; } /*! * \brief Removes a polygon-point from a polygon. */ static void * RemovePolygonPoint (LayerType *Layer, PolygonType *Polygon, PointType *Point) { Cardinal point_idx; Cardinal i; Cardinal contour; Cardinal contour_start, contour_end, contour_points; point_idx = polygon_point_idx (Polygon, Point); contour = polygon_point_contour (Polygon, point_idx); contour_start = (contour == 0) ? 0 : Polygon->HoleIndex[contour - 1]; contour_end = (contour == Polygon->HoleIndexN) ? Polygon->PointN : Polygon->HoleIndex[contour]; contour_points = contour_end - contour_start; if (contour_points <= 3) return RemovePolygonContour (Layer, Polygon, contour); if (Layer->On) ErasePolygon (Polygon); /* insert the polygon-point into the undo list */ AddObjectToRemovePointUndoList (POLYGONPOINT_TYPE, Layer, Polygon, point_idx); r_delete_entry (Layer->polygon_tree, (BoxType *) Polygon); /* remove point from list, keep point order */ for (i = point_idx; i < Polygon->PointN - 1; i++) Polygon->Points[i] = Polygon->Points[i + 1]; Polygon->PointN--; /* Shift down indices of any holes */ for (i = 0; i < Polygon->HoleIndexN; i++) if (Polygon->HoleIndex[i] > point_idx) Polygon->HoleIndex[i]--; SetPolygonBoundingBox (Polygon); r_insert_entry (Layer->polygon_tree, (BoxType *) Polygon, 0); RemoveExcessPolygonPoints (Layer, Polygon); InitClip (PCB->Data, Layer, Polygon); /* redraw polygon if necessary */ if (Layer->On) { DrawPolygon (Layer, Polygon); if (!Bulk) Draw (); } return NULL; } /*! * \brief Removes an element. */ void * RemoveElement (ElementType *Element) { /* erase from screen */ if ((PCB->ElementOn || PCB->PinOn) && (FRONT (Element) || PCB->InvisibleObjectsOn)) { EraseElement (Element); if (!Bulk) Draw (); } MoveObjectToRemoveUndoList (ELEMENT_TYPE, Element, Element, Element); return NULL; } /*! * \brief Removes all selected and visible objects. * * \return true if any objects have been removed. */ bool RemoveSelected (void) { Bulk = true; if (SelectedOperation (&RemoveFunctions, false, ALL_TYPES)) { IncrementUndoSerialNumber (); Draw (); Bulk = false; return (true); } Bulk = false; return (false); } void RemoveDegradedVias (void) { Bulk = true; VIA_LOOP (PCB->Data); { if (VIA_IS_BURIED (via) && (via->BuriedFrom == via->BuriedTo)) RemoveVia (via); } END_LOOP; Bulk = false; } /*! * \brief Remove object as referred by pointers and type, * allocated memory is passed to the 'remove undo' list. */ void * RemoveObject (int Type, void *Ptr1, void *Ptr2, void *Ptr3) { void *ptr = ObjectOperation (&RemoveFunctions, Type, Ptr1, Ptr2, Ptr3); return (ptr); } /*! * \brief Deletes rat lines only. * * Can delete all rat lines, or only selected one. */ bool DeleteRats (bool selected) { bool changed = false; Bulk = true; RAT_LOOP (PCB->Data); { if ((!selected) || TEST_FLAG (SELECTEDFLAG, line)) { changed = true; RemoveRat (line); } } END_LOOP; Bulk = false; if (changed) { Draw (); IncrementUndoSerialNumber (); } return (changed); } /*! * \brief Remove object as referred by pointers and type. * * Allocated memory is destroyed assumed to already be erased. */ void * DestroyObject (DataType *Target, int Type, void *Ptr1, void *Ptr2, void *Ptr3) { DestroyTarget = Target; return (ObjectOperation (&DestroyFunctions, Type, Ptr1, Ptr2, Ptr3)); } pcb-4.3.0/src/search.c0000664000175000017500000012307413773431044011422 00000000000000/*! * \file src/search.c * * \brief Search routines. * * Some of the functions use dummy parameters. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * * Thomas.Nau@rz.uni-ulm.de */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "global.h" #include "box.h" #include "data.h" #include "draw.h" #include "error.h" #include "find.h" #include "misc.h" #include "polygon.h" #include "rtree.h" #include "search.h" #ifdef HAVE_LIBDMALLOC #include #endif /* --------------------------------------------------------------------------- * some local identifiers */ static double PosX, PosY; /* search position for subroutines */ static Coord SearchRadius; static BoxType SearchBox; static LayerType *SearchLayer; /* --------------------------------------------------------------------------- * some local prototypes. The first parameter includes LOCKED_TYPE if we * want to include locked types in the search. */ static bool SearchLineByLocation (int, LayerType **, LineType **, LineType **); static bool SearchArcByLocation (int, LayerType **, ArcType **, ArcType **); static bool SearchRatLineByLocation (int, RatType **, RatType **, RatType **); static bool SearchTextByLocation (int, LayerType **, TextType **, TextType **); static bool SearchPolygonByLocation (int, LayerType **, PolygonType **, PolygonType **); static bool SearchPinByLocation (int, ElementType **, PinType **, PinType **); static bool SearchPadByLocation (int, ElementType **, PadType **, PadType **, bool); static bool SearchViaByLocation (int, PinType **, PinType **, PinType **); static bool SearchElementNameByLocation (int, ElementType **, TextType **, TextType **, bool); static bool SearchLinePointByLocation (int, LayerType **, LineType **, PointType **); static bool SearchPointByLocation (int, LayerType **, PolygonType **, PointType **); static bool SearchElementByLocation (int, ElementType **, ElementType **, ElementType **, bool); struct ans_info { void **ptr1, **ptr2, **ptr3; bool BackToo; double area; jmp_buf env; int locked; /*!< This will be zero or \c LOCKFLAG. */ bool found_anything; double nearest_sq_dist; }; static int pinorvia_callback (const BoxType * box, void *cl) { struct ans_info *i = (struct ans_info *) cl; PinType *pin = (PinType *) box; AnyObjectType *ptr1 = pin->Element ? pin->Element : pin; if (TEST_FLAG (i->locked, ptr1)) return 0; if (!IsPointOnPin (PosX, PosY, SearchRadius, pin)) return 0; *i->ptr1 = ptr1; *i->ptr2 = *i->ptr3 = pin; longjmp (i->env, 1); return 1; /* never reached */ } /*! * \brief Searches a via. */ static bool SearchViaByLocation (int locked, PinType ** Via, PinType ** Dummy1, PinType ** Dummy2) { struct ans_info info; /* search only if via-layer is visible */ if (!PCB->ViaOn) return false; info.ptr1 = (void **) Via; info.ptr2 = (void **) Dummy1; info.ptr3 = (void **) Dummy2; info.locked = (locked & LOCKED_TYPE) ? 0 : LOCKFLAG; if (setjmp (info.env) == 0) { r_search (PCB->Data->via_tree, &SearchBox, NULL, pinorvia_callback, &info); return false; } return true; } /*! * \brief Searches a pin. * * Starts with the newest element. */ static bool SearchPinByLocation (int locked, ElementType ** Element, PinType ** Pin, PinType ** Dummy) { struct ans_info info; /* search only if pin-layer is visible */ if (!PCB->PinOn) return false; info.ptr1 = (void **) Element; info.ptr2 = (void **) Pin; info.ptr3 = (void **) Dummy; info.locked = (locked & LOCKED_TYPE) ? 0 : LOCKFLAG; if (setjmp (info.env) == 0) r_search (PCB->Data->pin_tree, &SearchBox, NULL, pinorvia_callback, &info); else return true; return false; } static int pad_callback (const BoxType * b, void *cl) { PadType *pad = (PadType *) b; struct ans_info *i = (struct ans_info *) cl; AnyObjectType *ptr1 = pad->Element; double sq_dist; /* Reject locked pads, backside pads (if !BackToo), and non-hit pads */ if (TEST_FLAG (i->locked, ptr1) || (!FRONT (pad) && !i->BackToo) || !IsPointInPad (PosX, PosY, SearchRadius, pad)) return 0; /* Determine how close our test-position was to the center of the pad */ sq_dist = (PosX - (pad->Point1.X + (pad->Point2.X - pad->Point1.X) / 2)) * (PosX - (pad->Point1.X + (pad->Point2.X - pad->Point1.X) / 2)) + (PosY - (pad->Point1.Y + (pad->Point2.Y - pad->Point1.Y) / 2)) * (PosY - (pad->Point1.Y + (pad->Point2.Y - pad->Point1.Y) / 2)); /* If this was the closest hit so far, record it */ if (!i->found_anything || sq_dist < i->nearest_sq_dist) { *i->ptr1 = ptr1; *i->ptr2 = *i->ptr3 = pad; i->found_anything = true; i->nearest_sq_dist = sq_dist; } return 0; } /*! * \brief Searches a pad. * * Starts with the newest element. */ static bool SearchPadByLocation (int locked, ElementType ** Element, PadType ** Pad, PadType ** Dummy, bool BackToo) { struct ans_info info; /* search only if pin-layer is visible */ if (!PCB->PinOn) return (false); info.ptr1 = (void **) Element; info.ptr2 = (void **) Pad; info.ptr3 = (void **) Dummy; info.locked = (locked & LOCKED_TYPE) ? 0 : LOCKFLAG; info.BackToo = (BackToo && PCB->InvisibleObjectsOn); info.found_anything = false; r_search (PCB->Data->pad_tree, &SearchBox, NULL, pad_callback, &info); return info.found_anything; } struct line_info { LineType **Line; PointType **Point; double least; jmp_buf env; int locked; }; static int line_callback (const BoxType * box, void *cl) { struct line_info *i = (struct line_info *) cl; LineType *l = (LineType *) box; if (TEST_FLAG (i->locked, l)) return 0; if (!IsPointInPad (PosX, PosY, SearchRadius, (PadType *)l)) return 0; *i->Line = l; *i->Point = (PointType *) l; longjmp (i->env, 1); return 1; /* never reached */ } /*! * \brief Searches ordinary line on the SearchLayer. */ static bool SearchLineByLocation (int locked, LayerType ** Layer, LineType ** Line, LineType ** Dummy) { struct line_info info; info.Line = Line; info.Point = (PointType **) Dummy; info.locked = (locked & LOCKED_TYPE) ? 0 : LOCKFLAG; *Layer = SearchLayer; if (setjmp (info.env) == 0) { r_search (SearchLayer->line_tree, &SearchBox, NULL, line_callback, &info); return false; } return (true); } static int rat_callback (const BoxType * box, void *cl) { LineType *line = (LineType *) box; struct ans_info *i = (struct ans_info *) cl; if (TEST_FLAG (i->locked, line)) return 0; if (TEST_FLAG (VIAFLAG, line) ? (Distance (line->Point1.X, line->Point1.Y, PosX, PosY) <= line->Thickness * 2 + SearchRadius) : IsPointOnLine (PosX, PosY, SearchRadius, line)) { *i->ptr1 = *i->ptr2 = *i->ptr3 = line; longjmp (i->env, 1); } return 0; } /*! * \brief Searches rat lines if they are visible. */ static bool SearchRatLineByLocation (int locked, RatType ** Line, RatType ** Dummy1, RatType ** Dummy2) { struct ans_info info; info.ptr1 = (void **) Line; info.ptr2 = (void **) Dummy1; info.ptr3 = (void **) Dummy2; info.locked = (locked & LOCKED_TYPE) ? 0 : LOCKFLAG; if (setjmp (info.env) == 0) { r_search (PCB->Data->rat_tree, &SearchBox, NULL, rat_callback, &info); return false; } return (true); } struct arc_info { ArcType **Arc, **Dummy; PointType **Point; double least; jmp_buf env; int locked; }; static int arc_callback (const BoxType * box, void *cl) { struct arc_info *i = (struct arc_info *) cl; ArcType *a = (ArcType *) box; if (TEST_FLAG (i->locked, a)) return 0; if (!IsPointOnArc (PosX, PosY, SearchRadius, a)) return 0; *i->Arc = a; *i->Dummy = a; longjmp (i->env, 1); return 1; /* never reached */ } /*! * \brief Searches arc on the SearchLayer. */ static bool SearchArcByLocation (int locked, LayerType ** Layer, ArcType ** Arc, ArcType ** Dummy) { struct arc_info info; info.Arc = Arc; info.Dummy = Dummy; info.locked = (locked & LOCKED_TYPE) ? 0 : LOCKFLAG; *Layer = SearchLayer; if (setjmp (info.env) == 0) { r_search (SearchLayer->arc_tree, &SearchBox, NULL, arc_callback, &info); return false; } return (true); } static int text_callback (const BoxType * box, void *cl) { TextType *text = (TextType *) box; struct ans_info *i = (struct ans_info *) cl; if (TEST_FLAG (i->locked, text)) return 0; if (POINT_IN_BOX (PosX, PosY, &text->BoundingBox)) { *i->ptr2 = *i->ptr3 = text; longjmp (i->env, 1); } return 0; } /*! * \brief Searches text on the SearchLayer. */ static bool SearchTextByLocation (int locked, LayerType ** Layer, TextType ** Text, TextType ** Dummy) { struct ans_info info; *Layer = SearchLayer; info.ptr2 = (void **) Text; info.ptr3 = (void **) Dummy; info.locked = (locked & LOCKED_TYPE) ? 0 : LOCKFLAG; if (setjmp (info.env) == 0) { r_search (SearchLayer->text_tree, &SearchBox, NULL, text_callback, &info); return false; } return (true); } static int polygon_callback (const BoxType * box, void *cl) { PolygonType *polygon = (PolygonType *) box; struct ans_info *i = (struct ans_info *) cl; if (TEST_FLAG (i->locked, polygon)) return 0; if (IsPointInPolygon (PosX, PosY, SearchRadius, polygon)) { *i->ptr2 = *i->ptr3 = polygon; longjmp (i->env, 1); } return 0; } /*! * \brief Searches a polygon on the SearchLayer. */ static bool SearchPolygonByLocation (int locked, LayerType ** Layer, PolygonType ** Polygon, PolygonType ** Dummy) { struct ans_info info; *Layer = SearchLayer; info.ptr2 = (void **) Polygon; info.ptr3 = (void **) Dummy; info.locked = (locked & LOCKED_TYPE) ? 0 : LOCKFLAG; if (setjmp (info.env) == 0) { r_search (SearchLayer->polygon_tree, &SearchBox, NULL, polygon_callback, &info); return false; } return (true); } static int linepoint_callback (const BoxType * b, void *cl) { LineType *line = (LineType *) b; struct line_info *i = (struct line_info *) cl; int ret_val = 0; double d; if (TEST_FLAG (i->locked, line)) return 0; /* some stupid code to check both points */ d = Distance (PosX, PosY, line->Point1.X, line->Point1.Y); if (d < i->least) { i->least = d; *i->Line = line; *i->Point = &line->Point1; ret_val = 1; } d = Distance (PosX, PosY, line->Point2.X, line->Point2.Y); if (d < i->least) { i->least = d; *i->Line = line; *i->Point = &line->Point2; ret_val = 1; } return ret_val; } /*! * \brief Searches a line-point on all the search layer. */ static bool SearchLinePointByLocation (int locked, LayerType ** Layer, LineType ** Line, PointType ** Point) { struct line_info info; *Layer = SearchLayer; info.Line = Line; info.Point = Point; *Point = NULL; info.least = MAX_LINE_POINT_DISTANCE + SearchRadius; info.locked = (locked & LOCKED_TYPE) ? 0 : LOCKFLAG; if (r_search (SearchLayer->line_tree, &SearchBox, NULL, linepoint_callback, &info)) return true; return false; } static int arcpoint_callback (const BoxType * b, void *cl) { ArcType *arc = (ArcType *) b; struct arc_info *i = (struct arc_info *) cl; int ret_val = 0; double d; if (TEST_FLAG (i->locked, arc)) return 0; d = Distance (PosX, PosY, arc->Point1.X, arc->Point1.Y); if (d < i->least) { i->least = d; *i->Arc = arc; *i->Point = &arc->Point1; ret_val = 1; } d = Distance (PosX, PosY, arc->Point2.X, arc->Point2.Y); if (d < i->least) { i->least = d; *i->Arc = arc; *i->Point = &arc->Point2; ret_val = 1; } return ret_val; } /*! * \brief Searches an arc-point on all the search layer. */ static bool SearchArcPointByLocation (int locked, LayerType **Layer, ArcType **arc, PointType **Point) { struct arc_info info; *Layer = SearchLayer; info.Arc = arc; info.Point = Point; *Point = NULL; info.least = MAX_ARC_POINT_DISTANCE + SearchRadius; info.locked = (locked & LOCKED_TYPE) ? 0 : LOCKFLAG; if (r_search (SearchLayer->arc_tree, &SearchBox, NULL, arcpoint_callback, &info)) return true; return false; } /*! * \brief Searches a polygon-point on all layers that are switched on * in layerstack order. */ static bool SearchPointByLocation (int locked, LayerType ** Layer, PolygonType ** Polygon, PointType ** Point) { double d, least; bool found = false; least = SearchRadius + MAX_POLYGON_POINT_DISTANCE; *Layer = SearchLayer; POLYGON_LOOP (*Layer); { POLYGONPOINT_LOOP (polygon); { d = Distance (point->X, point->Y, PosX, PosY); if (d < least) { least = d; *Polygon = polygon; *Point = point; found = true; } } END_LOOP; } END_LOOP; if (found) return (true); return (false); } static int name_callback (const BoxType * box, void *cl) { TextType *text = (TextType *) box; struct ans_info *i = (struct ans_info *) cl; ElementType *element = (ElementType *) text->Element; double newarea; if (TEST_FLAG (i->locked, text)) return 0; if ((FRONT (element) || i->BackToo) && !TEST_FLAG (HIDENAMEFLAG, element) && POINT_IN_BOX (PosX, PosY, &text->BoundingBox)) { /* use the text with the smallest bounding box */ newarea = (text->BoundingBox.X2 - text->BoundingBox.X1) * (double) (text->BoundingBox.Y2 - text->BoundingBox.Y1); if (newarea < i->area) { i->area = newarea; *i->ptr1 = element; *i->ptr2 = *i->ptr3 = text; } return 1; } return 0; } /*! * \brief Searches the name of an element. * * The search starts with the last element and goes back to the * beginning. */ static bool SearchElementNameByLocation (int locked, ElementType ** Element, TextType ** Text, TextType ** Dummy, bool BackToo) { struct ans_info info; /* package layer have to be switched on */ if (PCB->ElementOn) { info.ptr1 = (void **) Element; info.ptr2 = (void **) Text; info.ptr3 = (void **) Dummy; info.area = SQUARE (MAX_COORD); info.BackToo = (BackToo && PCB->InvisibleObjectsOn); info.locked = (locked & LOCKED_TYPE) ? 0 : LOCKFLAG; if (r_search (PCB->Data->name_tree[NAME_INDEX (PCB)], &SearchBox, NULL, name_callback, &info)) return true; } return (false); } static int element_callback (const BoxType * box, void *cl) { ElementType *element = (ElementType *) box; struct ans_info *i = (struct ans_info *) cl; double newarea; if (TEST_FLAG (i->locked, element)) return 0; if ((FRONT (element) || i->BackToo) && POINT_IN_BOX (PosX, PosY, &element->VBox)) { /* use the element with the smallest bounding box */ newarea = (element->VBox.X2 - element->VBox.X1) * (double) (element->VBox.Y2 - element->VBox.Y1); if (newarea < i->area) { i->area = newarea; *i->ptr1 = *i->ptr2 = *i->ptr3 = element; return 1; } } return 0; } /*! * \brief Searches an element. * * The search starts with the last element and goes back to the * beginning. * * If more than one element matches, the smallest one is taken. */ static bool SearchElementByLocation (int locked, ElementType ** Element, ElementType ** Dummy1, ElementType ** Dummy2, bool BackToo) { struct ans_info info; /* Both package layers have to be switched on */ if (PCB->ElementOn && PCB->PinOn) { info.ptr1 = (void **) Element; info.ptr2 = (void **) Dummy1; info.ptr3 = (void **) Dummy2; info.area = SQUARE (MAX_COORD); info.BackToo = (BackToo && PCB->InvisibleObjectsOn); info.locked = (locked & LOCKED_TYPE) ? 0 : LOCKFLAG; if (r_search (PCB->Data->element_tree, &SearchBox, NULL, element_callback, &info)) return true; } return false; } /*! * \brief Checks if a point is on a pin. */ bool IsPointOnPin (Coord X, Coord Y, Coord Radius, PinType *pin) { Coord t = PIN_SIZE (pin) / 2; if (TEST_FLAG (SQUAREFLAG, pin)) { BoxType b; b.X1 = pin->X - t; b.X2 = pin->X + t; b.Y1 = pin->Y - t; b.Y2 = pin->Y + t; if (IsPointInBox (X, Y, &b, Radius)) return true; } else if (Distance (pin->X, pin->Y, X, Y) <= Radius + t) return true; return false; } /*! * \brief Checks if a rat-line end is on a PV. */ bool IsPointOnLineEnd (Coord X, Coord Y, RatType *Line) { if (((X == Line->Point1.X) && (Y == Line->Point1.Y)) || ((X == Line->Point2.X) && (Y == Line->Point2.Y))) return (true); return (false); } /*! * \brief Checks if a line intersects with a PV. * *
 * let the point be (X,Y) and the line (X1,Y1)(X2,Y2).
 * Let L be a vector along the line: 
 *
 *   vec(L) = (X2-X1, Y2-Y1)
 *       L  = ((X2-X1)^2 + (Y2-Y1)^2)^0.5
 *
 * Let P be a vector from the endpoint of the line to the point in question:
 * The vector P is: 
 *
 *   vec(P) = (X-X1, Y-Y1)
 * 
 * let Q be the point of perpendicular projection of (X,Y) onto the line
 *
 *   QX = X1 + D1*(X2-X1) / L
 *   QY = Y1 + D1*(Y2-Y1) / L
 *
 * where D1 is the distance from (X1, Y1) to (QX, QY). The magnitude of D1
 * can be written as:
 *
 *   D1 = vec(L) . vec(P) / abs(L)    (dot product)
 *
 * or (from vector geometry):
 *
 *        (Y1-Y)(Y1-Y2)+(X1-X)(X1-X2)
 *   D1 = ---------------------------
 *                     L
 *
 *   D1 < 0   Q is on backward extension of the line
 *   D1 > L   Q is on forward extension of the line
 *   else     Q is on the line
 *
 * With some coordinate switcheroos, we can get a vector perpendicular to L
 *
 *                 Lp_x     Lp_y
 *   vec (Lp) =  (Y2-Y1, -(X2-X1))
 *
 * The distance from the line to the point, D2, can be computed with a
 * similar dot product. The signed distance from (X,Y) to Q is
 *
 *        (Y2-Y1)(X-X1)-(X2-X1)(Y-Y1)
 *   D2 = ----------------------------
 *                     L
 *
 * Finally, D1 and D2 are orthogonal, so we can sum them easily
 * by pythagorean theorem.
 * 
*/ bool IsPointOnLine (Coord X, Coord Y, Coord Radius, LineType *Line) { double D1, D2, L; /* Get length of segment */ L = Distance (Line->Point1.X, Line->Point1.Y, Line->Point2.X, Line->Point2.Y); if (L < 0.1) return Distance (X, Y, Line->Point1.X, Line->Point1.Y) < Radius + Line->Thickness / 2; /* Get distance from (X1, Y1) to Q (on the line) */ D1 = ((double) (Y - Line->Point1.Y) * (Line->Point2.Y - Line->Point1.Y) + (double) (X - Line->Point1.X) * (Line->Point2.X - Line->Point1.X)) / L; /* Translate this into distance to Q from segment */ if (D1 < 0) D1 = -D1; else if (D1 > L) D1 -= L; else D1 = 0; /* Get distance from (X, Y) to Q */ D2 = ((double) (X - Line->Point1.X) * (Line->Point2.Y - Line->Point1.Y) - (double) (Y - Line->Point1.Y) * (Line->Point2.X - Line->Point1.X)) / L; /* Total distance is then the pythagorean sum of these */ return hypot (D1, D2) <= Radius + Line->Thickness / 2; } /*! * \brief Checks if a line crosses a rectangle. */ bool IsLineInRectangle (Coord X1, Coord Y1, Coord X2, Coord Y2, LineType *Line) { LineType line; /* first, see if point 1 is inside the rectangle */ /* in case the whole line is inside the rectangle */ if (X1 < Line->Point1.X && X2 > Line->Point1.X && Y1 < Line->Point1.Y && Y2 > Line->Point1.Y) return (true); /* construct a set of dummy lines and check each of them */ line.Thickness = 0; line.Flags = NoFlags (); /* upper-left to upper-right corner */ line.Point1.Y = line.Point2.Y = Y1; line.Point1.X = X1; line.Point2.X = X2; if (LineLineIntersect (&line, Line)) return (true); /* upper-right to lower-right corner */ line.Point1.X = X2; line.Point1.Y = Y1; line.Point2.Y = Y2; if (LineLineIntersect (&line, Line)) return (true); /* lower-right to lower-left corner */ line.Point1.Y = Y2; line.Point1.X = X1; line.Point2.X = X2; if (LineLineIntersect (&line, Line)) return (true); /* lower-left to upper-left corner */ line.Point2.X = X1; line.Point1.Y = Y1; line.Point2.Y = Y2; if (LineLineIntersect (&line, Line)) return (true); return (false); } /*! * \brief Checks if a point (of null radius) is in a slanted rectangle. */ static int IsPointInQuadrangle(PointType p[4], PointType *l) { Coord dx, dy, x, y; double prod0, prod1; dx = p[1].X - p[0].X; dy = p[1].Y - p[0].Y; x = l->X - p[0].X; y = l->Y - p[0].Y; prod0 = (double) x * dx + (double) y * dy; x = l->X - p[1].X; y = l->Y - p[1].Y; prod1 = (double) x * dx + (double) y * dy; if (prod0 * prod1 <= 0) { dx = p[1].X - p[2].X; dy = p[1].Y - p[2].Y; prod0 = (double) x * dx + (double) y * dy; x = l->X - p[2].X; y = l->Y - p[2].Y; prod1 = (double) x * dx + (double) y * dy; if (prod0 * prod1 <= 0) return true; } return false; } /*! * \brief Checks if a line crosses a quadrangle: almost copied from * IsLineInRectangle(). * * \note Actually this quadrangle is a slanted rectangle. */ bool IsLineInQuadrangle (PointType p[4], LineType *Line) { LineType line; /* first, see if point 1 is inside the rectangle */ /* in case the whole line is inside the rectangle */ if (IsPointInQuadrangle(p,&(Line->Point1))) return true; if (IsPointInQuadrangle(p,&(Line->Point2))) return true; /* construct a set of dummy lines and check each of them */ line.Thickness = 0; line.Flags = NoFlags (); /* upper-left to upper-right corner */ line.Point1.X = p[0].X; line.Point1.Y = p[0].Y; line.Point2.X = p[1].X; line.Point2.Y = p[1].Y; if (LineLineIntersect (&line, Line)) return (true); /* upper-right to lower-right corner */ line.Point1.X = p[2].X; line.Point1.Y = p[2].Y; if (LineLineIntersect (&line, Line)) return (true); /* lower-right to lower-left corner */ line.Point2.X = p[3].X; line.Point2.Y = p[3].Y; if (LineLineIntersect (&line, Line)) return (true); /* lower-left to upper-left corner */ line.Point1.X = p[0].X; line.Point1.Y = p[0].Y; if (LineLineIntersect (&line, Line)) return (true); return (false); } /*! * \brief Checks if an arc crosses a square. */ bool IsArcInRectangle (Coord X1, Coord Y1, Coord X2, Coord Y2, ArcType *Arc) { LineType line; /* construct a set of dummy lines and check each of them */ line.Thickness = 0; line.Flags = NoFlags (); /* upper-left to upper-right corner */ line.Point1.Y = line.Point2.Y = Y1; line.Point1.X = X1; line.Point2.X = X2; if (LineArcIntersect (&line, Arc)) return (true); /* upper-right to lower-right corner */ line.Point1.X = line.Point2.X = X2; line.Point1.Y = Y1; line.Point2.Y = Y2; if (LineArcIntersect (&line, Arc)) return (true); /* lower-right to lower-left corner */ line.Point1.Y = line.Point2.Y = Y2; line.Point1.X = X1; line.Point2.X = X2; if (LineArcIntersect (&line, Arc)) return (true); /* lower-left to upper-left corner */ line.Point1.X = line.Point2.X = X1; line.Point1.Y = Y1; line.Point2.Y = Y2; if (LineArcIntersect (&line, Arc)) return (true); return (false); } /*! * \brief Check if a circle of Radius with center at (X, Y) intersects * a Pad. * * Written to enable arbitrary pad directions; for rounded pads, too. */ bool IsPointInPad (Coord X, Coord Y, Coord Radius, PadType *Pad) { double r, Sin, Cos; Coord x; Coord t2 = (Pad->Thickness + 1) / 2, range; PadType pad = *Pad; /* series of transforms saving range */ /* move Point1 to the origin */ X -= pad.Point1.X; Y -= pad.Point1.Y; pad.Point2.X -= pad.Point1.X; pad.Point2.Y -= pad.Point1.Y; /* so, pad.Point1.X = pad.Point1.Y = 0; */ /* rotate round (0, 0) so that Point2 coordinates be (r, 0) */ r = Distance (0, 0, pad.Point2.X, pad.Point2.Y); if (r < .1) { Cos = 1; Sin = 0; } else { Sin = pad.Point2.Y / r; Cos = pad.Point2.X / r; } x = X; X = X * Cos + Y * Sin; Y = Y * Cos - x * Sin; /* now pad.Point2.X = r; pad.Point2.Y = 0; */ /* take into account the ends */ if (TEST_FLAG (SQUAREFLAG, Pad)) { r += Pad->Thickness; X += t2; } if (Y < 0) Y = -Y; /* range value is evident now*/ if (TEST_FLAG (SQUAREFLAG, Pad)) { if (X <= 0) { if (Y <= t2) range = -X; else return Radius > Distance (0, t2, X, Y); } else if (X >= r) { if (Y <= t2) range = X - r; else return Radius > Distance (r, t2, X, Y); } else range = Y - t2; } else/*Rounded pad: even more simple*/ { if (X <= 0) return (Radius + t2) > Distance (0, 0, X, Y); else if (X >= r) return (Radius + t2) > Distance (r, 0, X, Y); else range = Y - t2; } return range < Radius; } /*! * \brief . * * \note Assumes box has point1 with numerically lower X and Y * coordinates. */ bool IsPointInBox (Coord X, Coord Y, BoxType *box, Coord Radius) { Coord width, height, range; /* Compute coordinates relative to Point1 */ X -= box->X1; Y -= box->Y1; width = box->X2 - box->X1; height = box->Y2 - box->Y1; if (X <= 0) { if (Y < 0) return Radius > Distance (0, 0, X, Y); else if (Y > height) return Radius > Distance (0, height, X, Y); else range = -X; } else if (X >= width) { if (Y < 0) return Radius > Distance (width, 0, X, Y); else if (Y > height) return Radius > Distance (width, height, X, Y); else range = X - width; } else { if (Y < 0) range = -Y; else if (Y > height) range = Y - height; else return true; } return range < Radius; } /*! * \brief . * * \todo This code is BROKEN in the case of non-circular arcs, and in * the case that the arc thickness is greater than the radius. */ bool IsPointOnArc (Coord X, Coord Y, Coord Radius, ArcType *Arc) { /* Calculate angle of point from arc center */ double p_dist = Distance (X, Y, Arc->X, Arc->Y); double p_cos = (X - Arc->X) / p_dist; Angle p_ang = acos (p_cos) * RAD_TO_DEG; Angle ang1, ang2; /* Convert StartAngle, Delta into bounding angles in [0, 720) */ if (Arc->Delta > 0) { ang1 = NormalizeAngle (Arc->StartAngle); ang2 = NormalizeAngle (Arc->StartAngle + Arc->Delta); } else { ang1 = NormalizeAngle (Arc->StartAngle + Arc->Delta); ang2 = NormalizeAngle (Arc->StartAngle); } /* This could be the case if one of the angles was negative or > 360 * degrees before the call to NormalizeAngles * */ if (ang1 > ang2) ang2 += 360; /* Make sure full circles aren't treated as zero-length arcs */ if (Arc->Delta == 360 || Arc->Delta == -360) ang2 = ang1 + 360; if (Y > Arc->Y) p_ang = -p_ang; /* In pcb, theta = 0 points to the left (-x) */ p_ang += 180; /*If either angle is greater than 360, then we're into the second time * around the circle, so, we need to make sure our target is also. * */ if ((ang2 > 360) && p_ang < ang1) p_ang += 360; /* Check point is outside arc range, check distance from endpoints */ if (ang1 >= p_ang || ang2 <= p_ang) { Coord ArcX, ArcY; ArcX = Arc->X + Arc->Width * cos ((Arc->StartAngle + 180) / RAD_TO_DEG); ArcY = Arc->Y - Arc->Width * sin ((Arc->StartAngle + 180) / RAD_TO_DEG); if (Distance (X, Y, ArcX, ArcY) < Radius + Arc->Thickness / 2) return true; ArcX = Arc->X + Arc->Width * cos ((Arc->StartAngle + Arc->Delta + 180) / RAD_TO_DEG); ArcY = Arc->Y - Arc->Width * sin ((Arc->StartAngle + Arc->Delta + 180) / RAD_TO_DEG); if (Distance (X, Y, ArcX, ArcY) < Radius + Arc->Thickness / 2) return true; return false; } /* If point is inside the arc range, just compare it to the arc */ return fabs (Distance (X, Y, Arc->X, Arc->Y) - Arc->Width) < Radius + Arc->Thickness / 2; } static unsigned int SearchLayerObjectInternal (LayerType *layer, unsigned int Type, unsigned int HigherAvail, double HigherBound, void **Result1, void **Result2, void **Result3) { int locked = Type & LOCKED_TYPE; if (!layer->On) return NO_TYPE; SearchLayer = layer; if ((HigherAvail & (PIN_TYPE | PAD_TYPE)) == 0 && Type & POLYGONPOINT_TYPE && SearchPointByLocation (locked, (LayerType **)Result1, (PolygonType **) Result2, (PointType **) Result3)) return POLYGONPOINT_TYPE; if ((HigherAvail & (PIN_TYPE | PAD_TYPE)) == 0 && Type & LINEPOINT_TYPE && SearchLinePointByLocation (locked, (LayerType **)Result1, (LineType **) Result2, (PointType **) Result3)) return LINEPOINT_TYPE; if ((HigherAvail & (PIN_TYPE | PAD_TYPE)) == 0 && Type & LINE_TYPE && SearchLineByLocation (locked, (LayerType **)Result1, (LineType **) Result2, (LineType **) Result3)) return LINE_TYPE; if ((HigherAvail & (PIN_TYPE | PAD_TYPE)) == 0 && Type & ARCPOINT_TYPE && SearchArcPointByLocation (locked, (LayerType **)Result1, (ArcType **) Result2, (PointType **) Result3)) return ARCPOINT_TYPE; if ((HigherAvail & (PIN_TYPE | PAD_TYPE)) == 0 && Type & ARC_TYPE && SearchArcByLocation (locked, (LayerType **)Result1, (ArcType **) Result2, (ArcType **) Result3)) return ARC_TYPE; if ((HigherAvail & (PIN_TYPE | PAD_TYPE)) == 0 && Type & TEXT_TYPE && SearchTextByLocation (locked, (LayerType **)Result1, (TextType **) Result2, (TextType **) Result3)) return TEXT_TYPE; if (Type & POLYGON_TYPE && SearchPolygonByLocation (locked, (LayerType **)Result1, (PolygonType **) Result2, (PolygonType **) Result3)) { if (HigherAvail) { BoxType *box = &(*(PolygonType **) Result2)->BoundingBox; double area = (double) (box->X2 - box->X1) * (double) (box->X2 - box->X1); /* XXX: BEHAVIOURAL CHANGE */ if (HigherBound < area) // break; return NO_TYPE; else return POLYGON_TYPE; } else { return POLYGON_TYPE; } } return NO_TYPE; } /*! * \brief Searches for any kind of object or for a set of object types * the calling routine passes two pointers to allocated memory for * storing the results. * * A type value is returned too which is NO_TYPE if no objects has been * found. * * A set of object types is passed in. * * The object is located by it's position. * * The layout is checked in the following order: * polygon-point, pin, via, line, text, elementname, polygon, element * * \note That if Type includes LOCKED_TYPE, then the search includes * locked items. Otherwise, locked items are ignored. */ int SearchObjectByLocation (unsigned Type, void **Result1, void **Result2, void **Result3, Coord X, Coord Y, Coord Radius) { void *r1, *r2, *r3; void **pr1 = &r1, **pr2 = &r2, **pr3 = &r3; int i; double HigherBound = 0; unsigned int HigherAvail = NO_TYPE; int locked = Type & LOCKED_TYPE; unsigned int type; /* setup variables used by local functions */ PosX = X; PosY = Y; SearchRadius = Radius; if (Radius) { SearchBox.X1 = X - Radius; SearchBox.Y1 = Y - Radius; SearchBox.X2 = X + Radius; SearchBox.Y2 = Y + Radius; } else { SearchBox = point_box (X, Y); } if (TEST_FLAG (LOCKNAMESFLAG, PCB)) { Type &= ~ (ELEMENTNAME_TYPE | TEXT_TYPE); } if (TEST_FLAG (HIDENAMESFLAG, PCB)) { Type &= ~ELEMENTNAME_TYPE; } if (TEST_FLAG (ONLYNAMESFLAG, PCB)) { Type &= (ELEMENTNAME_TYPE | TEXT_TYPE); } if (TEST_FLAG (THINDRAWFLAG, PCB) || TEST_FLAG (THINDRAWPOLYFLAG, PCB)) { Type &= ~POLYGON_TYPE; } if (Type & RATLINE_TYPE && PCB->RatOn && SearchRatLineByLocation (locked, (RatType **) Result1, (RatType **) Result2, (RatType **) Result3)) return (RATLINE_TYPE); if (Type & VIA_TYPE && SearchViaByLocation (locked, (PinType **) Result1, (PinType **) Result2, (PinType **) Result3)) return (VIA_TYPE); if (Type & PIN_TYPE && SearchPinByLocation (locked, (ElementType **) pr1, (PinType **) pr2, (PinType **) pr3)) HigherAvail = PIN_TYPE; if (!HigherAvail && Type & PAD_TYPE && SearchPadByLocation (locked, (ElementType **) pr1, (PadType **) pr2, (PadType **) pr3, false)) HigherAvail = PAD_TYPE; if (!HigherAvail && Type & ELEMENTNAME_TYPE && SearchElementNameByLocation (locked, (ElementType **) pr1, (TextType **) pr2, (TextType **) pr3, false)) { BoxType *box = &((TextType *) r2)->BoundingBox; HigherBound = (double) (box->X2 - box->X1) * (double) (box->Y2 - box->Y1); HigherAvail = ELEMENTNAME_TYPE; } if (!HigherAvail && Type & ELEMENT_TYPE && SearchElementByLocation (locked, (ElementType **) pr1, (ElementType **) pr2, (ElementType **) pr3, false)) { BoxType *box = &((ElementType *) r1)->BoundingBox; HigherBound = (double) (box->X2 - box->X1) * (double) (box->Y2 - box->Y1); HigherAvail = ELEMENT_TYPE; } /* uncomment if merged with peterc_layers type = SearchLayerObjectInternal (&PCB->Data->SOLDERMASKLAYER, Type, HigherAvail, HigherBound, Result1, Result2, Result3); if (type != NO_TYPE) return type; */ type = SearchLayerObjectInternal (&PCB->Data->SILKLAYER, Type, HigherAvail, HigherBound, Result1, Result2, Result3); if (type != NO_TYPE) return type; for (i = 0; i < max_copper_layer; i++) { type = SearchLayerObjectInternal (LAYER_ON_STACK (i), Type, HigherAvail, HigherBound, Result1, Result2, Result3); if (type != NO_TYPE) return type; } if (PCB->InvisibleObjectsOn) { type = SearchLayerObjectInternal (&PCB->Data->BACKSILKLAYER, Type, HigherAvail, HigherBound, Result1, Result2, Result3); if (type != NO_TYPE) return type; /* uncomment if merged with peterc_layers type = SearchLayerObjectInternal (&PCB->Data->BACKSOLDERMASKLAYER, Type, HigherAvail, HigherBound, Result1, Result2, Result3); if (type != NO_TYPE) return type; */ } /* return any previously found objects */ if (HigherAvail & PIN_TYPE) { *Result1 = r1; *Result2 = r2; *Result3 = r3; return (PIN_TYPE); } if (HigherAvail & PAD_TYPE) { *Result1 = r1; *Result2 = r2; *Result3 = r3; return (PAD_TYPE); } if (HigherAvail & ELEMENTNAME_TYPE) { *Result1 = r1; *Result2 = r2; *Result3 = r3; return (ELEMENTNAME_TYPE); } if (HigherAvail & ELEMENT_TYPE) { *Result1 = r1; *Result2 = r2; *Result3 = r3; return (ELEMENT_TYPE); } /* search the 'invisible objects' last */ if (!PCB->InvisibleObjectsOn) return (NO_TYPE); if (Type & PAD_TYPE && SearchPadByLocation (locked, (ElementType **) Result1, (PadType **) Result2, (PadType **) Result3, true)) return (PAD_TYPE); if (Type & ELEMENTNAME_TYPE && SearchElementNameByLocation (locked, (ElementType **) Result1, (TextType **) Result2, (TextType **) Result3, true)) return (ELEMENTNAME_TYPE); if (Type & ELEMENT_TYPE && SearchElementByLocation (locked, (ElementType **) Result1, (ElementType **) Result2, (ElementType **) Result3, true)) return (ELEMENT_TYPE); return (NO_TYPE); } /*! * \brief Searches for a object by it's unique ID. * * It doesn't matter if the object is visible or not. * * The search is performed on a PCB, a buffer or on the remove list. * * The calling routine passes two pointers to allocated memory for * storing the results. * * \return A type value is returned too which is NO_TYPE if no objects * has been found. */ int SearchObjectByID (DataType *Base, void **Result1, void **Result2, void **Result3, int ID, int type) { if (type & (LINE_TYPE | LINEPOINT_TYPE)) { ALLLINE_LOOP (Base); { if (line->ID == ID) { *Result1 = (void *) layer; *Result2 = *Result3 = (void *) line; return (LINE_TYPE); } if (line->Point1.ID == ID) { *Result1 = (void *) layer; *Result2 = (void *) line; *Result3 = (void *) &line->Point1; return (LINEPOINT_TYPE); } if (line->Point2.ID == ID) { *Result1 = (void *) layer; *Result2 = (void *) line; *Result3 = (void *) &line->Point2; return (LINEPOINT_TYPE); } } ENDALL_LOOP; } if (type & ARC_TYPE) { ALLARC_LOOP (Base); { if (arc->ID == ID) { *Result1 = (void *) layer; *Result2 = *Result3 = (void *) arc; return (ARC_TYPE); } } ENDALL_LOOP; } if (type & TEXT_TYPE) { ALLTEXT_LOOP (Base); { if (text->ID == ID) { *Result1 = (void *) layer; *Result2 = *Result3 = (void *) text; return (TEXT_TYPE); } } ENDALL_LOOP; } if (type & (POLYGON_TYPE | POLYGONPOINT_TYPE)) { ALLPOLYGON_LOOP (Base); { if (polygon->ID == ID) { *Result1 = (void *) layer; *Result2 = *Result3 = (void *) polygon; return (POLYGON_TYPE); } if (type & POLYGONPOINT_TYPE) POLYGONPOINT_LOOP (polygon); { if (point->ID == ID) { *Result1 = (void *) layer; *Result2 = (void *) polygon; *Result3 = (void *) point; return (POLYGONPOINT_TYPE); } } END_LOOP; } ENDALL_LOOP; } if (type & VIA_TYPE) { VIA_LOOP (Base); { if (via->ID == ID) { *Result1 = *Result2 = *Result3 = (void *) via; return (VIA_TYPE); } } END_LOOP; } if (type & (RATLINE_TYPE | LINEPOINT_TYPE)) { RAT_LOOP (Base); { if (line->ID == ID) { *Result1 = *Result2 = *Result3 = (void *) line; return (RATLINE_TYPE); } if (line->Point1.ID == ID) { *Result1 = (void *) NULL; *Result2 = (void *) line; *Result3 = (void *) &line->Point1; return (LINEPOINT_TYPE); } if (line->Point2.ID == ID) { *Result1 = (void *) NULL; *Result2 = (void *) line; *Result3 = (void *) &line->Point2; return (LINEPOINT_TYPE); } } END_LOOP; } if (type & (ELEMENT_TYPE | PAD_TYPE | PIN_TYPE | ELEMENTLINE_TYPE | ELEMENTNAME_TYPE | ELEMENTARC_TYPE)) /* check pins and elementnames too */ ELEMENT_LOOP (Base); { if (element->ID == ID) { *Result1 = *Result2 = *Result3 = (void *) element; return (ELEMENT_TYPE); } if (type & ELEMENTLINE_TYPE) ELEMENTLINE_LOOP (element); { if (line->ID == ID) { *Result1 = (void *) element; *Result2 = *Result3 = (void *) line; return (ELEMENTLINE_TYPE); } } END_LOOP; if (type & ELEMENTARC_TYPE) ARC_LOOP (element); { if (arc->ID == ID) { *Result1 = (void *) element; *Result2 = *Result3 = (void *) arc; return (ELEMENTARC_TYPE); } } END_LOOP; if (type & ELEMENTNAME_TYPE) ELEMENTTEXT_LOOP (element); { if (text->ID == ID) { *Result1 = (void *) element; *Result2 = *Result3 = (void *) text; return (ELEMENTNAME_TYPE); } } END_LOOP; if (type & PIN_TYPE) PIN_LOOP (element); { if (pin->ID == ID) { *Result1 = (void *) element; *Result2 = *Result3 = (void *) pin; return (PIN_TYPE); } } END_LOOP; if (type & PAD_TYPE) PAD_LOOP (element); { if (pad->ID == ID) { *Result1 = (void *) element; *Result2 = *Result3 = (void *) pad; return (PAD_TYPE); } } END_LOOP; } END_LOOP; #ifdef DEBUG Message ("hace: Internal error, search for ID %d failed\n", ID); #endif /* DEBUG */ return (NO_TYPE); } /*! * \brief Searches for an element by its board name. * * \return The function returns a pointer to the element, NULL if not * found. */ ElementType * SearchElementByName (DataType *Base, char *Name) { ElementType *result = NULL; ELEMENT_LOOP (Base); { if (element->Name[1].TextString && NSTRCMP (element->Name[1].TextString, Name) == 0) { result = element; return (result); } } END_LOOP; return result; } /*! * \brief Searches for an layer by its board name. * * \return The function returns an index of the layer, -1 if not * found. */ int SearchLayerByName (DataType *Base, char *Name) { int result = 0; LAYER_LOOP (Base, max_copper_layer); { if (layer->Name && NSTRCMP (layer->Name, Name) == 0) { return result; } else result++; } END_LOOP; return -1; } /*! * \brief Searches the cursor position for the type. */ int SearchScreen (Coord X, Coord Y, int Type, void **Result1, void **Result2, void **Result3) { int ans; ans = SearchObjectByLocation (Type, Result1, Result2, Result3, X, Y, SLOP * pixel_slop); return (ans); } pcb-4.3.0/src/error.h0000664000175000017500000000263213773431044011307 00000000000000/*! * \file src/error.h * * \brief Prototypes for error and debug functions. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * Thomas.Nau@rz.uni-ulm.de */ #ifndef PCB_ERROR_H #define PCB_ERROR_H #define STATUS_OK 0 #define STATUS_BREAK 1 #define STATUS_ERROR -1 void Message (const char *Format, ...); void MyFatal (char *Format, ...); void OpenErrorMessage (char *); void PopenErrorMessage (char *); void OpendirErrorMessage (char *); void ChdirErrorMessage (char *); void CatchSignal (int); #endif pcb-4.3.0/src/autoplace.c0000664000175000017500000006317013773431044012132 00000000000000/*! * \file src/autoplace.c * * \brief Functions used to autoplace elements. * * \author This module, autoplace.c, was written by and is * Copyright (c) 2001 C. Scott Ananian * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * Copyright (C) 1998,1999,2000,2001 harry eaton * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA * haceaton@aplcomm.jhuapl.edu */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "global.h" #include "autoplace.h" #include "box.h" #include "compat.h" #include "data.h" #include "draw.h" #include "error.h" #include "intersect.h" #include "rtree.h" #include "macro.h" #include "mirror.h" #include "misc.h" #include "move.h" #include "mymem.h" #include "rats.h" #include "remove.h" #include "rotate.h" #ifdef HAVE_LIBDMALLOC #include #endif #define EXPANDRECTXY(r1, x1, y1, x2, y2) { \ r1->X1=MIN(r1->X1, x1); r1->Y1=MIN(r1->Y1, y1); \ r1->X2=MAX(r1->X2, x2); r1->Y2=MAX(r1->Y2, y2); \ } #define EXPANDRECT(r1, r2) EXPANDRECTXY(r1, r2->X1, r2->Y1, r2->X2, r2->Y2) /* --------------------------------------------------------------------------- * some local prototypes */ static double ComputeCost (NetListType *Nets, double T0, double T); /* --------------------------------------------------------------------------- * some local types */ const struct { double via_cost; double congestion_penalty; /* penalty length / unit area */ double overlap_penalty_min; /* penalty length / unit area at start */ double overlap_penalty_max; /* penalty length / unit area at end */ double out_of_bounds_penalty; /* assessed for each component oob */ double overall_area_penalty; /* penalty length / unit area */ double matching_neighbor_bonus; /* length bonus per same-type neigh. */ double aligned_neighbor_bonus; /* length bonus per aligned neigh. */ double oriented_neighbor_bonus; /* length bonus per same-rot neigh. */ #if 0 double pin_alignment_bonus; /* length bonus per exact alignment */ double bound_alignment_bonus; /* length bonus per exact alignment */ #endif double m; /* annealing stage cutoff constant */ double gamma; /* annealing schedule constant */ int good_ratio; /* ratio of moves to good moves for halting */ bool fast; /* ignore SMD/pin conflicts */ Coord large_grid_size; /* snap perturbations to this grid when T is high */ Coord small_grid_size; /* snap to this grid when T is small. */ } /*! * \brief Wire cost is manhattan distance (in mils), thus 1 inch = 1000. */ CostParameter = { 3e3, /* via cost */ 2e-2, /* congestion penalty */ 1e-2, /* initial overlap penalty */ 1e2, /* final overlap penalty */ 1e3, /* out of bounds penalty */ 1e0, /* penalty for total area used */ 1e0, /* subtract 1000 from cost for every same-type neighbor */ 1e0, /* subtract 1000 from cost for every aligned neighbor */ 1e0, /* subtract 1000 from cost for every same-rotation neighbor */ 20, /* move on when each module has been profitably moved 20 times */ 0.75, /* annealing schedule constant: 0.85 */ 40, /* halt when there are 60 times as many moves as good moves */ false, /* don't ignore SMD/pin conflicts */ MIL_TO_COORD (100), /* coarse grid is 100 mils */ MIL_TO_COORD (10), /* fine grid is 10 mils */ }; typedef struct { ElementType **element; Cardinal elementN; } ElementPtrListType; enum ewhich { SHIFT, ROTATE, EXCHANGE }; typedef struct { ElementType *element; enum ewhich which; Coord DX, DY; /* for shift */ unsigned rotate; /* for rotate/flip */ ElementType *other; /* for exchange */ } PerturbationType; /* --------------------------------------------------------------------------- * some local identifiers */ /*! * \brief Update the X, Y and group position information stored in the * NetList after elements have possibly been moved, rotated, flipped, * etc. */ static void UpdateXY (NetListType *Nets) { Cardinal top_group, bottom_group; Cardinal i, j; /* find layer groups of the top and bottom sides */ top_group = GetLayerGroupNumberBySide (TOP_SIDE); bottom_group = GetLayerGroupNumberBySide (BOTTOM_SIDE); /* update all nets */ for (i = 0; i < Nets->NetN; i++) { for (j = 0; j < Nets->Net[i].ConnectionN; j++) { ConnectionType *c = &(Nets->Net[i].Connection[j]); switch (c->type) { case PAD_TYPE: c->group = TEST_FLAG (ONSOLDERFLAG, (ElementType *) c->ptr1) ? bottom_group : top_group; c->X = ((PadType *) c->ptr2)->Point1.X; c->Y = ((PadType *) c->ptr2)->Point1.Y; break; case PIN_TYPE: c->group = bottom_group; /* any layer will do */ c->X = ((PinType *) c->ptr2)->X; c->Y = ((PinType *) c->ptr2)->Y; break; default: Message ("Odd connection type encountered in " "UpdateXY"); break; } } } } /*! * \brief Create a list of selected elements. */ static PointerListType collectSelectedElements () { PointerListType list = { 0, 0, NULL }; ELEMENT_LOOP (PCB->Data); { if (TEST_FLAG (SELECTEDFLAG, element)) { ElementType **epp = (ElementType **) GetPointerMemory (&list); *epp = element; } } END_LOOP; return list; } #if 0 /* only for debugging box lists */ #include "create.h" /*! * \brief Makes a line on the bottom silk layer surrounding all boxes in * blist */ static void showboxes (BoxListType *blist) { Cardinal i; LayerType *layer = &(PCB->Data->Layer[bottom_silk_layer]); for (i = 0; i < blist->BoxN; i++) { CreateNewLineOnLayer (layer, blist->Box[i].X1, blist->Box[i].Y1, blist->Box[i].X2, blist->Box[i].Y1, 1, 1, 0); CreateNewLineOnLayer (layer, blist->Box[i].X1, blist->Box[i].Y2, blist->Box[i].X2, blist->Box[i].Y2, 1, 1, 0); CreateNewLineOnLayer (layer, blist->Box[i].X1, blist->Box[i].Y1, blist->Box[i].X1, blist->Box[i].Y2, 1, 1, 0); CreateNewLineOnLayer (layer, blist->Box[i].X2, blist->Box[i].Y1, blist->Box[i].X2, blist->Box[i].Y2, 1, 1, 0); } } #endif /*! * \brief Helper function to compute "closest neighbor" for a box in a * rtree. * * The closest neighbor on a certain side is the closest one in a * trapezoid emanating from that side. */ struct r_neighbor_info { const BoxType *neighbor; BoxType trap; direction_t search_dir; }; #define ROTATEBOX(box) { Coord t;\ t = (box).X1; (box).X1 = - (box).Y1; (box).Y1 = t;\ t = (box).X2; (box).X2 = - (box).Y2; (box).Y2 = t;\ t = (box).X1; (box).X1 = (box).X2; (box).X2 = t;\ } /*! * \brief Helper methods for __r_find_neighbor. * *
  ______________ __ trap.y1     __
  \            /               |__| query rect.
   \__________/  __ trap.y2
   |          |
   trap.x1    trap.x2   sides at 45-degree angle

 * 
*/ static int __r_find_neighbor_reg_in_sea (const BoxType * region, void *cl) { struct r_neighbor_info *ni = (struct r_neighbor_info *) cl; BoxType query = *region; ROTATEBOX_TO_NORTH (query, ni->search_dir); return (query.Y2 > ni->trap.Y1) && (query.Y1 < ni->trap.Y2) && (query.X2 + ni->trap.Y2 > ni->trap.X1 + query.Y1) && (query.X1 + query.Y1 < ni->trap.X2 + ni->trap.Y2); } /*! * \brief . * *

  ______________ __ trap.y1     __
  \            /               |__| query rect.
   \__________/  __ trap.y2
   |          |
   trap.x1    trap.x2   sides at 45-degree angle

 * 
*/ static int __r_find_neighbor_rect_in_reg (const BoxType * box, void *cl) { struct r_neighbor_info *ni = (struct r_neighbor_info *) cl; BoxType query = *box; int r; ROTATEBOX_TO_NORTH (query, ni->search_dir); r = (query.Y2 > ni->trap.Y1) && (query.Y1 < ni->trap.Y2) && (query.X2 + ni->trap.Y2 > ni->trap.X1 + query.Y1) && (query.X1 + query.Y1 < ni->trap.X2 + ni->trap.Y2); r = r && (query.Y2 <= ni->trap.Y2); if (r) { ni->trap.Y1 = query.Y2; ni->neighbor = box; } return r; } /*! * \brief main r_find_neighbor routine. * * Returns NULL if no neighbor in the requested direction. */ static const BoxType * r_find_neighbor (rtree_t * rtree, const BoxType * box, direction_t search_direction) { struct r_neighbor_info ni; BoxType bbox; ni.neighbor = NULL; ni.trap = *box; ni.search_dir = search_direction; bbox.X1 = bbox.Y1 = 0; bbox.X2 = PCB->MaxWidth; bbox.Y2 = PCB->MaxHeight; /* rotate so that we can use the 'north' case for everything */ ROTATEBOX_TO_NORTH (bbox, search_direction); ROTATEBOX_TO_NORTH (ni.trap, search_direction); /* shift Y's such that trap contains full bounds of trapezoid */ ni.trap.Y2 = ni.trap.Y1; ni.trap.Y1 = bbox.Y1; /* do the search! */ r_search (rtree, NULL, __r_find_neighbor_reg_in_sea, __r_find_neighbor_rect_in_reg, &ni); return ni.neighbor; } /*! * \brief Compute cost function. * * Note that area overlap cost is correct for SMD devices: SMD devices on * opposite sides of the board don't overlap. * * Algorithms follow those described in sections 4.1 of * "Placement and Routing of Electronic Modules" edited by Michael Pecht * Marcel Dekker, Inc. 1993. ISBN: 0-8247-8916-4 TK7868.P7.P57 1993 */ static double ComputeCost (NetListType *Nets, double T0, double T) { double W = 0; /* wire cost */ double delta1 = 0; /* wire congestion penalty function */ double delta2 = 0; /* module overlap penalty function */ double delta3 = 0; /* out of bounds penalty */ double delta4 = 0; /* alignment bonus */ double delta5 = 0; /* total area penalty */ Cardinal i, j; Coord minx, maxx, miny, maxy; bool allpads, allsameside; Cardinal thegroup; BoxListType bounds = { 0, 0, NULL }; /* save bounding rectangles here */ BoxListType solderside = { 0, 0, NULL }; /* solder side component bounds */ BoxListType componentside = { 0, 0, NULL }; /* component side bounds */ /* make sure the NetList have the proper updated X and Y coords */ UpdateXY (Nets); /* wire length term. approximated by half-perimeter of minimum * rectangle enclosing the net. Note that we penalize vias in * all-SMD nets by making the rectangle a cube and weighting * the "layer height" of the net. */ for (i = 0; i < Nets->NetN; i++) { NetType *n = &Nets->Net[i]; if (n->ConnectionN < 2) continue; /* no cost to go nowhere */ minx = maxx = n->Connection[0].X; miny = maxy = n->Connection[0].Y; thegroup = n->Connection[0].group; allpads = (n->Connection[0].type == PAD_TYPE); allsameside = true; for (j = 1; j < n->ConnectionN; j++) { ConnectionType *c = &(n->Connection[j]); MAKEMIN (minx, c->X); MAKEMAX (maxx, c->X); MAKEMIN (miny, c->Y); MAKEMAX (maxy, c->Y); if (c->type != PAD_TYPE) allpads = false; if (c->group != thegroup) allsameside = false; } /* save bounding rectangle */ { BoxType *box = GetBoxMemory (&bounds); box->X1 = minx; box->Y1 = miny; box->X2 = maxx; box->Y2 = maxy; } /* okay, add half-perimeter to cost! */ W += COORD_TO_MIL(maxx - minx) + COORD_TO_MIL(maxy - miny) + ((allpads && !allsameside) ? CostParameter.via_cost : 0); } /* now compute penalty function Wc which is proportional to * amount of overlap and congestion. */ /* delta1 is congestion penalty function */ delta1 = CostParameter.congestion_penalty * sqrt (fabs (ComputeIntersectionArea (&bounds))); #if 0 printf ("Wire Congestion Area: %f\n", ComputeIntersectionArea (&bounds)); #endif /* free bounding rectangles */ FreeBoxListMemory (&bounds); /* now collect module areas (bounding rect of pins/pads) */ /* two lists for solder side / component side. */ ELEMENT_LOOP (PCB->Data); { BoxListType *thisside; BoxListType *otherside; BoxType *box; BoxType *lastbox = NULL; Coord thickness; Coord clearance; if (TEST_FLAG (ONSOLDERFLAG, element)) { thisside = &solderside; otherside = &componentside; } else { thisside = &componentside; otherside = &solderside; } box = GetBoxMemory (thisside); /* protect against elements with no pins/pads */ if (element->PinN == 0 && element->PadN == 0) continue; /* initialize box so that it will take the dimensions of * the first pin/pad */ box->X1 = MAX_COORD; box->Y1 = MAX_COORD; box->X2 = -MAX_COORD; box->Y2 = -MAX_COORD; PIN_LOOP (element); { thickness = pin->Thickness / 2; clearance = pin->Clearance * 2; EXPANDRECTXY (box, pin->X - (thickness + clearance), pin->Y - (thickness + clearance), pin->X + (thickness + clearance), pin->Y + (thickness + clearance))} END_LOOP; PAD_LOOP (element); { thickness = pad->Thickness / 2; clearance = pad->Clearance * 2; EXPANDRECTXY (box, MIN (pad->Point1.X, pad->Point2.X) - (thickness + clearance), MIN (pad->Point1.Y, pad->Point2.Y) - (thickness + clearance), MAX (pad->Point1.X, pad->Point2.X) + (thickness + clearance), MAX (pad->Point1.Y, pad->Point2.Y) + (thickness + clearance))} END_LOOP; /* add a box for each pin to the "opposite side": * surface mount components can't sit on top of pins */ if (!CostParameter.fast) PIN_LOOP (element); { box = GetBoxMemory (otherside); thickness = pin->Thickness / 2; clearance = pin->Clearance * 2; /* we ignore clearance here */ /* (otherwise pins don't fit next to each other) */ box->X1 = pin->X - thickness; box->Y1 = pin->Y - thickness; box->X2 = pin->X + thickness; box->Y2 = pin->Y + thickness; /* speed hack! coalesce with last box if we can */ if (lastbox != NULL && ((lastbox->X1 == box->X1 && lastbox->X2 == box->X2 && MIN (abs (lastbox->Y1 - box->Y2), abs (box->Y1 - lastbox->Y2)) < clearance) || (lastbox->Y1 == box->Y1 && lastbox->Y2 == box->Y2 && MIN (abs (lastbox->X1 - box->X2), abs (box->X1 - lastbox->X2)) < clearance))) { EXPANDRECT (lastbox, box); otherside->BoxN--; } else lastbox = box; } END_LOOP; /* assess out of bounds penalty */ if (element->VBox.X1 < 0 || element->VBox.Y1 < 0 || element->VBox.X2 > PCB->MaxWidth || element->VBox.Y2 > PCB->MaxHeight) delta3 += CostParameter.out_of_bounds_penalty; } END_LOOP; /* compute intersection area of module areas box list */ delta2 = sqrt (fabs (ComputeIntersectionArea (&solderside) + ComputeIntersectionArea (&componentside))) * (CostParameter.overlap_penalty_min + (1 - (T / T0)) * CostParameter.overlap_penalty_max); #if 0 printf ("Module Overlap Area (solder): %f\n", ComputeIntersectionArea (&solderside)); printf ("Module Overlap Area (component): %f\n", ComputeIntersectionArea (&componentside)); #endif FreeBoxListMemory (&solderside); FreeBoxListMemory (&componentside); /* reward pin/pad x/y alignment */ /* score higher if pins/pads belong to same *type* of component */ /* XXX: subkey should be *distance* from thing aligned with, so that * aligning to something far away isn't profitable */ { /* create r tree */ PointerListType seboxes = { 0, 0, NULL } , ceboxes = { 0, 0, NULL}; struct ebox { BoxType box; ElementType *element; }; direction_t dir[4] = { NORTH, EAST, SOUTH, WEST }; struct ebox **boxpp, *boxp; rtree_t *rt_s, *rt_c; int factor; ELEMENT_LOOP (PCB->Data); { boxpp = (struct ebox **) GetPointerMemory (TEST_FLAG (ONSOLDERFLAG, element) ? &seboxes : &ceboxes); *boxpp = (struct ebox *)malloc (sizeof (**boxpp)); if (*boxpp == NULL ) { fprintf (stderr, "malloc() failed in %s\n", __FUNCTION__); exit (1); } (*boxpp)->box = element->VBox; (*boxpp)->element = element; } END_LOOP; rt_s = r_create_tree ((const BoxType **) seboxes.Ptr, seboxes.PtrN, 1); rt_c = r_create_tree ((const BoxType **) ceboxes.Ptr, ceboxes.PtrN, 1); FreePointerListMemory (&seboxes); FreePointerListMemory (&ceboxes); /* now, for each element, find its neighbor on all four sides */ delta4 = 0; for (i = 0; i < 4; i++) ELEMENT_LOOP (PCB->Data); { boxp = (struct ebox *) r_find_neighbor (TEST_FLAG (ONSOLDERFLAG, element) ? rt_s : rt_c, &element->VBox, dir[i]); /* score bounding box alignments */ if (!boxp) continue; factor = 1; if (element->Name[0].TextString && boxp->element->Name[0].TextString && 0 == NSTRCMP (element->Name[0].TextString, boxp->element->Name[0].TextString)) { delta4 += CostParameter.matching_neighbor_bonus; factor++; } if (element->Name[0].Direction == boxp->element->Name[0].Direction) delta4 += factor * CostParameter.oriented_neighbor_bonus; if (element->VBox.X1 == boxp->element->VBox.X1 || element->VBox.X1 == boxp->element->VBox.X2 || element->VBox.X2 == boxp->element->VBox.X1 || element->VBox.X2 == boxp->element->VBox.X2 || element->VBox.Y1 == boxp->element->VBox.Y1 || element->VBox.Y1 == boxp->element->VBox.Y2 || element->VBox.Y2 == boxp->element->VBox.Y1 || element->VBox.Y2 == boxp->element->VBox.Y2) delta4 += factor * CostParameter.aligned_neighbor_bonus; } END_LOOP; /* free k-d tree memory */ r_destroy_tree (&rt_s); r_destroy_tree (&rt_c); } /* penalize total area used by this layout */ { Coord minX = MAX_COORD, minY = MAX_COORD; Coord maxX = -MAX_COORD, maxY = -MAX_COORD; ELEMENT_LOOP (PCB->Data); { MAKEMIN (minX, element->VBox.X1); MAKEMIN (minY, element->VBox.Y1); MAKEMAX (maxX, element->VBox.X2); MAKEMAX (maxY, element->VBox.Y2); } END_LOOP; if (minX < maxX && minY < maxY) delta5 = CostParameter.overall_area_penalty * sqrt (COORD_TO_MIL (maxX - minX) * COORD_TO_MIL (maxY - minY)); } if (T == 5) { T = W + delta1 + delta2 + delta3 - delta4 + delta5; printf ("cost components are %.3f %.3f %.3f %.3f %.3f %.3f\n", W / T, delta1 / T, delta2 / T, delta3 / T, -delta4 / T, delta5 / T); } /* done! */ return W + (delta1 + delta2 + delta3 - delta4 + delta5); } /*! * \brief . * * Perturb: * 1) flip SMD from solder side to component side or vice-versa.\n * 2) rotate component 90, 180, or 270 degrees.\n * 3) shift component random + or - amount in random direction.\n * (magnitude of shift decreases over time)\n * -- Only perturb selected elements (need count/list of selected?) -- */ PerturbationType createPerturbation (PointerListType *selected, double T) { PerturbationType pt = { 0 }; /* pick element to perturb */ pt.element = (ElementType *) selected->Ptr[random () % selected->PtrN]; /* exchange, flip/rotate or shift? */ switch (random () % ((selected->PtrN > 1) ? 3 : 2)) { case 0: { /* shift! */ Coord grid; double scaleX = CLAMP (sqrt (T), MIL_TO_COORD (2.5), PCB->MaxWidth / 3); double scaleY = CLAMP (sqrt (T), MIL_TO_COORD (2.5), PCB->MaxHeight / 3); pt.which = SHIFT; pt.DX = scaleX * 2 * ((((double) random ()) / RAND_MAX) - 0.5); pt.DY = scaleY * 2 * ((((double) random ()) / RAND_MAX) - 0.5); /* snap to grid. different grids for "high" and "low" T */ grid = (T > MIL_TO_COORD (10)) ? CostParameter.large_grid_size : CostParameter.small_grid_size; /* (round away from zero) */ pt.DX = ((pt.DX / grid) + SGN (pt.DX)) * grid; pt.DY = ((pt.DY / grid) + SGN (pt.DY)) * grid; /* limit DX/DY so we don't fall off board */ pt.DX = MAX (pt.DX, -pt.element->VBox.X1); pt.DX = MIN (pt.DX, PCB->MaxWidth - pt.element->VBox.X2); pt.DY = MAX (pt.DY, -pt.element->VBox.Y1); pt.DY = MIN (pt.DY, PCB->MaxHeight - pt.element->VBox.Y2); /* all done but the movin' */ break; } case 1: { /* flip/rotate! */ /* only flip if it's an SMD component */ bool isSMD = pt.element->PadN != 0; pt.which = ROTATE; pt.rotate = isSMD ? (random () & 3) : (1 + (random () % 3)); /* 0 - flip; 1-3, rotate. */ break; } case 2: { /* exchange! */ pt.which = EXCHANGE; pt.other = (ElementType *) selected->Ptr[random () % (selected->PtrN - 1)]; if (pt.other == pt.element) pt.other = (ElementType *) selected->Ptr[selected->PtrN - 1]; /* don't allow exchanging a solderside-side SMD component * with a non-SMD component. */ if ((pt.element->PinN != 0 /* non-SMD */ && TEST_FLAG (ONSOLDERFLAG, pt.other)) || (pt.other->PinN != 0 /* non-SMD */ && TEST_FLAG (ONSOLDERFLAG, pt.element))) return createPerturbation (selected, T); break; } default: assert (0); } return pt; } void doPerturb (PerturbationType * pt, bool undo) { Coord bbcx, bbcy; /* compute center of element bounding box */ bbcx = (pt->element->VBox.X1 + pt->element->VBox.X2) / 2; bbcy = (pt->element->VBox.Y1 + pt->element->VBox.Y2) / 2; /* do exchange, shift or flip/rotate */ switch (pt->which) { case SHIFT: { Coord DX = pt->DX, DY = pt->DY; if (undo) { DX = -DX; DY = -DY; } MoveElementLowLevel (PCB->Data, pt->element, DX, DY); return; } case ROTATE: { unsigned b = pt->rotate; if (undo) b = (4 - b) & 3; /* 0 - flip; 1-3, rotate. */ if (b) RotateElementLowLevel (PCB->Data, pt->element, bbcx, bbcy, b); else { Coord y = pt->element->VBox.Y1; MirrorElementCoordinates (PCB->Data, pt->element, 0); /* mirroring moves the element. move it back. */ MoveElementLowLevel (PCB->Data, pt->element, 0, y - pt->element->VBox.Y1); } return; } case EXCHANGE: { /* first exchange positions */ Coord x1 = pt->element->VBox.X1; Coord y1 = pt->element->VBox.Y1; Coord x2 = pt->other->BoundingBox.X1; Coord y2 = pt->other->BoundingBox.Y1; MoveElementLowLevel (PCB->Data, pt->element, x2 - x1, y2 - y1); MoveElementLowLevel (PCB->Data, pt->other, x1 - x2, y1 - y2); /* then flip both elements if they are on opposite sides */ if (TEST_FLAG (ONSOLDERFLAG, pt->element) != TEST_FLAG (ONSOLDERFLAG, pt->other)) { PerturbationType mypt; mypt.element = pt->element; mypt.which = ROTATE; mypt.rotate = 0; /* flip */ doPerturb (&mypt, undo); mypt.element = pt->other; doPerturb (&mypt, undo); } /* done */ return; } default: assert (0); } } /*! * \brief Auto-place selected components. */ bool AutoPlaceSelected (void) { NetListType *Nets; PointerListType Selected = { 0, 0, NULL }; PerturbationType pt; double C0, T0; bool changed = false; /* (initial netlist processing copied from AddAllRats) */ /* the netlist library has the text form * ProcNetlist fills in the Netlist * structure the way the final routing * is supposed to look */ Nets = ProcNetlist (&PCB->NetlistLib); if (!Nets) { Message (_("Can't add rat lines because no netlist is loaded.\n")); goto done; } Selected = collectSelectedElements (); if (Selected.PtrN == 0) { Message (_("No elements selected to autoplace.\n")); goto done; } /* simulated annealing */ { /* compute T0 by doing a random series of moves. */ const int TRIALS = 10; const double Tx = MIL_TO_COORD (300), P = 0.95; double Cs = 0.0; int i; C0 = ComputeCost (Nets, Tx, Tx); for (i = 0; i < TRIALS; i++) { pt = createPerturbation (&Selected, INCH_TO_COORD (1)); doPerturb (&pt, false); Cs += fabs (ComputeCost (Nets, Tx, Tx) - C0); doPerturb (&pt, true); } T0 = -(Cs / TRIALS) / log (P); printf ("Initial T: %f\n", T0); } /* now anneal in earnest */ { double T = T0; long steps = 0; int good_moves = 0, moves = 0; const int good_move_cutoff = CostParameter.m * Selected.PtrN; const int move_cutoff = 2 * good_move_cutoff; printf ("Starting cost is %.0f\n", ComputeCost (Nets, T0, 5)); C0 = ComputeCost (Nets, T0, T); while (1) { double Cprime; pt = createPerturbation (&Selected, T); doPerturb (&pt, false); Cprime = ComputeCost (Nets, T0, T); if (Cprime < C0) { /* good move! */ C0 = Cprime; good_moves++; steps++; } else if ((random () / (double) RAND_MAX) < exp (MIN (MAX (-20, (C0 - Cprime) / T), 20))) { /* not good but keep it anyway */ C0 = Cprime; steps++; } else doPerturb (&pt, true); /* undo last change */ moves++; /* are we at the end of a stage? */ if (good_moves >= good_move_cutoff || moves >= move_cutoff) { printf ("END OF STAGE: COST %.0f\t" "GOOD_MOVES %d\tMOVES %d\t" "T: %.1f\n", C0, good_moves, moves, T); /* is this the end? */ if (T < 5 || good_moves < moves / CostParameter.good_ratio) break; /* nope, adjust T and continue */ moves = good_moves = 0; T *= CostParameter.gamma; /* cost is T dependent, so recompute */ C0 = ComputeCost (Nets, T0, T); } } changed = (steps > 0); } done: if (changed) { DeleteRats (false); AddAllRats (false, NULL); Redraw (); } FreePointerListMemory (&Selected); return (changed); } pcb-4.3.0/src/rtree.h0000664000175000017500000000451013773431044011274 00000000000000/*! * \file src/rtree.h * * \brief Prototypes for r-tree routines. * * \author This file, rtree.h, was written and is Copyright (c) 2004 * harry eaton, it's based on C. Scott's kdtree.h template. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * Copyright (C) 1998,1999,2000,2001 harry eaton * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA * * haceaton@aplcomm.jhuapl.edu */ #ifndef PCB_RTREE_H #define PCB_RTREE_H #include "global.h" rtree_t *r_create_tree (const BoxType * boxlist[], int N, int manage); void r_destroy_tree (rtree_t ** rtree); bool r_delete_entry (rtree_t * rtree, const BoxType * which); void r_insert_entry (rtree_t * rtree, const BoxType * which, int manage); int r_search (rtree_t * rtree, const BoxType * starting_region, int (*region_in_search) (const BoxType * region, void *cl), int (*rectangle_in_region) (const BoxType * box, void *cl), void *closure); static inline int r_search_pt (rtree_t * rtree, const PointType * pt, int radius, int (*region_in_search) (const BoxType * region, void *cl), int (*rectangle_in_region) (const BoxType * box, void *cl), void *closure) { BoxType box; box.X1 = pt->X - radius; box.X2 = pt->X + radius; box.Y1 = pt->Y - radius; box.Y2 = pt->Y + radius; return r_search(rtree, &box, region_in_search, rectangle_in_region, closure); } int r_region_is_empty (rtree_t * rtree, const BoxType * region); void __r_dump_tree (struct rtree_node *, int); #endif pcb-4.3.0/src/autoroute.h0000664000175000017500000000246513773431044012211 00000000000000/*! * \file src/autoroute.h * * \brief Prototypes for autoroute routines. * * \author This file, autoroute.h, was written and is * Copyright (c) 2001 C. Scott Ananian. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * Copyright (C) 1994,1995,1996 Thomas Nau * Copyright (C) 1998,1999,2000,2001 harry eaton * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA * haceaton@aplcomm.jhuapl.edu * */ #ifndef PCB_AUTOROUTE_H #define PCB_AUTOROUTE_H #include "global.h" bool AutoRoute (bool); #endif pcb-4.3.0/src/remove.h0000664000175000017500000000355013773431044011453 00000000000000/*! * \file src/remove.h * * \brief Prototypes for remove routines. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design. * * Copyright (C) 1994,1995,1996 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * * Thomas.Nau@rz.uni-ulm.de * */ #ifndef PCB_REMOVE_H #define PCB_REMOVE_H #include "global.h" /* --------------------------------------------------------------------------- * some constants */ #define REMOVE_TYPES \ (VIA_TYPE | LINEPOINT_TYPE | LINE_TYPE | TEXT_TYPE | ELEMENT_TYPE | \ POLYGONPOINT_TYPE | POLYGON_TYPE | RATLINE_TYPE | ARC_TYPE) void *RemoveLine (LayerType *, LineType *); void *RemoveArc (LayerType *, ArcType *); void *RemovePolygon (LayerType *, PolygonType *); void *RemoveText (LayerType *, TextType *); void *RemoveElement (ElementType *); void ClearRemoveList (void); void RemovePCB (PCBType *); bool RemoveSelected (void); bool DeleteRats (bool); void *RemoveObject (int, void *, void *, void *); void *DestroyObject (DataType *, int, void *, void *, void *); void RemoveDegradedVias (void); #endif pcb-4.3.0/src/check_icon.data0000664000175000017500000000022613773431044012722 00000000000000#define check_icon_width 8 #define check_icon_height 8 static unsigned char check_icon_bits[] = { 0x80, 0xc0, 0x61, 0x31, 0x1b, 0x0f, 0x06, 0x00}; pcb-4.3.0/src/vector.h0000664000175000017500000000466013773431044011463 00000000000000/*! * \file src/vector.h * * \brief Prototypes for vectors routines. * * \author this file, vector.c, was written and is * Copyright (c) 2001 C. Scott Ananian. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * Copyright (C) 1998,1999,2000,2001 harry eaton * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA * * haceaton@aplcomm.jhuapl.edu */ #ifndef PCB_VECTOR_H #define PCB_VECTOR_H /*! * \brief What a vector looks like. */ typedef struct vector_struct vector_t; /*! * \brief What data in a vector looks like. */ typedef void *vector_element_t; vector_t *vector_create (); void vector_destroy (vector_t ** vector); vector_t *vector_duplicate (vector_t * vector); /* -- interrogation -- */ int vector_is_empty (vector_t * vector); int vector_size (vector_t * vector); vector_element_t vector_element (vector_t * vector, int N); vector_element_t vector_element_first (vector_t * vector); vector_element_t vector_element_last (vector_t * vector); /* -- mutation -- */ void vector_append (vector_t * vector, vector_element_t data); void vector_append_many (vector_t * vector, vector_element_t data[], int count); void vector_append_vector (vector_t * vector, vector_t * other_vector); void vector_insert (vector_t * vector, int N, vector_element_t data); void vector_insert_many (vector_t * vector, int N, vector_element_t data[], int count); vector_element_t vector_remove_last (vector_t * vector); vector_element_t vector_remove (vector_t * vector, int N); vector_element_t vector_replace (vector_t * vector, vector_element_t data, int N); #endif /* PCB_VECTOR_H */ pcb-4.3.0/src/rtree.c0000664000175000017500000007634313773431044011304 00000000000000/*! * \file src/rtree.c * * \brief Implements r-tree structures. * * These should be much faster for the auto-router because the recursive * search is much more efficient and that's where the auto-router spends * all its time. * * \author this file, rtree.c, was written and is Copyright (c) 2004, * harry eaton * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * Copyright (C) 1998,1999,2000,2001,2002,2003,2004 harry eaton * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA * * haceaton@aplcomm.jhuapl.edu */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "global.h" #include #include #include #include "mymem.h" #include "rtree.h" #ifdef HAVE_LIBDMALLOC #include #endif #define SLOW_ASSERTS /* All rectangles are closed on the bottom left and open on the * top right. i.e. they contain one corner point, but not the other. * This requires that the corner points not be equal! */ /* the number of entries in each rtree node * 4 - 7 seem to be pretty good settings */ #define M_SIZE 6 /* it seems that sorting the leaf order slows us down * but sometimes gives better routes */ #undef SORT #define SORT_NONLEAF #define DELETE_BY_POINTER typedef struct { const BoxType *bptr; /* pointer to the box */ BoxType bounds; /* copy of the box for locality of reference */ } Rentry; struct rtree_node { BoxType box; /* bounds rectangle of this node */ struct rtree_node *parent; /* parent of this node, NULL = root */ struct { unsigned is_leaf:1; /* this is a leaf node */ unsigned manage:31; /* true==should free 'rect.bptr' if node is destroyed */ } flags; union { struct rtree_node *kids[M_SIZE + 1]; /* when not leaf */ Rentry rects[M_SIZE + 1]; /* when leaf */ } u; }; #ifndef NDEBUG #ifdef SLOW_ASSERTS static int __r_node_is_good (struct rtree_node *node) { int i, flag = 1; int kind = -1; bool last = false; if (node == NULL) return 1; for (i = 0; i < M_SIZE; i++) { if (node->flags.is_leaf) { if (!node->u.rects[i].bptr) { last = true; continue; } /* check that once one entry is empty, all the rest are too */ if (node->u.rects[i].bptr && last) assert (0); /* check that the box makes sense */ if (node->box.X1 > node->box.X2) assert (0); if (node->box.Y1 > node->box.Y2) assert (0); /* check that bounds is the same as the pointer */ if (node->u.rects[i].bounds.X1 != node->u.rects[i].bptr->X1) assert (0); if (node->u.rects[i].bounds.Y1 != node->u.rects[i].bptr->Y1) assert (0); if (node->u.rects[i].bounds.X2 != node->u.rects[i].bptr->X2) assert (0); if (node->u.rects[i].bounds.Y2 != node->u.rects[i].bptr->Y2) assert (0); /* check that entries are within node bounds */ if (node->u.rects[i].bounds.X1 < node->box.X1) assert (0); if (node->u.rects[i].bounds.X2 > node->box.X2) assert (0); if (node->u.rects[i].bounds.Y1 < node->box.Y1) assert (0); if (node->u.rects[i].bounds.Y2 > node->box.Y2) assert (0); } else { if (!node->u.kids[i]) { last = true; continue; } /* make sure all children are the same type */ if (kind == -1) kind = node->u.kids[i]->flags.is_leaf; else if (kind != node->u.kids[i]->flags.is_leaf) assert (0); /* check that once one entry is empty, all the rest are too */ if (node->u.kids[i] && last) assert (0); /* check that entries are within node bounds */ if (node->u.kids[i]->box.X1 < node->box.X1) assert (0); if (node->u.kids[i]->box.X2 > node->box.X2) assert (0); if (node->u.kids[i]->box.Y1 < node->box.Y1) assert (0); if (node->u.kids[i]->box.Y2 > node->box.Y2) assert (0); } flag <<= 1; } /* check that we're completely in the parent's bounds */ if (node->parent) { if (node->parent->box.X1 > node->box.X1) assert (0); if (node->parent->box.X2 < node->box.X2) assert (0); if (node->parent->box.Y1 > node->box.Y1) assert (0); if (node->parent->box.Y2 < node->box.Y2) assert (0); } /* make sure overflow is empty */ if (!node->flags.is_leaf && node->u.kids[i]) assert (0); if (node->flags.is_leaf && node->u.rects[i].bptr) assert (0); return 1; } /*! * \brief Check the whole tree from this node down for consistency. */ static bool __r_tree_is_good (struct rtree_node *node) { int i; if (!node) return 1; if (!__r_node_is_good (node)) assert (0); if (node->flags.is_leaf) return 1; for (i = 0; i < M_SIZE; i++) { if (!__r_tree_is_good (node->u.kids[i])) return 0; } return 1; } #endif #endif #ifndef NDEBUG /*! * \brief Print out the tree. */ void __r_dump_tree (struct rtree_node *node, int depth) { int i, j; static int count; static double area; if (depth == 0) { area = 0; count = 0; } area += (node->box.X2 - node->box.X1) * (double) (node->box.Y2 - node->box.Y1); count++; for (i = 0; i < depth; i++) printf (" "); if (!node->flags.is_leaf) { printf ( "p=0x%p node X(%" PRIi64 ", %" PRIi64 ") Y(%" PRIi64 ", %" PRIi64 ")\n", (void *) node, (int64_t) (node->box.X1), (int64_t) (node->box.X2), (int64_t) (node->box.Y1), (int64_t) (node->box.Y2) ); } else { printf ( "p=0x%p leaf manage(%02x) X(%" PRIi64 ", %" PRIi64 ") Y(%" PRIi64 ", %" PRIi64 ")\n", (void *) node, node->flags.manage, (int64_t) (node->box.X1), (int64_t) (node->box.X2), (int64_t) (node->box.Y1), (int64_t) (node->box.Y2) ); for (j = 0; j < M_SIZE; j++) { if (!node->u.rects[j].bptr) break; area += (node->u.rects[j].bounds.X2 - node->u.rects[j].bounds.X1) * (double) (node->u.rects[j].bounds.Y2 - node->u.rects[j].bounds.Y1); count++; for (i = 0; i < depth + 1; i++) printf (" "); printf ( "entry 0x%p X(%" PRIi64 ", %" PRIi64 ") Y(%" PRIi64 ", " "%" PRIi64 ")\n", (void *) (node->u.rects[j].bptr), (int64_t) (node->u.rects[j].bounds.X1), (int64_t) (node->u.rects[j].bounds.X2), (int64_t) (node->u.rects[j].bounds.Y1), (int64_t) (node->u.rects[j].bounds.Y2) ); } return; } for (i = 0; i < M_SIZE; i++) if (node->u.kids[i]) __r_dump_tree (node->u.kids[i], depth + 1); if (depth == 0) printf ("average box area is %g\n", area / count); } #endif #ifdef SORT /*! * \brief Sort the children or entries of a node according to the * largest side. * * Compare two box coordinates so that the __r_search will fail at the * earliest comparison possible. * * It needs to see the biggest X1 first, then the smallest X2, the * biggest Y1 and smallest Y2. */ static int cmp_box (const BoxType * a, const BoxType * b) { if (a->X1 < b->X1) return 0; if (a->X1 > b->X1) return 1; if (a->X2 > b->X2) return 0; if (a->X2 < b->X2) return 1; if (a->Y1 < b->Y1) return 0; if (a->Y1 > b->Y1) return 1; if (a->Y2 > b->Y2) return 0; return 1; } static void sort_node (struct rtree_node *node) { if (node->flags.is_leaf) { register Rentry *r, *i, temp; for (r = &node->u.rects[1]; r->bptr; r++) { temp = *r; i = r - 1; while (i >= &node->u.rects[0]) { if (cmp_box (&i->bounds, &r->bounds)) break; *(i + 1) = *i; i--; } *(i + 1) = temp; } } #ifdef SORT_NONLEAF else { register struct rtree_node **r, **i, *temp; for (r = &node->u.kids[1]; *r; r++) { temp = *r; i = r - 1; while (i >= &node->u.kids[0]) { if (cmp_box (&(*i)->box, &(*r)->box)) break; *(i + 1) = *i; i--; } *(i + 1) = temp; } } #endif } #else #define sort_node(x) #endif /*! * \brief Set the node bounds large enough to encompass all of the * children's rectangles. */ static void adjust_bounds (struct rtree_node *node) { int i; assert (node); assert (node->u.kids[0]); if (node->flags.is_leaf) { node->box = node->u.rects[0].bounds; for (i = 1; i < M_SIZE + 1; i++) { if (!node->u.rects[i].bptr) return; MAKEMIN (node->box.X1, node->u.rects[i].bounds.X1); MAKEMAX (node->box.X2, node->u.rects[i].bounds.X2); MAKEMIN (node->box.Y1, node->u.rects[i].bounds.Y1); MAKEMAX (node->box.Y2, node->u.rects[i].bounds.Y2); } } else { node->box = node->u.kids[0]->box; for (i = 1; i < M_SIZE + 1; i++) { if (!node->u.kids[i]) return; MAKEMIN (node->box.X1, node->u.kids[i]->box.X1); MAKEMAX (node->box.X2, node->u.kids[i]->box.X2); MAKEMIN (node->box.Y1, node->u.kids[i]->box.Y1); MAKEMAX (node->box.Y2, node->u.kids[i]->box.Y2); } } } /*! * \brief Create an r-tree from an unsorted list of boxes. * * Create an rtree from the list of boxes. If 'manage' is true, then * the tree will take ownership of 'boxlist' and free it when the tree * is destroyed. * * The r-tree will keep pointers into it, so don't free the box list * until you've called r_destroy_tree. * * If you set 'manage' to true, r_destroy_tree will free your boxlist. */ rtree_t * r_create_tree (const BoxType * boxlist[], int N, int manage) { rtree_t *rtree; struct rtree_node *node; int i; assert (N >= 0); rtree = (rtree_t *)calloc (1, sizeof (*rtree)); /* start with a single empty leaf node */ node = (struct rtree_node *)calloc (1, sizeof (*node)); node->flags.is_leaf = 1; node->parent = NULL; rtree->root = node; /* simple, just insert all of the boxes! */ for (i = 0; i < N; i++) { assert (boxlist[i]); r_insert_entry (rtree, boxlist[i], manage); } #ifdef SLOW_ASSERTS assert (__r_tree_is_good (rtree->root)); #endif return rtree; } /*! * \brief Destroy an rtree. */ static void __r_destroy_tree (struct rtree_node *node) { int i, flag = 1; if (node->flags.is_leaf) for (i = 0; i < M_SIZE; i++) { if (!node->u.rects[i].bptr) break; if (node->flags.manage & flag) free ((void *) node->u.rects[i].bptr); flag = flag << 1; } else for (i = 0; i < M_SIZE; i++) { if (!node->u.kids[i]) break; __r_destroy_tree (node->u.kids[i]); } free (node); } /*! * \brief Free the memory associated with an rtree. */ void r_destroy_tree (rtree_t ** rtree) { __r_destroy_tree ((*rtree)->root); free (*rtree); *rtree = NULL; } typedef struct { int (*check_it) (const BoxType * region, void *cl); int (*found_it) (const BoxType * box, void *cl); void *closure; } r_arg; /*! * \brief . * * Most of the auto-routing time is spent in this routine so some * careful thought has been given to maximizing the speed. * */ int __r_search (struct rtree_node *node, const BoxType * query, r_arg * arg) { assert (node); /* assert that starting_region is well formed */ assert (query->X1 < query->X2 && query->Y1 < query->Y2); assert (node->box.X1 < query->X2 && node->box.X2 > query->X1 && node->box.Y1 < query->Y2 && node->box.Y2 > query->Y1); #ifdef SLOW_ASSERTS /* assert that node is well formed */ assert (__r_node_is_good (node)); #endif /* the check for bounds is done before entry. This saves the overhead * of building/destroying the stack frame for each bounds that fails * to intersect, which is the most common condition. */ if (node->flags.is_leaf) { register int i; if (arg->found_it) /* test this once outside of loop */ { register int seen = 0; for (i = 0; node->u.rects[i].bptr; i++) { if ((node->u.rects[i].bounds.X1 < query->X2) && (node->u.rects[i].bounds.X2 > query->X1) && (node->u.rects[i].bounds.Y1 < query->Y2) && (node->u.rects[i].bounds.Y2 > query->Y1) && arg->found_it (node->u.rects[i].bptr, arg->closure)) seen++; } return seen; } else { register int seen = 0; for (i = 0; node->u.rects[i].bptr; i++) { if ((node->u.rects[i].bounds.X1 < query->X2) && (node->u.rects[i].bounds.X2 > query->X1) && (node->u.rects[i].bounds.Y1 < query->Y2) && (node->u.rects[i].bounds.Y2 > query->Y1)) seen++; } return seen; } } /* not a leaf, recurse on lower nodes */ if (arg->check_it) { int seen = 0; struct rtree_node **n; for (n = &node->u.kids[0]; *n; n++) { if ((*n)->box.X1 >= query->X2 || (*n)->box.X2 <= query->X1 || (*n)->box.Y1 >= query->Y2 || (*n)->box.Y2 <= query->Y1 || !arg->check_it (&(*n)->box, arg->closure)) continue; seen += __r_search (*n, query, arg); } return seen; } else { int seen = 0; struct rtree_node **n; for (n = &node->u.kids[0]; *n; n++) { if ((*n)->box.X1 >= query->X2 || (*n)->box.X2 <= query->X1 || (*n)->box.Y1 >= query->Y2 || (*n)->box.Y2 <= query->Y1) continue; seen += __r_search (*n, query, arg); } return seen; } } /*! * \brief Parameterized search in the rtree. * * Calls found_rectangle for each intersection seen and calls * \c check_region with the current sub-region to see whether deeper * searching is desired. * * Generic search routine. * * \c region_in_search should return true if "what you're looking for" * is within the specified region; regions, like rectangles, are closed * on top and left and open on bottom and right. * * rectangle_in_region should return true if the given rectangle is * "what you're looking for". * * The search will find all rectangles matching the criteria given * by region_in_search and rectangle_in_region and return a count of * how many things rectangle_in_region returned true for. * * Closure is used to abort the search if desired from within * rectangel_in_region. * * Look at the implementation of r_region_is_empty for how to abort the * search if that is the desired behavior. * * \return the number of rectangles found. */ int r_search (rtree_t * rtree, const BoxType * query, int (*check_region) (const BoxType * region, void *cl), int (*found_rectangle) (const BoxType * box, void *cl), void *cl) { r_arg arg; if (!rtree || rtree->size < 1) return 0; if (query) { #ifdef SLOW_ASSERTS assert (__r_tree_is_good (rtree->root)); #endif #ifdef DEBUG if (query->X2 <= query->X1 || query->Y2 <= query->Y1) return 0; #endif /* check this box. If it's not touched we're done here */ if (rtree->root->box.X1 >= query->X2 || rtree->root->box.X2 <= query->X1 || rtree->root->box.Y1 >= query->Y2 || rtree->root->box.Y2 <= query->Y1) return 0; arg.check_it = check_region; arg.found_it = found_rectangle; arg.closure = cl; return __r_search (rtree->root, query, &arg); } else { arg.check_it = check_region; arg.found_it = found_rectangle; arg.closure = cl; return __r_search (rtree->root, &rtree->root->box, &arg); } } /*! * \brief r_region_is_empty. */ static int __r_region_is_empty_rect_in_reg (const BoxType * box, void *cl) { jmp_buf *envp = (jmp_buf *) cl; longjmp (*envp, 1); /* found one! */ } /*! * \brief Special-purpose searches build upon r_search. * * \return 0 if there are any rectangles in the given region. */ int r_region_is_empty (rtree_t * rtree, const BoxType * region) { jmp_buf env; #ifndef NDEBUG int r; #endif if (setjmp (env)) return 0; #ifndef NDEBUG r = #endif r_search (rtree, region, NULL, __r_region_is_empty_rect_in_reg, &env); #ifndef NDEBUG assert (r == 0); /* otherwise longjmp would have been called */ #endif return 1; /* no rectangles found */ } struct centroid { float x, y, area; }; /*! * \brief Split the node into two nodes putting clusters in each use the * k-means clustering algorithm. */ struct rtree_node * find_clusters (struct rtree_node *node) { float total_a, total_b; float a_X, a_Y, b_X, b_Y; bool belong[M_SIZE + 1]; struct centroid center[M_SIZE + 1]; int clust_a, clust_b, tries; int a_manage = 0, b_manage = 0; int i, old_ax, old_ay, old_bx, old_by; struct rtree_node *new_node; BoxType *b; for (i = 0; i < M_SIZE + 1; i++) { if (node->flags.is_leaf) b = &(node->u.rects[i].bounds); else b = &(node->u.kids[i]->box); center[i].x = 0.5 * (b->X1 + b->X2); center[i].y = 0.5 * (b->Y1 + b->Y2); /* adding 1 prevents zero area */ center[i].area = 1. + (float) (b->X2 - b->X1) * (float) (b->Y2 - b->Y1); } /* starting 'A' cluster center */ a_X = center[0].x; a_Y = center[0].y; /* starting 'B' cluster center */ b_X = center[M_SIZE].x; b_Y = center[M_SIZE].y; /* don't allow the same cluster centers */ if (b_X == a_X && b_Y == a_Y) { b_X += 10000; a_Y -= 10000; } for (tries = 0; tries < M_SIZE; tries++) { old_ax = (int) a_X; old_ay = (int) a_Y; old_bx = (int) b_X; old_by = (int) b_Y; clust_a = clust_b = 0; for (i = 0; i < M_SIZE + 1; i++) { float dist1, dist2; dist1 = SQUARE (a_X - center[i].x) + SQUARE (a_Y - center[i].y); dist2 = SQUARE (b_X - center[i].x) + SQUARE (b_Y - center[i].y); if (dist1 * (clust_a + M_SIZE / 2) < dist2 * (clust_b + M_SIZE / 2)) { belong[i] = true; clust_a++; } else { belong[i] = false; clust_b++; } } /* kludge to fix degenerate cases */ if (clust_a == M_SIZE + 1) belong[M_SIZE / 2] = false; else if (clust_b == M_SIZE + 1) belong[M_SIZE / 2] = true; /* compute new center of gravity of clusters */ total_a = total_b = 0; a_X = a_Y = b_X = b_Y = 0; for (i = 0; i < M_SIZE + 1; i++) { if (belong[i]) { a_X += center[i].x * center[i].area; a_Y += center[i].y * center[i].area; total_a += center[i].area; } else { b_X += center[i].x * center[i].area; b_Y += center[i].y * center[i].area; total_b += center[i].area; } } a_X /= total_a; a_Y /= total_a; b_X /= total_b; b_Y /= total_b; if (old_ax == (int) a_X && old_ay == (int) a_Y && old_bx == (int) b_X && old_by == (int) b_Y) break; } /* Now 'belong' has the partition map */ new_node = (struct rtree_node *)calloc (1, sizeof (*new_node)); new_node->parent = node->parent; new_node->flags.is_leaf = node->flags.is_leaf; clust_a = clust_b = 0; if (node->flags.is_leaf) { int flag, a_flag, b_flag; flag = a_flag = b_flag = 1; for (i = 0; i < M_SIZE + 1; i++) { if (belong[i]) { node->u.rects[clust_a++] = node->u.rects[i]; if (node->flags.manage & flag) a_manage |= a_flag; a_flag <<= 1; } else { new_node->u.rects[clust_b++] = node->u.rects[i]; if (node->flags.manage & flag) b_manage |= b_flag; b_flag <<= 1; } flag <<= 1; } } else { for (i = 0; i < M_SIZE + 1; i++) { if (belong[i]) node->u.kids[clust_a++] = node->u.kids[i]; else { node->u.kids[i]->parent = new_node; new_node->u.kids[clust_b++] = node->u.kids[i]; } } } node->flags.manage = a_manage; new_node->flags.manage = b_manage; assert (clust_a != 0); assert (clust_b != 0); if (node->flags.is_leaf) for (; clust_a < M_SIZE + 1; clust_a++) node->u.rects[clust_a].bptr = NULL; else for (; clust_a < M_SIZE + 1; clust_a++) node->u.kids[clust_a] = NULL; adjust_bounds (node); sort_node (node); adjust_bounds (new_node); sort_node (new_node); return (new_node); } /*! * \brief Split a node according to clusters. */ static void split_node (struct rtree_node *node) { int i; struct rtree_node *new_node; assert (node); assert (node->flags.is_leaf ? (void *) node->u.rects[M_SIZE]. bptr : (void *) node->u.kids[M_SIZE]); new_node = find_clusters (node); if (node->parent == NULL) /* split root node */ { struct rtree_node *second; second = (struct rtree_node *)calloc (1, sizeof (*second)); *second = *node; if (!second->flags.is_leaf) for (i = 0; i < M_SIZE; i++) if (second->u.kids[i]) second->u.kids[i]->parent = second; node->flags.is_leaf = 0; node->flags.manage = 0; second->parent = new_node->parent = node; node->u.kids[0] = new_node; node->u.kids[1] = second; for (i = 2; i < M_SIZE + 1; i++) node->u.kids[i] = NULL; adjust_bounds (node); sort_node (node); #ifdef SLOW_ASSERTS assert (__r_tree_is_good (node)); #endif return; } for (i = 0; i < M_SIZE; i++) if (!node->parent->u.kids[i]) break; node->parent->u.kids[i] = new_node; #ifdef SLOW_ASSERTS assert (__r_node_is_good (node)); assert (__r_node_is_good (new_node)); #endif if (i < M_SIZE) { #ifdef SLOW_ASSERTS assert (__r_node_is_good (node->parent)); #endif sort_node (node->parent); return; } split_node (node->parent); } static inline int contained (struct rtree_node *node, const BoxType * query) { if (node->box.X1 > query->X1 || node->box.X2 < query->X2 || node->box.Y1 > query->Y1 || node->box.Y2 < query->Y2) return 0; return 1; } /*! * \brief Compute the area penalty for inserting here and return. * * The penalty is the increase in area necessary to include the query. */ static inline double penalty (struct rtree_node *node, const BoxType * query) { double score; score = (MAX (node->box.X2, query->X2) - MIN (node->box.X1, query->X1)); score *= (MAX (node->box.Y2, query->Y2) - MIN (node->box.Y1, query->Y1)); score -= (double)(node->box.X2 - node->box.X1) * (double)(node->box.Y2 - node->box.Y1); return score; } static void __r_insert_node (struct rtree_node *node, const BoxType * query, int manage, bool force) { #ifdef SLOW_ASSERTS assert (__r_node_is_good (node)); #endif /* Ok, at this point we must already enclose the query or we're forcing * this node to expand to enclose it, so if we're a leaf, simply store * the query here */ if (node->flags.is_leaf) { register int i; if (UNLIKELY (manage)) { register int flag = 1; for (i = 0; i < M_SIZE; i++) { if (!node->u.rects[i].bptr) break; flag <<= 1; } node->flags.manage |= flag; } else { for (i = 0; i < M_SIZE; i++) if (!node->u.rects[i].bptr) break; } /* the node always has an extra space available */ node->u.rects[i].bptr = query; node->u.rects[i].bounds = *query; /* first entry in node determines initial bounding box */ if (i == 0) node->box = *query; else if (force) { MAKEMIN (node->box.X1, query->X1); MAKEMAX (node->box.X2, query->X2); MAKEMIN (node->box.Y1, query->Y1); MAKEMAX (node->box.Y2, query->Y2); } if (i < M_SIZE) { sort_node (node); return; } /* we must split the node */ split_node (node); return; } else { int i; struct rtree_node *best_node; double score, best_score; if (force) { MAKEMIN (node->box.X1, query->X1); MAKEMAX (node->box.X2, query->X2); MAKEMIN (node->box.Y1, query->Y1); MAKEMAX (node->box.Y2, query->Y2); } /* this node encloses it, but it's not a leaf, so descend the tree */ /* First check if any children actually encloses it */ assert (node->u.kids[0]); for (i = 0; i < M_SIZE; i++) { if (!node->u.kids[i]) break; if (contained (node->u.kids[i], query)) { __r_insert_node (node->u.kids[i], query, manage, false); sort_node (node); return; } } /* see if there is room for a new leaf node */ if (node->u.kids[0]->flags.is_leaf && i < M_SIZE) { struct rtree_node *new_node; new_node = (struct rtree_node *)calloc (1, sizeof (*new_node)); new_node->parent = node; new_node->flags.is_leaf = true; node->u.kids[i] = new_node; new_node->u.rects[0].bptr = query; new_node->u.rects[0].bounds = *query; new_node->box = *query; if (UNLIKELY (manage)) new_node->flags.manage = 1; sort_node (node); return; } /* Ok, so we're still here - look for the best child to push it into */ best_score = penalty (node->u.kids[0], query); best_node = node->u.kids[0]; for (i = 1; i < M_SIZE; i++) { if (!node->u.kids[i]) break; score = penalty (node->u.kids[i], query); if (score < best_score) { best_score = score; best_node = node->u.kids[i]; } } __r_insert_node (best_node, query, manage, true); sort_node (node); return; } } void r_insert_entry (rtree_t * rtree, const BoxType * which, int man) { assert (which); assert (which->X1 <= which->X2); assert (which->Y1 <= which->Y2); /* recursively search the tree for the best leaf node */ assert (rtree->root); __r_insert_node (rtree->root, which, man, rtree->root->box.X1 > which->X1 || rtree->root->box.X2 < which->X2 || rtree->root->box.Y1 > which->Y1 || rtree->root->box.Y2 < which->Y2); rtree->size++; } bool __r_delete (struct rtree_node *node, const BoxType * query) { int i, flag, mask, a; /* the tree might be inconsistent during delete */ if (query->X1 < node->box.X1 || query->Y1 < node->box.Y1 || query->X2 > node->box.X2 || query->Y2 > node->box.Y2) return false; if (!node->flags.is_leaf) { for (i = 0; i < M_SIZE; i++) { /* if this is us being removed, free and copy over */ if (node->u.kids[i] == (struct rtree_node *) query) { free ((void *) query); for (; i < M_SIZE; i++) { node->u.kids[i] = node->u.kids[i + 1]; if (!node->u.kids[i]) break; } /* nobody home here now ? */ if (!node->u.kids[0]) { if (!node->parent) { /* wow, the root is empty! */ node->flags.is_leaf = 1; /* changing type of node, be sure it's all zero */ for (i = 1; i < M_SIZE + 1; i++) node->u.rects[i].bptr = NULL; return true; } return (__r_delete (node->parent, &node->box)); } else /* propegate boundary adjust upward */ while (node) { adjust_bounds (node); node = node->parent; } return true; } if (node->u.kids[i]) { if (__r_delete (node->u.kids[i], query)) return true; } else break; } return false; } /* leaf node here */ mask = 0; a = 1; for (i = 0; i < M_SIZE; i++) { #ifdef DELETE_BY_POINTER if (!node->u.rects[i].bptr || node->u.rects[i].bptr == query) #else if (node->u.rects[i].bounds.X1 == query->X1 && node->u.rects[i].bounds.X2 == query->X2 && node->u.rects[i].bounds.Y1 == query->Y1 && node->u.rects[i].bounds.Y2 == query->Y2) #endif break; mask |= a; a <<= 1; } if (!node->u.rects[i].bptr) return false; /* not at this leaf */ if (node->flags.manage & a) { free ((void *) node->u.rects[i].bptr); node->u.rects[i].bptr = NULL; } /* squeeze the manage flags together */ flag = node->flags.manage & mask; mask = (~mask) << 1; node->flags.manage = flag | ((node->flags.manage & mask) >> 1); /* remove the entry */ for (; i < M_SIZE; i++) { node->u.rects[i] = node->u.rects[i + 1]; if (!node->u.rects[i].bptr) break; } if (!node->u.rects[0].bptr) { if (node->parent) __r_delete (node->parent, &node->box); return true; } else /* propagate boundary adjustment upward */ while (node) { adjust_bounds (node); node = node->parent; } return true; } bool r_delete_entry (rtree_t * rtree, const BoxType * box) { bool r; assert (box); assert (rtree); r = __r_delete (rtree->root, box); if (r) rtree->size--; #ifdef SLOW_ASSERTS assert (__r_tree_is_good (rtree->root)); #endif return r; } pcb-4.3.0/src/dbus.h0000664000175000017500000000174413773431044011116 00000000000000/*! * \file src/dbus.h * * \brief D-Bus IPC logic * * PCB, an interactive printed circuit board editor * * Copyright (C) 2006 University of Cambridge * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef PCB_DBUS_H #define PCB_DBUS_H void pcb_dbus_setup (); void pcb_dbus_finish (); #endif /* !PCB_DBUS_H */ pcb-4.3.0/src/thermal.h0000664000175000017500000000310713773431044011610 00000000000000/*! * \file src/thermal.h * * \brief Prototypes for thermal routines. * * Thermals are normal lines on the layout. * * The only thing unique about them is that they have the USETHERMALFLAG * set so that they can be identified as thermals. * * It is handy for pcb to automatically make adjustments to the thermals * when the user performs certain operations, and the functions in * thermal.h help implement that. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996,2006 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * * Thomas.Nau@rz.uni-ulm.de */ #ifndef PCB_THERMAL_H #define PCB_THERMAL_H #include #include "global.h" #include "mymem.h" POLYAREA * ThermPoly (PCBType *, PinType *, Cardinal); #endif pcb-4.3.0/src/flags.c0000664000175000017500000003401113773431044011241 00000000000000/*! * \file src/flags.c * * \brief . * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 2005 DJ Delorie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifdef HAVE_STRING_H #include #endif #include "global.h" #include "data.h" #include "draw.h" #include "pcb-printf.h" #include "search.h" #include "set.h" /* SetChangedFlag */ #include "strflags.h" #include "undo.h" #include #ifdef HAVE_LIBDMALLOC #include #endif int pcb_flag_eq (FlagType *f1, FlagType *f2); /*! * \brief . * * \warning ignore unknowns for now: the only place where we use this * function, undo.c, won't care. */ int pcb_flag_eq (FlagType *f1, FlagType *f2) { if (f1->f != f2->f) return 0; return (memcmp(f1->t, &f2->t, sizeof(f1->t)) == 0); } static int FlagCurrentStyle (void *data) { STYLE_LOOP (PCB); { if (style->Thick == Settings.LineThickness && style->Diameter == Settings.ViaThickness && style->Hole == Settings.ViaDrillingHole && style->Keepaway == Settings.Keepaway) return n + 1; } END_LOOP; return 0; } static int FlagGrid (void *data) { return PCB->Grid > 1; } static int FlagGridSize (void *data) { return PCB->Grid; } static int FlagUnitsMm (void *data) { static const Unit *u = NULL; if (u == NULL) u = get_unit_struct ("mm"); return (Settings.grid_unit == u); } static int FlagUnitsMil (void *data) { static const Unit *u = NULL; if (u == NULL) u = get_unit_struct ("mil"); return (Settings.grid_unit == u); } static int FlagBuffer (void *data) { return (int) (Settings.BufferNumber + 1); } static int FlagElementName (void *data) { if (TEST_FLAG (NAMEONPCBFLAG, PCB)) return 2; if (TEST_FLAG (DESCRIPTIONFLAG, PCB)) return 1; return 3; } static int FlagTESTFLAG (void *data) { int bit = GPOINTER_TO_INT (data); return TEST_FLAG (bit, PCB) ? 1 : 0; } static int FlagSETTINGS (void *data) { size_t ofs = (size_t)data; return *(bool *) ((char *)(&Settings) + ofs); } static int FlagMode (void *data) { int x = GPOINTER_TO_INT (data); if (x == -1) return Settings.Mode; return Settings.Mode == x; } static int FlagHaveRegex (void *data) { #if defined(HAVE_REGCOMP) || defined(HAVE_RE_COMP) return 1; #else return 0; #endif } enum { FL_SILK = -6, FL_PINS, FL_RATS, FL_VIAS, FL_BACK, FL_MASK }; static int FlagLayerShown (void *data) { int n = GPOINTER_TO_INT (data); switch (n) { case FL_SILK: return PCB->ElementOn; case FL_PINS: return PCB->PinOn; case FL_RATS: return PCB->RatOn; case FL_VIAS: return PCB->ViaOn; case FL_BACK: return PCB->InvisibleObjectsOn; case FL_MASK: return TEST_FLAG (SHOWMASKFLAG, PCB); default: if (n >= 0 && n < max_copper_layer) return PCB->Data->Layer[n].On; } return 0; } static int FlagLayerActive (void *data) { int test_layer = GPOINTER_TO_INT (data); int current_layer; if (PCB->RatDraw) current_layer = FL_RATS; else if (PCB->SilkActive) current_layer = FL_SILK; else return 0; return current_layer == test_layer; } int mem_any_set (unsigned char *ptr, int bytes) { while (bytes--) if (*ptr++) return 1; return 0; } /*! * \brief This just fills in a FlagType with current flags. */ FlagType MakeFlags (unsigned int flags) { FlagType rv; memset (&rv, 0, sizeof (rv)); rv.f = flags; return rv; } /*! * \brief This converts old flag bits (from saved PCB files) to new * format. */ FlagType OldFlags (unsigned int flags) { FlagType rv; int i, f; memset (&rv, 0, sizeof (rv)); /* If we move flag bits around, this is where we map old bits to them. */ rv.f = flags & 0xffff; f = 0x10000; for (i = 0; i < 8; i++) { /* use the closest thing to the old thermal style */ if (flags & f) rv.t[i / 2] |= (1 << (4 * (i % 2))); f <<= 1; } return rv; } FlagType AddFlags (FlagType flag, unsigned int flags) { flag.f |= flags; return flag; } FlagType MaskFlags (FlagType flag, unsigned int flags) { flag.f &= ~flags; return flag; } /*! * \brief Resets all used flags of pins and vias. */ bool ClearFlagOnPinsViasAndPads (int flag, bool undoable) { bool change = false; VIA_LOOP (PCB->Data); { if (TEST_FLAG (flag, via)) { if (undoable) AddObjectToFlagUndoList (VIA_TYPE, via, via, via); CLEAR_FLAG (flag, via); change = true; } } END_LOOP; ELEMENT_LOOP (PCB->Data); { PIN_LOOP (element); { if (TEST_FLAG (flag, pin)) { if (undoable) AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin); CLEAR_FLAG (flag, pin); change = true; } } END_LOOP; PAD_LOOP (element); { if (TEST_FLAG (flag, pad)) { if (undoable) AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad); CLEAR_FLAG (flag, pad); change = true; } } END_LOOP; } END_LOOP; if (change) SetChangedFlag (true); return change; } /*! * \brief Resets all used flags of LOs. */ bool ClearFlagOnLinesAndPolygons (int flag, bool undoable) { bool change = false; RAT_LOOP (PCB->Data); { if (TEST_FLAG (flag, line)) { if (undoable) AddObjectToFlagUndoList (RATLINE_TYPE, line, line, line); CLEAR_FLAG (flag, line); change = true; } } END_LOOP; COPPERLINE_LOOP (PCB->Data); { if (TEST_FLAG (flag, line)) { if (undoable) AddObjectToFlagUndoList (LINE_TYPE, layer, line, line); CLEAR_FLAG (flag, line); change = true; } } ENDALL_LOOP; COPPERARC_LOOP (PCB->Data); { if (TEST_FLAG (flag, arc)) { if (undoable) AddObjectToFlagUndoList (ARC_TYPE, layer, arc, arc); CLEAR_FLAG (flag, arc); change = true; } } ENDALL_LOOP; COPPERPOLYGON_LOOP (PCB->Data); { if (TEST_FLAG (flag, polygon)) { if (undoable) AddObjectToFlagUndoList (POLYGON_TYPE, layer, polygon, polygon); CLEAR_FLAG (flag, polygon); change = true; } } ENDALL_LOOP; if (change) SetChangedFlag (true); return change; } /*! * \brief Resets all found connections. */ bool ClearFlagOnAllObjects (int flag, bool undoable) { bool change = false; change = ClearFlagOnPinsViasAndPads (flag, undoable) || change; change = ClearFlagOnLinesAndPolygons (flag, undoable) || change; return change; } static const char dump_flags_syntax[] = ("DumpFlags([Output file])"); static const char dump_flags_help[] = ("Write out a list of objects and their flags."); static int ActionDumpFlags(int argc, char **argv, Coord x, Coord y) { int i = -1; bool found_something = false; int type = 0; FILE * fp; void *p1, *p2, *p3, *p; if (argc == 1) fp = fopen(argv[0], "w"); else fp = stdout; while (1){ i++; type = SearchObjectByID(PCB->Data, &p1, &p2, &p3, i, ALL_TYPES); if (type == NO_TYPE){ /* There's a gap in the ID numbers at the beginning */ if (found_something) break; else continue; } found_something = true; /* Points don't use flags (I don't think) */ if (type & (LINEPOINT_TYPE | POLYGONPOINT_TYPE)) continue; /*p = p3;*/ else if (type && (LINE_TYPE | ARC_TYPE | TEXT_TYPE | POLYGON_TYPE | ELEMENTLINE_TYPE | ELEMENTARC_TYPE | ELEMENTNAME_TYPE | PIN_TYPE | PAD_TYPE)) p = p2; else p = p1; fprintf(fp, "%4d %3d %s\n", i, type, flags_to_string(((AnyObjectType*)p)->Flags, type)); } fclose(fp); return 0; } HID_Action flag_action_list[] = { {"DumpFlags", 0, ActionDumpFlags, dump_flags_help, dump_flags_syntax} }; REGISTER_ACTIONS (flag_action_list) #define OFFSET_POINTER(a, b) (&(((a *)0)->b)) HID_Flag flags_flag_list[] = { {"style", FlagCurrentStyle, NULL}, {"grid", FlagGrid, NULL}, {"gridsize", FlagGridSize, NULL}, {"elementname", FlagElementName, NULL}, {"have_regex", FlagHaveRegex, NULL}, {"silk_shown", FlagLayerShown, GINT_TO_POINTER (FL_SILK)}, {"pins_shown", FlagLayerShown, GINT_TO_POINTER (FL_PINS)}, {"rats_shown", FlagLayerShown, GINT_TO_POINTER (FL_RATS)}, {"vias_shown", FlagLayerShown, GINT_TO_POINTER (FL_VIAS)}, {"back_shown", FlagLayerShown, GINT_TO_POINTER (FL_BACK)}, {"mask_shown", FlagLayerShown, GINT_TO_POINTER (FL_MASK)}, {"silk_active", FlagLayerActive, GINT_TO_POINTER (FL_SILK)}, {"rats_active", FlagLayerActive, GINT_TO_POINTER (FL_RATS)}, {"mode", FlagMode, GINT_TO_POINTER (-1)}, {"nomode", FlagMode, GINT_TO_POINTER (NO_MODE)}, {"arcmode", FlagMode, GINT_TO_POINTER (ARC_MODE)}, {"arrowmode", FlagMode, GINT_TO_POINTER (ARROW_MODE)}, {"copymode", FlagMode, GINT_TO_POINTER (COPY_MODE)}, {"insertpointmode", FlagMode, GINT_TO_POINTER (INSERTPOINT_MODE)}, {"linemode", FlagMode, GINT_TO_POINTER (LINE_MODE)}, {"lockmode", FlagMode, GINT_TO_POINTER (LOCK_MODE)}, {"movemode", FlagMode, GINT_TO_POINTER (MOVE_MODE)}, {"pastebuffermode", FlagMode, GINT_TO_POINTER (PASTEBUFFER_MODE)}, {"polygonmode", FlagMode, GINT_TO_POINTER (POLYGON_MODE)}, {"polygonholemode", FlagMode, GINT_TO_POINTER (POLYGONHOLE_MODE)}, {"rectanglemode", FlagMode, GINT_TO_POINTER (RECTANGLE_MODE)}, {"removemode", FlagMode, GINT_TO_POINTER (REMOVE_MODE)}, {"rotatemode", FlagMode, GINT_TO_POINTER (ROTATE_MODE)}, {"rubberbandmovemode", FlagMode, GINT_TO_POINTER (RUBBERBANDMOVE_MODE)}, {"textmode", FlagMode, GINT_TO_POINTER (TEXT_MODE)}, {"thermalmode", FlagMode, GINT_TO_POINTER (THERMAL_MODE)}, {"viamode", FlagMode, GINT_TO_POINTER (VIA_MODE)}, {"shownumber", FlagTESTFLAG, GINT_TO_POINTER (SHOWNUMBERFLAG)}, {"localref", FlagTESTFLAG, GINT_TO_POINTER (LOCALREFFLAG)}, {"checkplanes", FlagTESTFLAG, GINT_TO_POINTER (CHECKPLANESFLAG)}, {"showdrc", FlagTESTFLAG, GINT_TO_POINTER (SHOWDRCFLAG)}, {"rubberband", FlagTESTFLAG, GINT_TO_POINTER (RUBBERBANDFLAG)}, {"description", FlagTESTFLAG, GINT_TO_POINTER (DESCRIPTIONFLAG)}, {"nameonpcb", FlagTESTFLAG, GINT_TO_POINTER (NAMEONPCBFLAG)}, {"autodrc", FlagTESTFLAG, GINT_TO_POINTER (AUTODRCFLAG)}, {"alldirection", FlagTESTFLAG, GINT_TO_POINTER (ALLDIRECTIONFLAG)}, {"swapstartdir", FlagTESTFLAG, GINT_TO_POINTER (SWAPSTARTDIRFLAG)}, {"uniquename", FlagTESTFLAG, GINT_TO_POINTER (UNIQUENAMEFLAG)}, {"clearnew", FlagTESTFLAG, GINT_TO_POINTER (CLEARNEWFLAG)}, {"snappin", FlagTESTFLAG, GINT_TO_POINTER (SNAPPINFLAG)}, {"showmask", FlagTESTFLAG, GINT_TO_POINTER (SHOWMASKFLAG)}, {"thindraw", FlagTESTFLAG, GINT_TO_POINTER (THINDRAWFLAG)}, {"orthomove", FlagTESTFLAG, GINT_TO_POINTER (ORTHOMOVEFLAG)}, {"liveroute", FlagTESTFLAG, GINT_TO_POINTER (LIVEROUTEFLAG)}, {"thindrawpoly", FlagTESTFLAG, GINT_TO_POINTER (THINDRAWPOLYFLAG)}, {"locknames", FlagTESTFLAG, GINT_TO_POINTER (LOCKNAMESFLAG)}, {"onlynames", FlagTESTFLAG, GINT_TO_POINTER (ONLYNAMESFLAG)}, {"newfullpoly", FlagTESTFLAG, GINT_TO_POINTER (NEWFULLPOLYFLAG)}, {"hidenames", FlagTESTFLAG, GINT_TO_POINTER (HIDENAMESFLAG)}, {"autoburiedvias", FlagTESTFLAG, GINT_TO_POINTER (AUTOBURIEDVIASFLAG)}, {"grid_units_mm", FlagUnitsMm, NULL}, {"grid_units_mil", FlagUnitsMil, NULL}, {"fullpoly", FlagSETTINGS, OFFSET_POINTER (SettingType, FullPoly)}, {"clearline", FlagSETTINGS, OFFSET_POINTER (SettingType, ClearLine)}, {"uniquenames", FlagSETTINGS, OFFSET_POINTER (SettingType, UniqueNames)}, {"showsolderside", FlagSETTINGS, OFFSET_POINTER (SettingType, ShowBottomSide)}, {"savelastcommand", FlagSETTINGS, OFFSET_POINTER (SettingType, SaveLastCommand)}, {"saveintmp", FlagSETTINGS, OFFSET_POINTER (SettingType, SaveInTMP)}, {"drawgrid", FlagSETTINGS, OFFSET_POINTER (SettingType, DrawGrid)}, {"ratwarn", FlagSETTINGS, OFFSET_POINTER (SettingType, RatWarn)}, {"stipplepolygons", FlagSETTINGS, OFFSET_POINTER (SettingType, StipplePolygons)}, {"alldirectionlines", FlagSETTINGS, OFFSET_POINTER (SettingType, AllDirectionLines)}, {"rubberbandmode", FlagSETTINGS, OFFSET_POINTER (SettingType, RubberBandMode)}, {"swapstartdirection", FlagSETTINGS, OFFSET_POINTER (SettingType, SwapStartDirection)}, {"showdrcmode", FlagSETTINGS, OFFSET_POINTER (SettingType, ShowDRC)}, {"resetafterelement", FlagSETTINGS, OFFSET_POINTER (SettingType, ResetAfterElement)}, {"ringbellwhenfinished", FlagSETTINGS, OFFSET_POINTER (SettingType, RingBellWhenFinished)}, {"buffer", FlagBuffer, NULL}, }; REGISTER_FLAGS (flags_flag_list) pcb-4.3.0/src/change.h0000664000175000017500000001006113773431044011376 00000000000000/*! * \file src/change.h * * \brief Prototypes to change object properties. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * Thomas.Nau@rz.uni-ulm.de */ #ifndef PCB_CHANGE_H #define PCB_CHANGE_H #include "global.h" /* --------------------------------------------------------------------------- * some defines */ #define CHANGENAME_TYPES \ (VIA_TYPE | PIN_TYPE | PAD_TYPE | TEXT_TYPE | ELEMENT_TYPE | ELEMENTNAME_TYPE | LINE_TYPE) #define CHANGESIZE_TYPES \ (POLYGON_TYPE | VIA_TYPE | PIN_TYPE | PAD_TYPE | LINE_TYPE | \ ARC_TYPE | TEXT_TYPE | ELEMENTNAME_TYPE | ELEMENT_TYPE) #define CHANGE2NDSIZE_TYPES \ (VIA_TYPE | PIN_TYPE | ELEMENT_TYPE) /* We include polygons here only to inform the user not to do it that way. */ #define CHANGECLEARSIZE_TYPES \ (PIN_TYPE | PAD_TYPE | VIA_TYPE | LINE_TYPE | ARC_TYPE | POLYGON_TYPE) #define CHANGESQUARE_TYPES \ (ELEMENT_TYPE | PIN_TYPE | PAD_TYPE) #define CHANGEOCTAGON_TYPES \ (ELEMENT_TYPE | PIN_TYPE | VIA_TYPE) #define CHANGEJOIN_TYPES \ (ARC_TYPE | LINE_TYPE | TEXT_TYPE) #define CHANGETHERMAL_TYPES \ (PIN_TYPE | VIA_TYPE) #define CHANGEMASKSIZE_TYPES \ (PIN_TYPE | VIA_TYPE | PAD_TYPE) bool ChangeLayoutName (char *); bool ChangeLayerName (LayerType *, char *); bool ChangeSelectedSize (int, Coord, bool); bool ChangeSelectedClearSize (int, Coord, bool); bool ChangeSelected2ndSize (int, Coord, bool); bool ChangeSelectedMaskSize (int, Coord, bool); bool ChangeSelectedJoin (int); bool SetSelectedJoin (int); bool ClrSelectedJoin (int); bool ChangeSelectedSquare (int); bool SetSelectedSquare (int); bool ClrSelectedSquare (int); bool ChangeSelectedThermals (int, int); bool ChangeSelectedViaLayers (int, int); bool ChangeSelectedHole (void); bool ChangeSelectedPaste (void); bool ChangeSelectedOctagon (int); bool SetSelectedOctagon (int); bool ClrSelectedOctagon (int); bool ChangeSelectedElementSide (void); bool ChangeElementSide (ElementType *, Coord); bool ChangeHole (PinType *); bool ChangePaste (PadType *); bool ChangeObjectSize (int, void *, void *, void *, Coord, bool); bool ChangeObjectThermal (int, void *, void *, void *, int); bool ChangeObjectViaLayers (void *, void *, void *, int, int); bool ChangeObjectClearSize (int, void *, void *, void *, Coord, bool); bool ChangeObject2ndSize (int, void *, void *, void *, Coord, bool, bool); bool ChangeObjectMaskSize (int, void *, void *, void *, Coord, bool); bool ChangeObjectJoin (int, void *, void *, void *); bool SetObjectJoin (int, void *, void *, void *); bool ClrObjectJoin (int, void *, void *, void *); bool ChangeObjectSquare (int, void *, void *, void *); bool SetObjectSquare (int, void *, void *, void *); bool ClrObjectSquare (int, void *, void *, void *); bool ChangeObjectOctagon (int, void *, void *, void *); bool SetObjectOctagon (int, void *, void *, void *); bool ClrObjectOctagon (int, void *, void *, void *); void *ChangeObjectName (int, void *, void *, void *, char *); void *QueryInputAndChangeObjectName (int, void *, void *, void *); void ChangePCBSize (Coord, Coord); char *ChangeElementText (PCBType *pcb, DataType *data, ElementType *Element, int which, char *new_name); #endif pcb-4.3.0/src/drill.h0000664000175000017500000000233713773431044011266 00000000000000/*! * \file src/drill.h * * \brief . * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * This module, drill.h, was written and is Copyright (C) 1997 harry eaton * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * Thomas.Nau@rz.uni-ulm.de */ DrillInfoType * GetDrillInfo (DataType *); void FreeDrillInfo (DrillInfoType *); void RoundDrillInfo (DrillInfoType *, int); pcb-4.3.0/src/layerflags.h0000664000175000017500000000262413773431044012310 00000000000000/*! * \file src/layerflags.h * * \brief Prototypes for changing layer flags. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 2007 DJ Delorie * * Copyright (C) 2015 Markus "Traumflug" Hitter * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef PCB_LAYERFLAGS_H #define PCB_LAYERFLAGS_H unsigned int string_to_layertype (const char *typestring, int (*error) (const char *msg)); const char *layertype_to_string (unsigned int type); unsigned int guess_layertype (const char *name, int layer_number, DataType *data); #endif /* PCB_LAYERFLAGS_H */ pcb-4.3.0/src/const.h0000664000175000017500000003530313773431044011305 00000000000000/*! * \file src/const.h * * \brief Global source constants. * *
* * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * Thomas.Nau@rz.uni-ulm.de */ #ifndef PCB_CONST_H #define PCB_CONST_H #include #include #include "globalconst.h" /* --------------------------------------------------------------------------- * integer codings for the board sides. */ #define BOTTOM_SIDE 0 #define TOP_SIDE 1 /*! * Layer Stack. * * The situation is not ideal, because on top of the ordinary layer stack * there are two (both) silk layers. It was a hack to separate these and * probably done to easier iterate through non-silk layers, only. As we have * layer types now, iterating through any kind of distinct layer type has * become simple, see LAYER_TYPE_LOOP() in macro.h. * * Accordingly, the separation of these two silk layers should go away, they * should return to be "normal" layers. One might want to have more than two * silk layers, after all. * * Anyways, here's the current setup: * * Copper layer 0 \ * Copper layer 1 | * Outline layer >- in unspecified order * Routing layer | * (...additional layers...) / <== max_copper_layer * Bottom silk layer * Top silk layer <== max_copper_layer + SILK_LAYER * (...unused layers...) * (last layer - 2) <== MAX_LAYER * (last layer - 1) * (last layer) <== MAX_ALL_LAYER * ( == MAX_LAYER + SILK_LAYER) * * With all layers in use (rarely the case), max_copper_layer == MAX_LAYER. * * \note Position on the layer stack does not decide whether a layer is on the * top side, on the bottom side or in between. Each layer is part of a * layer group, and this group represents the physical layer, like top, * inner or bottom. */ /* --------------------------------------------------------------------------- * the layer-numbers of the two additional special (silkscreen) layers * 'bottom' and 'top'. The offset of MAX_LAYER is not added */ #define SILK_LAYER 2 #define BOTTOM_SILK_LAYER 0 #define TOP_SILK_LAYER 1 /* --------------------------------------------------------------------------- * the resulting maximum number of layers, including additional silk layers */ #define MAX_ALL_LAYER (MAX_LAYER + SILK_LAYER) /* --------------------------------------------------------------------------- * misc constants */ #define MARK_SIZE MIL_TO_COORD(50) /*!< relative marker size */ #define UNDO_WARNING_SIZE (1024*1024) /*!< warning limit of undo */ #define USERMEDIANAME "user defined" /*!< label of default media */ /* --------------------------------------------------------------------------- * some math constants */ #ifndef M_PI #define M_PI 3.14159265358979323846 #endif #ifndef M_SQRT1_2 #define M_SQRT1_2 0.707106781 /*!< 1/sqrt(2) */ #endif #define M180 (M_PI/180.0) #define RAD_TO_DEG (180.0/M_PI) #define TAN_22_5_DEGREE_2 0.207106781 /*!< 0.5*tan(22.5) */ #define COS_22_5_DEGREE 0.923879533 /*!< cos(22.5) */ #define TAN_30_DEGREE 0.577350269 /*!< tan(30) */ #define TAN_60_DEGREE 1.732050808 /*!< tan(60) */ #define LN_2_OVER_2 0.346573590 /* PCB/physical unit conversions */ #define COORD_TO_MIL(n) ((n) / 25400.0) #define MIL_TO_COORD(n) ((n) * 25400.0) #define COORD_TO_MM(n) ((n) / 1000000.0) #define MM_TO_COORD(n) ((n) * 1000000.0) #define COORD_TO_INCH(n) (COORD_TO_MIL(n) / 1000.0) #define INCH_TO_COORD(n) (MIL_TO_COORD(n) * 1000.0) /* These need to be carefully written to avoid overflows, and return a Coord type. */ #define SCALE_TEXT(COORD,TEXTSCALE) ((Coord)((COORD) * ((double)(TEXTSCALE) / 100.0))) #define UNSCALE_TEXT(COORD,TEXTSCALE) ((Coord)((COORD) * (100.0 / (double)(TEXTSCALE)))) /* --------------------------------------------------------------------------- * modes */ #define NO_MODE 0 /*!< no mode selected */ #define VIA_MODE 1 /*!< draw vias */ #define LINE_MODE 2 /*!< draw lines */ #define RECTANGLE_MODE 3 /*!< create rectangles */ #define POLYGON_MODE 4 /*!< draw filled polygons */ #define PASTEBUFFER_MODE 5 /*!< paste objects from buffer */ #define TEXT_MODE 6 /*!< create text objects */ #define ROTATE_MODE 102 /*!< rotate objects */ #define REMOVE_MODE 103 /*!< remove objects */ #define MOVE_MODE 104 /*!< move objects */ #define COPY_MODE 105 /*!< copy objects */ #define INSERTPOINT_MODE 106 /*!< insert point into line/polygon */ #define RUBBERBANDMOVE_MODE 107 /*!< move objects and attached lines */ #define THERMAL_MODE 108 /*!< toggle thermal layer flag */ #define ARC_MODE 109 /*!< draw arcs */ #define ARROW_MODE 110 /*!< selection with arrow mode */ #define PAN_MODE 0 /*!< same as no mode */ #define LOCK_MODE 111 /*!< lock/unlock objects */ #define POLYGONHOLE_MODE 112 /*!< cut holes in filled polygons */ /* --------------------------------------------------------------------------- * object flags */ /* %start-doc pcbfile ~objectflags @node Object Flags @section Object Flags Note that object flags can be given numerically (like @code{0x0147}) or symbolically (like @code{"found,showname,square"}. Some numeric values are reused for different object types. The table below lists the numeric value followed by the symbolic name. @table @code @item 0x0001 pin If set, this object is a pin. This flag is for internal use only. @item 0x0002 via Likewise, for vias. @item 0x0004 found If set, this object has been found by @code{FindConnection()}. @item 0x0008 hole For pins and vias, this flag means that the pin or via is a hole without a copper annulus. @item 0x0008 nopaste For pads, set to prevent a solderpaste stencil opening for the pad. Primarily used for pads used as fiducials. @item 0x0010 rat If set for a line, indicates that this line is a rat line instead of a copper trace. @item 0x0010 pininpoly For pins and pads, this flag is used internally to indicate that the pin or pad overlaps a polygon on some layer. @item 0x0010 clearpoly For polygons, this flag means that pins and vias will normally clear these polygons (thus, thermals are required for electrical connection). When clear, polygons will solidly connect to pins and vias. @item 0x0010 hidename For elements, when set the name of the element is hidden. @item 0x0020 showname For elements, when set the names of pins are shown. @item 0x0020 clearline For lines and arcs, the line/arc will clear polygons instead of connecting to them. @item 0x0020 fullpoly For polygons, the full polygon is drawn (i.e. all parts instead of only the biggest one). @item 0x0040 selected Set when the object is selected. @item 0x0080 onsolder For elements and pads, indicates that they are on the solder side. @item 0x0080 auto For lines and vias, indicates that these were created by the autorouter. @item 0x0100 square For pins and pads, indicates a square (vs round) pin/pad. @item 0x0200 rubberend For lines, used internally for rubber band moves. @item 0x0200 warn For pins, vias, and pads, set to indicate a warning. @item 0x0400 usetherm Obsolete, indicates that pins/vias should be drawn with thermal fingers. @item 0x0400 Obsolete, old files used this to indicate lines drawn on silk. @item 0x0800 octagon Draw pins and vias as octagons. @item 0x1000 drc Set for objects that fail DRC. @item 0x2000 lock Set for locked objects. @item 0x4000 edge2 For pads, indicates that the second point is closer to the edge. For pins, indicates that the pin is closer to a horizontal edge and thus pinout text should be vertical. @item 0x8000 marker Marker used internally to avoid revisiting an object. @item 0x10000 connected If set, this object has been as physically connected by @code{FindConnection()}. @end table %end-doc */ #define NOFLAG 0x0000 #define PINFLAG 0x0001 /*!< is a pin */ #define VIAFLAG 0x0002 /*!< is a via */ #define FOUNDFLAG 0x0004 /*!< used by 'FindConnection()' */ #define HOLEFLAG 0x0008 /*!< pin or via is only a hole */ #define NOPASTEFLAG 0x0008 /*!< pad should not receive solderpaste. This is to support fiducials */ #define RATFLAG 0x0010 /*!< indicates line is a rat line */ #define PININPOLYFLAG 0x0010 /*!< pin found inside poly - same as */ /*!< rat line since not used on lines */ #define CLEARPOLYFLAG 0x0010 /*!< pins/vias clear these polygons */ #define HIDENAMEFLAG 0x0010 /*!< hide the element name */ #define DISPLAYNAMEFLAG 0x0020 /*!< display the names of pins/pads of an element */ #define CLEARLINEFLAG 0x0020 /*!< line doesn't touch polygons */ #define FULLPOLYFLAG 0x0020 /*!< full polygon is drawn (i.e. all parts instead of only the biggest one) */ #define SELECTEDFLAG 0x0040 /*!< object has been selected */ #define ONSOLDERFLAG 0x0080 /*!< element is on bottom side */ #define AUTOFLAG 0x0080 /*!< line/via created by auto-router */ #define SQUAREFLAG 0x0100 /*!< pin is square, not round */ #define RUBBERENDFLAG 0x0200 /*!< indicates one end already rubber banding same as warn flag since pins/pads won't use it */ #define WARNFLAG 0x0200 /*!< Warning for pin/via/pad */ #define USETHERMALFLAG 0x0400 /*!< draw pin, via with thermal fingers */ #define ONSILKFLAG 0x0400 /*!< old files use this to indicate silk */ #define OCTAGONFLAG 0x0800 /*!< draw pin/via as octagon instead of round */ #define DRCFLAG 0x1000 /*!< flag like FOUND flag for DRC checking */ #define LOCKFLAG 0x2000 /*!< object locked in place */ #define EDGE2FLAG 0x4000 /*!< Padr.Point2 is closer to outside edge also pinout text for pins is vertical */ #define VISITFLAG 0x8000 /*!< marker to avoid re-visiting an object */ #define CONNECTEDFLAG 0x10000 /*!< flag like FOUND flag, but used to identify physically connected objects (not rats) */ #define NOCOPY_FLAGS (FOUNDFLAG | CONNECTEDFLAG) /* --------------------------------------------------------------------------- * PCB flags */ /* %start-doc pcbfile ~pcbflags @node PCBFlags @section PCBFlags @table @code @item 0x00001 Pinout displays pin numbers instead of pin names. @item 0x00002 Use local reference for moves, by setting the mark at the beginning of each move. @item 0x00004 When set, only polygons and their clearances are drawn, to see if polygons have isolated regions. @item 0x00008 Display DRC region on crosshair. @item 0x00010 Do all move, mirror, rotate with rubberband connections. @item 0x00020 Display descriptions of elements, instead of refdes. @item 0x00040 Display names of elements, instead of refdes. @item 0x00080 Auto-DRC flag. When set, PCB doesn't let you place copper that violates DRC. @item 0x00100 Enable 'all-direction' lines. @item 0x00200 Switch starting angle after each click. @item 0x00400 Force unique names on board. @item 0x00800 New lines/arc clear polygons. @item 0x01000 Crosshair snaps to pins and pads. @item 0x02000 Show the solder mask layer. @item 0x04000 Draw with thin lines. @item 0x08000 Move items orthogonally. @item 0x10000 Draw autoroute paths real-time. @item 0x20000 New polygons are full ones. @item 0x40000 Names are locked, the mouse cannot select them. @item 0x80000 Everything but names are locked, the mouse cannot select anything else. @item 0x100000 New polygons are full polygons. @item 0x200000 When set, element names are not drawn. @end table %end-doc */ #define PCB_FLAGS 0x000fffff /* all used flags */ #define SHOWNUMBERFLAG 0x00000001 #define LOCALREFFLAG 0x00000002 #define CHECKPLANESFLAG 0x00000004 #define SHOWDRCFLAG 0x00000008 #define RUBBERBANDFLAG 0x00000010 #define DESCRIPTIONFLAG 0x00000020 #define NAMEONPCBFLAG 0x00000040 #define AUTODRCFLAG 0x00000080 #define ALLDIRECTIONFLAG 0x00000100 #define SWAPSTARTDIRFLAG 0x00000200 #define UNIQUENAMEFLAG 0x00000400 #define CLEARNEWFLAG 0x00000800 #define SNAPPINFLAG 0x00001000 #define SHOWMASKFLAG 0x00002000 #define THINDRAWFLAG 0x00004000 #define ORTHOMOVEFLAG 0x00008000 #define LIVEROUTEFLAG 0x00010000 #define THINDRAWPOLYFLAG 0x00020000 #define LOCKNAMESFLAG 0x00040000 #define ONLYNAMESFLAG 0x00080000 #define NEWFULLPOLYFLAG 0x00100000 #define HIDENAMESFLAG 0x00200000 #define AUTOBURIEDVIASFLAG 0x00400000 /* --------------------------------------------------------------------------- * object types */ #define NO_TYPE 0x00000 /*!< no object */ #define VIA_TYPE 0x00001 #define ELEMENT_TYPE 0x00002 #define LINE_TYPE 0x00004 #define POLYGON_TYPE 0x00008 #define TEXT_TYPE 0x00010 #define RATLINE_TYPE 0x00020 #define PIN_TYPE 0x00100 /*!< objects that are part */ #define PAD_TYPE 0x00200 /*!< 'pin' of SMD element */ #define ELEMENTNAME_TYPE 0x00400 /*!< of others */ #define POLYGONPOINT_TYPE 0x00800 #define LINEPOINT_TYPE 0x01000 #define ELEMENTLINE_TYPE 0x02000 #define ARC_TYPE 0x04000 #define ELEMENTARC_TYPE 0x08000 #define LOCKED_TYPE 0x10000 /*!< used to tell search to include locked items. */ #define NET_TYPE 0x20000 /*!< used to select whole net. */ #define ARCPOINT_TYPE 0x40000 #define PIN_TYPES (VIA_TYPE | PIN_TYPE) #define LOCK_TYPES (VIA_TYPE | LINE_TYPE | ARC_TYPE | POLYGON_TYPE | ELEMENT_TYPE \ | TEXT_TYPE | ELEMENTNAME_TYPE | LOCKED_TYPE) #define ALL_TYPES (~0) /*!< all bits set */ #endif pcb-4.3.0/src/hid.h0000664000175000017500000006576313773431044010740 00000000000000/*! * \file src/hid.h * * \brief Human Interface Device. * * \author This file, hid.h, was written and is * Copyright (c) 2006 DJ Delorie * * The way the HID layer works is that you instantiate a HID device * structure, and invoke functions through its members. * * Code in the common part of PCB may *not* rely on *anything* other * than what's defined in this file. * * Code in the HID layers *may* rely on data and functions in the common * code (like, board size and such) but it's considered bad form to do * so when not needed. * * Coordinates are ALWAYS in pcb's default resolution. * * Positive X is right, positive Y is down. * * Angles are degrees, with 0 being right (positive X) and 90 being up * (negative Y). * * All zoom, scaling, panning, and conversions are hidden inside the HID * layers. * * The main structure is at the end of this file. * * Data structures passed to the HIDs will be copied if the HID needs to * save them. * * Data structures retured from the HIDs must not be freed, and may be * changed by the HID in response to new information. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * Copyright (C) 1998,1999,2000,2001 harry eaton * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA * haceaton@aplcomm.jhuapl.edu */ #ifndef PCB_HID_H #define PCB_HID_H #include #include "drc/drc_violation.h" /* DrcViolationType */ #if defined(__cplusplus) && __cplusplus extern "C" { #endif /*! * \brief Like end cap styles. * * The cap *always* extends beyond the coordinates given, by half the * width of the line. * * Beveled ends can used to make octagonal pads by giving the same x,y * coordinate twice. */ typedef enum { Trace_Cap, /*!< This means we're drawing a trace, which has round caps. */ Square_Cap, /*!< Square pins or pads. */ Round_Cap, /*!< Round pins or round-ended pads, thermals. */ Beveled_Cap /*!< Octagon pins or bevel-cornered pads. */ } EndCapStyle; /*! * \brief The HID may need something more than an "int" for colors, * timers, etc. * * So it passes/returns one of these, which is castable to a variety * of things. */ typedef union { long lval; void *ptr; } hidval; /*! * This graphics context is an opaque pointer defined by the HID. * * GCs are HID-specific; attempts to use one HID's GC for a different * HID will result in a fatal error. */ typedef struct hid_gc_struct *hidGC; #define HIDCONCAT(a,b) a##b /*! * \brief This is used to register the action callbacks (for menus and * whatnot). * * HID assumes the following actions are available for its use: * - SaveAs(filename); * - Quit(); */ typedef struct { char *name; /*!< This is matched against action names in the GUI configuration */ const char *need_coord_msg; /*!< If this string is non-NULL, the action needs to know the X,Y * coordinates to act on, and this string may be used to prompt * the user to select a coordinate. If NULL, the coordinates may * be 0,0 if none are known. */ int (*trigger_cb) (int argc, char **argv, Coord x, Coord y); /*!< Called when the action is triggered. If this function returns * non-zero, no further actions will be invoked for this key/mouse * event. */ const char *description; /*!< Short description that sometimes accompanies the name. */ const char *syntax; /*!< Full allowed syntax; use \\n to separate lines. */ } HID_Action; extern void hid_register_action (HID_Action *); extern void hid_register_actions (HID_Action *, int); #define REGISTER_ACTIONS(a) HIDCONCAT(void register_,a) ()\ { hid_register_actions(a, sizeof(a)/sizeof(a[0])); } /* Note that PCB expects the gui to provide the following actions: PCBChanged(); RouteStylesChanged() NetlistChanged() (but core should call "void NetlistChanged(int);" in netlist.c) LayersChanged() LibraryChanged() Busy() */ extern const char pcbchanged_help[]; extern const char pcbchanged_syntax[]; extern const char routestyleschanged_help[]; extern const char routestyleschanged_syntax[]; extern const char netlistchanged_help[]; extern const char netlistchanged_syntax[]; extern const char layerschanged_help[]; extern const char layerschanged_syntax[]; extern const char librarychanged_help[]; extern const char librarychanged_syntax[]; int hid_action (const char *action_); int hid_actionl (const char *action_, ...); /* NULL terminated */ int hid_actionv (const char *action_, int argc_, char **argv_); void hid_save_settings (int); void hid_load_settings (void); /*! * \brief Parse the given command string into action calls, and call * hid_actionv for each action found. * * Accepts both "action(arg1, arg2)" and command-style * "action arg1 arg2", allowing only one action in the later case. * * \return Returns nonzero if the action handler(s) return nonzero. */ int hid_parse_command (const char *str_); /*! * \brief Parse the given string into action calls, and call hid_actionv * for each action found. * * Accepts only "action(arg1, arg2)". */ int hid_parse_actions (const char *str_); typedef struct { char *name; /*!< Name of the flag */ int (*function) (void *); /*!< Function to call to get the value of the flag. */ void *parm; /*!< Additional parameter to pass to that function. */ } HID_Flag; extern void hid_register_flags (HID_Flag *, int); #define REGISTER_FLAGS(a) HIDCONCAT(void register_,a) ()\ { hid_register_flags(a, sizeof(a)/sizeof(a[0])); } /*! * \brief Looks up one of the flags registered above. * * \return If the flag is unknown, returns zero. */ int hid_get_flag (const char *name_); /*! * \brief Used for HID attributes (exporting and printing, mostly). * * HA_boolean uses int_value, HA_enum sets int_value to the index and * str_value to the enumeration string. * * HID_Label just shows the default str_value. * * HID_Mixed is a real_value followed by an enum, like 0.5in or 100mm. */ typedef struct { int int_value; const char *str_value; double real_value; Coord coord_value; } HID_Attr_Val; enum hids { HID_Label, HID_Integer, HID_Real, HID_String, HID_Boolean, HID_Enum, HID_Mixed, HID_Path, HID_Unit, HID_Coord }; typedef struct { char *name; #define ATTR_UNDOCUMENTED ((char *)(1)) char *help_text; /*!< If the help_text is this, usage() won't show this option */ enum hids type; int min_val; /*!< For integer and real */ int max_val; /*!< For integer and real */ HID_Attr_Val default_val; /*!< Also actual value for global attributes. */ const char **enumerations; void *value; /*!< If set, this is used for global attributes (i.e. those set * statically with REGISTER_ATTRIBUTES below) instead of changing * the default_val. * \note Note that a HID_Mixed attribute must specify a pointer to * HID_Attr_Val here, and HID_Boolean assumes this is "char *" so * the value should be initialized to zero, and may be set to * non-zero (not always one). */ int hash; /*!< For detecting changes. */ } HID_Attribute; extern void hid_register_attributes (HID_Attribute *, int); #define REGISTER_ATTRIBUTES(a) HIDCONCAT(void register_,a) ()\ { hid_register_attributes(a, sizeof(a)/sizeof(a[0])); } /* These three are set by hid_parse_command_line(). */ extern char *program_name; extern char *program_directory; extern char *program_basename; /* These are used for set_layer(). */ #define SL_0_SIDE 0x0000 #define SL_TOP_SIDE 0x0001 #define SL_BOTTOM_SIDE 0x0002 #define SL_INNER_SIDE 0x0004 /* * These are types of "layers" without direct physical representation. * Their content can be derived from other layers and element data. * * These values are used by DrawEverything() in draw.c to ask the active * GUI or exporter to act on these layers. Depending on the GUI/exporter * they result in a per-layer file, in some additional graphics or just * nothing. */ #define SL_SILK 0x0010 /*!< Physical layer, deprecated, use LT_SILK. */ #define SL_MASK 0x0020 #define SL_PDRILL 0x0030 #define SL_UDRILL 0x0040 #define SL_PASTE 0x0050 #define SL_INVISIBLE 0x0060 #define SL_FAB 0x0070 #define SL_ASSY 0x0080 #define SL_RATS 0x0090 /* Callers should use this. */ #define SL(type,side) (~0xfff | SL_##type | SL_##side##_SIDE) /*! * These are layers with direct physical representation, like copper, dye * or to be milled paths. Their data can't be derived from other layers or * element data. * * To add more layer types, add them to the list here and in layerflags.c. * Order of entries in both lists must be the same. */ typedef enum { LT_COPPER = 0, LT_SILK, LT_MASK, /*!< Complements SL_MASK above. */ LT_PASTE, /*!< Complements SL_PASTE above. */ LT_OUTLINE, /*!< Board outline; exists only once. */ LT_ROUTE, LT_KEEPOUT, LT_FAB, /*!< Complements SL_FAB above. */ LT_ASSY, /*!< Complements SL_ASSY above. */ LT_NOTES, LT_NUM_LAYERTYPES /*!< Must be the last one. */ } LayertypeType; /*! * \brief File Watch flags. * * Based upon those in dbus/dbus-connection.h. */ typedef enum { PCB_WATCH_READABLE = 1 << 0, /*!< As in POLLIN */ PCB_WATCH_WRITABLE = 1 << 1, /*!< As in POLLOUT */ PCB_WATCH_ERROR = 1 << 2, /*!< As in POLLERR */ PCB_WATCH_HANGUP = 1 << 3 /*!< As in POLLHUP */ } PCBWatchFlags; /*! * \brief DRC GUI Hooks. */ typedef struct { int log_drc_overview; int log_drc_violations; void (*reset_drc_dialog_message) (void); void (*append_drc_violation) (DrcViolationType *violation); int (*throw_drc_dialog) (void); } HID_DRC_GUI; typedef struct hid_st HID; typedef struct hid_draw_st HID_DRAW; /*! * \brief This is the main HID structure. */ struct hid_st { int struct_size; /*!< The size of this structure. * * We use this as a compatibility check; a HID built with a * different hid.h than we're expecting should have a different * size here. */ const char *name; /*!< The name of this HID. * * This should be suitable for command line options, * multi-selection menus, file names, etc. */ const char *description; /*!< Likewise, but allowed to be longer and more descriptive. */ char gui:1; /*!< If set, this is the GUI HID. * * Exactly one of these three flags must be set; setting "gui" * lets the expose callback optimize and coordinate itself. */ char printer:1; /*!< If set, this is the printer-class HID. * * The common part of PCB may use this to do command-line printing, * without having instantiated any GUI HIDs. * Only one printer HID is normally defined at a time. */ char exporter:1; /*!< If set, this HID provides an export option, and should be * used as part of the File->Export menu option. * * Examples are PNG, Gerber, and EPS exporters. */ char poly_before:1; /*!< If set, the redraw code will draw polygons before erasing the * clearances. */ char poly_after:1; /*!< If set, the redraw code will draw polygons after erasing the * clearances. * * \note Note that HIDs may set both of these, in which case * polygons will be drawn twice. */ HID_Attribute *(*get_export_options) (int *n_ret_); /*!< Returns a set of resources describing options the export or * print HID supports. * * In GUI mode, the print/export dialogs use this to set up the * selectable options. * * In command line mode, these are used to interpret command line * options. * * If \c n_ret_ is non-NULL, the number of attributes is stored * there. */ void (*do_export) (HID_Attr_Val * options_); /*!< Export (or print) the current PCB. * * The options given represent the choices made from the options * returned from get_export_options. * * Call with options == NULL to start the primary GUI (create a * main window, print, export, etc). */ void (*uninit) (HID *hid); /*!< uninit a GUI hid. */ void (*do_exit) (HID *hid); /*!< uninit a GUI hid. */ void (*parse_arguments) (int *argc_, char ***argv_); /*!< Parse the command line. * * Call this early for whatever HID will be the primary HID, as it * will set all the registered attributes. * * The HID should remove all arguments, leaving any possible file * names behind. */ void (*invalidate_lr) (Coord left_, Coord right_, Coord top_, Coord bottom_); /*!< This may be called to ask the GUI to force a redraw of a * given area. */ void (*invalidate_all) (void); void (*notify_crosshair_change) (bool changes_complete); void (*notify_mark_change) (bool changes_complete); int (*set_layer) (const char *name_, int group_, int _empty); /*!< During redraw or print/export cycles, this is called once per * layer (or layer group, for copper layers). * * If it returns false (zero), the HID does not want that layer, * and none of the drawing functions should be called. * * If it returns true (nonzero), the items in that layer [group] * should be drawn using the various drawing functions. * * In addition to the MAX_GROUP copper layer groups, you may * select layers indicated by the macros SL_* defined above, or * any others with an index of -1. * * For copper layer groups, you may pass NULL for name to have a * name fetched from the PCB struct. * * The EMPTY argument is a hint - if set, the layer is empty, if * zero it may be non-empty. */ void (*end_layer) (void); /*!< Tell the GUI the layer last selected has been finished with. */ HID_DRAW *graphics; void (*calibrate) (double xval_, double yval_); /*!< This is for the printer. * * If you call this for the GUI, \c xval_ and \c yval_ are ignored, * and a dialog pops up to lead you through the calibration * procedure. * * For the printer, if \c xval_ and \c yval_ are zero, a * calibration page is printed with instructions for calibrating * your printer. * * After calibrating, nonzero \c xval_ and \c yval_ are passed * according to the instructions. * * Metric is nonzero if the user prefers metric units, else inches * are used. */ /* GUI layout functions. Not used or defined for print/export HIDs. */ /* Temporary */ int (*shift_is_pressed) (void); int (*control_is_pressed) (void); int (*mod1_is_pressed) (void); void (*get_coords) (const char *msg_, Coord *x_, Coord *y_); void (*set_crosshair) (int x_, int y_, int cursor_action_); /*!< Sets the crosshair, which may differ from the pointer * depending on grid and pad snap. * * \note Note that the HID is responsible for hiding, showing, * redrawing, etc. The core just tells it what coordinates it's * actually using. * * \note Note that this routine may need to know what "pcb units" * are so it can display them in mm or mils accordingly. * * If \c cursor_action_ is set, the cursor or screen may be * adjusted so that the cursor and the crosshair are at the same * point on the screen. */ #define HID_SC_DO_NOTHING 0 #define HID_SC_WARP_POINTER 1 #define HID_SC_PAN_VIEWPORT 2 #define HID_SC_CENTER_IN_VIEWPORT 3 #define HID_SC_CENTER_IN_VIEWPORT_AND_WARP_POINTER 4 hidval (*add_timer) (void (*func) (hidval user_data_), unsigned long milliseconds_, hidval user_data_); /*!< Causes func to be called at some point in the future. * * Timers are only good for *one* call; if you want it to * repeat, add another timer during the callback for the first. * * \c user_data can be anything, it's just passed to func. * * \warning Times are not guaranteed to be accurate. */ void (*stop_timer) (hidval timer_); /*!< Use this to stop a timer that hasn't triggered yet. */ hidval (*watch_file) (int fd_, unsigned int condition_, void (*func_) (hidval watch_, int fd_, unsigned int condition_, hidval user_data_), hidval user_data); /*!< Causes \c func_ to be called when some condition occurs on * the file descriptor passed. * * Conditions include data for reading, writing, hangup, and * errors. * * \c user_data can be anything, it's just passed to \c func_. */ void (*unwatch_file) (hidval watch_); /*!< Use this to stop a file watch. */ hidval (*add_block_hook) (void (*func_) (hidval data_), hidval data_); /*!< Causes \c func to be called in the main loop prior to * blocking. */ void (*stop_block_hook) (hidval block_hook_); /*!< Use this to stop a main loop block hook. */ /* Various dialogs */ void (*log) (const char *fmt_, ...); /*!< Log a message to the log window. */ void (*logv) (const char *fmt_, va_list args_); /*!< Log a message to the log window. */ int (*confirm_dialog) (char *msg_, ...); /*!< A generic yes/no dialog. * * Returns zero if the cancel button is pressed, one for the ok * button. * * If you specify alternate labels for ..., they are used instead * of the default OK/Cancel ones, and the return value is the * index of the label chosen. * * \warning You MUST pass NULL as the last parameter to this. */ int (*close_confirm_dialog) (); /*!< A close confirmation dialog for unsaved pages, for example, * with options "Close without saving", "Cancel" and "Save". * * Returns zero if the close is cancelled, or one if it should * proceed. * * The HID is responsible for any "Save" action the user may wish * before confirming the close. */ #define HID_CLOSE_CONFIRM_CANCEL 0 #define HID_CLOSE_CONFIRM_OK 1 void (*report_dialog) (char *title_, char *msg_); /*!< Just prints text. */ char *(*prompt_for) (const char *msg_, const char *default_string_); /*!< Prompts the user to enter a string, returns the string. * * If \c default_string isn't NULL, the form is pre-filled with * this value. * * "msg" is like "Enter value:". */ #define HID_FILESELECT_READ 0x01 /*!< Prompts the user for a filename or directory name. * * For GUI HID's this would mean a file select dialog box. * * The 'flags' argument is the bitwise OR of the following values. */ #define HID_FILESELECT_MAY_NOT_EXIST 0x02 /*!< The function calling hid->fileselect will deal with the case * where the selected file already exists. * * If not given, then the gui will prompt with an "overwrite?" * prompt. * * Only used when writing. */ #define HID_FILESELECT_IS_TEMPLATE 0x04 /*!< The call is supposed to return a file template (for gerber * output for example) instead of an actual file. * * Only used when writing. */ char *(*fileselect) (const char *title_, const char *descr_, char *default_file_, char *default_ext_, const char *history_tag_, int flags_); /*!< \c title_ may be used as a dialog box title. Ignored if NULL. * * \c descr_ is a longer help string. Ignored if NULL. * * \c default_file_ is the default file name. Ignored if NULL. * * \c default_ext_ is the default file extension, like ".pdf". * Ignored if NULL. * * \c history_tag_ may be used by the GUI to keep track of file * history. Examples would be "board", "vendor", "renumber", * etc. If NULL, no specific history is kept. * * \c flags_ are the bitwise or of the HID_FILESELECT defines * above. */ int (*attribute_dialog) (HID_Attribute * attrs_, int n_attrs_, HID_Attr_Val * results_, const char * title_, const char * descr_); /*!< A generic dialog to ask for a set of attributes. * * If \c n_attrs_ is zero, \c attrs(.name) must be NULL terminated. * * Returns non-zero if an error occurred (usually, this means the * user cancelled the dialog or something). * * \c title_ is the title of the dialog box. * * \c descr_ (if not NULL) can be a longer description of what the * attributes are used for. * * The HID may choose to ignore it or it may use it for a tooltip * or text in a dialog box, or a help string. */ void (*show_item) (void *item_); /*!< This causes a second window to display, which only shows the * selected item. * * The expose callback is called twice; once to size the extents * of the item, and once to draw it. * * To pass magic values, pass the address of a variable created * for this purpose. */ void (*beep) (void); /*!< Something to alert the user. */ int (*progress) (int so_far_, int total_, const char *message_); /*!< Used by optimizers and autorouter to show progress to the * user. * * Pass all zeros to flush display and remove any dialogs. * * Returns nonzero if the user wishes to cancel the operation. */ HID_DRC_GUI *drc_gui; void (*edit_attributes) (char *owner, AttributeListType *attrlist_); /* Debug drawing support. These APIs must be implemented (non NULL), * but they do not have to be functional. request_debug_draw can * return NULL to indicate debug drawing is not permitted. * * Debug drawing is not guaranteed to be re-entrant. * The caller must not nest requests for debug drawing. */ HID_DRAW *(*request_debug_draw) (void); /*!< Request permission for debug drawing. * * Returns a HID_DRAW pointer which should be used rather than the * global gui->graphics-> for making drawing calls. * * If the return value is NULL, then permission has been denied, * and the drawing must not continue. * * \warning Debug drawing is not guaranteed to be re-entrant. * The caller must not nest requests for debug drawing. */ void (*flush_debug_draw) (void); /*!< Flush pending drawing to the screen. * * May be implemented as a NOOP if the GUI has chosen to send the * debug drawing directly to the screen. */ void (*finish_debug_draw) (void); /*!< When finished, the user must inform the GUI to clean up * resources. * * Any remaining rendering will be flushed to the screen. */ void (*notify_save_pcb) (const char *filename, bool done); /*!< Notification to the GUI around saving the PCB file. * * Called with a false parameter before the save, called again * with true after the save. * * Allows GUIs which watch for file-changes on disk to ignore * our deliberate changes. */ void (*notify_filename_changed) (void); /*!< Notification to the GUI that the PCB file has been renamed. */ }; /*! * \brief Call this as soon as possible from main(). * * No other HID calls are valid until this is called. */ void hid_init (void); /*! * \brief Call this at exit. */ void hid_uninit (void); /*! * \brief When PCB runs in interactive mode, this is called to * instantiate one GUI HID which happens to be the GUI. * * This HID is the one that interacts with the mouse and keyboard. */ HID *hid_find_gui (); /*! * \brief Finds the one printer HID and instantiates it. */ HID *hid_find_printer (void); /*! * \brief Finds the indicated exporter HID and instantiates it. */ HID *hid_find_exporter (const char *); /*! * \brief This returns a NULL-terminated array of available HIDs. * * The only real reason to use this is to locate all the export-style * HIDs. */ HID **hid_enumerate (void); /*! * \brief This function (in the common code) will be called whenever * the GUI needs to redraw the screen, print the board, or export a * layer. * * If item is not NULL, only draw the given item. * Item is only non-NULL if the HID was created via show_item. * * Each time func is called, it should do the following: * * allocate any colors needed, via get_color. * * cycle through the layers, calling set_layer for each layer to be * drawn, and only drawing elements (all or specified) of desired * layers. * * Do *not* assume that the hid that is passed is the GUI hid. * * This callback is also used for printing and exporting. */ void hid_expose_callback (HID * hid_, struct BoxType *region_, void *item_); extern HID *gui; /*!< This is initially set to a "no-gui" gui, and later reset by * main. * * hid_expose_callback also temporarily set it for drawing. */ extern HID *exporter; /*!< This is either NULL or points to the current HID that is being * called to do the exporting. * * The gui HIDs set and unset this var. */ extern HID_Action *current_action; /*!< This is either NULL or points to the current HID_Action that is * being called. * * The action launcher sets and unsets this variable. */ extern int pixel_slop; /*!< The GUI may set this to be approximately the PCB size of a * pixel, to allow for near-misses in selection and changes in * drawing items smaller than a screen pixel. */ #if defined(__cplusplus) && __cplusplus } #endif #endif pcb-4.3.0/src/rats.c0000664000175000017500000006734513773431044011136 00000000000000/*! * \file src/rats.c * * \brief Rats nest routines. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * Copyright (C) 1997, harry eaton * * This module, rats.c, was written and is Copyright (C) 1997 by * harry eaton. * * This module is also subject to the GNU GPL as described below. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* Change History: * Started 6/10/97 * Added support for minimum length rat lines 6/13/97 * rat lines to nearest line/via 8/29/98 * support for netlist window 10/24/98 */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "global.h" #include "create.h" #include "data.h" #include "draw.h" #include "error.h" #include "file.h" #include "find.h" #include "flags.h" #include "misc.h" #include "mymem.h" #include "polygon.h" #include "rats.h" #include "search.h" #include "set.h" #include "undo.h" #ifdef HAVE_LIBDMALLOC #include #endif #define TRIEDFIRST 0x1 #define BESTFOUND 0x2 /* --------------------------------------------------------------------------- * some forward declarations */ static bool FindPad (char *, char *, ConnectionType *, bool); static bool ParseConnection (char *, char *, char *); static bool DrawShortestRats (NetListType *, void (*)(register ConnectionType *, register ConnectionType *, register RouteStyleType *)); static bool GatherSubnets (NetListType *, bool, bool); static bool CheckShorts (LibraryMenuType *); static void TransferNet (NetListType *, NetType *, NetType *); /* --------------------------------------------------------------------------- * some local identifiers */ static bool badnet = false; static Cardinal top_group, bottom_group; /* layer group holding top/bottom side */ /*! * \brief Parse a connection description from a string. * * Puts the element name in the string and the pin number in * the number. * * \return If a valid connection is found, it returns the number of characters * processed from the string, otherwise it returns 0. */ static bool ParseConnection (char *InString, char *ElementName, char *PinNum) { int i, j; /* copy element name portion */ for (j = 0; InString[j] != '\0' && InString[j] != '-'; j++) ElementName[j] = InString[j]; if (InString[j] == '-') { for (i = j; i > 0 && ElementName[i - 1] >= 'a'; i--); ElementName[i] = '\0'; for (i = 0, j++; InString[j] != '\0'; i++, j++) PinNum[i] = InString[j]; PinNum[i] = '\0'; return (false); } else { ElementName[j] = '\0'; Message (_("Bad net-list format encountered near: \"%s\"\n"), ElementName); return (true); } } /*! * \brief Find a particular pad from an element name and pin number. */ static bool FindPad (char *ElementName, char *PinNum, ConnectionType * conn, bool Same) { ElementType *element; GList *i; if ((element = SearchElementByName (PCB->Data, ElementName)) == NULL) return false; for (i = element->Pad; i != NULL; i = g_list_next (i)) { PadType *pad = i->data; if (NSTRCMP (PinNum, pad->Number) == 0 && (!Same || !TEST_FLAG (DRCFLAG, pad))) { conn->type = PAD_TYPE; conn->ptr1 = element; conn->ptr2 = pad; conn->group = TEST_FLAG (ONSOLDERFLAG, pad) ? bottom_group : top_group; if (TEST_FLAG (EDGE2FLAG, pad)) { conn->X = pad->Point2.X; conn->Y = pad->Point2.Y; } else { conn->X = pad->Point1.X; conn->Y = pad->Point1.Y; } return true; } } for (i = element->Pin; i != NULL; i = g_list_next (i)) { PinType *pin = i->data; if (!TEST_FLAG (HOLEFLAG, pin) && pin->Number && NSTRCMP (PinNum, pin->Number) == 0 && (!Same || !TEST_FLAG (DRCFLAG, pin))) { conn->type = PIN_TYPE; conn->ptr1 = element; conn->ptr2 = pin; conn->group = bottom_group; /* any layer will do */ conn->X = pin->X; conn->Y = pin->Y; return true; } } return false; } /*! * \brief Parse a netlist menu entry and locate the corresponding pad. * * \return true if found, and fills in Connection information. */ bool SeekPad (LibraryEntryType * entry, ConnectionType * conn, bool Same) { int j; char ElementName[256]; char PinNum[256]; if (ParseConnection (entry->ListEntry, ElementName, PinNum)) return (false); for (j = 0; PinNum[j] != '\0'; j++); if (j == 0) { Message (_("Error! Netlist file is missing pin!\n" "white space after \"%s-\"\n"), ElementName); badnet = true; } else { if (FindPad (ElementName, PinNum, conn, Same)) return (true); if (Same) return (false); if (PinNum[j - 1] < '0' || PinNum[j - 1] > '9') { Message ("WARNING! Pin number ending with '%c'" " encountered in netlist file\n" "Probably a bad netlist file format\n", PinNum[j - 1]); } } Message (_("Can't find %s pin %s called for in netlist.\n"), ElementName, PinNum); return (false); } /*! * \brief Read the library-netlist build a true Netlist structure. */ NetListType * ProcNetlist (LibraryType *net_menu) { ConnectionType *connection; ConnectionType LastPoint; NetType *net; static NetListType *Wantlist = NULL; if (!net_menu->MenuN) return (NULL); FreeNetListMemory (Wantlist); free (Wantlist); badnet = false; /* find layer groups of the component side and solder side */ bottom_group = GetLayerGroupNumberBySide (BOTTOM_SIDE); top_group = GetLayerGroupNumberBySide (TOP_SIDE); Wantlist = (NetListType *)calloc (1, sizeof (NetListType)); if (Wantlist) { ALLPIN_LOOP (PCB->Data); { pin->Spare = NULL; CLEAR_FLAG (DRCFLAG, pin); } ENDALL_LOOP; ALLPAD_LOOP (PCB->Data); { pad->Spare = NULL; CLEAR_FLAG (DRCFLAG, pad); } ENDALL_LOOP; MENU_LOOP (net_menu); { if (menu->Name[0] == '*' || menu->flag == 0) { badnet = true; continue; } net = GetNetMemory (Wantlist); if (menu->Style) { STYLE_LOOP (PCB); { if (style->Name && !NSTRCMP (style->Name, menu->Style)) { net->Style = style; break; } } END_LOOP; } else /* default to NULL if none found */ net->Style = NULL; ENTRY_LOOP (menu); { if (SeekPad (entry, &LastPoint, false)) { if (TEST_FLAG (DRCFLAG, (PinType *) LastPoint.ptr2)) Message (_ ("Error! Element %s pin %s appears multiple times in the netlist file.\n"), NAMEONPCB_NAME ((ElementType *) LastPoint.ptr1), (LastPoint.type == PIN_TYPE) ? ((PinType *) LastPoint.ptr2)-> Number : ((PadType *) LastPoint.ptr2)->Number); else { connection = GetConnectionMemory (net); *connection = LastPoint; /* indicate expect net */ connection->menu = menu; /* mark as visited */ SET_FLAG (DRCFLAG, (PinType *) LastPoint.ptr2); if (LastPoint.type == PIN_TYPE) ((PinType *) LastPoint.ptr2)->Spare = (void *) menu; else ((PadType *) LastPoint.ptr2)->Spare = (void *) menu; } } else badnet = true; /* check for more pins with the same number */ for (; SeekPad (entry, &LastPoint, true);) { connection = GetConnectionMemory (net); *connection = LastPoint; /* indicate expect net */ connection->menu = menu; /* mark as visited */ SET_FLAG (DRCFLAG, (PinType *) LastPoint.ptr2); if (LastPoint.type == PIN_TYPE) ((PinType *) LastPoint.ptr2)->Spare = (void *) menu; else ((PadType *) LastPoint.ptr2)->Spare = (void *) menu; } } END_LOOP; } END_LOOP; } /* clear all visit marks */ ALLPIN_LOOP (PCB->Data); { CLEAR_FLAG (DRCFLAG, pin); } ENDALL_LOOP; ALLPAD_LOOP (PCB->Data); { CLEAR_FLAG (DRCFLAG, pad); } ENDALL_LOOP; return (Wantlist); } /*! * \brief Copy all connections from one net into another and then remove * the first net from its netlist. */ static void TransferNet (NetListType *Netl, NetType *SourceNet, NetType *DestNet) { ConnectionType *conn; /* It would be worth checking if SourceNet is NULL here to avoid a segfault. Seb James. */ CONNECTION_LOOP (SourceNet); { conn = GetConnectionMemory (DestNet); *conn = *connection; } END_LOOP; DestNet->Style = SourceNet->Style; /* free the connection memory */ FreeNetMemory (SourceNet); /* remove SourceNet from its netlist */ *SourceNet = Netl->Net[--(Netl->NetN)]; /* zero out old garbage */ memset (&Netl->Net[Netl->NetN], 0, sizeof (NetType)); } static bool CheckShorts (LibraryMenuType *theNet) { bool newone, warn = false; PointerListType *generic = (PointerListType *)calloc (1, sizeof (PointerListType)); /* the first connection was starting point so * the menu is always non-null */ void **menu = GetPointerMemory (generic); *menu = theNet; ALLPIN_LOOP (PCB->Data); { if (TEST_FLAG (DRCFLAG, pin)) { warn = true; if (!pin->Spare) { Message (_("Warning! Net \"%s\" is shorted to %s pin %s\n"), &theNet->Name[2], UNKNOWN (NAMEONPCB_NAME (element)), UNKNOWN (pin->Number)); SET_FLAG (WARNFLAG, pin); continue; } newone = true; POINTER_LOOP (generic); { if (*ptr == pin->Spare) { newone = false; break; } } END_LOOP; if (newone) { menu = GetPointerMemory (generic); *menu = pin->Spare; Message (_("Warning! Net \"%s\" is shorted to net \"%s\"\n"), &theNet->Name[2], &((LibraryMenuType *) (pin->Spare))->Name[2]); SET_FLAG (WARNFLAG, pin); } } } ENDALL_LOOP; ALLPAD_LOOP (PCB->Data); { if (TEST_FLAG (DRCFLAG, pad)) { warn = true; if (!pad->Spare) { Message (_("Warning! Net \"%s\" is shorted to %s pad %s\n"), &theNet->Name[2], UNKNOWN (NAMEONPCB_NAME (element)), UNKNOWN (pad->Number)); SET_FLAG (WARNFLAG, pad); continue; } newone = true; POINTER_LOOP (generic); { if (*ptr == pad->Spare) { newone = false; break; } } END_LOOP; if (newone) { menu = GetPointerMemory (generic); *menu = pad->Spare; Message (_("Warning! Net \"%s\" is shorted to net \"%s\"\n"), &theNet->Name[2], &((LibraryMenuType *) (pad->Spare))->Name[2]); SET_FLAG (WARNFLAG, pad); } } } ENDALL_LOOP; FreePointerListMemory (generic); free (generic); return (warn); } /*! * \brief Determine existing interconnections of the net and gather into * sub-nets. * * Initially the netlist has each connection in its own individual net * afterwards there can be many fewer nets with multiple connections * each. */ static bool GatherSubnets (NetListType *Netl, bool NoWarn, bool AndRats) { NetType *a, *b; ConnectionType *conn; Cardinal m, n; bool Warned = false; for (m = 0; Netl->NetN > 0 && m < Netl->NetN; m++) { a = &Netl->Net[m]; ClearFlagOnAllObjects (DRCFLAG, false); RatFindHook (a->Connection[0].type, a->Connection[0].ptr1, a->Connection[0].ptr2, a->Connection[0].ptr2, false, DRCFLAG, AndRats); /* now anybody connected to the first point has DRCFLAG set */ /* so move those to this subnet */ CLEAR_FLAG (DRCFLAG, (PinType *) a->Connection[0].ptr2); for (n = m + 1; n < Netl->NetN; n++) { b = &Netl->Net[n]; /* There can be only one connection in net b */ if (TEST_FLAG (DRCFLAG, (PinType *) b->Connection[0].ptr2)) { CLEAR_FLAG (DRCFLAG, (PinType *) b->Connection[0].ptr2); TransferNet (Netl, b, a); /* back up since new subnet is now at old index */ n--; } } /* now add other possible attachment points to the subnet */ /* e.g. line end-points and vias */ /* don't add non-manhattan lines, the auto-router can't route to them */ ALLLINE_LOOP (PCB->Data); { if (TEST_FLAG (DRCFLAG, line)) { conn = GetConnectionMemory (a); conn->X = line->Point1.X; conn->Y = line->Point1.Y; conn->type = LINE_TYPE; conn->ptr1 = layer; conn->ptr2 = line; conn->group = GetLayerGroupNumberByPointer (layer); conn->menu = NULL; /* agnostic view of where it belongs */ conn = GetConnectionMemory (a); conn->X = line->Point2.X; conn->Y = line->Point2.Y; conn->type = LINE_TYPE; conn->ptr1 = layer; conn->ptr2 = line; conn->group = GetLayerGroupNumberByPointer (layer); conn->menu = NULL; } } ENDALL_LOOP; /* add polygons so the auto-router can see them as targets */ ALLPOLYGON_LOOP (PCB->Data); { if (TEST_FLAG (DRCFLAG, polygon)) { conn = GetConnectionMemory (a); /* make point on a vertex */ conn->X = polygon->Clipped->contours->head.point[0]; conn->Y = polygon->Clipped->contours->head.point[1]; conn->type = POLYGON_TYPE; conn->ptr1 = layer; conn->ptr2 = polygon; conn->group = GetLayerGroupNumberByPointer (layer); conn->menu = NULL; /* agnostic view of where it belongs */ } } ENDALL_LOOP; VIA_LOOP (PCB->Data); { if (TEST_FLAG (DRCFLAG, via)) { conn = GetConnectionMemory (a); conn->X = via->X; conn->Y = via->Y; conn->type = VIA_TYPE; conn->ptr1 = via; conn->ptr2 = via; conn->group = bottom_group; } } END_LOOP; if (!NoWarn) Warned |= CheckShorts (a->Connection[0].menu); } ClearFlagOnAllObjects (DRCFLAG, false); return (Warned); } /*! * \brief Draw a rat net (tree) having the shortest lines. * * This also frees the subnet memory as they are consumed. * * \note The \c Netl we are passed is NOT the main netlist - it's the * connectivity for ONE net. * It represents the CURRENT connectivity state for the net, with each * Netl->Net[N] representing one copper-connected subset of the net. * * Everything inside the NetList Netl should be connected together. * * Each Net in \c Netl is a group of Connections which are already * connected together somehow, either by real wires or by rats we've * already drawn. * * Each Connection is a vertex within that blob of connected items. * * This loop finds the closest vertex pairs between each blob and draws * rats that merge the blobs until there's just one big blob. * * Just to clarify, with some examples: * * Each \c Netl is one full net from a netlist, like from gnetlist. * * Each Netl->Net[N] is a subset of that net that's already * physically connected on the pcb. * * So a new design with no traces yet, would have a huge list of Net[N], * each with one pin in it. * * A fully routed design would have one Net[N] with all the pins * (for that net) in it. */ static bool DrawShortestRats (NetListType *Netl, void (*funcp) (register ConnectionType *, register ConnectionType *, register RouteStyleType *)) { RatType *line; register float distance, temp; register ConnectionType *conn1, *conn2, *firstpoint, *secondpoint; PolygonType *polygon; bool changed = false; bool havepoints; Cardinal n, m, j; NetType *next, *subnet, *theSubnet = NULL; /* This is just a sanity check, to make sure we're passed * *something*. */ if (!Netl || Netl->NetN < 1) return false; /* * We keep doing this do/while loop until everything's connected. * I.e. once per rat we add. */ distance = 0.0; havepoints = true; /* so we run the loop at least once */ while (Netl->NetN > 1 && havepoints) { /* This is the top of the "find one rat" logic. */ havepoints = false; firstpoint = secondpoint = NULL; /* Test Net[0] vs Net[N] for N=1..max. Find the shortest distance between any two points in different blobs. */ subnet = &Netl->Net[0]; for (j = 1; j < Netl->NetN; j++) { /* * Scan between Net[0] blob (subnet) and Net[N] blob (next). * Note the shortest distance we find. */ next = &Netl->Net[j]; for (n = subnet->ConnectionN - 1; n != -1; n--) { conn1 = &subnet->Connection[n]; for (m = next->ConnectionN - 1; m != -1; m--) { conn2 = &next->Connection[m]; /* * At this point, conn1 and conn2 are two pins in * different blobs of the same net. See how far * apart they are, and if they're "closer" than what * we already have. */ /* * Prefer to connect Connections over polygons to the * polygons (ie assume the user wants a via to a plane, * not a daisy chain). Further prefer to pick an existing * via in the Net to make that connection. */ if (conn1->type == POLYGON_TYPE && (polygon = (PolygonType *)conn1->ptr2) && !(distance == 0 && firstpoint && firstpoint->type == VIA_TYPE) && IsPointInPolygonIgnoreHoles (conn2->X, conn2->Y, polygon)) { distance = 0; firstpoint = conn2; secondpoint = conn1; theSubnet = next; havepoints = true; } else if (conn2->type == POLYGON_TYPE && (polygon = (PolygonType *)conn2->ptr2) && !(distance == 0 && firstpoint && firstpoint->type == VIA_TYPE) && IsPointInPolygonIgnoreHoles (conn1->X, conn1->Y, polygon)) { distance = 0; firstpoint = conn1; secondpoint = conn2; theSubnet = next; havepoints = true; } else if ((temp = SQUARE (conn1->X - conn2->X) + SQUARE (conn1->Y - conn2->Y)) < distance || !firstpoint) { distance = temp; firstpoint = conn1; secondpoint = conn2; theSubnet = next; havepoints = true; } } } } /* * If HAVEPOINTS is true, we've found a pair of points in two * separate blobs of the net, and need to connect them together. */ if (havepoints) { if (funcp) { (*funcp) (firstpoint, secondpoint, subnet->Style); } else { /* found the shortest distance subnet, draw the rat */ if ((line = CreateNewRat (PCB->Data, firstpoint->X, firstpoint->Y, secondpoint->X, secondpoint->Y, firstpoint->group, secondpoint->group, Settings.RatThickness, NoFlags ())) != NULL) { if (distance == 0) SET_FLAG (VIAFLAG, line); AddObjectToCreateUndoList (RATLINE_TYPE, line, line, line); DrawRat (line); changed = true; } } /* copy theSubnet into the current subnet */ TransferNet (Netl, theSubnet, subnet); } } /* presently nothing to do with the new subnet */ /* so we throw it away and free the space */ FreeNetMemory (&Netl->Net[--(Netl->NetN)]); /* Sadly adding a rat line messes up the sorted arrays in connection finder */ /* hace: perhaps not necessarily now that they aren't stored in normal layers */ if (changed) { FreeConnectionLookupMemory (); InitConnectionLookup (); } return (changed); } /*! * \brief AddAllRats puts the rats nest into the layout from the loaded * netlist. * * If SelectedOnly is true, it will only draw rats to selected pins and * pads. */ bool AddAllRats (bool SelectedOnly, void (*funcp) (register ConnectionType *, register ConnectionType *, register RouteStyleType *)) { NetListType *Nets, *Wantlist; NetType *lonesome; ConnectionType *onepin; bool changed, Warned = false; /* the netlist library has the text form * ProcNetlist fills in the Netlist * structure the way the final routing * is supposed to look */ Wantlist = ProcNetlist (&PCB->NetlistLib); if (!Wantlist) { Message (_("Can't add rat lines because no netlist is loaded.\n")); return (false); } changed = false; /* initialize finding engine */ InitConnectionLookup (); Nets = (NetListType *)calloc (1, sizeof (NetListType)); /* now we build another netlist (Nets) for each * net in Wantlist that shows how it actually looks now, * then fill in any missing connections with rat lines. * * we first assume each connection is separate * (no routing), then gather them into groups * if the net is all routed, the new netlist (Nets) * will have only one net entry. * Note that DrawShortestRats consumes all nets * from Nets, so *Nets is empty after the * DrawShortestRats call */ NET_LOOP (Wantlist); { CONNECTION_LOOP (net); { if (!SelectedOnly || TEST_FLAG (SELECTEDFLAG, (PinType *) connection->ptr2)) { lonesome = GetNetMemory (Nets); onepin = GetConnectionMemory (lonesome); *onepin = *connection; lonesome->Style = net->Style; } } END_LOOP; Warned |= GatherSubnets (Nets, SelectedOnly, true); if (Nets->NetN > 0) changed |= DrawShortestRats (Nets, funcp); } END_LOOP; FreeNetListMemory (Nets); free (Nets); FreeConnectionLookupMemory (); if (funcp) return (true); if (Warned || changed) Draw (); if (Warned) Settings.RatWarn = true; if (changed) { IncrementUndoSerialNumber (); if (PCB->Data->RatN > 0) { Message ("%d rat line%s remaining\n", PCB->Data->RatN, PCB->Data->RatN > 1 ? "s" : ""); } return (true); } if (!SelectedOnly && !Warned) { if (!PCB->Data->RatN && !badnet) Message (_("Congratulations!!\n" "The layout is complete and has no shorted nets.\n")); else Message (_("Nothing more to add, but there are\n" "either rat-lines in the layout, disabled nets\n" "in the net-list, or missing components\n")); } return (false); } /*! * \todo This is copied in large part from AddAllRats above; for * maintainability, AddAllRats probably wants to be tweaked to use this * version of the code so that we don't have duplication. */ NetListListType CollectSubnets (bool SelectedOnly) { NetListListType result = { 0, 0, NULL }; NetListType *Nets, *Wantlist; NetType *lonesome; ConnectionType *onepin; /* the netlist library has the text form * ProcNetlist fills in the Netlist * structure the way the final routing * is supposed to look */ Wantlist = ProcNetlist (&PCB->NetlistLib); if (!Wantlist) { Message (_("Can't add rat lines because no netlist is loaded.\n")); return result; } /* initialize finding engine */ InitConnectionLookup (); /* now we build another netlist (Nets) for each * net in Wantlist that shows how it actually looks now, * then fill in any missing connections with rat lines. * * we first assume each connection is separate * (no routing), then gather them into groups * if the net is all routed, the new netlist (Nets) * will have only one net entry. * Note that DrawShortestRats consumes all nets * from Nets, so *Nets is empty after the * DrawShortestRats call */ NET_LOOP (Wantlist); { Nets = GetNetListMemory (&result); CONNECTION_LOOP (net); { if (!SelectedOnly || TEST_FLAG (SELECTEDFLAG, (PinType *) connection->ptr2)) { lonesome = GetNetMemory (Nets); onepin = GetConnectionMemory (lonesome); *onepin = *connection; lonesome->Style = net->Style; } } END_LOOP; /* Note that AndRats is *FALSE* here! */ GatherSubnets (Nets, SelectedOnly, false); } END_LOOP; FreeConnectionLookupMemory (); return result; } /*! * \brief Check to see if a particular name is the name of an already * existing rats line. */ static int rat_used (char *name) { if (name == NULL) return -1; MENU_LOOP (&PCB->NetlistLib); { if (menu->Name && (strcmp (menu->Name, name) == 0)) return 1; } END_LOOP; return 0; } /*! * \brief This function is moved from the original netlist.c as * part of the gui code separation for the Gtk port. */ RatType * AddNet (void) { static int ratDrawn = 0; char name1[256], *name2; Cardinal group1, group2; char ratname[22]; int found; void *ptr1, *ptr2, *ptr3; LibraryMenuType *menu; LibraryEntryType *entry; if (Crosshair.AttachedLine.Point1.X == Crosshair.AttachedLine.Point2.X && Crosshair.AttachedLine.Point1.Y == Crosshair.AttachedLine.Point2.Y) return (NULL); found = SearchObjectByLocation (PAD_TYPE | PIN_TYPE, &ptr1, &ptr2, &ptr3, Crosshair.AttachedLine.Point1.X, Crosshair.AttachedLine.Point1.Y, 5); if (found == NO_TYPE) { Message (_("No pad/pin under rat line\n")); return (NULL); } if (NAMEONPCB_NAME ((ElementType *) ptr1) == NULL || *NAMEONPCB_NAME ((ElementType *) ptr1) == 0) { Message (_("You must name the starting element first\n")); return (NULL); } /* will work for pins to since the FLAG is common */ group1 = GetLayerGroupNumberBySide ( TEST_FLAG (ONSOLDERFLAG, (PadType *) ptr2) ? BOTTOM_SIDE : TOP_SIDE); strcpy (name1, ConnectionName (found, ptr1, ptr2)); found = SearchObjectByLocation (PAD_TYPE | PIN_TYPE, &ptr1, &ptr2, &ptr3, Crosshair.AttachedLine.Point2.X, Crosshair.AttachedLine.Point2.Y, 5); if (found == NO_TYPE) { Message (_("No pad/pin under rat line\n")); return (NULL); } if (NAMEONPCB_NAME ((ElementType *) ptr1) == NULL || *NAMEONPCB_NAME ((ElementType *) ptr1) == 0) { Message (_("You must name the ending element first\n")); return (NULL); } group2 = GetLayerGroupNumberBySide ( TEST_FLAG (ONSOLDERFLAG, (PadType *) ptr2) ? BOTTOM_SIDE : TOP_SIDE); name2 = ConnectionName (found, ptr1, ptr2); menu = netnode_to_netname (name1); if (menu) { if (netnode_to_netname (name2)) { Message (_ ("Both connections already in netlist - cannot merge nets\n")); return (NULL); } entry = GetLibraryEntryMemory (menu); entry->ListEntry = strdup (name2); netnode_to_netname (name2); goto ratIt; } /* ok, the first name did not belong to a net */ menu = netnode_to_netname (name2); if (menu) { entry = GetLibraryEntryMemory (menu); entry->ListEntry = strdup (name1); netnode_to_netname (name1); goto ratIt; } /* * neither belong to a net, so create a new one. * * before creating a new rats here, we need to search * for a unique name. */ sprintf (ratname, " ratDrawn%i", ++ratDrawn); while (rat_used (ratname)) { sprintf (ratname, " ratDrawn%i", ++ratDrawn); } menu = GetLibraryMenuMemory (&PCB->NetlistLib); menu->Name = strdup (ratname); entry = GetLibraryEntryMemory (menu); entry->ListEntry = strdup (name1); entry = GetLibraryEntryMemory (menu); entry->ListEntry = strdup (name2); menu->flag = 1; ratIt: NetlistChanged (0); return (CreateNewRat (PCB->Data, Crosshair.AttachedLine.Point1.X, Crosshair.AttachedLine.Point1.Y, Crosshair.AttachedLine.Point2.X, Crosshair.AttachedLine.Point2.Y, group1, group2, Settings.RatThickness, NoFlags ())); } /*! * \brief This function is moved from the original netlist.c as * part of the gui code separation for the Gtk port. */ char * ConnectionName (int type, void *ptr1, void *ptr2) { static char name[256]; char *num; switch (type) { case PIN_TYPE: num = ((PinType *) ptr2)->Number; break; case PAD_TYPE: num = ((PadType *) ptr2)->Number; break; default: return (NULL); } strcpy (name, UNKNOWN (NAMEONPCB_NAME ((ElementType *) ptr1))); strcat (name, "-"); strcat (name, UNKNOWN (num)); return (name); } pcb-4.3.0/src/mtspace.c0000664000175000017500000004245613773431044011615 00000000000000/*! * \file src/mtspace.c * * \brief Implementation for "empty space" routines (needed for * via-space tracking in the auto-router. * * mtspace data structures are built on r-trees. * * This file, mtspace.c, was written and is * * Copyright (c) 2001 C. Scott Ananian. * * Copyright (c) 2006 harry eaton. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * Copyright (C) 1998,1999,2000,2001 harry eaton * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA * * haceaton@aplcomm.jhuapl.edu */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "global.h" #include #include #include "box.h" #include "heap.h" #include "rtree.h" #include "mtspace.h" #include "vector.h" #ifdef HAVE_LIBDMALLOC #include #endif /* --------------------------------------------------------------------------- * some local types */ typedef struct mtspacebox { const BoxType box; Coord keepaway; /*!< the smallest keepaway around this box */ } mtspacebox_t; /*! * \brief This is an mtspace_t. * * \c rtrees keeping track of regions expanded by their required * clearance. * One for fixed, even, and odd. */ struct mtspace { rtree_t *ftree, *etree, *otree; }; typedef union { vector_t * v; heap_t * h; } heap_or_vector; /*! * \brief This is a vetting_t. */ struct vetting { heap_or_vector untested; heap_or_vector no_fix; heap_or_vector no_hi; heap_or_vector hi_candidate; Coord radius; Coord keepaway; CheapPointType desired; }; #define SPECIAL 823157 mtspacebox_t * mtspace_create_box (const BoxType * box, Coord keepaway) { mtspacebox_t *mtsb; assert (box_is_good (box)); mtsb = (mtspacebox_t *)malloc (sizeof (*mtsb)); /* the box was sent to us pre-bloated by the keepaway amount */ *((BoxType *) & mtsb->box) = *box; mtsb->keepaway = keepaway; assert (box_is_good (&mtsb->box)); return mtsb; } /*! * \brief Create an "empty space" representation with a shrunken * boundary. */ mtspace_t * mtspace_create (void) { mtspace_t *mtspace; /* create mtspace data structure */ mtspace = (mtspace_t *)malloc (sizeof (*mtspace)); mtspace->ftree = r_create_tree (NULL, 0, 0); mtspace->etree = r_create_tree (NULL, 0, 0); mtspace->otree = r_create_tree (NULL, 0, 0); /* done! */ return mtspace; } /*! * \brief Destroy an "empty space" representation. */ void mtspace_destroy (mtspace_t ** mtspacep) { assert (mtspacep); r_destroy_tree (&(*mtspacep)->ftree); r_destroy_tree (&(*mtspacep)->etree); r_destroy_tree (&(*mtspacep)->otree); free (*mtspacep); *mtspacep = NULL; } struct mts_info { Coord keepaway; BoxType box; rtree_t *tree; jmp_buf env; }; static int mts_remove_one (const BoxType * b, void *cl) { struct mts_info *info = (struct mts_info *) cl; mtspacebox_t *box = (mtspacebox_t *) b; /* there can be duplicate boxes, we just remove one */ /* the info box is pre-bloated, so just check equality */ if (b->X1 == info->box.X1 && b->X2 == info->box.X2 && b->Y1 == info->box.Y1 && b->Y2 == info->box.Y2 && box->keepaway == info->keepaway) { r_delete_entry (info->tree, b); longjmp (info->env, 1); } return 0; } rtree_t * which_tree (mtspace_t * mtspace, mtspace_type_t which) { switch (which) { case FIXED: return mtspace->ftree; case EVEN: return mtspace->etree; default: return mtspace->otree; } } /*! * \brief Add a space-filler to the empty space representation. * * The given box should *not* be bloated; it should be "true". * The feature will fill *at least* a radius of keepaway around it; */ void mtspace_add (mtspace_t * mtspace, const BoxType * box, mtspace_type_t which, Coord keepaway) { mtspacebox_t *filler = mtspace_create_box (box, keepaway); r_insert_entry (which_tree (mtspace, which), (const BoxType *) filler, 1); } /*! * \brief Remove a space-filler from the empty space representation. * * The given box should *not* be bloated; it should be "true". * The feature will fill *at least* a radius of keepaway around it; */ void mtspace_remove (mtspace_t * mtspace, const BoxType * box, mtspace_type_t which, Coord keepaway) { struct mts_info cl; BoxType small_search; cl.keepaway = keepaway; cl.box = *box; cl.tree = which_tree (mtspace, which); small_search = box_center(box); if (setjmp (cl.env) == 0) { r_search (cl.tree, &small_search, NULL, mts_remove_one, &cl); assert (0); /* didn't find it?? */ } } struct query_closure { BoxType *cbox; heap_or_vector checking; heap_or_vector touching; CheapPointType *desired; Coord radius, keepaway; jmp_buf env; bool touch_is_vec; }; static inline void heap_append (heap_t *heap, CheapPointType *desired, BoxType *newone) { CheapPointType p = *desired; assert (desired); closest_point_in_box (&p, newone); heap_insert (heap, ABS(p.X - desired->X) + (p.Y - desired->Y), newone); } static inline void append (struct query_closure * qc, BoxType *newone) { if (qc->desired) heap_append (qc->checking.h, qc->desired, newone); else vector_append (qc->checking.v, newone); } /*! * \brief We found some space filler that may intersect this query. * * First check if it does intersect, then break it into overlaping * regions that don't intersect this box. */ static int query_one (const BoxType * box, void *cl) { struct query_closure *qc = (struct query_closure *) cl; mtspacebox_t *mtsb = (mtspacebox_t *) box; Coord shrink; assert (box_intersect (qc->cbox, &mtsb->box)); /* we need to satisfy the larger of the two keepaways */ if (qc->keepaway > mtsb->keepaway) shrink = mtsb->keepaway; else shrink = qc->keepaway; /* if we shrink qc->box by this amount and it doesn't intersect * then we didn't actually touch this box */ if (qc->cbox->X1 + shrink >= mtsb->box.X2 || qc->cbox->X2 - shrink <= mtsb->box.X1 || qc->cbox->Y1 + shrink >= mtsb->box.Y2 || qc->cbox->Y2 - shrink <= mtsb->box.Y1) return 0; /* ok, we do touch this box, now create up to 4 boxes that don't */ if (mtsb->box.Y1 > qc->cbox->Y1 + shrink) /* top region exists */ { Coord Y1 = qc->cbox->Y1; Coord Y2 = mtsb->box.Y1 + shrink; if (Y2 - Y1 >= 2 * (qc->radius + qc->keepaway)) { BoxType *newone = (BoxType *) malloc (sizeof (BoxType)); newone->X1 = qc->cbox->X1; newone->X2 = qc->cbox->X2; newone->Y1 = Y1; newone->Y2 = Y2; assert (newone->Y2 < qc->cbox->Y2); append(qc, newone); } } if (mtsb->box.Y2 < qc->cbox->Y2 - shrink) /* bottom region exists */ { Coord Y1 = mtsb->box.Y2 - shrink; Coord Y2 = qc->cbox->Y2; if (Y2 - Y1 >= 2 * (qc->radius + qc->keepaway)) { BoxType *newone = (BoxType *) malloc (sizeof (BoxType)); newone->X1 = qc->cbox->X1; newone->X2 = qc->cbox->X2; newone->Y2 = qc->cbox->Y2; newone->Y1 = Y1; assert (newone->Y1 > qc->cbox->Y1); append (qc, newone); } } if (mtsb->box.X1 > qc->cbox->X1 + shrink) /* left region exists */ { Coord X1 = qc->cbox->X1; Coord X2 = mtsb->box.X1 + shrink; if (X2 - X1 >= 2 * (qc->radius + qc->keepaway)) { BoxType *newone; newone = (BoxType *) malloc (sizeof (BoxType)); newone->Y1 = qc->cbox->Y1; newone->Y2 = qc->cbox->Y2; newone->X1 = qc->cbox->X1; newone->X2 = X2; assert (newone->X2 < qc->cbox->X2); append (qc, newone); } } if (mtsb->box.X2 < qc->cbox->X2 - shrink) /* right region exists */ { Coord X1 = mtsb->box.X2 - shrink; Coord X2 = qc->cbox->X2; if (X2 - X1 >= 2 * (qc->radius + qc->keepaway)) { BoxType *newone = (BoxType *) malloc (sizeof (BoxType)); newone->Y1 = qc->cbox->Y1; newone->Y2 = qc->cbox->Y2; newone->X2 = qc->cbox->X2; newone->X1 = X1; assert (newone->X1 > qc->cbox->X1); append (qc, newone); } } if (qc->touching.v) { if (qc->touch_is_vec || !qc->desired) vector_append (qc->touching.v, qc->cbox); else heap_append (qc->touching.h, qc->desired, qc->cbox); } else free (qc->cbox); /* done with this one */ longjmp (qc->env, 1); return 1; /* never reached */ } /*! * \brief qloop takes a vector (or heap) of regions to check (checking) * if they don't intersect anything. * * If a region does intersect something, it is broken into pieces that * don't intersect that thing (if possible) which are put back into the * vector/heap of regions to check. * * \return qloop returns false when it finds the first empty region. * It returns true if it has exhausted the region vector/heap and never * found an empty area. */ static void qloop (struct query_closure *qc, rtree_t * tree, heap_or_vector res, bool is_vec) { BoxType *cbox; #ifndef NDEBUG int n; #endif while (!(qc->desired ? heap_is_empty (qc->checking.h) : vector_is_empty (qc->checking.v))) { cbox = qc->desired ? (BoxType *)heap_remove_smallest (qc->checking.h) : (BoxType *)vector_remove_last (qc->checking.v); if (setjmp (qc->env) == 0) { assert (box_is_good (cbox)); qc->cbox = cbox; #ifndef NDEBUG n = #endif r_search (tree, cbox, NULL, query_one, qc); assert (n == 0); /* nothing intersected with this tree, put it in the result vector */ if (is_vec) vector_append (res.v, cbox); else { if (qc->desired) heap_append (res.h, qc->desired, cbox); else vector_append (res.v, cbox); } return; /* found one - perhaps one answer is good enough */ } } } /*! * \brief Free the memory used by the vetting structure. */ void mtsFreeWork (vetting_t ** w) { vetting_t *work = (*w); if (work->desired.X != -SPECIAL || work->desired.Y != -SPECIAL) { heap_free (work->untested.h, free); heap_destroy (&work->untested.h); heap_free (work->no_fix.h, free); heap_destroy (&work->no_fix.h); heap_free (work->no_hi.h, free); heap_destroy (&work->no_hi.h); heap_free (work->hi_candidate.h, free); heap_destroy (&work->hi_candidate.h); } else { while (!vector_is_empty (work->untested.v)) free (vector_remove_last (work->untested.v)); vector_destroy (&work->untested.v); while (!vector_is_empty (work->no_fix.v)) free (vector_remove_last (work->no_fix.v)); vector_destroy (&work->no_fix.v); while (!vector_is_empty (work->no_hi.v)) free (vector_remove_last (work->no_hi.v)); vector_destroy (&work->no_hi.v); while (!vector_is_empty (work->hi_candidate.v)) free (vector_remove_last (work->hi_candidate.v)); vector_destroy (&work->hi_candidate.v); } free (work); (*w) = NULL; } /*! * \brief . * * It tries first to find Completely empty regions (which are * appended to the free_space_vec vector). * If that fails, it looks for regions filled only by objects generated * by the previous pass (which are appended to the lo_conflict_space_vec * vector). * Then it looks for regions that are filled by objects generated during * *this* pass (which are appended to the hi_conflict_space_vec vector). * The current pass identity is given by 'is_odd'. * As soon as one completely free region is found, it returns with that * answer. * It saves partially searched regions in vectors "untested", "no_fix", * "no_hi", and "hi_candidate" which can be passed to future calls of * this function to search harder for such regions if the computation * becomes necessary. * * \return returns some empty spaces in 'region' (or former narrowed regions) * that may hold a feature with the specified radius and keepaway */ vetting_t * mtspace_query_rect (mtspace_t * mtspace, const BoxType * region, Coord radius, Coord keepaway, vetting_t * work, vector_t * free_space_vec, vector_t * lo_conflict_space_vec, vector_t * hi_conflict_space_vec, bool is_odd, bool with_conflicts, CheapPointType *desired) { struct query_closure qc; /* pre-assertions */ assert (free_space_vec); assert (lo_conflict_space_vec); assert (hi_conflict_space_vec); /* search out to anything that might matter */ if (region) { BoxType *cbox; assert (work == NULL); assert (box_is_good (region)); assert(vector_is_empty (free_space_vec)); assert(vector_is_empty (lo_conflict_space_vec)); assert(vector_is_empty (hi_conflict_space_vec)); work = (vetting_t *) malloc (sizeof (vetting_t)); work->keepaway = keepaway; work->radius = radius; cbox = (BoxType *) malloc (sizeof (BoxType)); *cbox = bloat_box (region, keepaway + radius); if (desired) { work->untested.h = heap_create (); work->no_fix.h = heap_create (); work->hi_candidate.h = heap_create (); work->no_hi.h =heap_create (); assert (work->untested.h && work->no_fix.h && work->no_hi.h && work->hi_candidate.h); heap_insert (work->untested.h, 0, cbox); work->desired = *desired; } else { work->untested.v = vector_create (); work->no_fix.v = vector_create (); work->hi_candidate.v = vector_create (); work->no_hi.v = vector_create (); assert (work->untested.v && work->no_fix.v && work->no_hi.v && work->hi_candidate.v); vector_append (work->untested.v, cbox); work->desired.X = work->desired.Y = -SPECIAL; } return work; } qc.keepaway = work->keepaway; qc.radius = work->radius; if (work->desired.X == -SPECIAL && work->desired.Y == -SPECIAL) qc.desired = NULL; else qc.desired = &work->desired; /* do the query */ do { heap_or_vector temporary = {free_space_vec}; /* search the fixed object tree discarding any intersections * and placing empty regions in the no_fix vector. */ qc.checking = work->untested; qc.touching.v = NULL; qloop (&qc, mtspace->ftree, work->no_fix, false); /* search the hi-conflict tree placing intersectors in the * hi_candidate vector (if conflicts are allowed) and * placing empty regions in the no_hi vector. */ qc.checking.v = work->no_fix.v; qc.touching.v = with_conflicts ? work->hi_candidate.v : NULL; qc.touch_is_vec = false; qloop (&qc, is_odd ? mtspace->otree : mtspace->etree, work->no_hi, false); /* search the lo-conflict tree placing intersectors in the * lo-conflict answer vector (if conflicts allowed) and * placing emptry regions in the free-space answer vector. */ qc.checking = work->no_hi; /* XXX lo_conflict_space_vec will be treated like a heap! */ qc.touching.v = (with_conflicts ? lo_conflict_space_vec : NULL); qc.touch_is_vec = true; qloop (&qc, is_odd ? mtspace->etree : mtspace->otree, temporary, true); /* qloop (&qc, is_odd ? mtspace->etree : mtspace->otree, (heap_or_vector)free_space_vec, true); */ if (!vector_is_empty (free_space_vec)) { if (qc.desired) { if (heap_is_empty (work->untested.h)) break; } else { if (vector_is_empty (work->untested.v)) break; } return work; } /* finally check the hi-conflict intersectors against the * lo-conflict tree discarding intersectors (two types of conflict is real bad) * and placing empty regions in the hi-conflict answer vector. */ if (with_conflicts) { heap_or_vector temporary = {hi_conflict_space_vec}; qc.checking = work->hi_candidate; qc.touching.v = NULL; qloop (&qc, is_odd ? mtspace->etree : mtspace->otree, temporary, true); /* qloop (&qc, is_odd ? mtspace->etree : mtspace->otree, */ /* (heap_or_vector)hi_conflict_space_vec, true); */ } } while (!(qc.desired ? heap_is_empty(work->untested.h) : vector_is_empty (work->untested.v))); if (qc.desired) { if (heap_is_empty (work->no_fix.h) && heap_is_empty (work->no_hi.h) && heap_is_empty (work->hi_candidate.h)) { mtsFreeWork (&work); return NULL; } } else { if (vector_is_empty (work->no_fix.v) && vector_is_empty (work->no_hi.v) && vector_is_empty (work->hi_candidate.v)) { mtsFreeWork (&work); return NULL; } } return work; } int mtsBoxCount (vetting_t * w) { #if 0 int ans; ans = 3 * vector_size (w->untested); ans += 2 * vector_size (w->no_fix); ans += vector_size (w->no_hi); ans += vector_size (w->hi_candidate); return ans; #endif return 100; } pcb-4.3.0/src/getline.c0000775000175000017500000000661313773431044011606 00000000000000/* getline.c -- Replacement for GNU C library function getline Copyright (C) 1993 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ /* Written by Jan Brittenson, bson@gnu.ai.mit.edu. */ #ifdef HAVE_CONFIG_H #include #endif #if ! HAVE_GETLINE #include #include #include #include #if STDC_HEADERS #include #else char *malloc (), *realloc (); #endif /* Always add at least this many bytes when extending the buffer. */ #define MIN_CHUNK 64 /* Read up to (and including) a TERMINATOR from STREAM into *LINEPTR + OFFSET (and null-terminate it). *LINEPTR is a pointer returned from malloc (or NULL), pointing to *N characters of space. It is realloc'd as necessary. Return the number of characters read (not including the null terminator), or -1 on error or EOF. On a -1 return, the caller should check feof(), if not then errno has been set to indicate the error. */ int getstr (lineptr, n, stream, terminator, offset) char **lineptr; size_t *n; FILE *stream; char terminator; int offset; { int nchars_avail; /* Allocated but unused chars in *LINEPTR. */ char *read_pos; /* Where we're reading into *LINEPTR. */ int ret; if (!lineptr || !n || !stream) { errno = EINVAL; return -1; } if (!*lineptr) { *n = MIN_CHUNK; *lineptr = malloc (*n); if (!*lineptr) { errno = ENOMEM; return -1; } } nchars_avail = *n - offset; read_pos = *lineptr + offset; for (;;) { int save_errno; register int c = getc (stream); save_errno = errno; /* We always want at least one char left in the buffer, since we always (unless we get an error while reading the first char) NUL-terminate the line buffer. */ assert((*lineptr + *n) == (read_pos + nchars_avail)); if (nchars_avail < 2) { if (*n > MIN_CHUNK) *n *= 2; else *n += MIN_CHUNK; nchars_avail = *n + *lineptr - read_pos; *lineptr = realloc (*lineptr, *n); if (!*lineptr) { errno = ENOMEM; return -1; } read_pos = *n - nchars_avail + *lineptr; assert((*lineptr + *n) == (read_pos + nchars_avail)); } if (ferror (stream)) { /* Might like to return partial line, but there is no place for us to store errno. And we don't want to just lose errno. */ errno = save_errno; return -1; } if (c == EOF) { /* Return partial line, if any. */ if (read_pos == *lineptr) return -1; else break; } *read_pos++ = c; nchars_avail--; if (c == terminator) /* Return the line. */ break; } /* Done - NUL terminate and return the number of chars read. */ *read_pos = '\0'; ret = read_pos - (*lineptr + offset); return ret; } int getline (lineptr, n, stream) char **lineptr; size_t *n; FILE *stream; { return getstr (lineptr, n, stream, '\n', 0); } #endif /* !HAVE_GETLINE */ pcb-4.3.0/src/lrealpath.c0000664000175000017500000001162713773431044012131 00000000000000/*! * \file src/lrealpath.c * * \brief Libiberty realpath. * * Like realpath, but more consistent behavior. * * Based on gdb_realpath from GDB. * * Copyright 2003 Free Software Foundation, Inc. * * This file is part of the libiberty library. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* @deftypefn Replacement {const char*} lrealpath (const char *@var{name}) Given a pointer to a string containing a pathname, returns a canonical version of the filename. Symlinks will be resolved, and ``.'' and ``..'' components will be simplified. The returned value will be allocated using @code{malloc}, or @code{NULL} will be returned on a memory allocation error. @end deftypefn */ #include "config.h" #include "lrealpath.h" #ifdef HAVE_LIMITS_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_STRING_H #include #endif /* On GNU libc systems the declaration is only visible with _GNU_SOURCE. */ #if defined(HAVE_CANONICALIZE_FILE_NAME) \ && defined(NEED_DECLARATION_CANONICALIZE_FILE_NAME) extern char *canonicalize_file_name (const char *); #endif #if defined(HAVE_REALPATH) # if defined (PATH_MAX) # define REALPATH_LIMIT PATH_MAX # else # if defined (MAXPATHLEN) # define REALPATH_LIMIT MAXPATHLEN # endif # endif #else /* cygwin has realpath, so it won't get here. */ # if defined (_WIN32) # define WIN32_LEAN_AND_MEAN # include /* for GetFullPathName */ # endif #endif /*! * \brief A well-defined realpath () that is always compiled in. */ char * lrealpath (const char *filename) { /* Method 1: The system has a compile time upper bound on a filename path. Use that and realpath() to canonicalize the name. This is the most common case. Note that, if there isn't a compile time upper bound, you want to avoid realpath() at all costs. */ #if defined(REALPATH_LIMIT) { char buf[REALPATH_LIMIT]; const char *rp = realpath (filename, buf); if (rp == NULL) rp = filename; return strdup (rp); } /* REALPATH_LIMIT */ /* Method 2: The host system (i.e., GNU) has the function canonicalize_file_name() which malloc's a chunk of memory and returns that, use that. */ #elif defined(HAVE_CANONICALIZE_FILE_NAME) { char *rp = canonicalize_file_name (filename); if (rp == NULL) return strdup (filename); else return rp; } /* HAVE_CANONICALIZE_FILE_NAME */ /* Method 3: Now we're getting desperate! The system doesn't have a compile time buffer size and no alternative function. Query the OS, using pathconf(), for the buffer limit. Care is needed though, some systems do not limit PATH_MAX (return -1 for pathconf()) making it impossible to pass a correctly sized buffer to realpath() (it could always overflow). On those systems, we skip this. */ #elif defined (HAVE_REALPATH) && defined (HAVE_UNISTD_H) { /* Find out the max path size. */ long path_max = pathconf ("/", _PC_PATH_MAX); if (path_max > 0) { /* PATH_MAX is bounded. */ char *buf, *rp, *ret; buf = (char *) malloc (path_max); if (buf == NULL) return NULL; rp = realpath (filename, buf); ret = strdup (rp ? rp : filename); free (buf); return ret; } } /* HAVE_REALPATH && HAVE_UNISTD_H */ /* The MS Windows method. If we don't have realpath, we assume we don't have symlinks and just canonicalize to a Windows absolute path. GetFullPath converts ../ and ./ in relative paths to absolute paths, filling in current drive if one is not given or using the current directory of a specified drive (eg, "E:foo"). It also converts all forward slashes to back slashes. */ #elif defined (_WIN32) { char buf[MAX_PATH]; char* basename; DWORD len = GetFullPathName (filename, MAX_PATH, buf, &basename); if (len == 0 || len > MAX_PATH - 1) return strdup (filename); else { /* The file system is case-preserving but case-insensitive, Canonicalize to lowercase, using the codepage associated with the process locale. */ CharLowerBuff (buf, len); return strdup (buf); } } #else /* This system is a lost cause, just duplicate the filename. */ return strdup (filename); #endif } pcb-4.3.0/src/box.h0000664000175000017500000001420113773431044010741 00000000000000/*! * \file src/box.h * * \brief Random box-related utilities. * * \author This file, box.h, was written and is * Copyright (c) 2001 C. Scott Ananian. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * Copyright (C) 1998,1999,2000,2001 harry eaton * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA * haceaton@aplcomm.jhuapl.edu * */ #ifndef PCB_BOX_H #define PCB_BOX_H #include #include "global.h" #include "misc.h" typedef enum { NORTH = 0, EAST = 1, SOUTH = 2, WEST = 3, NE = 4, SE = 5, SW = 6, NW = 7, ALL = 8 } direction_t; /*! * \brief Rotates box 90-degrees cw. * * That's a strange rotation! */ #define ROTATEBOX_CW(box) { Coord t;\ t = (box).X1; (box).X1 = -(box).Y2; (box).Y2 = (box).X2;\ (box).X2 = -(box).Y1; (box).Y1 = t;\ } #define ROTATEBOX_TO_NORTH(box, dir) do { Coord t;\ switch(dir) {\ case EAST: \ t = (box).X1; (box).X1 = (box).Y1; (box).Y1 = -(box).X2;\ (box).X2 = (box).Y2; (box).Y2 = -t; break;\ case SOUTH: \ t = (box).X1; (box).X1 = -(box).X2; (box).X2 = -t;\ t = (box).Y1; (box).Y1 = -(box).Y2; (box).Y2 = -t; break;\ case WEST: \ t = (box).X1; (box).X1 = -(box).Y2; (box).Y2 = (box).X2;\ (box).X2 = -(box).Y1; (box).Y1 = t; break;\ case NORTH: break;\ default: assert(0);\ }\ } while (0) #define ROTATEBOX_FROM_NORTH(box, dir) do { Coord t;\ switch(dir) {\ case WEST: \ t = (box).X1; (box).X1 = (box).Y1; (box).Y1 = -(box).X2;\ (box).X2 = (box).Y2; (box).Y2 = -t; break;\ case SOUTH: \ t = (box).X1; (box).X1 = -(box).X2; (box).X2 = -t;\ t = (box).Y1; (box).Y1 = -(box).Y2; (box).Y2 = -t; break;\ case EAST: \ t = (box).X1; (box).X1 = -(box).Y2; (box).Y2 = (box).X2;\ (box).X2 = -(box).Y1; (box).Y1 = t; break;\ case NORTH: break;\ default: assert(0);\ }\ } while (0) /* to avoid overflow, we calculate centers this way */ #define CENTER_X(b) ((b).X1 + ((b).X2 - (b).X1)/2) #define CENTER_Y(b) ((b).Y1 + ((b).Y2 - (b).Y1)/2) /* some useful box utilities. */ typedef struct cheap_point { Coord X, Y; } CheapPointType; /* note that boxes are closed on top and left and open on bottom and right. */ /* this means that top-left corner is in box, *but bottom-right corner is * not*. */ static inline bool point_in_box (const BoxType * box, Coord X, Coord Y) { return (X >= box->X1) && (Y >= box->Y1) && (X < box->X2) && (Y < box->Y2); } static inline bool point_in_closed_box (const BoxType * box, Coord X, Coord Y) { return (X >= box->X1) && (Y >= box->Y1) && (X <= box->X2) && (Y <= box->Y2); } static inline bool box_is_good (const BoxType * b) { return (b->X1 < b->X2) && (b->Y1 < b->Y2); } static inline bool box_intersect (const BoxType * a, const BoxType * b) { return (a->X1 < b->X2) && (b->X1 < a->X2) && (a->Y1 < b->Y2) && (b->Y1 < a->Y2); } static inline CheapPointType closest_point_in_box (const CheapPointType * from, const BoxType * box) { CheapPointType r; assert (box->X1 < box->X2 && box->Y1 < box->Y2); r.X = (from->X < box->X1) ? box->X1 : (from->X > box->X2 - 1) ? box->X2 - 1 : from->X; r.Y = (from->Y < box->Y1) ? box->Y1 : (from->Y > box->Y2 - 1) ? box->Y2 - 1 : from->Y; assert (point_in_box (box, r.X, r.Y)); return r; } static inline bool box_in_box (const BoxType * outer, const BoxType * inner) { return (outer->X1 <= inner->X1) && (inner->X2 <= outer->X2) && (outer->Y1 <= inner->Y1) && (inner->Y2 <= outer->Y2); } static inline BoxType clip_box (const BoxType * box, const BoxType * clipbox) { BoxType r; assert (box_intersect (box, clipbox)); r.X1 = MAX (box->X1, clipbox->X1); r.X2 = MIN (box->X2, clipbox->X2); r.Y1 = MAX (box->Y1, clipbox->Y1); r.Y2 = MIN (box->Y2, clipbox->Y2); assert (box_in_box (clipbox, &r)); return r; } static inline BoxType shrink_box (const BoxType * box, Coord amount) { BoxType r = *box; r.X1 += amount; r.Y1 += amount; r.X2 -= amount; r.Y2 -= amount; return r; } static inline BoxType bloat_box (const BoxType * box, Coord amount) { return shrink_box (box, -amount); } /*! * \brief Construct a minimum box that touches the input box at the * center. */ static inline BoxType box_center (const BoxType * box) { BoxType r; r.X1 = box->X1 + (box->X2 - box->X1)/2; r.X2 = r.X1 + 1; r.Y1 = box->Y1 + (box->Y2 - box->Y1)/2; r.Y2 = r.Y1 + 1; return r; } /*! * \brief Construct a minimum box that touches the input box at the * corner. */ static inline BoxType box_corner (const BoxType * box) { BoxType r; r.X1 = box->X1; r.X2 = r.X1 + 1; r.Y1 = box->Y1; r.Y2 = r.Y1 + 1; return r; } /*! * \brief Construct a box that holds a single point. */ static inline BoxType point_box (Coord X, Coord Y) { BoxType r; r.X1 = X; r.X2 = X + 1; r.Y1 = Y; r.Y2 = Y + 1; return r; } /*! * \brief Close a bounding box by pushing its upper right corner. */ static inline void close_box (BoxType * r) { r->X2++; r->Y2++; } /*! * \brief Return the square of the minimum distance from a point to some * point inside a box. * * The box is half-closed!\n * That is, the top-left corner is considered in the box, but the * bottom-right corner is not. */ static inline double dist2_to_box (const CheapPointType * p, const BoxType * b) { CheapPointType r = closest_point_in_box (p, b); return Distance (r.X, r.Y, p->X, p->Y); } #endif /* __BOX_H_INCLUDED__ */ pcb-4.3.0/src/flags.h0000664000175000017500000000603113773431044011247 00000000000000/*! * \file src/flags.h * * \brief Some commonly used macros not related to a special C-file. * * The file is included by global.h after const.h * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * Thomas.Nau@rz.uni-ulm.de */ #ifndef PCB_FLAGS_H #define PCB_FLAGS_H #include #include "globalconst.h" /*! * \brief Nobody should know about the internals of this except the * macros below that access it. * * This structure must be simple-assignable for now. */ typedef struct { unsigned long f; /* generic flags */ unsigned char t[(MAX_LAYER + 1) / 2]; /* thermals */ } FlagType; int pcb_flag_eq (FlagType *f1, FlagType *f2); /* --------------------------------------------------------------------------- * some routines for flag setting, clearing, changing and testing */ #define SET_FLAG(F,P) ((P)->Flags.f |= (F)) #define CLEAR_FLAG(F,P) ((P)->Flags.f &= (~(F))) #define TEST_FLAG(F,P) ((P)->Flags.f & (F) ? 1 : 0) #define TOGGLE_FLAG(F,P) ((P)->Flags.f ^= (F)) #define ASSIGN_FLAG(F,V,P) ((P)->Flags.f = ((P)->Flags.f & (~(F))) | ((V) ? (F) : 0)) #define TEST_FLAGS(F,P) (((P)->Flags.f & (F)) == (F) ? 1 : 0) #define FLAGS_EQUAL(F1,F2) pcb_flag_eq(&(F1), &(F2)) #define THERMFLAG(L) (0xf << (4 *((L) % 2))) #define TEST_THERM(L,P) ((P)->Flags.t[(L)/2] & THERMFLAG(L) ? 1 : 0) #define GET_THERM(L,P) (((P)->Flags.t[(L)/2] >> (4 * ((L) % 2))) & 0xf) #define CLEAR_THERM(L,P) (P)->Flags.t[(L)/2] &= ~THERMFLAG(L) #define ASSIGN_THERM(L,V,P) (P)->Flags.t[(L)/2] = ((P)->Flags.t[(L)/2] & ~THERMFLAG(L)) | ((V) << (4 * ((L) % 2))) //defined in misc.c extern int mem_any_set (unsigned char *, int); #define TEST_ANY_THERMS(P) mem_any_set((P)->Flags.t, sizeof((P)->Flags.t)) /* For passing modified flags to other functions. */ FlagType MakeFlags (unsigned int); FlagType OldFlags (unsigned int); FlagType AddFlags (FlagType, unsigned int); FlagType MaskFlags (FlagType, unsigned int); #define NoFlags() MakeFlags(0) bool ClearFlagOnLinesAndPolygons (int flag, bool undoable); bool ClearFlagOnPinsViasAndPads (int flag, bool undoable); bool ClearFlagOnAllObjects (int flag, bool undoable); #endif // ifndef PCB_FLAGS_H pcb-4.3.0/src/parse_y.c0000664000175000017500000036021313773432505011620 00000000000000/* A Bison parser, made by GNU Bison 3.5.1. */ /* Bison implementation for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Undocumented macros, especially those whose name start with YY_, are private implementation details. Do not rely on them. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "3.5.1" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 0 /* Push parsers. */ #define YYPUSH 0 /* Pull parsers. */ #define YYPULL 1 /* First part of user prologue. */ #line 10 "parse_y.y" /* * COPYRIGHT * * PCB, interactive printed circuit board design * Copyright (C) 1994,1995,1996 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * Thomas.Nau@rz.uni-ulm.de * */ /* grammar to parse ASCII input of PCB description */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "global.h" #include "create.h" #include "data.h" #include "error.h" #include "file.h" #include "flags.h" #include "layerflags.h" #include "mymem.h" #include "misc.h" #include "parse_l.h" #include "polygon.h" #include "remove.h" #include "rtree.h" #include "strflags.h" #include "thermal.h" #include "move.h" #ifdef HAVE_LIBDMALLOC # include /* see http://dmalloc.com */ #endif static LayerType *Layer; static PolygonType *Polygon; static SymbolType *Symbol; static int pin_num; static LibraryMenuType *Menu; static bool LayerFlag[MAX_ALL_LAYER]; enum FileType {NOFILE=0, PCBFILE, DATAFILE, FONTFILE} file_type; extern char *yytext; /* defined by LEX */ extern PCBType *yyPCB; extern DataType *yyData; extern ElementType *yyElement; extern FontType *yyFont; extern int yylineno; /* linenumber */ extern char *yyfilename; /* in this file */ static AttributeListType *attr_list; int yyerror(const char *s); int yylex(); static int check_file_version (int); static void do_measure (PLMeasure *m, Coord i, double d, int u); #define M(r,f,d) do_measure (&(r), f, d, 1) /* Macros for interpreting what "measure" means - integer value only, old units (mil), or new units (cmil). */ #define IV(m) integer_value (m) #define OU(m) old_units (m) #define NU(m) new_units (m) static int integer_value (PLMeasure m); static Coord old_units (PLMeasure m); static Coord new_units (PLMeasure m); /* #define YYDEBUG 1 #define YYERROR_VERBOSE 1 int yydebug=1; */ #include "parse_y.h" #line 171 "parse_y.c" # ifndef YY_CAST # ifdef __cplusplus # define YY_CAST(Type, Val) static_cast (Val) # define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) # else # define YY_CAST(Type, Val) ((Type) (Val)) # define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) # endif # endif # ifndef YY_NULLPTR # if defined __cplusplus # if 201103L <= __cplusplus # define YY_NULLPTR nullptr # else # define YY_NULLPTR 0 # endif # else # define YY_NULLPTR ((void*)0) # endif # endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif /* Use api.header.include to #include this header instead of duplicating it here. */ #ifndef YY_YY_Y_TAB_H_INCLUDED # define YY_YY_Y_TAB_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif #if YYDEBUG extern int yydebug; #endif /* Token type. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE enum yytokentype { FLOATING = 258, INTEGER = 259, CHAR_CONST = 260, STRING = 261, T_FILEVERSION = 262, T_PCB = 263, T_LAYER = 264, T_VIA = 265, T_RAT = 266, T_LINE = 267, T_ARC = 268, T_RECTANGLE = 269, T_TEXT = 270, T_ELEMENTLINE = 271, T_ELEMENT = 272, T_PIN = 273, T_PAD = 274, T_GRID = 275, T_FLAGS = 276, T_SYMBOL = 277, T_SYMBOLLINE = 278, T_CURSOR = 279, T_ELEMENTARC = 280, T_MARK = 281, T_GROUPS = 282, T_STYLES = 283, T_POLYGON = 284, T_POLYGON_HOLE = 285, T_NETLIST = 286, T_NET = 287, T_CONN = 288, T_AREA = 289, T_THERMAL = 290, T_DRC = 291, T_ATTRIBUTE = 292, T_UMIL = 293, T_CMIL = 294, T_MIL = 295, T_IN = 296, T_NM = 297, T_UM = 298, T_MM = 299, T_M = 300, T_KM = 301, T_PX = 302 }; #endif /* Tokens. */ #define FLOATING 258 #define INTEGER 259 #define CHAR_CONST 260 #define STRING 261 #define T_FILEVERSION 262 #define T_PCB 263 #define T_LAYER 264 #define T_VIA 265 #define T_RAT 266 #define T_LINE 267 #define T_ARC 268 #define T_RECTANGLE 269 #define T_TEXT 270 #define T_ELEMENTLINE 271 #define T_ELEMENT 272 #define T_PIN 273 #define T_PAD 274 #define T_GRID 275 #define T_FLAGS 276 #define T_SYMBOL 277 #define T_SYMBOLLINE 278 #define T_CURSOR 279 #define T_ELEMENTARC 280 #define T_MARK 281 #define T_GROUPS 282 #define T_STYLES 283 #define T_POLYGON 284 #define T_POLYGON_HOLE 285 #define T_NETLIST 286 #define T_NET 287 #define T_CONN 288 #define T_AREA 289 #define T_THERMAL 290 #define T_DRC 291 #define T_ATTRIBUTE 292 #define T_UMIL 293 #define T_CMIL 294 #define T_MIL 295 #define T_IN 296 #define T_NM 297 #define T_UM 298 #define T_MM 299 #define T_M 300 #define T_KM 301 #define T_PX 302 /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { #line 114 "parse_y.y" int integer; double number; char *string; FlagType flagtype; PLMeasure measure; #line 325 "parse_y.c" }; typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif extern YYSTYPE yylval; int yyparse (void); #endif /* !YY_YY_Y_TAB_H_INCLUDED */ #ifdef short # undef short #endif /* On compilers that do not define __PTRDIFF_MAX__ etc., make sure and (if available) are included so that the code can choose integer types of a good width. */ #ifndef __PTRDIFF_MAX__ # include /* INFRINGES ON USER NAME SPACE */ # if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ # include /* INFRINGES ON USER NAME SPACE */ # define YY_STDINT_H # endif #endif /* Narrow types that promote to a signed type and that can represent a signed or unsigned integer of at least N bits. In tables they can save space and decrease cache pressure. Promoting to a signed type helps avoid bugs in integer arithmetic. */ #ifdef __INT_LEAST8_MAX__ typedef __INT_LEAST8_TYPE__ yytype_int8; #elif defined YY_STDINT_H typedef int_least8_t yytype_int8; #else typedef signed char yytype_int8; #endif #ifdef __INT_LEAST16_MAX__ typedef __INT_LEAST16_TYPE__ yytype_int16; #elif defined YY_STDINT_H typedef int_least16_t yytype_int16; #else typedef short yytype_int16; #endif #if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ typedef __UINT_LEAST8_TYPE__ yytype_uint8; #elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ && UINT_LEAST8_MAX <= INT_MAX) typedef uint_least8_t yytype_uint8; #elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX typedef unsigned char yytype_uint8; #else typedef short yytype_uint8; #endif #if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ typedef __UINT_LEAST16_TYPE__ yytype_uint16; #elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ && UINT_LEAST16_MAX <= INT_MAX) typedef uint_least16_t yytype_uint16; #elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX typedef unsigned short yytype_uint16; #else typedef int yytype_uint16; #endif #ifndef YYPTRDIFF_T # if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ # define YYPTRDIFF_T __PTRDIFF_TYPE__ # define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ # elif defined PTRDIFF_MAX # ifndef ptrdiff_t # include /* INFRINGES ON USER NAME SPACE */ # endif # define YYPTRDIFF_T ptrdiff_t # define YYPTRDIFF_MAXIMUM PTRDIFF_MAX # else # define YYPTRDIFF_T long # define YYPTRDIFF_MAXIMUM LONG_MAX # endif #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned # endif #endif #define YYSIZE_MAXIMUM \ YY_CAST (YYPTRDIFF_T, \ (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ ? YYPTRDIFF_MAXIMUM \ : YY_CAST (YYSIZE_T, -1))) #define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) /* Stored state numbers (used for stacks). */ typedef yytype_int16 yy_state_t; /* State numbers in computations. */ typedef int yy_state_fast_t; #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ # define YY_(Msgid) dgettext ("bison-runtime", Msgid) # endif # endif # ifndef YY_ # define YY_(Msgid) Msgid # endif #endif #ifndef YY_ATTRIBUTE_PURE # if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) # define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) # else # define YY_ATTRIBUTE_PURE # endif #endif #ifndef YY_ATTRIBUTE_UNUSED # if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) # define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) # else # define YY_ATTRIBUTE_UNUSED # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(E) ((void) (E)) #else # define YYUSE(E) /* empty */ #endif #if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ /* Suppress an incorrect diagnostic about yylval being uninitialized. */ # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") # define YY_IGNORE_MAYBE_UNINITIALIZED_END \ _Pragma ("GCC diagnostic pop") #else # define YY_INITIAL_VALUE(Value) Value #endif #ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_END #endif #ifndef YY_INITIAL_VALUE # define YY_INITIAL_VALUE(Value) /* Nothing. */ #endif #if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ # define YY_IGNORE_USELESS_CAST_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") # define YY_IGNORE_USELESS_CAST_END \ _Pragma ("GCC diagnostic pop") #endif #ifndef YY_IGNORE_USELESS_CAST_BEGIN # define YY_IGNORE_USELESS_CAST_BEGIN # define YY_IGNORE_USELESS_CAST_END #endif #define YY_ASSERT(E) ((void) (0 && (E))) #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS # include /* INFRINGES ON USER NAME SPACE */ /* Use EXIT_SUCCESS as a witness for stdlib.h. */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's 'empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined EXIT_SUCCESS \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined EXIT_SUCCESS void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined EXIT_SUCCESS void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yy_state_t yyss_alloc; YYSTYPE yyvs_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) # define YYCOPY_NEEDED 1 /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ YYPTRDIFF_T yynewbytes; \ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ Stack = &yyptr->Stack_alloc; \ yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / YYSIZEOF (*yyptr); \ } \ while (0) #endif #if defined YYCOPY_NEEDED && YYCOPY_NEEDED /* Copy COUNT objects from SRC to DST. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(Dst, Src, Count) \ __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) # else # define YYCOPY(Dst, Src, Count) \ do \ { \ YYPTRDIFF_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (Dst)[yyi] = (Src)[yyi]; \ } \ while (0) # endif # endif #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ #define YYFINAL 9 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 771 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 52 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 110 /* YYNRULES -- Number of rules. */ #define YYNRULES 209 /* YYNSTATES -- Number of states. */ #define YYNSTATES 631 #define YYUNDEFTOK 2 #define YYMAXUTOK 302 /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM as returned by yylex, with out-of-bounds checking. */ #define YYTRANSLATE(YYX) \ (0 <= (YYX) && (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM as returned by yylex. */ static const yytype_int8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 50, 51, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 48, 2, 49, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int16 yyrline[] = { 0, 140, 140, 141, 142, 143, 179, 179, 234, 234, 262, 262, 265, 270, 270, 311, 312, 351, 357, 363, 401, 402, 403, 406, 414, 427, 466, 471, 476, 493, 494, 520, 521, 553, 554, 555, 556, 560, 570, 581, 608, 612, 617, 645, 654, 710, 719, 728, 732, 733, 737, 738, 742, 743, 743, 744, 745, 746, 746, 784, 785, 786, 787, 788, 789, 851, 861, 871, 882, 892, 902, 942, 947, 991, 990, 1020, 1021, 1025, 1026, 1030, 1031, 1032, 1033, 1034, 1035, 1037, 1042, 1043, 1044, 1045, 1045, 1046, 1085, 1094, 1103, 1160, 1169, 1178, 1224, 1234, 1252, 1316, 1315, 1356, 1357, 1362, 1361, 1369, 1370, 1375, 1379, 1450, 1451, 1452, 1453, 1454, 1462, 1461, 1480, 1479, 1498, 1497, 1518, 1516, 1540, 1538, 1640, 1641, 1645, 1646, 1647, 1648, 1649, 1651, 1656, 1661, 1666, 1671, 1676, 1681, 1681, 1685, 1686, 1690, 1691, 1692, 1693, 1694, 1695, 1697, 1703, 1710, 1715, 1720, 1720, 1770, 1782, 1794, 1805, 1821, 1883, 1897, 1923, 1936, 1961, 1972, 1983, 1984, 1988, 1989, 2022, 2024, 2040, 2059, 2060, 2064, 2065, 2066, 2096, 2103, 2119, 2120, 2124, 2129, 2130, 2134, 2135, 2158, 2157, 2167, 2168, 2172, 2173, 2192, 2251, 2259, 2260, 2264, 2265, 2270, 2271, 2272, 2273, 2274, 2275, 2276, 2277, 2278, 2279, 2280 }; #endif #if YYDEBUG || YYERROR_VERBOSE || 0 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "FLOATING", "INTEGER", "CHAR_CONST", "STRING", "T_FILEVERSION", "T_PCB", "T_LAYER", "T_VIA", "T_RAT", "T_LINE", "T_ARC", "T_RECTANGLE", "T_TEXT", "T_ELEMENTLINE", "T_ELEMENT", "T_PIN", "T_PAD", "T_GRID", "T_FLAGS", "T_SYMBOL", "T_SYMBOLLINE", "T_CURSOR", "T_ELEMENTARC", "T_MARK", "T_GROUPS", "T_STYLES", "T_POLYGON", "T_POLYGON_HOLE", "T_NETLIST", "T_NET", "T_CONN", "T_AREA", "T_THERMAL", "T_DRC", "T_ATTRIBUTE", "T_UMIL", "T_CMIL", "T_MIL", "T_IN", "T_NM", "T_UM", "T_MM", "T_M", "T_KM", "T_PX", "'['", "']'", "'('", "')'", "$accept", "parse", "parsepcb", "$@1", "parsedata", "$@2", "pcbfont", "$@3", "parsefont", "$@4", "pcbfileversion", "pcbname", "pcbgrid", "pcbgridold", "pcbgridnew", "pcbhigrid", "pcbcursor", "polyarea", "pcbthermal", "pcbdrc", "pcbdrc1", "pcbdrc2", "pcbdrc3", "pcbflags", "pcbgroups", "pcbstyles", "pcbdata", "pcbdefinitions", "pcbdefinition", "$@5", "$@6", "via", "via_ehi_format", "via_hi_format", "via_2.0_format", "via_1.7_format", "via_newformat", "via_oldformat", "rats", "layer", "$@7", "layerdata", "layerdefinitions", "layerdefinition", "$@8", "line_hi_format", "line_1.7_format", "line_oldformat", "arc_hi_format", "arc_1.7_format", "arc_oldformat", "text_oldformat", "text_newformat", "text_hi_format", "polygon_format", "$@9", "polygonholes", "polygonhole", "$@10", "polygonpoints", "polygonpoint", "element", "element_oldformat", "$@11", "element_1.3.4_format", "$@12", "element_newformat", "$@13", "element_1.7_format", "$@14", "element_hi_format", "$@15", "elementdefinitions", "elementdefinition", "$@16", "relementdefs", "relementdef", "$@17", "pin_hi_format", "pin_1.7_format", "pin_1.6.3_format", "pin_newformat", "pin_oldformat", "pad_hi_format", "pad_hic_format", "pad_1.7_format", "pad_1.7c_format", "pad_newformat", "pad", "flags", "symbols", "symbol", "symbolhead", "symbolid", "symboldata", "symboldefinition", "hiressymbol", "pcbnetlist", "pcbnetdef", "nets", "netdefs", "net", "$@18", "connections", "conndefs", "conn", "attribute", "opt_string", "number", "measure", YY_NULLPTR }; #endif # ifdef YYPRINT /* YYTOKNUM[NUM] -- (External) token number corresponding to the (internal) symbol number NUM (which must be that of a token). */ static const yytype_int16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 91, 93, 40, 41 }; # endif #define YYPACT_NINF (-468) #define yypact_value_is_default(Yyn) \ ((Yyn) == YYPACT_NINF) #define YYTABLE_NINF (-90) #define yytable_value_is_error(Yyn) \ 0 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ static const yytype_int16 yypact[] = { 152, -468, 37, -468, 33, -468, 55, -468, -5, -468, -4, 45, 27, 90, 108, -468, 55, -468, 32, 74, -468, -468, -468, -468, -468, -468, -468, -468, -468, 132, -5, -468, -468, 110, 138, 95, 114, 19, 19, 19, 19, -468, 60, -468, 168, -468, -468, -468, -468, -468, -468, 23, 23, -468, -2, 70, 117, 120, 184, 105, -468, -468, -468, 127, -468, -468, 154, 19, 19, 19, 19, 135, 48, 198, -468, -468, 19, 19, 197, -468, -468, -468, -468, 19, 4, 19, 19, 209, 111, 148, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, 19, 19, 171, 183, 158, -468, -468, 166, 204, 222, 186, 189, 19, 19, 19, -468, 19, 19, 19, 19, 19, 200, 214, -468, 213, 19, 67, 19, 19, 226, 274, 291, 19, 260, 267, 19, 19, 277, 276, 19, 19, 19, 19, 19, 280, 293, 285, 19, 326, 80, 19, 19, -468, 330, 131, 19, -468, -468, 19, 19, -468, -468, 333, -1, 19, 19, 289, 19, 292, 318, -468, -468, -468, -468, 19, 290, 338, 211, 339, 348, 19, 19, 19, 354, 19, 19, 311, 308, -468, 312, 313, -468, 316, 19, 317, 341, 136, 254, -468, 315, 365, 370, 48, 373, 19, 19, 19, 327, 19, 19, -468, -468, -468, -468, -468, 19, 261, 329, 352, 220, 221, 331, 233, 334, 335, 136, -468, 32, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, 381, 48, -468, 340, 385, 343, 342, 19, 19, 19, 344, 353, 350, 19, 355, 356, 397, 237, 382, 19, 19, 19, 19, 19, 19, 19, 48, -468, -468, -468, 399, 359, -468, 358, -468, -468, 19, 19, 406, -468, -468, -468, 8, -468, -468, 362, 408, 410, 55, -468, 19, 19, 19, 19, 19, 19, 19, 366, 48, -468, -468, 19, 92, 367, 165, -468, 10, -468, 371, 368, 390, -468, 19, 19, 19, 19, 19, 19, 19, 374, 376, 19, 379, 19, 377, 238, 383, 384, 241, 242, 0, -468, 32, -468, -468, -468, -468, -468, -468, 19, -468, -468, 386, -468, -468, 19, 19, 19, 19, 19, 19, 223, -468, -468, 48, 387, 427, -468, 19, 19, 19, 19, 19, 19, 19, 19, -468, -468, -468, 389, 388, 19, 19, 19, 19, 428, 429, 436, 435, 245, 393, -468, 392, 165, 19, 19, 19, 19, 19, 19, 19, 19, -468, 394, 19, 19, 19, 19, 395, 48, 398, 441, 19, 19, -468, 245, 400, 165, 401, 17, 19, 19, 19, 19, 19, 19, 403, 402, 416, 48, 5, 19, 19, -468, 405, -468, 404, 19, 19, -10, -468, -468, 106, -468, -468, 19, 19, 227, 19, 19, 19, -468, -468, 407, 411, 416, -468, 409, 412, -468, 19, 96, -468, -468, 415, 414, 424, -468, -468, 187, -468, 187, 19, 19, 452, 453, 19, 19, 19, 469, -468, -468, -468, -468, 48, 425, 473, -468, -468, -468, 246, 250, 253, 265, 42, -468, 32, -468, -468, -468, -468, -468, -468, 160, 430, 431, 432, 298, 472, 19, 19, 474, 437, -468, 438, 245, 19, 19, 19, 19, 19, 19, 19, 19, -468, -468, -468, -468, -468, -468, -468, 447, 477, 310, 19, 19, 448, -468, -468, 449, 19, 19, 19, 19, 19, 19, 19, 19, -468, 450, 451, 483, 439, 454, 464, -468, 19, 19, 19, 19, 19, 19, 19, 19, -468, -468, 465, -468, -468, -468, 19, 19, 19, 19, 19, 19, 19, 19, -468, 471, 19, 19, 19, 19, 19, 19, 19, 19, 467, 468, 471, -468, 466, 478, 19, 19, 19, 19, 19, 19, 512, -468, -468, -468, -468, 522, 530, 235, 240, 19, 19, 488, 534, 535, 536, 537, 545, 546, 504, 503, -468, 48, 551, 48, 550, 557, 556, -468, -468, 514, 513, 516, 48, 515, 563, -468, -468, -468, 520, -468, 519, -468, -468 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. Performed when YYTABLE does not specify something else to do. Zero means the default is an error. */ static const yytype_uint8 yydefact[] = { 0, 5, 0, 2, 15, 3, 49, 4, 0, 1, 0, 0, 0, 0, 0, 9, 48, 50, 0, 0, 52, 59, 60, 61, 62, 63, 64, 55, 56, 0, 14, 168, 175, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 54, 0, 58, 111, 112, 113, 114, 115, 0, 0, 169, 0, 0, 0, 0, 0, 28, 20, 21, 22, 0, 197, 198, 199, 0, 0, 0, 0, 0, 0, 0, 173, 174, 0, 0, 0, 170, 176, 177, 16, 0, 0, 0, 0, 0, 29, 196, 200, 201, 202, 203, 204, 206, 207, 208, 209, 205, 0, 0, 0, 0, 0, 166, 167, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 31, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 194, 0, 0, 0, 171, 172, 0, 0, 19, 18, 0, 0, 0, 0, 0, 0, 0, 42, 34, 35, 36, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 30, 0, 0, 0, 44, 76, 0, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 24, 27, 26, 32, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 75, 77, 0, 79, 80, 81, 82, 83, 84, 88, 87, 86, 91, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 74, 78, 90, 0, 0, 68, 0, 71, 72, 0, 0, 0, 116, 179, 178, 0, 40, 41, 0, 0, 0, 49, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 67, 0, 0, 0, 139, 37, 0, 43, 0, 0, 181, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, 0, 0, 0, 0, 0, 0, 0, 139, 126, 0, 128, 129, 130, 131, 132, 38, 0, 46, 45, 0, 7, 180, 0, 0, 0, 0, 0, 0, 0, 101, 65, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 117, 127, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 0, 120, 0, 139, 0, 0, 0, 0, 0, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 103, 107, 0, 139, 0, 139, 0, 0, 0, 0, 0, 0, 0, 0, 184, 0, 0, 0, 0, 85, 0, 98, 0, 0, 0, 0, 108, 124, 139, 122, 119, 0, 0, 0, 0, 0, 0, 137, 138, 0, 0, 183, 185, 0, 0, 94, 0, 0, 100, 99, 0, 0, 0, 102, 104, 153, 121, 153, 0, 0, 0, 0, 0, 0, 0, 0, 182, 186, 92, 93, 0, 198, 0, 110, 109, 105, 0, 0, 0, 0, 153, 141, 0, 144, 143, 147, 148, 145, 146, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 0, 107, 0, 0, 0, 0, 0, 0, 0, 0, 125, 142, 154, 123, 133, 134, 159, 0, 0, 0, 0, 0, 0, 95, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 158, 0, 0, 0, 0, 0, 0, 106, 0, 0, 0, 0, 0, 0, 0, 0, 157, 165, 0, 135, 136, 187, 0, 0, 0, 0, 0, 0, 0, 0, 164, 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 189, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 188, 192, 149, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 193, 0, 0, 0, 0, 0, 0, 151, 152, 0, 0, 0, 0, 0, 0, 155, 156, 161, 0, 163, 0, 160, 162 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { -468, -468, -468, -468, -468, -468, -468, -468, 284, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, 286, -468, 558, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, 351, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -398, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -371, -322, -468, 116, -467, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, 151, -468, 543, -468, 525, -468, -468, -468, -468, -468, -468, -468, 137, -468, -468, -468, 1, -223, -468, -37, -38 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { -1, 2, 3, 4, 5, 6, 286, 287, 7, 8, 11, 35, 59, 60, 61, 62, 88, 122, 145, 169, 170, 171, 172, 195, 218, 256, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 196, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 377, 427, 456, 503, 402, 403, 45, 46, 302, 47, 381, 48, 405, 49, 459, 50, 457, 328, 329, 330, 482, 483, 484, 485, 486, 331, 332, 333, 487, 488, 489, 490, 334, 335, 107, 30, 31, 32, 76, 54, 80, 81, 341, 342, 442, 443, 444, 567, 577, 578, 579, 43, 124, 66, 67 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule whose number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { 68, 69, 70, 187, 267, 428, 365, 64, 65, 446, 407, 64, 65, 64, 65, 513, 323, 29, 324, 325, 454, 78, 64, 65, 513, 326, 327, 74, 75, 100, 101, 102, 103, 323, 430, 324, 325, 9, 110, 111, 10, 455, 326, 327, 33, 114, 116, 117, 118, 79, 188, 364, 105, 34, 106, 115, 447, 303, 478, 336, 479, 480, 125, 126, 12, 13, 14, 481, 432, 42, 64, 65, -57, 148, 135, 136, 137, 36, 138, 139, 140, 141, 142, 64, 65, 365, 176, 147, 149, 150, 151, 44, -53, 512, 155, 64, 320, 158, 159, 64, 473, 162, 163, 164, 165, 527, 166, 366, 365, 174, 71, 177, 178, 179, 55, 58, 182, 183, 63, 82, 184, 185, 323, 83, 324, 325, 84, 189, 190, 87, 192, 326, 327, 89, 64, 65, 197, 181, 37, 201, 38, 104, 204, 205, 206, 121, 208, 209, 219, 220, 221, 222, -8, 1, 123, 215, 39, 458, 40, -6, -6, -8, -8, -8, 129, 223, 245, 246, 247, -8, 249, 250, 130, -89, -13, 127, 478, 251, 479, 480, 51, 323, 52, 324, 325, 481, 56, 128, 57, -8, 326, 327, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 108, 478, 109, 479, 480, 274, 275, 276, 131, 515, 481, 280, 64, 65, 72, 200, 73, 288, 289, 290, 291, 292, 293, 294, 64, 65, 132, 375, 64, 65, 85, 462, 86, 133, 299, 300, 64, 65, 134, 602, 304, 64, 65, 112, 604, 113, 143, 144, 310, 311, 312, 313, 314, 315, 316, 119, 238, 120, 239, 514, 319, 321, 146, 252, 337, 253, 257, 259, 258, 260, 343, 344, 345, 346, 347, 152, 348, 349, 153, 262, 352, 263, 354, 284, 356, 285, 357, 360, 362, 361, 363, 400, 504, 401, 505, 154, 506, 367, 507, 508, 519, 509, 520, 369, 370, 371, 372, 373, 156, 374, 376, 510, 538, 511, 539, 157, 382, 383, 384, 385, 386, 387, 388, 389, 160, 161, 167, 168, 175, 392, 393, 394, 395, 173, 180, 186, 191, 194, 193, 198, 199, 202, 408, 409, 410, 411, 412, 413, 414, 415, 203, 243, 417, 418, 419, 420, 207, 211, 210, 212, 425, 426, 213, 214, 240, 216, 217, 241, 433, 434, 435, 436, 437, 438, 242, 244, 248, 254, 255, 261, 448, 449, 264, 268, 265, 452, 453, 271, 269, 270, 272, 273, 277, 460, 461, 463, 464, 465, 466, 279, 278, 283, -10, 296, 281, 282, 297, 298, 301, 472, 474, 305, 306, 295, 307, 317, 322, 339, 338, 340, 492, 493, 350, 351, 496, 355, 497, 498, 353, 380, 396, 358, 359, 397, 368, 379, 390, 391, 398, 399, 404, 406, 416, 424, 421, 318, 441, 423, 429, 431, 439, 440, 450, 451, 494, 467, 470, 495, 522, 523, 468, 471, 475, 476, 528, 529, 530, 531, 532, 533, 534, 535, 477, 499, 501, 502, 521, 516, 524, 537, 517, 518, 540, 541, 525, 554, 555, 526, 544, 545, 546, 547, 548, 549, 550, 551, 536, 542, 543, 552, 553, 378, 576, 556, 558, 559, 560, 561, 562, 563, 564, 565, 557, 591, 566, 588, 599, 589, 568, 569, 570, 571, 572, 573, 574, 575, 600, 592, 580, 581, 582, 583, 584, 585, 601, 586, 587, 608, 609, 610, 611, 612, 593, 594, 595, 596, 422, 597, 598, 613, 614, 615, 616, 618, 620, 603, 605, 606, 607, 621, 622, 623, 624, 625, 627, 628, 445, 629, 630, 309, 308, 53, 41, 491, 266, 77, 0, 590, 469, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 617, 0, 619, 0, 0, 0, 0, 0, 0, 0, 0, 626 }; static const yytype_int16 yycheck[] = { 38, 39, 40, 4, 227, 403, 328, 3, 4, 4, 381, 3, 4, 3, 4, 482, 16, 22, 18, 19, 30, 23, 3, 4, 491, 25, 26, 4, 5, 67, 68, 69, 70, 16, 405, 18, 19, 0, 76, 77, 7, 51, 25, 26, 48, 83, 84, 85, 86, 51, 51, 51, 4, 8, 6, 51, 51, 49, 16, 49, 18, 19, 100, 101, 9, 10, 11, 25, 51, 37, 3, 4, 17, 6, 112, 113, 114, 50, 116, 117, 118, 119, 120, 3, 4, 407, 6, 125, 126, 127, 128, 17, 37, 51, 132, 3, 4, 135, 136, 3, 4, 139, 140, 141, 142, 503, 143, 330, 430, 147, 50, 149, 150, 151, 4, 20, 154, 155, 4, 49, 158, 159, 16, 6, 18, 19, 6, 164, 165, 24, 167, 25, 26, 6, 3, 4, 174, 6, 48, 177, 50, 6, 180, 181, 182, 34, 184, 185, 12, 13, 14, 15, 0, 1, 6, 193, 48, 51, 50, 7, 8, 9, 10, 11, 6, 29, 204, 205, 206, 17, 208, 209, 6, 37, 22, 4, 16, 215, 18, 19, 48, 16, 50, 18, 19, 25, 48, 4, 50, 37, 25, 26, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 4, 16, 6, 18, 19, 245, 246, 247, 6, 51, 25, 251, 3, 4, 48, 6, 50, 257, 258, 259, 260, 261, 262, 263, 3, 4, 6, 6, 3, 4, 48, 6, 50, 49, 274, 275, 3, 4, 51, 6, 280, 3, 4, 48, 6, 50, 48, 35, 288, 289, 290, 291, 292, 293, 294, 48, 4, 50, 6, 484, 299, 300, 51, 4, 304, 6, 48, 48, 50, 50, 310, 311, 312, 313, 314, 51, 315, 316, 6, 48, 319, 50, 321, 48, 48, 50, 50, 48, 48, 50, 50, 48, 48, 50, 50, 6, 48, 337, 50, 48, 4, 50, 6, 343, 344, 345, 346, 347, 50, 348, 349, 48, 4, 50, 6, 50, 356, 357, 358, 359, 360, 361, 362, 363, 49, 51, 48, 36, 4, 369, 370, 371, 372, 50, 6, 4, 49, 21, 48, 51, 4, 4, 382, 383, 384, 385, 386, 387, 388, 389, 4, 202, 392, 393, 394, 395, 4, 51, 49, 49, 400, 401, 51, 49, 51, 50, 27, 4, 408, 409, 410, 411, 412, 413, 6, 4, 51, 50, 28, 50, 419, 420, 50, 4, 51, 425, 426, 4, 239, 51, 49, 51, 50, 433, 434, 435, 436, 437, 438, 51, 49, 6, 22, 6, 51, 51, 49, 51, 4, 448, 449, 51, 6, 264, 6, 51, 51, 51, 49, 31, 460, 461, 50, 49, 464, 50, 465, 466, 51, 4, 4, 50, 50, 6, 50, 50, 49, 51, 4, 6, 49, 51, 50, 4, 51, 296, 32, 51, 50, 50, 49, 51, 49, 51, 4, 50, 49, 6, 497, 498, 51, 51, 49, 51, 504, 505, 506, 507, 508, 509, 510, 511, 50, 6, 51, 4, 6, 49, 6, 4, 51, 51, 522, 523, 49, 4, 49, 51, 528, 529, 530, 531, 532, 533, 534, 535, 51, 51, 51, 51, 51, 352, 33, 51, 544, 545, 546, 547, 548, 549, 550, 551, 50, 49, 51, 50, 6, 51, 558, 559, 560, 561, 562, 563, 564, 565, 6, 51, 568, 569, 570, 571, 572, 573, 6, 574, 575, 51, 6, 6, 6, 6, 582, 583, 584, 585, 397, 586, 587, 6, 6, 49, 51, 4, 6, 595, 596, 597, 598, 4, 6, 49, 51, 49, 51, 4, 417, 49, 51, 287, 286, 30, 16, 459, 225, 52, -1, 578, 443, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 609, -1, 611, -1, -1, -1, -1, -1, -1, -1, -1, 620 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 1, 53, 54, 55, 56, 57, 60, 61, 0, 7, 62, 9, 10, 11, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 22, 142, 143, 144, 48, 8, 63, 50, 48, 50, 48, 50, 80, 37, 158, 17, 113, 114, 116, 118, 120, 122, 48, 50, 143, 146, 4, 48, 50, 20, 64, 65, 66, 67, 4, 3, 4, 160, 161, 161, 161, 161, 50, 48, 50, 4, 5, 145, 145, 23, 51, 147, 148, 49, 6, 6, 48, 50, 24, 68, 6, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 161, 161, 161, 161, 6, 4, 6, 141, 4, 6, 161, 161, 48, 50, 161, 51, 161, 161, 161, 48, 50, 34, 69, 6, 159, 161, 161, 4, 4, 6, 6, 6, 6, 49, 51, 161, 161, 161, 161, 161, 161, 161, 161, 48, 35, 70, 51, 161, 6, 161, 161, 161, 51, 6, 6, 161, 50, 50, 161, 161, 49, 51, 161, 161, 161, 161, 160, 48, 36, 71, 72, 73, 74, 50, 161, 4, 6, 161, 161, 161, 6, 6, 161, 161, 161, 161, 4, 4, 51, 160, 160, 49, 160, 48, 21, 75, 92, 161, 51, 4, 6, 161, 4, 4, 161, 161, 161, 4, 161, 161, 49, 51, 49, 51, 49, 161, 50, 27, 76, 12, 13, 14, 15, 29, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 4, 6, 51, 4, 6, 141, 4, 161, 161, 161, 51, 161, 161, 161, 4, 6, 50, 28, 77, 48, 50, 48, 50, 50, 48, 50, 50, 51, 95, 158, 4, 141, 51, 4, 49, 51, 161, 161, 161, 50, 49, 51, 161, 51, 51, 6, 48, 50, 58, 59, 161, 161, 161, 161, 161, 161, 161, 141, 6, 49, 51, 161, 161, 4, 115, 49, 161, 51, 6, 6, 78, 60, 161, 161, 161, 161, 161, 161, 161, 51, 141, 160, 4, 160, 51, 16, 18, 19, 25, 26, 124, 125, 126, 132, 133, 134, 139, 140, 49, 161, 49, 51, 31, 149, 150, 161, 161, 161, 161, 161, 160, 160, 50, 49, 160, 51, 160, 50, 48, 50, 50, 50, 48, 50, 48, 50, 51, 125, 158, 161, 50, 161, 161, 161, 161, 161, 160, 6, 160, 107, 141, 50, 4, 117, 161, 161, 161, 161, 161, 161, 161, 161, 49, 51, 161, 161, 161, 161, 4, 6, 4, 6, 48, 50, 111, 112, 49, 119, 51, 124, 161, 161, 161, 161, 161, 161, 161, 161, 50, 161, 161, 161, 161, 51, 141, 51, 4, 161, 161, 108, 111, 50, 124, 50, 51, 161, 161, 161, 161, 161, 161, 49, 51, 32, 151, 152, 153, 141, 4, 51, 160, 160, 49, 51, 161, 161, 30, 51, 109, 123, 51, 121, 161, 161, 6, 161, 161, 161, 161, 50, 51, 153, 49, 51, 160, 4, 160, 49, 51, 50, 16, 18, 19, 25, 127, 128, 129, 130, 131, 135, 136, 137, 138, 127, 161, 161, 4, 6, 161, 160, 160, 6, 141, 51, 4, 110, 48, 50, 48, 50, 48, 50, 48, 50, 51, 128, 158, 51, 49, 51, 51, 4, 6, 6, 160, 160, 6, 49, 51, 111, 161, 161, 161, 161, 161, 161, 161, 161, 51, 4, 4, 6, 161, 161, 51, 51, 161, 161, 161, 161, 161, 161, 161, 161, 51, 51, 4, 49, 51, 50, 161, 161, 161, 161, 161, 161, 161, 161, 51, 154, 161, 161, 161, 161, 161, 161, 161, 161, 33, 155, 156, 157, 161, 161, 161, 161, 161, 161, 160, 160, 50, 51, 157, 49, 51, 161, 161, 161, 161, 160, 160, 6, 6, 6, 6, 161, 6, 161, 161, 161, 51, 6, 6, 6, 6, 6, 6, 49, 51, 141, 4, 141, 6, 4, 6, 49, 51, 49, 141, 51, 4, 49, 51 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { 0, 52, 53, 53, 53, 53, 55, 54, 57, 56, 59, 58, 58, 61, 60, 62, 62, 63, 63, 63, 64, 64, 64, 65, 66, 67, 68, 68, 68, 69, 69, 70, 70, 71, 71, 71, 71, 72, 73, 74, 75, 75, 75, 76, 76, 77, 77, 77, 78, 78, 79, 79, 80, 81, 80, 80, 80, 82, 80, 83, 83, 83, 83, 83, 83, 84, 85, 86, 87, 88, 89, 90, 90, 92, 91, 93, 93, 94, 94, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 96, 95, 95, 97, 98, 99, 100, 101, 102, 103, 104, 105, 107, 106, 108, 108, 110, 109, 111, 111, 112, 112, 113, 113, 113, 113, 113, 115, 114, 117, 116, 119, 118, 121, 120, 123, 122, 124, 124, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 126, 125, 127, 127, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 129, 128, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 141, 142, 142, 143, 144, 144, 145, 145, 146, 146, 146, 147, 148, 149, 149, 150, 151, 151, 152, 152, 154, 153, 155, 155, 156, 156, 157, 158, 159, 159, 160, 160, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ static const yytype_int8 yyr2[] = { 0, 2, 1, 1, 1, 1, 0, 14, 0, 2, 0, 2, 0, 0, 2, 0, 4, 4, 6, 6, 1, 1, 1, 6, 7, 7, 6, 6, 0, 0, 4, 0, 4, 0, 1, 1, 1, 6, 7, 9, 4, 4, 0, 4, 0, 4, 4, 0, 1, 0, 1, 2, 1, 0, 2, 1, 1, 0, 2, 1, 1, 1, 1, 1, 1, 13, 11, 11, 10, 9, 8, 10, 10, 0, 10, 1, 0, 1, 2, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 0, 2, 1, 10, 10, 9, 12, 12, 11, 8, 9, 9, 0, 9, 0, 2, 0, 5, 0, 2, 4, 4, 1, 1, 1, 1, 1, 0, 12, 0, 15, 0, 16, 0, 18, 0, 18, 1, 2, 1, 1, 1, 1, 1, 8, 8, 10, 10, 5, 5, 0, 2, 1, 2, 1, 1, 1, 1, 1, 1, 8, 8, 10, 10, 0, 2, 12, 12, 10, 9, 8, 13, 12, 13, 12, 11, 10, 1, 1, 1, 2, 3, 6, 6, 1, 1, 0, 2, 2, 8, 8, 1, 0, 6, 1, 0, 1, 2, 0, 9, 1, 0, 1, 2, 4, 5, 1, 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY) \ { \ yychar = (Token); \ yylval = (Value); \ YYPOPSTACK (yylen); \ yystate = *yyssp; \ goto yybackup; \ } \ else \ { \ yyerror (YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (0) /* Error token number */ #define YYTERROR 1 #define YYERRCODE 256 /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (0) /* This macro is provided for backward compatibility. */ #ifndef YY_LOCATION_PRINT # define YY_LOCATION_PRINT(File, Loc) ((void) 0) #endif # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value); \ YYFPRINTF (stderr, "\n"); \ } \ } while (0) /*-----------------------------------. | Print this symbol's value on YYO. | `-----------------------------------*/ static void yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep) { FILE *yyoutput = yyo; YYUSE (yyoutput); if (!yyvaluep) return; # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyo, yytoknum[yytype], *yyvaluep); # endif YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN YYUSE (yytype); YY_IGNORE_MAYBE_UNINITIALIZED_END } /*---------------------------. | Print this symbol on YYO. | `---------------------------*/ static void yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep) { YYFPRINTF (yyo, "%s %s (", yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); yy_symbol_value_print (yyo, yytype, yyvaluep); YYFPRINTF (yyo, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ static void yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) { YYFPRINTF (stderr, "Stack now"); for (; yybottom <= yytop; yybottom++) { int yybot = *yybottom; YYFPRINTF (stderr, " %d", yybot); } YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (0) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ static void yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, int yyrule) { int yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yystos[+yyssp[yyi + 1 - yynrhs]], &yyvsp[(yyi + 1) - (yynrhs)] ); YYFPRINTF (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyssp, yyvsp, Rule); \ } while (0) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S))) # else /* Return the length of YYSTR. */ static YYPTRDIFF_T yystrlen (const char *yystr) { YYPTRDIFF_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ static char * yystpcpy (char *yydest, const char *yysrc) { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYPTRDIFF_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYPTRDIFF_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; else goto append; append: default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (yyres) return yystpcpy (yyres, yystr) - yyres; else return yystrlen (yystr); } # endif /* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message about the unexpected token YYTOKEN for the state stack whose top is YYSSP. Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is not large enough to hold the message. In that case, also set *YYMSG_ALLOC to the required number of bytes. Return 2 if the required number of bytes is too large to store. */ static int yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, yy_state_t *yyssp, int yytoken) { enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; /* Internationalized format string. */ const char *yyformat = YY_NULLPTR; /* Arguments of yyformat: reported tokens (one for the "unexpected", one per "expected"). */ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; /* Actual size of YYARG. */ int yycount = 0; /* Cumulated lengths of YYARG. */ YYPTRDIFF_T yysize = 0; /* There are many possibilities here to consider: - If this state is a consistent state with a default action, then the only way this function was invoked is if the default action is an error action. In that case, don't check for expected tokens because there are none. - The only way there can be no lookahead present (in yychar) is if this state is a consistent state with a default action. Thus, detecting the absence of a lookahead is sufficient to determine that there is no unexpected or expected token to report. In that case, just report a simple "syntax error". - Don't assume there isn't a lookahead just because this state is a consistent state with a default action. There might have been a previous inconsistent state, consistent state with a non-default action, or user semantic action that manipulated yychar. - Of course, the expected token list depends on states to have correct lookahead information, and it depends on the parser not to perform extra reductions after fetching a lookahead from the scanner and before detecting a syntax error. Thus, state merging (from LALR or IELR) and default reductions corrupt the expected token list. However, the list is correct for canonical LR with one exception: it will still contain any token that will not be accepted due to an error action in a later state. */ if (yytoken != YYEMPTY) { int yyn = yypact[+*yyssp]; YYPTRDIFF_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); yysize = yysize0; yyarg[yycount++] = yytname[yytoken]; if (!yypact_value_is_default (yyn)) { /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. In other words, skip the first -YYN actions for this state because they are default actions. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yyx; for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR && !yytable_value_is_error (yytable[yyx + yyn])) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; break; } yyarg[yycount++] = yytname[yyx]; { YYPTRDIFF_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) yysize = yysize1; else return 2; } } } } switch (yycount) { # define YYCASE_(N, S) \ case N: \ yyformat = S; \ break default: /* Avoid compiler warnings. */ YYCASE_(0, YY_("syntax error")); YYCASE_(1, YY_("syntax error, unexpected %s")); YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); # undef YYCASE_ } { /* Don't count the "%s"s in the final size, but reserve room for the terminator. */ YYPTRDIFF_T yysize1 = yysize + (yystrlen (yyformat) - 2 * yycount) + 1; if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) yysize = yysize1; else return 2; } if (*yymsg_alloc < yysize) { *yymsg_alloc = 2 * yysize; if (! (yysize <= *yymsg_alloc && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; return 1; } /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ { char *yyp = *yymsg; int yyi = 0; while ((*yyp = *yyformat) != '\0') if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyformat += 2; } else { ++yyp; ++yyformat; } } return 0; } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) { YYUSE (yyvaluep); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN YYUSE (yytype); YY_IGNORE_MAYBE_UNINITIALIZED_END } /* The lookahead symbol. */ int yychar; /* The semantic value of the lookahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; /*----------. | yyparse. | `----------*/ int yyparse (void) { yy_state_fast_t yystate; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* The stacks and their tools: 'yyss': related to states. 'yyvs': related to semantic values. Refer to the stacks through separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yy_state_t yyssa[YYINITDEPTH]; yy_state_t *yyss; yy_state_t *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs; YYSTYPE *yyvsp; YYPTRDIFF_T yystacksize; int yyn; int yyresult; /* Lookahead token as an internal (translated) token number. */ int yytoken = 0; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYPTRDIFF_T yymsg_alloc = sizeof yymsgbuf; #endif #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; yyssp = yyss = yyssa; yyvsp = yyvs = yyvsa; yystacksize = YYINITDEPTH; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ goto yysetstate; /*------------------------------------------------------------. | yynewstate -- push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; /*--------------------------------------------------------------------. | yysetstate -- set current state (the top of the stack) to yystate. | `--------------------------------------------------------------------*/ yysetstate: YYDPRINTF ((stderr, "Entering state %d\n", yystate)); YY_ASSERT (0 <= yystate && yystate < YYNSTATES); YY_IGNORE_USELESS_CAST_BEGIN *yyssp = YY_CAST (yy_state_t, yystate); YY_IGNORE_USELESS_CAST_END if (yyss + yystacksize - 1 <= yyssp) #if !defined yyoverflow && !defined YYSTACK_RELOCATE goto yyexhaustedlab; #else { /* Get the current used size of the three stacks, in elements. */ YYPTRDIFF_T yysize = yyssp - yyss + 1; # if defined yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ yy_state_t *yyss1 = yyss; YYSTYPE *yyvs1 = yyvs; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * YYSIZEOF (*yyssp), &yyvs1, yysize * YYSIZEOF (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } # else /* defined YYSTACK_RELOCATE */ /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yy_state_t *yyss1 = yyss; union yyalloc *yyptr = YY_CAST (union yyalloc *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YY_IGNORE_USELESS_CAST_BEGIN YYDPRINTF ((stderr, "Stack size increased to %ld\n", YY_CAST (long, yystacksize))); YY_IGNORE_USELESS_CAST_END if (yyss + yystacksize - 1 <= yyssp) YYABORT; } #endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ if (yystate == YYFINAL) YYACCEPT; goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yypact_value_is_default (yyn)) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = yylex (); } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yytable_value_is_error (yyn)) goto yyerrlab; yyn = -yyn; goto yyreduce; } /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); yystate = yyn; YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END /* Discard the shifted token. */ yychar = YYEMPTY; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: '$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 5: #line 143 "parse_y.y" { YYABORT; } #line 1949 "parse_y.c" break; case 6: #line 179 "parse_y.y" { /* reset flags for 'used layers'; * init font and data pointers */ int i; file_type = PCBFILE; if (!yyPCB) { Message(_("illegal pcb file format\n")); YYABORT; } for (i = 0; i < MAX_ALL_LAYER; i++) LayerFlag[i] = false; yyFont = &yyPCB->Font; yyData = yyPCB->Data; yyData->pcb = yyPCB; yyData->LayerN = 0; /* Parse the default layer group string, just in case the file doesn't have one */ if (ParseGroupString (Settings.Groups, &yyPCB->LayerGroups, &yyData->LayerN)) { Message(_("illegal default layer-group string\n")); YYABORT; } } #line 1977 "parse_y.c" break; case 7: #line 215 "parse_y.y" { PCBType *pcb_save = PCB; CreateNewPCBPost (yyPCB, 0); /* initialize the polygon clipping now since * we didn't know the layer grouping before. */ PCB = yyPCB; ALLPOLYGON_LOOP (yyData); { InitClip (yyData, layer, polygon); } ENDALL_LOOP; PCB = pcb_save; } #line 1997 "parse_y.c" break; case 8: #line 234 "parse_y.y" { /* reset flags for 'used layers'; * init font and data pointers */ int i; file_type = DATAFILE; /* Loading a footprint file as a layout */ if (yyPCB) { yyFont = &yyPCB->Font; yyData = yyPCB->Data; yyData->pcb = yyPCB; } /* e.g. loading data to a buffer */ else if (!yyData || !yyFont) { Message(_("PCB data not initialized! Cannot load data file\n")); YYABORT; } for (i = 0; i < MAX_ALL_LAYER; i++) LayerFlag[i] = false; yyData->LayerN = 0; } #line 2026 "parse_y.c" break; case 10: #line 262 "parse_y.y" { file_type = FONTFILE; } #line 2034 "parse_y.c" break; case 13: #line 270 "parse_y.y" { /* mark all symbols invalid */ int i; if (!yyFont) { Message(_("illegal file format\n")); YYABORT; } yyFont->Valid = false; for (i = 0; i <= MAX_FONTPOSITION; i++) free (yyFont->Symbol[i].Line); bzero(yyFont->Symbol, sizeof(yyFont->Symbol)); } #line 2053 "parse_y.c" break; case 14: #line 285 "parse_y.y" { yyFont->Valid = true; SetFontInfo(yyFont); } #line 2062 "parse_y.c" break; case 16: #line 313 "parse_y.y" { if (check_file_version ((yyvsp[-1].integer)) != 0) { YYABORT; } } #line 2073 "parse_y.c" break; case 17: #line 352 "parse_y.y" { yyPCB->Name = (yyvsp[-1].string); yyPCB->MaxWidth = MAX_COORD; yyPCB->MaxHeight = MAX_COORD; } #line 2083 "parse_y.c" break; case 18: #line 358 "parse_y.y" { yyPCB->Name = (yyvsp[-3].string); yyPCB->MaxWidth = OU ((yyvsp[-2].measure)); yyPCB->MaxHeight = OU ((yyvsp[-1].measure)); } #line 2093 "parse_y.c" break; case 19: #line 364 "parse_y.y" { yyPCB->Name = (yyvsp[-3].string); yyPCB->MaxWidth = NU ((yyvsp[-2].measure)); yyPCB->MaxHeight = NU ((yyvsp[-1].measure)); } #line 2103 "parse_y.c" break; case 23: #line 407 "parse_y.y" { yyPCB->Grid = OU ((yyvsp[-3].measure)); yyPCB->GridOffsetX = OU ((yyvsp[-2].measure)); yyPCB->GridOffsetY = OU ((yyvsp[-1].measure)); } #line 2113 "parse_y.c" break; case 24: #line 415 "parse_y.y" { yyPCB->Grid = OU ((yyvsp[-4].measure)); yyPCB->GridOffsetX = OU ((yyvsp[-3].measure)); yyPCB->GridOffsetY = OU ((yyvsp[-2].measure)); if ((yyvsp[-1].integer)) Settings.DrawGrid = true; else Settings.DrawGrid = false; } #line 2127 "parse_y.c" break; case 25: #line 428 "parse_y.y" { yyPCB->Grid = NU ((yyvsp[-4].measure)); yyPCB->GridOffsetX = NU ((yyvsp[-3].measure)); yyPCB->GridOffsetY = NU ((yyvsp[-2].measure)); if ((yyvsp[-1].integer)) Settings.DrawGrid = true; else Settings.DrawGrid = false; } #line 2141 "parse_y.c" break; case 26: #line 467 "parse_y.y" { yyPCB->CursorX = OU ((yyvsp[-3].measure)); yyPCB->CursorY = OU ((yyvsp[-2].measure)); } #line 2150 "parse_y.c" break; case 27: #line 472 "parse_y.y" { yyPCB->CursorX = NU ((yyvsp[-3].measure)); yyPCB->CursorY = NU ((yyvsp[-2].measure)); } #line 2159 "parse_y.c" break; case 30: #line 495 "parse_y.y" { /* Read in cmil^2 for now; in future this should be a noop. */ yyPCB->IsleArea = MIL_TO_COORD (MIL_TO_COORD ((yyvsp[-1].number)) / 100.0) / 100.0; } #line 2168 "parse_y.c" break; case 32: #line 522 "parse_y.y" { yyPCB->ThermScale = (yyvsp[-1].number); } #line 2176 "parse_y.c" break; case 37: #line 561 "parse_y.y" { yyPCB->Bloat = NU ((yyvsp[-3].measure)); yyPCB->Shrink = NU ((yyvsp[-2].measure)); yyPCB->minWid = NU ((yyvsp[-1].measure)); yyPCB->minRing = NU ((yyvsp[-1].measure)); } #line 2187 "parse_y.c" break; case 38: #line 571 "parse_y.y" { yyPCB->Bloat = NU ((yyvsp[-4].measure)); yyPCB->Shrink = NU ((yyvsp[-3].measure)); yyPCB->minWid = NU ((yyvsp[-2].measure)); yyPCB->minSlk = NU ((yyvsp[-1].measure)); yyPCB->minRing = NU ((yyvsp[-2].measure)); } #line 2199 "parse_y.c" break; case 39: #line 582 "parse_y.y" { yyPCB->Bloat = NU ((yyvsp[-6].measure)); yyPCB->Shrink = NU ((yyvsp[-5].measure)); yyPCB->minWid = NU ((yyvsp[-4].measure)); yyPCB->minSlk = NU ((yyvsp[-3].measure)); yyPCB->minDrill = NU ((yyvsp[-2].measure)); yyPCB->minRing = NU ((yyvsp[-1].measure)); } #line 2212 "parse_y.c" break; case 40: #line 609 "parse_y.y" { yyPCB->Flags = MakeFlags ((yyvsp[-1].integer) & PCB_FLAGS); } #line 2220 "parse_y.c" break; case 41: #line 613 "parse_y.y" { yyPCB->Flags = string_to_pcbflags ((yyvsp[-1].string), yyerror); free ((yyvsp[-1].string)); } #line 2229 "parse_y.c" break; case 43: #line 646 "parse_y.y" { if (ParseGroupString ((yyvsp[-1].string), &yyPCB->LayerGroups, &yyData->LayerN)) { Message(_("illegal layer-group string\n")); YYABORT; } free ((yyvsp[-1].string)); } #line 2242 "parse_y.c" break; case 45: #line 711 "parse_y.y" { if (ParseRouteString(((yyvsp[-1].string) == NULL ? "" : (yyvsp[-1].string)), &yyPCB->RouteStyle[0], "mil")) { Message(_("illegal route-style string\n")); YYABORT; } free ((yyvsp[-1].string)); } #line 2255 "parse_y.c" break; case 46: #line 720 "parse_y.y" { if (ParseRouteString(((yyvsp[-1].string) == NULL ? "" : (yyvsp[-1].string)), &yyPCB->RouteStyle[0], "cmil")) { Message(_("illegal route-style string\n")); YYABORT; } free ((yyvsp[-1].string)); } #line 2268 "parse_y.c" break; case 53: #line 743 "parse_y.y" { attr_list = & yyPCB->Attributes; } #line 2274 "parse_y.c" break; case 57: #line 746 "parse_y.y" { if ( file_type == DATAFILE ) { if (yyPCB != NULL) { /* This case is when we load a footprint with file->open, or from the command line */ yyFont = &yyPCB->Font; yyData = yyPCB->Data; yyData->pcb = yyPCB; yyData->LayerN = 0; } } } #line 2292 "parse_y.c" break; case 58: #line 760 "parse_y.y" { if (file_type == DATAFILE){ PCBType *pcb_save = PCB; ElementType *e; if (yyPCB != NULL) { /* This case is when we load a footprint with file->open, or from the command line */ CreateNewPCBPost (yyPCB, 0); ParseGroupString("1,c:2,s", &yyPCB->LayerGroups, &yyData->LayerN); e = yyPCB->Data->Element->data; /* we know there's only one */ PCB = yyPCB; MoveElementLowLevel (yyPCB->Data, e, -e->BoundingBox.X1, -e->BoundingBox.Y1); PCB = pcb_save; yyPCB->MaxWidth = e->BoundingBox.X2; yyPCB->MaxHeight = e->BoundingBox.Y2; yyPCB->is_footprint = 1; } } } #line 2316 "parse_y.c" break; case 65: #line 852 "parse_y.y" { CreateNewViaEx (yyData, NU ((yyvsp[-10].measure)), NU ((yyvsp[-9].measure)), NU ((yyvsp[-8].measure)), NU ((yyvsp[-7].measure)), NU ((yyvsp[-6].measure)), NU ((yyvsp[-5].measure)), (yyvsp[-2].string), (yyvsp[-1].flagtype), (yyvsp[-4].integer), (yyvsp[-3].integer)); free ((yyvsp[-2].string)); } #line 2326 "parse_y.c" break; case 66: #line 862 "parse_y.y" { CreateNewVia(yyData, NU ((yyvsp[-8].measure)), NU ((yyvsp[-7].measure)), NU ((yyvsp[-6].measure)), NU ((yyvsp[-5].measure)), NU ((yyvsp[-4].measure)), NU ((yyvsp[-3].measure)), (yyvsp[-2].string), (yyvsp[-1].flagtype)); free ((yyvsp[-2].string)); } #line 2336 "parse_y.c" break; case 67: #line 872 "parse_y.y" { CreateNewVia(yyData, OU ((yyvsp[-8].measure)), OU ((yyvsp[-7].measure)), OU ((yyvsp[-6].measure)), OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), OU ((yyvsp[-3].measure)), (yyvsp[-2].string), OldFlags((yyvsp[-1].integer))); free ((yyvsp[-2].string)); } #line 2346 "parse_y.c" break; case 68: #line 883 "parse_y.y" { CreateNewVia(yyData, OU ((yyvsp[-7].measure)), OU ((yyvsp[-6].measure)), OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), OU ((yyvsp[-5].measure)) + OU((yyvsp[-4].measure)), OU ((yyvsp[-3].measure)), (yyvsp[-2].string), OldFlags((yyvsp[-1].integer))); free ((yyvsp[-2].string)); } #line 2356 "parse_y.c" break; case 69: #line 893 "parse_y.y" { CreateNewVia(yyData, OU ((yyvsp[-6].measure)), OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), 2*GROUNDPLANEFRAME, OU((yyvsp[-4].measure)) + 2*MASKFRAME, OU ((yyvsp[-3].measure)), (yyvsp[-2].string), OldFlags((yyvsp[-1].integer))); free ((yyvsp[-2].string)); } #line 2366 "parse_y.c" break; case 70: #line 903 "parse_y.y" { Coord hole = (OU((yyvsp[-3].measure)) * DEFAULT_DRILLINGHOLE); CreateNewVia(yyData, OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), OU ((yyvsp[-3].measure)), 2*GROUNDPLANEFRAME, OU((yyvsp[-3].measure)) + 2*MASKFRAME, hole, (yyvsp[-2].string), OldFlags((yyvsp[-1].integer))); free ((yyvsp[-2].string)); } #line 2378 "parse_y.c" break; case 71: #line 943 "parse_y.y" { CreateNewRat(yyData, NU ((yyvsp[-7].measure)), NU ((yyvsp[-6].measure)), NU ((yyvsp[-4].measure)), NU ((yyvsp[-3].measure)), (yyvsp[-5].integer), (yyvsp[-2].integer), Settings.RatThickness, (yyvsp[-1].flagtype)); } #line 2387 "parse_y.c" break; case 72: #line 948 "parse_y.y" { CreateNewRat(yyData, OU ((yyvsp[-7].measure)), OU ((yyvsp[-6].measure)), OU ((yyvsp[-4].measure)), OU ((yyvsp[-3].measure)), (yyvsp[-5].integer), (yyvsp[-2].integer), Settings.RatThickness, OldFlags((yyvsp[-1].integer))); } #line 2396 "parse_y.c" break; case 73: #line 991 "parse_y.y" { if ((yyvsp[-4].integer) <= 0 || (yyvsp[-4].integer) > MAX_ALL_LAYER) { yyerror("Layernumber out of range"); YYABORT; } if (LayerFlag[(yyvsp[-4].integer)-1]) { yyerror("Layernumber used twice"); YYABORT; } Layer = &yyData->Layer[(yyvsp[-4].integer)-1]; /* memory for name is already allocated */ Layer->Name = (yyvsp[-3].string); if (Layer->Name == NULL) Layer->Name = strdup(""); LayerFlag[(yyvsp[-4].integer)-1] = true; if ((yyvsp[-2].string)) Layer->Type = string_to_layertype ((yyvsp[-2].string), yyerror); else Layer->Type = guess_layertype ((yyvsp[-3].string), (yyvsp[-4].integer), yyData); if ((yyvsp[-2].string) != NULL) free ((yyvsp[-2].string)); } #line 2426 "parse_y.c" break; case 85: #line 1038 "parse_y.y" { CreateNewPolygonFromRectangle(Layer, OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), OU ((yyvsp[-5].measure)) + OU ((yyvsp[-3].measure)), OU ((yyvsp[-4].measure)) + OU ((yyvsp[-2].measure)), OldFlags((yyvsp[-1].integer))); } #line 2435 "parse_y.c" break; case 89: #line 1045 "parse_y.y" { attr_list = & Layer->Attributes; } #line 2441 "parse_y.c" break; case 92: #line 1086 "parse_y.y" { CreateNewLineOnLayer(Layer, NU ((yyvsp[-7].measure)), NU ((yyvsp[-6].measure)), NU ((yyvsp[-5].measure)), NU ((yyvsp[-4].measure)), NU ((yyvsp[-3].measure)), NU ((yyvsp[-2].measure)), (yyvsp[-1].flagtype)); } #line 2450 "parse_y.c" break; case 93: #line 1095 "parse_y.y" { CreateNewLineOnLayer(Layer, OU ((yyvsp[-7].measure)), OU ((yyvsp[-6].measure)), OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), OU ((yyvsp[-3].measure)), OU ((yyvsp[-2].measure)), OldFlags((yyvsp[-1].integer))); } #line 2459 "parse_y.c" break; case 94: #line 1104 "parse_y.y" { /* eliminate old-style rat-lines */ if ((IV ((yyvsp[-1].measure)) & RATFLAG) == 0) CreateNewLineOnLayer(Layer, OU ((yyvsp[-6].measure)), OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), OU ((yyvsp[-3].measure)), OU ((yyvsp[-2].measure)), 200*GROUNDPLANEFRAME, OldFlags(IV ((yyvsp[-1].measure)))); } #line 2470 "parse_y.c" break; case 95: #line 1161 "parse_y.y" { CreateNewArcOnLayer(Layer, NU ((yyvsp[-9].measure)), NU ((yyvsp[-8].measure)), NU ((yyvsp[-7].measure)), NU ((yyvsp[-6].measure)), (yyvsp[-3].number), (yyvsp[-2].number), NU ((yyvsp[-5].measure)), NU ((yyvsp[-4].measure)), (yyvsp[-1].flagtype)); } #line 2479 "parse_y.c" break; case 96: #line 1170 "parse_y.y" { CreateNewArcOnLayer(Layer, OU ((yyvsp[-9].measure)), OU ((yyvsp[-8].measure)), OU ((yyvsp[-7].measure)), OU ((yyvsp[-6].measure)), (yyvsp[-3].number), (yyvsp[-2].number), OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), OldFlags((yyvsp[-1].integer))); } #line 2488 "parse_y.c" break; case 97: #line 1179 "parse_y.y" { CreateNewArcOnLayer(Layer, OU ((yyvsp[-8].measure)), OU ((yyvsp[-7].measure)), OU ((yyvsp[-6].measure)), OU ((yyvsp[-6].measure)), IV ((yyvsp[-3].measure)), (yyvsp[-2].number), OU ((yyvsp[-4].measure)), 200*GROUNDPLANEFRAME, OldFlags((yyvsp[-1].integer))); } #line 2497 "parse_y.c" break; case 98: #line 1225 "parse_y.y" { /* use a default scale of 100% */ CreateNewText(Layer,yyFont,OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), (yyvsp[-3].number), 100, (yyvsp[-2].string), OldFlags((yyvsp[-1].integer))); free ((yyvsp[-2].string)); } #line 2507 "parse_y.c" break; case 99: #line 1235 "parse_y.y" { if ((yyvsp[-1].integer) & ONSILKFLAG) { LayerType *lay = &yyData->Layer[yyData->LayerN + (((yyvsp[-1].integer) & ONSOLDERFLAG) ? BOTTOM_SILK_LAYER : TOP_SILK_LAYER)]; CreateNewText(lay ,yyFont, OU ((yyvsp[-6].measure)), OU ((yyvsp[-5].measure)), (yyvsp[-4].number), (yyvsp[-3].number), (yyvsp[-2].string), OldFlags((yyvsp[-1].integer))); } else CreateNewText(Layer, yyFont, OU ((yyvsp[-6].measure)), OU ((yyvsp[-5].measure)), (yyvsp[-4].number), (yyvsp[-3].number), (yyvsp[-2].string), OldFlags((yyvsp[-1].integer))); free ((yyvsp[-2].string)); } #line 2526 "parse_y.c" break; case 100: #line 1253 "parse_y.y" { /* FIXME: shouldn't know about .f */ /* I don't think this matters because anything with hi_format * will have the silk on its own layer in the file rather * than using the ONSILKFLAG and having it in a copper layer. * Thus there is no need for anything besides the 'else' * part of this code. */ if ((yyvsp[-1].flagtype).f & ONSILKFLAG) { LayerType *lay = &yyData->Layer[yyData->LayerN + (((yyvsp[-1].flagtype).f & ONSOLDERFLAG) ? BOTTOM_SILK_LAYER : TOP_SILK_LAYER)]; CreateNewText(lay, yyFont, NU ((yyvsp[-6].measure)), NU ((yyvsp[-5].measure)), (yyvsp[-4].number), (yyvsp[-3].number), (yyvsp[-2].string), (yyvsp[-1].flagtype)); } else CreateNewText(Layer, yyFont, NU ((yyvsp[-6].measure)), NU ((yyvsp[-5].measure)), (yyvsp[-4].number), (yyvsp[-3].number), (yyvsp[-2].string), (yyvsp[-1].flagtype)); free ((yyvsp[-2].string)); } #line 2550 "parse_y.c" break; case 101: #line 1316 "parse_y.y" { Polygon = CreateNewPolygon(Layer, (yyvsp[-2].flagtype)); } #line 2558 "parse_y.c" break; case 102: #line 1321 "parse_y.y" { Cardinal contour, contour_start, contour_end; bool bad_contour_found = false; /* ignore junk */ for (contour = 0; contour <= Polygon->HoleIndexN; contour++) { contour_start = (contour == 0) ? 0 : Polygon->HoleIndex[contour - 1]; contour_end = (contour == Polygon->HoleIndexN) ? Polygon->PointN : Polygon->HoleIndex[contour]; if (contour_end - contour_start < 3) bad_contour_found = true; } if (bad_contour_found) { Message(_("WARNING parsing file '%s'\n" " line: %i\n" " description: 'ignored polygon " "(< 3 points in a contour)'\n"), yyfilename, yylineno); DestroyObject(yyData, POLYGON_TYPE, Layer, Polygon, Polygon); } else { SetPolygonBoundingBox (Polygon); if (!Layer->polygon_tree) Layer->polygon_tree = r_create_tree (NULL, 0, 0); r_insert_entry (Layer->polygon_tree, (BoxType *) Polygon, 0); } } #line 2595 "parse_y.c" break; case 105: #line 1362 "parse_y.y" { CreateNewHoleInPolygon (Polygon); } #line 2603 "parse_y.c" break; case 109: #line 1376 "parse_y.y" { CreateNewPointInPolygon(Polygon, OU ((yyvsp[-2].measure)), OU ((yyvsp[-1].measure))); } #line 2611 "parse_y.c" break; case 110: #line 1380 "parse_y.y" { CreateNewPointInPolygon(Polygon, NU ((yyvsp[-2].measure)), NU ((yyvsp[-1].measure))); } #line 2619 "parse_y.c" break; case 116: #line 1462 "parse_y.y" { yyElement = CreateNewElement(yyData, yyFont, NoFlags(), (yyvsp[-6].string), (yyvsp[-5].string), NULL, OU ((yyvsp[-4].measure)), OU ((yyvsp[-3].measure)), (yyvsp[-2].integer), 100, NoFlags(), false); free ((yyvsp[-6].string)); free ((yyvsp[-5].string)); pin_num = 1; } #line 2631 "parse_y.c" break; case 117: #line 1470 "parse_y.y" { SetElementBoundingBox(yyData, yyElement, yyFont); } #line 2639 "parse_y.c" break; case 118: #line 1480 "parse_y.y" { yyElement = CreateNewElement(yyData, yyFont, OldFlags((yyvsp[-9].integer)), (yyvsp[-8].string), (yyvsp[-7].string), NULL, OU ((yyvsp[-6].measure)), OU ((yyvsp[-5].measure)), IV ((yyvsp[-4].measure)), IV ((yyvsp[-3].measure)), OldFlags((yyvsp[-2].integer)), false); free ((yyvsp[-8].string)); free ((yyvsp[-7].string)); pin_num = 1; } #line 2651 "parse_y.c" break; case 119: #line 1488 "parse_y.y" { SetElementBoundingBox(yyData, yyElement, yyFont); } #line 2659 "parse_y.c" break; case 120: #line 1498 "parse_y.y" { yyElement = CreateNewElement(yyData, yyFont, OldFlags((yyvsp[-10].integer)), (yyvsp[-9].string), (yyvsp[-8].string), (yyvsp[-7].string), OU ((yyvsp[-6].measure)), OU ((yyvsp[-5].measure)), IV ((yyvsp[-4].measure)), IV ((yyvsp[-3].measure)), OldFlags((yyvsp[-2].integer)), false); free ((yyvsp[-9].string)); free ((yyvsp[-8].string)); free ((yyvsp[-7].string)); pin_num = 1; } #line 2672 "parse_y.c" break; case 121: #line 1507 "parse_y.y" { SetElementBoundingBox(yyData, yyElement, yyFont); } #line 2680 "parse_y.c" break; case 122: #line 1518 "parse_y.y" { yyElement = CreateNewElement(yyData, yyFont, OldFlags((yyvsp[-12].integer)), (yyvsp[-11].string), (yyvsp[-10].string), (yyvsp[-9].string), OU ((yyvsp[-8].measure)) + OU ((yyvsp[-6].measure)), OU ((yyvsp[-7].measure)) + OU ((yyvsp[-5].measure)), (yyvsp[-4].number), (yyvsp[-3].number), OldFlags((yyvsp[-2].integer)), false); yyElement->MarkX = OU ((yyvsp[-8].measure)); yyElement->MarkY = OU ((yyvsp[-7].measure)); free ((yyvsp[-11].string)); free ((yyvsp[-10].string)); free ((yyvsp[-9].string)); } #line 2695 "parse_y.c" break; case 123: #line 1529 "parse_y.y" { SetElementBoundingBox(yyData, yyElement, yyFont); } #line 2703 "parse_y.c" break; case 124: #line 1540 "parse_y.y" { yyElement = CreateNewElement(yyData, yyFont, (yyvsp[-12].flagtype), (yyvsp[-11].string), (yyvsp[-10].string), (yyvsp[-9].string), NU ((yyvsp[-8].measure)) + NU ((yyvsp[-6].measure)), NU ((yyvsp[-7].measure)) + NU ((yyvsp[-5].measure)), (yyvsp[-4].number), (yyvsp[-3].number), (yyvsp[-2].flagtype), false); yyElement->MarkX = NU ((yyvsp[-8].measure)); yyElement->MarkY = NU ((yyvsp[-7].measure)); free ((yyvsp[-11].string)); free ((yyvsp[-10].string)); free ((yyvsp[-9].string)); } #line 2718 "parse_y.c" break; case 125: #line 1551 "parse_y.y" { SetElementBoundingBox(yyData, yyElement, yyFont); } #line 2726 "parse_y.c" break; case 133: #line 1652 "parse_y.y" { CreateNewLineInElement(yyElement, NU ((yyvsp[-5].measure)), NU ((yyvsp[-4].measure)), NU ((yyvsp[-3].measure)), NU ((yyvsp[-2].measure)), NU ((yyvsp[-1].measure))); } #line 2734 "parse_y.c" break; case 134: #line 1657 "parse_y.y" { CreateNewLineInElement(yyElement, OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), OU ((yyvsp[-3].measure)), OU ((yyvsp[-2].measure)), OU ((yyvsp[-1].measure))); } #line 2742 "parse_y.c" break; case 135: #line 1662 "parse_y.y" { CreateNewArcInElement(yyElement, NU ((yyvsp[-7].measure)), NU ((yyvsp[-6].measure)), NU ((yyvsp[-5].measure)), NU ((yyvsp[-4].measure)), (yyvsp[-3].number), (yyvsp[-2].number), NU ((yyvsp[-1].measure))); } #line 2750 "parse_y.c" break; case 136: #line 1667 "parse_y.y" { CreateNewArcInElement(yyElement, OU ((yyvsp[-7].measure)), OU ((yyvsp[-6].measure)), OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), (yyvsp[-3].number), (yyvsp[-2].number), OU ((yyvsp[-1].measure))); } #line 2758 "parse_y.c" break; case 137: #line 1672 "parse_y.y" { yyElement->MarkX = NU ((yyvsp[-2].measure)); yyElement->MarkY = NU ((yyvsp[-1].measure)); } #line 2767 "parse_y.c" break; case 138: #line 1677 "parse_y.y" { yyElement->MarkX = OU ((yyvsp[-2].measure)); yyElement->MarkY = OU ((yyvsp[-1].measure)); } #line 2776 "parse_y.c" break; case 139: #line 1681 "parse_y.y" { attr_list = & yyElement->Attributes; } #line 2782 "parse_y.c" break; case 149: #line 1698 "parse_y.y" { CreateNewLineInElement(yyElement, NU ((yyvsp[-5].measure)) + yyElement->MarkX, NU ((yyvsp[-4].measure)) + yyElement->MarkY, NU ((yyvsp[-3].measure)) + yyElement->MarkX, NU ((yyvsp[-2].measure)) + yyElement->MarkY, NU ((yyvsp[-1].measure))); } #line 2792 "parse_y.c" break; case 150: #line 1704 "parse_y.y" { CreateNewLineInElement(yyElement, OU ((yyvsp[-5].measure)) + yyElement->MarkX, OU ((yyvsp[-4].measure)) + yyElement->MarkY, OU ((yyvsp[-3].measure)) + yyElement->MarkX, OU ((yyvsp[-2].measure)) + yyElement->MarkY, OU ((yyvsp[-1].measure))); } #line 2802 "parse_y.c" break; case 151: #line 1711 "parse_y.y" { CreateNewArcInElement(yyElement, NU ((yyvsp[-7].measure)) + yyElement->MarkX, NU ((yyvsp[-6].measure)) + yyElement->MarkY, NU ((yyvsp[-5].measure)), NU ((yyvsp[-4].measure)), (yyvsp[-3].number), (yyvsp[-2].number), NU ((yyvsp[-1].measure))); } #line 2811 "parse_y.c" break; case 152: #line 1716 "parse_y.y" { CreateNewArcInElement(yyElement, OU ((yyvsp[-7].measure)) + yyElement->MarkX, OU ((yyvsp[-6].measure)) + yyElement->MarkY, OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), (yyvsp[-3].number), (yyvsp[-2].number), OU ((yyvsp[-1].measure))); } #line 2820 "parse_y.c" break; case 153: #line 1720 "parse_y.y" { attr_list = & yyElement->Attributes; } #line 2826 "parse_y.c" break; case 155: #line 1771 "parse_y.y" { CreateNewPin(yyElement, NU ((yyvsp[-9].measure)) + yyElement->MarkX, NU ((yyvsp[-8].measure)) + yyElement->MarkY, NU ((yyvsp[-7].measure)), NU ((yyvsp[-6].measure)), NU ((yyvsp[-5].measure)), NU ((yyvsp[-4].measure)), (yyvsp[-3].string), (yyvsp[-2].string), (yyvsp[-1].flagtype)); free ((yyvsp[-3].string)); free ((yyvsp[-2].string)); } #line 2838 "parse_y.c" break; case 156: #line 1783 "parse_y.y" { CreateNewPin(yyElement, OU ((yyvsp[-9].measure)) + yyElement->MarkX, OU ((yyvsp[-8].measure)) + yyElement->MarkY, OU ((yyvsp[-7].measure)), OU ((yyvsp[-6].measure)), OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), (yyvsp[-3].string), (yyvsp[-2].string), OldFlags((yyvsp[-1].integer))); free ((yyvsp[-3].string)); free ((yyvsp[-2].string)); } #line 2850 "parse_y.c" break; case 157: #line 1795 "parse_y.y" { CreateNewPin(yyElement, OU ((yyvsp[-7].measure)), OU ((yyvsp[-6].measure)), OU ((yyvsp[-5].measure)), 2*GROUNDPLANEFRAME, OU ((yyvsp[-5].measure)) + 2*MASKFRAME, OU ((yyvsp[-4].measure)), (yyvsp[-3].string), (yyvsp[-2].string), OldFlags((yyvsp[-1].integer))); free ((yyvsp[-3].string)); free ((yyvsp[-2].string)); } #line 2861 "parse_y.c" break; case 158: #line 1806 "parse_y.y" { char p_number[8]; sprintf(p_number, "%d", pin_num++); CreateNewPin(yyElement, OU ((yyvsp[-6].measure)), OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), 2*GROUNDPLANEFRAME, OU ((yyvsp[-4].measure)) + 2*MASKFRAME, OU ((yyvsp[-3].measure)), (yyvsp[-2].string), p_number, OldFlags((yyvsp[-1].integer))); free ((yyvsp[-2].string)); } #line 2875 "parse_y.c" break; case 159: #line 1822 "parse_y.y" { Coord hole = OU ((yyvsp[-3].measure)) * DEFAULT_DRILLINGHOLE; char p_number[8]; sprintf(p_number, "%d", pin_num++); CreateNewPin(yyElement, OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), OU ((yyvsp[-3].measure)), 2*GROUNDPLANEFRAME, OU ((yyvsp[-3].measure)) + 2*MASKFRAME, hole, (yyvsp[-2].string), p_number, OldFlags((yyvsp[-1].integer))); free ((yyvsp[-2].string)); } #line 2889 "parse_y.c" break; case 160: #line 1884 "parse_y.y" { CreateNewPad(yyElement, NU ((yyvsp[-10].measure)) + yyElement->MarkX, NU ((yyvsp[-9].measure)) + yyElement->MarkY, NU ((yyvsp[-8].measure)) + yyElement->MarkX, NU ((yyvsp[-7].measure)) + yyElement->MarkY, NU ((yyvsp[-6].measure)), NU ((yyvsp[-5].measure)), NU ((yyvsp[-4].measure)), (yyvsp[-3].string), (yyvsp[-2].string), (yyvsp[-1].flagtype)); free ((yyvsp[-3].string)); free ((yyvsp[-2].string)); } #line 2903 "parse_y.c" break; case 161: #line 1898 "parse_y.y" { Coord tx = NU ((yyvsp[-9].measure)), ty = NU ((yyvsp[-8].measure)), tw = NU ((yyvsp[-7].measure)), th = NU ((yyvsp[-6].measure)), thk, dx, dy; thk = (tw > th)?th:tw; dx = (tw > th)?((tw - th)/2):0; dy = (tw > th)?0:((th - tw)/2); CreateNewPad(yyElement, tx - dx + yyElement->MarkX, ty - dy + yyElement->MarkY, tx + dx + yyElement->MarkX, ty + dy + yyElement->MarkY, thk, NU ((yyvsp[-5].measure)), NU ((yyvsp[-4].measure)), (yyvsp[-3].string), (yyvsp[-2].string), (yyvsp[-1].flagtype)); free ((yyvsp[-3].string)); free ((yyvsp[-2].string)); } #line 2929 "parse_y.c" break; case 162: #line 1924 "parse_y.y" { CreateNewPad(yyElement,OU ((yyvsp[-10].measure)) + yyElement->MarkX, OU ((yyvsp[-9].measure)) + yyElement->MarkY, OU ((yyvsp[-8].measure)) + yyElement->MarkX, OU ((yyvsp[-7].measure)) + yyElement->MarkY, OU ((yyvsp[-6].measure)), OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), (yyvsp[-3].string), (yyvsp[-2].string), OldFlags((yyvsp[-1].integer))); free ((yyvsp[-3].string)); free ((yyvsp[-2].string)); } #line 2942 "parse_y.c" break; case 163: #line 1937 "parse_y.y" { Coord tx = OU ((yyvsp[-9].measure)), ty = OU ((yyvsp[-8].measure)), tw = OU ((yyvsp[-7].measure)), th = OU ((yyvsp[-6].measure)), thk, dx, dy; thk = (tw > th)?th:tw; dx = (tw > th)?((tw - th)/2):0; dy = (tw > th)?0:((th - tw)/2); CreateNewPad(yyElement, tx - dx + yyElement->MarkX, ty - dy + yyElement->MarkY, tx + dx + yyElement->MarkX, ty + dy + yyElement->MarkY, thk, OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), (yyvsp[-3].string), (yyvsp[-2].string), OldFlags((yyvsp[-1].integer))); free ((yyvsp[-3].string)); free ((yyvsp[-2].string)); } #line 2967 "parse_y.c" break; case 164: #line 1962 "parse_y.y" { CreateNewPad(yyElement,OU ((yyvsp[-8].measure)),OU ((yyvsp[-7].measure)),OU ((yyvsp[-6].measure)),OU ((yyvsp[-5].measure)),OU ((yyvsp[-4].measure)), 2*GROUNDPLANEFRAME, OU ((yyvsp[-4].measure)) + 2*MASKFRAME, (yyvsp[-3].string), (yyvsp[-2].string), OldFlags((yyvsp[-1].integer))); free ((yyvsp[-3].string)); free ((yyvsp[-2].string)); } #line 2978 "parse_y.c" break; case 165: #line 1973 "parse_y.y" { char p_number[8]; sprintf(p_number, "%d", pin_num++); CreateNewPad(yyElement,OU ((yyvsp[-7].measure)),OU ((yyvsp[-6].measure)),OU ((yyvsp[-5].measure)),OU ((yyvsp[-4].measure)),OU ((yyvsp[-3].measure)), 2*GROUNDPLANEFRAME, OU ((yyvsp[-3].measure)) + 2*MASKFRAME, (yyvsp[-2].string),p_number, OldFlags((yyvsp[-1].integer))); free ((yyvsp[-2].string)); } #line 2991 "parse_y.c" break; case 166: #line 1983 "parse_y.y" { (yyval.flagtype) = OldFlags((yyvsp[0].integer)); } #line 2997 "parse_y.c" break; case 167: #line 1984 "parse_y.y" { (yyval.flagtype) = string_to_flags ((yyvsp[0].string), yyerror); free((yyvsp[0].string)); } #line 3003 "parse_y.c" break; case 171: #line 2025 "parse_y.y" { if ((yyvsp[-3].integer) <= 0 || (yyvsp[-3].integer) > MAX_FONTPOSITION) { yyerror("fontposition out of range"); YYABORT; } Symbol = &yyFont->Symbol[(yyvsp[-3].integer)]; if (Symbol->Valid) { yyerror("symbol ID used twice"); YYABORT; } Symbol->Valid = true; Symbol->Delta = NU ((yyvsp[-2].measure)); } #line 3023 "parse_y.c" break; case 172: #line 2041 "parse_y.y" { if ((yyvsp[-3].integer) <= 0 || (yyvsp[-3].integer) > MAX_FONTPOSITION) { yyerror("fontposition out of range"); YYABORT; } Symbol = &yyFont->Symbol[(yyvsp[-3].integer)]; if (Symbol->Valid) { yyerror("symbol ID used twice"); YYABORT; } Symbol->Valid = true; Symbol->Delta = OU ((yyvsp[-2].measure)); } #line 3043 "parse_y.c" break; case 178: #line 2097 "parse_y.y" { CreateNewLineInSymbol(Symbol, OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), OU ((yyvsp[-3].measure)), OU ((yyvsp[-2].measure)), OU ((yyvsp[-1].measure))); } #line 3051 "parse_y.c" break; case 179: #line 2104 "parse_y.y" { CreateNewLineInSymbol(Symbol, NU ((yyvsp[-5].measure)), NU ((yyvsp[-4].measure)), NU ((yyvsp[-3].measure)), NU ((yyvsp[-2].measure)), NU ((yyvsp[-1].measure))); } #line 3059 "parse_y.c" break; case 187: #line 2158 "parse_y.y" { Menu = CreateNewNet(&yyPCB->NetlistLib, (yyvsp[-3].string), (yyvsp[-2].string)); free ((yyvsp[-3].string)); free ((yyvsp[-2].string)); } #line 3069 "parse_y.c" break; case 193: #line 2193 "parse_y.y" { CreateNewConnection(Menu, (yyvsp[-1].string)); free ((yyvsp[-1].string)); } #line 3078 "parse_y.c" break; case 194: #line 2252 "parse_y.y" { CreateNewAttribute (attr_list, (yyvsp[-2].string), (yyvsp[-1].string) ? (yyvsp[-1].string) : (char *)""); free ((yyvsp[-2].string)); free ((yyvsp[-1].string)); } #line 3088 "parse_y.c" break; case 195: #line 2259 "parse_y.y" { (yyval.string) = (yyvsp[0].string); } #line 3094 "parse_y.c" break; case 196: #line 2260 "parse_y.y" { (yyval.string) = 0; } #line 3100 "parse_y.c" break; case 197: #line 2264 "parse_y.y" { (yyval.number) = (yyvsp[0].number); } #line 3106 "parse_y.c" break; case 198: #line 2265 "parse_y.y" { (yyval.number) = (yyvsp[0].integer); } #line 3112 "parse_y.c" break; case 199: #line 2270 "parse_y.y" { do_measure(&(yyval.measure), (yyvsp[0].number), MIL_TO_COORD ((yyvsp[0].number)) / 100.0, 0); } #line 3118 "parse_y.c" break; case 200: #line 2271 "parse_y.y" { M ((yyval.measure), (yyvsp[-1].number), MIL_TO_COORD ((yyvsp[-1].number)) / 1000000.0); } #line 3124 "parse_y.c" break; case 201: #line 2272 "parse_y.y" { M ((yyval.measure), (yyvsp[-1].number), MIL_TO_COORD ((yyvsp[-1].number)) / 100.0); } #line 3130 "parse_y.c" break; case 202: #line 2273 "parse_y.y" { M ((yyval.measure), (yyvsp[-1].number), MIL_TO_COORD ((yyvsp[-1].number))); } #line 3136 "parse_y.c" break; case 203: #line 2274 "parse_y.y" { M ((yyval.measure), (yyvsp[-1].number), INCH_TO_COORD ((yyvsp[-1].number))); } #line 3142 "parse_y.c" break; case 204: #line 2275 "parse_y.y" { M ((yyval.measure), (yyvsp[-1].number), MM_TO_COORD ((yyvsp[-1].number)) / 1000000.0); } #line 3148 "parse_y.c" break; case 205: #line 2276 "parse_y.y" { M ((yyval.measure), (yyvsp[-1].number), MM_TO_COORD ((yyvsp[-1].number)) / 1000000.0); } #line 3154 "parse_y.c" break; case 206: #line 2277 "parse_y.y" { M ((yyval.measure), (yyvsp[-1].number), MM_TO_COORD ((yyvsp[-1].number)) / 1000.0); } #line 3160 "parse_y.c" break; case 207: #line 2278 "parse_y.y" { M ((yyval.measure), (yyvsp[-1].number), MM_TO_COORD ((yyvsp[-1].number))); } #line 3166 "parse_y.c" break; case 208: #line 2279 "parse_y.y" { M ((yyval.measure), (yyvsp[-1].number), MM_TO_COORD ((yyvsp[-1].number)) * 1000.0); } #line 3172 "parse_y.c" break; case 209: #line 2280 "parse_y.y" { M ((yyval.measure), (yyvsp[-1].number), MM_TO_COORD ((yyvsp[-1].number)) * 1000000.0); } #line 3178 "parse_y.c" break; #line 3182 "parse_y.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires that yytoken be updated with the new translation. We take the approach of translating immediately before every use of yytoken. One alternative is translating here after every semantic action, but that translation would be missed if the semantic action invokes YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an incorrect destructor might then be invoked immediately. In the case of YYERROR or YYBACKUP, subsequent parser actions might lead to an incorrect destructor call or verbose syntax error message before the lookahead is translated. */ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ { const int yylhs = yyr1[yyn] - YYNTOKENS; const int yyi = yypgoto[yylhs] + *yyssp; yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp ? yytable[yyi] : yydefgoto[yylhs]); } goto yynewstate; /*--------------------------------------. | yyerrlab -- here on detecting error. | `--------------------------------------*/ yyerrlab: /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (YY_("syntax error")); #else # define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ yyssp, yytoken) { char const *yymsgp = YY_("syntax error"); int yysyntax_error_status; yysyntax_error_status = YYSYNTAX_ERROR; if (yysyntax_error_status == 0) yymsgp = yymsg; else if (yysyntax_error_status == 1) { if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = YY_CAST (char *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, yymsg_alloc))); if (!yymsg) { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; yysyntax_error_status = 2; } else { yysyntax_error_status = YYSYNTAX_ERROR; yymsgp = yymsg; } } yyerror (yymsgp); if (yysyntax_error_status == 2) goto yyexhaustedlab; } # undef YYSYNTAX_ERROR #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval); yychar = YYEMPTY; } } /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (0) YYERROR; /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (!yypact_value_is_default (yyn)) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", yystos[yystate], yyvsp); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #if !defined yyoverflow || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif /*-----------------------------------------------------. | yyreturn -- parsing is finished, return the result. | `-----------------------------------------------------*/ yyreturn: if (yychar != YYEMPTY) { /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = YYTRANSLATE (yychar); yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval); } /* Do not reclaim the symbols of the rule whose action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[+*yyssp], yyvsp); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif return yyresult; } #line 2283 "parse_y.y" /* --------------------------------------------------------------------------- * error routine called by parser library */ int yyerror(const char * s) { Message(_("ERROR parsing file '%s'\n" " line: %i\n" " description: '%s'\n"), yyfilename, yylineno, s); return(0); } int yywrap() { return 1; } static int check_file_version (int ver) { if ( ver > PCB_FILE_VERSION ) { Message (_("ERROR: The file you are attempting to load is in a format\n" "which is too new for this version of pcb. To load this file\n" "you need a version of pcb which is >= %d. If you are\n" "using a version built from git source, the source date\n" "must be >= %d. This copy of pcb can only read files\n" "up to file version %d.\n"), ver, ver, PCB_FILE_VERSION); return 1; } return 0; } static void do_measure (PLMeasure *m, Coord i, double d, int u) { m->ival = i; m->bval = round (d); m->dval = d; m->has_units = u; } static int integer_value (PLMeasure m) { if (m.has_units) yyerror("units ignored here"); return m.ival; } static Coord old_units (PLMeasure m) { if (m.has_units) return m.bval; return round (MIL_TO_COORD (m.ival)); } static Coord new_units (PLMeasure m) { if (m.has_units) return m.bval; return round (MIL_TO_COORD (m.ival) / 100.0); } pcb-4.3.0/src/draw.c0000664000175000017500000012165414016760750011114 00000000000000/*! * \file src/draw.c * * \brief Drawing routines. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996, 2003, 2004 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * Thomas.Nau@rz.uni-ulm.de */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "global.h" #include "hid_draw.h" /*#include "clip.h"*/ #include "compat.h" #include "crosshair.h" #include "data.h" #include "draw.h" #include "error.h" #include "mymem.h" #include "misc.h" #include "rotate.h" #include "rtree.h" #include "search.h" #include "select.h" #include "print.h" #ifdef HAVE_LIBDMALLOC #include #endif #undef NDEBUG #include #ifndef MAXINT #define MAXINT (((unsigned int)(~0))>>1) #endif #define SMALL_SMALL_TEXT_SIZE 0 #define SMALL_TEXT_SIZE 1 #define NORMAL_TEXT_SIZE 2 #define LARGE_TEXT_SIZE 3 #define N_TEXT_SIZES 4 /* --------------------------------------------------------------------------- * some local identifiers */ static BoxType Block = {MAXINT, MAXINT, -MAXINT, -MAXINT}; static int doing_pinout = 0; static bool doing_assy = false; static int current_layergroup; /* used by via_callback */ /* --------------------------------------------------------------------------- * some local prototypes */ static void DrawEverything (const BoxType *); static void DrawPPV (int group, const BoxType *); static void AddPart (void *); static void DrawEMark (ElementType *, Coord, Coord, bool); static void DrawRats (const BoxType *); static void set_object_color (AnyObjectType *obj, char *warn_color, char *selected_color, char *connected_color, char *found_color, char *normal_color) { char *color; if (warn_color != NULL && TEST_FLAG (WARNFLAG, obj)) color = warn_color; else if (selected_color != NULL && TEST_FLAG (SELECTEDFLAG, obj)) color = selected_color; else if (connected_color != NULL && TEST_FLAG (CONNECTEDFLAG, obj)) color = connected_color; else if (found_color != NULL && TEST_FLAG (FOUNDFLAG, obj)) color = found_color; else color = normal_color; gui->graphics->set_color (Output.fgGC, color); } static void set_layer_object_color (LayerType *layer, AnyObjectType *obj) { set_object_color (obj, NULL, layer->SelectedColor, PCB->ConnectedColor, PCB->FoundColor, layer->Color); } /*! * \brief Adds the update rect to the update region. */ static void AddPart (void *b) { BoxType *box = (BoxType *) b; Block.X1 = MIN (Block.X1, box->X1); Block.X2 = MAX (Block.X2, box->X2); Block.Y1 = MIN (Block.Y1, box->Y1); Block.Y2 = MAX (Block.Y2, box->Y2); } /*! * \brief Initiate the actual redrawing of the updated area. */ void Draw (void) { if (Block.X1 <= Block.X2 && Block.Y1 <= Block.Y2) gui->invalidate_lr (Block.X1, Block.X2, Block.Y1, Block.Y2); /* shrink the update block */ Block.X1 = Block.Y1 = MAXINT; Block.X2 = Block.Y2 = -MAXINT; } /*! * \brief Redraws all the data by the event handlers. */ void Redraw (void) { gui->invalidate_all (); } static void _draw_pv_name (PinType *pv) { BoxType box; bool vert; TextType text; if (!pv->Name || !pv->Name[0]) text.TextString = EMPTY (pv->Number); else text.TextString = EMPTY (TEST_FLAG (SHOWNUMBERFLAG, PCB) ? pv->Number : pv->Name); vert = TEST_FLAG (EDGE2FLAG, pv); if (vert) { box.X1 = pv->X - pv->Thickness / 2 + Settings.PinoutTextOffsetY; box.Y1 = pv->Y - pv->DrillingHole / 2 - Settings.PinoutTextOffsetX; } else { box.X1 = pv->X + pv->DrillingHole / 2 + Settings.PinoutTextOffsetX; box.Y1 = pv->Y - pv->Thickness / 2 + Settings.PinoutTextOffsetY; } gui->graphics->set_color (Output.fgGC, PCB->PinNameColor); text.Flags = NoFlags (); /* Set font height to approx 56% of pin thickness */ text.Scale = 56 * pv->Thickness / FONT_CAPHEIGHT; text.X = box.X1; text.Y = box.Y1; text.Direction = vert ? 1 : 0; if (gui->gui) doing_pinout++; gui->graphics->draw_pcb_text (Output.fgGC, &text, 0); if (gui->gui) doing_pinout--; } static void _draw_pv (PinType *pv, bool draw_hole) { if (TEST_FLAG (THINDRAWFLAG, PCB)) gui->graphics->thindraw_pcb_pv (Output.fgGC, Output.fgGC, pv, draw_hole, false); else if (!ViaIsOnAnyVisibleLayer (pv)) gui->graphics->thindraw_pcb_pv (Output.fgGC, Output.fgGC, pv, false, false); else { gui->graphics->fill_pcb_pv (Output.fgGC, Output.bgGC, pv, draw_hole, false); if (gui->gui && VIA_IS_BURIED (pv) && !(TEST_FLAG (SELECTEDFLAG, pv) || TEST_FLAG (CONNECTEDFLAG, pv) || TEST_FLAG (FOUNDFLAG, pv))) { int w = (pv->Thickness - pv->DrillingHole) / 4; int r = pv->DrillingHole / 2 + w / 2; gui->graphics->set_line_cap (Output.fgGC, Square_Cap); gui->graphics->set_color (Output.fgGC, PCB->Data->Layer[pv->BuriedFrom].Color); gui->graphics->set_line_width (Output.fgGC, w); gui->graphics->draw_arc (Output.fgGC, pv->X, pv->Y, r, r, 270, 180); gui->graphics->set_color (Output.fgGC, PCB->Data->Layer[pv->BuriedTo].Color); gui->graphics->set_line_width (Output.fgGC, w); gui->graphics->draw_arc (Output.fgGC, pv->X, pv->Y, r, r, 90, 180); } } if ((!TEST_FLAG (HOLEFLAG, pv) && TEST_FLAG (DISPLAYNAMEFLAG, pv)) || doing_pinout) _draw_pv_name (pv); } static void draw_pin (PinType *pin, bool draw_hole) { if (doing_pinout) gui->graphics->set_color (Output.fgGC, PCB->PinColor); else set_object_color ((AnyObjectType *)pin, PCB->WarnColor, PCB->PinSelectedColor, PCB->ConnectedColor, PCB->FoundColor, PCB->PinColor); _draw_pv (pin, draw_hole); } static int pin_callback (const BoxType * b, void *cl) { draw_pin ((PinType *)b, false); return 1; } static void draw_via (PinType *via, bool draw_hole) { if (doing_pinout) gui->graphics->set_color (Output.fgGC, PCB->ViaColor); else set_object_color ((AnyObjectType *)via, PCB->WarnColor, PCB->ViaSelectedColor, PCB->ConnectedColor, PCB->FoundColor, PCB->ViaColor); _draw_pv (via, draw_hole); } static bool via_visible_on_layer_group (PinType *via) { if (current_layergroup == -1) return true; else return ViaIsOnLayerGroup (via, current_layergroup); } static int via_callback (const BoxType * b, void *cl) { PinType *via = (PinType *)b; if (via_visible_on_layer_group (via)) draw_via (via, false); return 1; } static void draw_pad_name (PadType *pad) { BoxType box; bool vert; TextType text; if (!pad->Name || !pad->Name[0]) text.TextString = EMPTY (pad->Number); else text.TextString = EMPTY (TEST_FLAG (SHOWNUMBERFLAG, PCB) ? pad->Number : pad->Name); /* should text be vertical ? */ vert = (pad->Point1.X == pad->Point2.X); if (vert) { box.X1 = pad->Point1.X - pad->Thickness / 2; box.Y1 = MAX (pad->Point1.Y, pad->Point2.Y) + pad->Thickness / 2; box.X1 += Settings.PinoutTextOffsetY; box.Y1 -= Settings.PinoutTextOffsetX; } else { box.X1 = MIN (pad->Point1.X, pad->Point2.X) - pad->Thickness / 2; box.Y1 = pad->Point1.Y - pad->Thickness / 2; box.X1 += Settings.PinoutTextOffsetX; box.Y1 += Settings.PinoutTextOffsetY; } gui->graphics->set_color (Output.fgGC, PCB->PinNameColor); text.Flags = NoFlags (); /* Set font height to approx 90% of pin thickness */ text.Scale = 90 * pad->Thickness / FONT_CAPHEIGHT; text.X = box.X1; text.Y = box.Y1; text.Direction = vert ? 1 : 0; gui->graphics->draw_pcb_text (Output.fgGC, &text, 0); } static void _draw_pad (hidGC gc, PadType *pad, bool clear, bool mask) { if (clear && !mask && pad->Clearance <= 0) return; if (TEST_FLAG (THINDRAWFLAG, PCB) || (clear && TEST_FLAG (THINDRAWPOLYFLAG, PCB))) gui->graphics->thindraw_pcb_pad (gc, pad, clear, mask); else gui->graphics->fill_pcb_pad (gc, pad, clear, mask); } static void draw_pad (PadType *pad) { if (doing_pinout) gui->graphics->set_color (Output.fgGC, PCB->PinColor); else set_object_color ((AnyObjectType *)pad, PCB->WarnColor, PCB->PinSelectedColor, PCB->ConnectedColor, PCB->FoundColor, FRONT (pad) ? PCB->PinColor : PCB->InvisibleObjectsColor); _draw_pad (Output.fgGC, pad, false, false); if (doing_pinout || TEST_FLAG (DISPLAYNAMEFLAG, pad)) draw_pad_name (pad); } static int pad_callback (const BoxType * b, void *cl) { PadType *pad = (PadType *) b; int *side = cl; if (ON_SIDE (pad, *side)) draw_pad (pad); return 1; } static void draw_element_name (ElementType *element) { if ((TEST_FLAG (HIDENAMESFLAG, PCB) && gui->gui) || TEST_FLAG (HIDENAMEFLAG, element)) return; if (doing_pinout || doing_assy) gui->graphics->set_color (Output.fgGC, PCB->ElementColor); else if (TEST_FLAG (SELECTEDFLAG, &ELEMENT_TEXT (PCB, element))) gui->graphics->set_color (Output.fgGC, PCB->ElementSelectedColor); else if (FRONT (element)) gui->graphics->set_color (Output.fgGC, PCB->ElementColor); else gui->graphics->set_color (Output.fgGC, PCB->InvisibleObjectsColor); gui->graphics->draw_pcb_text (Output.fgGC, &ELEMENT_TEXT (PCB, element), PCB->minSlk); } static int name_callback (const BoxType * b, void *cl) { TextType *text = (TextType *) b; ElementType *element = (ElementType *) text->Element; int *side = cl; if (TEST_FLAG (HIDENAMEFLAG, element)) return 0; if (ON_SIDE (element, *side)) draw_element_name (element); return 0; } static void draw_element_pins_and_pads (ElementType *element) { PAD_LOOP (element); { if (doing_pinout || doing_assy || FRONT (pad) || PCB->InvisibleObjectsOn) draw_pad (pad); } END_LOOP; PIN_LOOP (element); { draw_pin (pin, true); } END_LOOP; } static int EMark_callback (const BoxType * b, void *cl) { ElementType *element = (ElementType *) b; DrawEMark (element, element->MarkX, element->MarkY, !FRONT (element)); return 1; } typedef struct { int plated; bool drill_pair; Cardinal group_from; Cardinal group_to; } hole_info; static int hole_callback (const BoxType * b, void *cl) { hole_info his = {-1, false, 0, 0}; hole_info *hi = &his; PinType *pv = (PinType *) b; if (cl) hi = (hole_info *)cl; if (hi->drill_pair) { if (hi->group_from != 0 || hi->group_to != 0) { if (VIA_IS_BURIED (pv)) { if (hi->group_from == GetLayerGroupNumberByNumber (pv->BuriedFrom) && hi->group_to == GetLayerGroupNumberByNumber (pv->BuriedTo)) goto via_ok; } } else if (!VIA_IS_BURIED (pv)) goto via_ok; return 1; } via_ok: if ((hi->plated == 0 && !TEST_FLAG (HOLEFLAG, pv)) || (hi->plated == 1 && TEST_FLAG (HOLEFLAG, pv))) return 1; if (!via_visible_on_layer_group (pv)) return 1; if (TEST_FLAG (THINDRAWFLAG, PCB)) { if (!TEST_FLAG (HOLEFLAG, pv)) { gui->graphics->set_line_cap (Output.fgGC, Round_Cap); gui->graphics->set_line_width (Output.fgGC, 0); gui->graphics->draw_arc (Output.fgGC, pv->X, pv->Y, pv->DrillingHole / 2, pv->DrillingHole / 2, 0, 360); } } else if (ViaIsOnAnyVisibleLayer (pv)) gui->graphics->fill_circle (Output.bgGC, pv->X, pv->Y, pv->DrillingHole / 2); else { gui->graphics->set_line_cap (Output.fgGC, Round_Cap); gui->graphics->set_line_width (Output.fgGC, 0); gui->graphics->draw_arc (Output.fgGC, pv->X, pv->Y, pv->DrillingHole / 2, pv->DrillingHole / 2, 0, 360); } if (TEST_FLAG (HOLEFLAG, pv)) { set_object_color ((AnyObjectType *) pv, PCB->WarnColor, PCB->ViaSelectedColor, NULL, NULL, Settings.BlackColor); gui->graphics->set_line_cap (Output.fgGC, Round_Cap); gui->graphics->set_line_width (Output.fgGC, 0); gui->graphics->draw_arc (Output.fgGC, pv->X, pv->Y, pv->DrillingHole / 2, pv->DrillingHole / 2, 0, 360); } return 1; } void DrawHoles (bool draw_plated, bool draw_unplated, const BoxType *drawn_area, Cardinal g_from, Cardinal g_to) { hole_info hi = {-1, true, g_from, g_to}; if ( draw_plated && !draw_unplated) hi.plated = 1; if (!draw_plated && draw_unplated) hi.plated = 0; current_layergroup = -1; r_search (PCB->Data->pin_tree, drawn_area, NULL, hole_callback, &hi); r_search (PCB->Data->via_tree, drawn_area, NULL, hole_callback, &hi); } static int line_callback (const BoxType * b, void *cl) { LayerType *layer = (LayerType *) cl; LineType *line = (LineType *) b; set_layer_object_color (layer, (AnyObjectType *) line); gui->graphics->draw_pcb_line (Output.fgGC, line); return 1; } static int rat_callback (const BoxType * b, void *cl) { RatType *rat = (RatType *)b; set_object_color ((AnyObjectType *) rat, NULL, PCB->RatSelectedColor, PCB->ConnectedColor, PCB->FoundColor, PCB->RatColor); if (Settings.RatThickness < 100) rat->Thickness = pixel_slop * Settings.RatThickness; /* rats.c set VIAFLAG if this rat goes to a containing poly: draw a donut */ if (TEST_FLAG(VIAFLAG, rat)) { int w = rat->Thickness; if (TEST_FLAG (THINDRAWFLAG, PCB)) gui->graphics->set_line_width (Output.fgGC, 0); else gui->graphics->set_line_width (Output.fgGC, w); gui->graphics->draw_arc (Output.fgGC, rat->Point1.X, rat->Point1.Y, w * 2, w * 2, 0, 360); } else gui->graphics->draw_pcb_line (Output.fgGC, (LineType *) rat); return 1; } static int arc_callback (const BoxType * b, void *cl) { LayerType *layer = (LayerType *) cl; ArcType *arc = (ArcType *) b; set_layer_object_color (layer, (AnyObjectType *) arc); gui->graphics->draw_pcb_arc (Output.fgGC, arc); return 1; } static void draw_element_package (ElementType *element) { /* set color and draw lines, arcs, text and pins */ if (doing_pinout || doing_assy) gui->graphics->set_color (Output.fgGC, PCB->ElementColor); else if (TEST_FLAG (SELECTEDFLAG, element)) gui->graphics->set_color (Output.fgGC, PCB->ElementSelectedColor); else if (FRONT (element)) gui->graphics->set_color (Output.fgGC, PCB->ElementColor); else gui->graphics->set_color (Output.fgGC, PCB->InvisibleObjectsColor); /* draw lines, arcs, text and pins */ ELEMENTLINE_LOOP (element); { gui->graphics->draw_pcb_line (Output.fgGC, line); } END_LOOP; ARC_LOOP (element); { gui->graphics->draw_pcb_arc (Output.fgGC, arc); } END_LOOP; } static int element_callback (const BoxType * b, void *cl) { ElementType *element = (ElementType *) b; int *side = cl; if (ON_SIDE (element, *side)) draw_element_package (element); return 1; } /*! * \brief Prints assembly drawing. */ void PrintAssembly (int side, const BoxType * drawn_area) { int side_group = GetLayerGroupNumberBySide (side); doing_assy = true; gui->graphics->set_draw_faded (Output.fgGC, 1); DrawLayerGroup (side_group, drawn_area); gui->graphics->set_draw_faded (Output.fgGC, 0); /* draw package */ DrawSilk (side, drawn_area); doing_assy = false; } /*! * \brief Initializes some identifiers for a new zoom factor and redraws * whole screen. */ static void DrawEverything (const BoxType *drawn_area) { int i, ngroups, side; int top_group, bottom_group; /* This is the list of layer groups we will draw. */ int do_group[MAX_GROUP]; /* This is the reverse of the order in which we draw them. */ int drawn_groups[MAX_GROUP]; int plated, unplated; bool paste_empty; int g_from, g_to; char s[22]; PCB->Data->SILKLAYER.Color = PCB->ElementColor; PCB->Data->BACKSILKLAYER.Color = PCB->InvisibleObjectsColor; memset (do_group, 0, sizeof (do_group)); for (ngroups = 0, i = 0; i < max_copper_layer; i++) { LayerType *l = LAYER_ON_STACK (i); int group = GetLayerGroupNumberByNumber (LayerStack[i]); if (l->On && !do_group[group]) { do_group[group] = 1; drawn_groups[ngroups++] = group; } } top_group = GetLayerGroupNumberBySide (TOP_SIDE); bottom_group = GetLayerGroupNumberBySide (BOTTOM_SIDE); /* * first draw all 'invisible' stuff */ if (!TEST_FLAG (CHECKPLANESFLAG, PCB) && gui->set_layer ("invisible", SL (INVISIBLE, 0), 0)) { side = SWAP_IDENT ? TOP_SIDE : BOTTOM_SIDE; if (PCB->ElementOn) { r_search (PCB->Data->element_tree, drawn_area, NULL, element_callback, &side); r_search (PCB->Data->name_tree[NAME_INDEX (PCB)], drawn_area, NULL, name_callback, &side); DrawLayer (&(PCB->Data->Layer[max_copper_layer + side]), drawn_area); } r_search (PCB->Data->pad_tree, drawn_area, NULL, pad_callback, &side); gui->end_layer (); } /* draw all layers in layerstack order */ for (i = ngroups - 1; i >= 0; i--) { int group = drawn_groups[i]; if (gui->set_layer (0, group, 0)) { DrawLayerGroup (group, drawn_area); gui->end_layer (); } } if (TEST_FLAG (CHECKPLANESFLAG, PCB) && gui->gui) return; /* Draw pins, pads, vias below silk */ if (gui->gui) DrawPPV (SWAP_IDENT ? bottom_group : top_group, drawn_area); else { CountHoles (&plated, &unplated, drawn_area); if (plated && gui->set_layer ("plated-drill", SL (PDRILL, 0), 0)) { DrawHoles (true, false, drawn_area, 0, 0); gui->end_layer (); } if (unplated && gui->set_layer ("unplated-drill", SL (UDRILL, 0), 0)) { DrawHoles (false, true, drawn_area, 0, 0); gui->end_layer (); } for (g_from = 0; g_from < (max_group - 1); g_from++) for (g_to = g_from+1 ; g_to < max_group; g_to++ ) { CountHolesEx (&plated, &unplated, drawn_area, g_from, g_to); sprintf (s, "plated-drill_%02d-%02d", g_from+1, g_to+1); if (plated && gui->set_layer (s, SL (PDRILL, 0), 0)) { DrawHoles (true, false, drawn_area, g_from, g_to); gui->end_layer (); } sprintf (s, "unplated-drill_%02d-%02d", g_from+1, g_to+1); if (unplated && gui->set_layer (s, SL (UDRILL, 0), 0)) { DrawHoles (false, true, drawn_area, g_from, g_to); gui->end_layer (); } } } /* Draw the solder mask if turned on */ if (gui->set_layer ("componentmask", SL (MASK, TOP), 0)) { DrawMask (TOP_SIDE, drawn_area); gui->end_layer (); } if (gui->set_layer ("soldermask", SL (MASK, BOTTOM), 0)) { DrawMask (BOTTOM_SIDE, drawn_area); gui->end_layer (); } if (gui->set_layer ("topsilk", SL (SILK, TOP), 0)) { DrawSilk (TOP_SIDE, drawn_area); gui->end_layer (); } if (gui->set_layer ("bottomsilk", SL (SILK, BOTTOM), 0)) { DrawSilk (BOTTOM_SIDE, drawn_area); gui->end_layer (); } if (gui->gui) { /* Draw element Marks */ if (PCB->PinOn) r_search (PCB->Data->element_tree, drawn_area, NULL, EMark_callback, NULL); /* Draw rat lines on top */ if (gui->set_layer ("rats", SL (RATS, 0), 0)) { DrawRats(drawn_area); gui->end_layer (); } } paste_empty = IsPasteEmpty (TOP_SIDE); if (gui->set_layer ("toppaste", SL (PASTE, TOP), paste_empty)) { DrawPaste (TOP_SIDE, drawn_area); gui->end_layer (); } paste_empty = IsPasteEmpty (BOTTOM_SIDE); if (gui->set_layer ("bottompaste", SL (PASTE, BOTTOM), paste_empty)) { DrawPaste (BOTTOM_SIDE, drawn_area); gui->end_layer (); } if (gui->set_layer ("topassembly", SL (ASSY, TOP), 0)) { PrintAssembly (TOP_SIDE, drawn_area); gui->end_layer (); } if (gui->set_layer ("bottomassembly", SL (ASSY, BOTTOM), 0)) { PrintAssembly (BOTTOM_SIDE, drawn_area); gui->end_layer (); } if (gui->set_layer ("fab", SL (FAB, 0), 0)) { PrintFab (Output.fgGC); gui->end_layer (); } } static void DrawEMark (ElementType *e, Coord X, Coord Y, bool invisible) { Coord mark_size = EMARK_SIZE; if (!PCB->InvisibleObjectsOn && invisible) return; if (e->Pin != NULL) { PinType *pin0 = e->Pin->data; if (TEST_FLAG (HOLEFLAG, pin0)) mark_size = MIN (mark_size, pin0->DrillingHole / 2); else mark_size = MIN (mark_size, pin0->Thickness / 2); } if (e->Pad != NULL) { PadType *pad0 = e->Pad->data; mark_size = MIN (mark_size, pad0->Thickness / 2); } gui->graphics->set_color (Output.fgGC, invisible ? PCB->InvisibleMarkColor : PCB->ElementColor); gui->graphics->set_line_cap (Output.fgGC, Trace_Cap); gui->graphics->set_line_width (Output.fgGC, 0); gui->graphics->draw_line (Output.fgGC, X - mark_size, Y, X, Y - mark_size); gui->graphics->draw_line (Output.fgGC, X + mark_size, Y, X, Y - mark_size); gui->graphics->draw_line (Output.fgGC, X - mark_size, Y, X, Y + mark_size); gui->graphics->draw_line (Output.fgGC, X + mark_size, Y, X, Y + mark_size); /* * If an element is locked, place a "L" on top of the "diamond". * This provides a nice visual indication that it is locked that * works even for color blind users. */ if (TEST_FLAG (LOCKFLAG, e) ) { gui->graphics->draw_line (Output.fgGC, X, Y, X + 2 * mark_size, Y); gui->graphics->draw_line (Output.fgGC, X, Y, X, Y - 4* mark_size); } } /*! * \brief Draws pins pads and vias - Always draws for non-gui HIDs, * otherwise drawing depends on PCB->PinOn and PCB->ViaOn. */ static void DrawPPV (int group, const BoxType *drawn_area) { int top_group = GetLayerGroupNumberBySide (TOP_SIDE); int bottom_group = GetLayerGroupNumberBySide (BOTTOM_SIDE); int side; if (PCB->PinOn || !gui->gui) { /* draw element pins */ r_search (PCB->Data->pin_tree, drawn_area, NULL, pin_callback, NULL); /* draw element pads */ if (group == top_group) { side = TOP_SIDE; r_search (PCB->Data->pad_tree, drawn_area, NULL, pad_callback, &side); } if (group == bottom_group) { side = BOTTOM_SIDE; r_search (PCB->Data->pad_tree, drawn_area, NULL, pad_callback, &side); } } /* draw vias */ if (PCB->ViaOn || !gui->gui) { current_layergroup = (gui->gui)?(-1):group; /* Limit vias only for layer group */ r_search (PCB->Data->via_tree, drawn_area, NULL, via_callback, NULL); r_search (PCB->Data->via_tree, drawn_area, NULL, hole_callback, NULL); } if (PCB->PinOn || doing_assy) r_search (PCB->Data->pin_tree, drawn_area, NULL, hole_callback, NULL); } static int clearPin_callback (const BoxType * b, void *cl) { PinType *pin = (PinType *) b; bool do_clear=true; int side; if (TEST_FLAG (VIAFLAG, pin) && VIA_IS_BURIED (pin)) { side=*((int*)cl); if ((side == TOP_SIDE && pin->BuriedFrom != 0) || (side == BOTTOM_SIDE && pin->BuriedTo != GetMaxBottomLayer ())) do_clear = false; } if (do_clear) { if (TEST_FLAG (THINDRAWFLAG, PCB) || TEST_FLAG (THINDRAWPOLYFLAG, PCB)) gui->graphics->thindraw_pcb_pv (Output.pmGC, Output.pmGC, pin, false, true); else gui->graphics->fill_pcb_pv (Output.pmGC, Output.pmGC, pin, false, true); } return 1; } struct poly_info { const BoxType *drawn_area; LayerType *layer; int fill; }; static int poly_callback (const BoxType * b, void *cl) { struct poly_info *i = cl; PolygonType *polygon = (PolygonType *)b; set_layer_object_color (i->layer, (AnyObjectType *) polygon); if(i->fill) gui->graphics->fill_pcb_polygon(Output.fgGC, polygon, i->drawn_area); else gui->graphics->draw_pcb_polygon (Output.fgGC, polygon, i->drawn_area); return 1; } static int clearPad_callback (const BoxType * b, void *cl) { PadType *pad = (PadType *) b; int *side = cl; if (ON_SIDE (pad, *side) && pad->Mask) _draw_pad (Output.pmGC, pad, true, true); return 1; } /*! * \brief Draws silk layer. */ void DrawSilk (int side, const BoxType * drawn_area) { #if 0 /* This code is used when you want to mask silk to avoid exposed pins and pads. We decided it was a bad idea to do this unconditionally, but the code remains. */ #endif #if 0 if (gui->poly_before) { gui->graphics->use_mask (HID_MASK_BEFORE); #endif DrawLayer (LAYER_PTR (max_copper_layer + side), drawn_area); /* draw package */ r_search (PCB->Data->element_tree, drawn_area, NULL, element_callback, &side); r_search (PCB->Data->name_tree[NAME_INDEX (PCB)], drawn_area, NULL, name_callback, &side); #if 0 } gui->graphics->use_mask (HID_MASK_CLEAR); r_search (PCB->Data->pin_tree, drawn_area, NULL, clearPin_callback, NULL); r_search (PCB->Data->via_tree, drawn_area, NULL, clearPin_callback, NULL); r_search (PCB->Data->pad_tree, drawn_area, NULL, clearPad_callback, &side); if (gui->poly_after) { gui->graphics->use_mask (HID_MASK_AFTER); DrawLayer (LAYER_PTR (max_copper_layer + layer), drawn_area); /* draw package */ r_search (PCB->Data->element_tree, drawn_area, NULL, element_callback, &side); r_search (PCB->Data->name_tree[NAME_INDEX (PCB)], drawn_area, NULL, name_callback, &side); } gui->graphics->use_mask (HID_MASK_OFF); #endif } static void DrawMaskBoardArea (int mask_type, const BoxType *drawn_area) { /* Skip the mask drawing if the GUI doesn't want this type */ if ((mask_type == HID_MASK_BEFORE && !gui->poly_before) || (mask_type == HID_MASK_AFTER && !gui->poly_after)) return; gui->graphics->use_mask (mask_type); gui->graphics->set_color (Output.fgGC, PCB->MaskColor); if (drawn_area == NULL) gui->graphics->fill_rect (Output.fgGC, 0, 0, PCB->MaxWidth, PCB->MaxHeight); else gui->graphics->fill_rect (Output.fgGC, drawn_area->X1, drawn_area->Y1, drawn_area->X2, drawn_area->Y2); } /*! * \brief Draws solder mask layer - this will cover nearly everything. */ void DrawMask (int side, const BoxType *screen) { int thin = TEST_FLAG(THINDRAWFLAG, PCB) || TEST_FLAG(THINDRAWPOLYFLAG, PCB); if (thin) gui->graphics->set_color (Output.pmGC, PCB->MaskColor); else { DrawMaskBoardArea (HID_MASK_BEFORE, screen); gui->graphics->use_mask (HID_MASK_CLEAR); } r_search (PCB->Data->pin_tree, screen, NULL, clearPin_callback, NULL); r_search (PCB->Data->via_tree, screen, NULL, clearPin_callback, &side); r_search (PCB->Data->pad_tree, screen, NULL, clearPad_callback, &side); if (thin) gui->graphics->set_color (Output.pmGC, "erase"); else { DrawMaskBoardArea (HID_MASK_AFTER, screen); gui->graphics->use_mask (HID_MASK_OFF); } } /*! * \brief Draws solder paste layer for a given side of the board. */ void DrawPaste (int side, const BoxType *drawn_area) { gui->graphics->set_color (Output.fgGC, PCB->ElementColor); ALLPAD_LOOP (PCB->Data); { if (ON_SIDE (pad, side) && !TEST_FLAG (NOPASTEFLAG, pad) && pad->Mask > 0) { Coord save_thickness = pad->Thickness; Coord save_mask = pad->Mask; if (Settings.PasteAdjust != 0) { pad->Thickness = pad->Thickness + Settings.PasteAdjust; pad->Mask = pad->Mask + Settings.PasteAdjust; if (pad->Thickness < 0) { printf ("adjust thickness %8.4f -> %8.4f mask %8.4f -> %8.4f\n", COORD_TO_MM(save_thickness), COORD_TO_MM(pad->Thickness), COORD_TO_MM(save_mask), COORD_TO_MM(pad->Mask)); pad->Thickness = 0; } if (pad->Mask < 0) pad->Mask = 0; } if (pad->Mask < pad->Thickness) _draw_pad (Output.fgGC, pad, true, true); else _draw_pad (Output.fgGC, pad, false, false); pad->Thickness = save_thickness; pad->Mask = save_mask; } } ENDALL_LOOP; } static void DrawRats (const BoxType *drawn_area) { /* * XXX lesstif allows positive AND negative drawing in HID_MASK_CLEAR. * XXX gtk only allows negative drawing. * XXX using the mask here is to get rat transparency */ int can_mask = strcmp(gui->name, "lesstif") == 0; if (can_mask) gui->graphics->use_mask (HID_MASK_CLEAR); r_search (PCB->Data->rat_tree, drawn_area, NULL, rat_callback, NULL); if (can_mask) gui->graphics->use_mask (HID_MASK_OFF); } static int text_callback (const BoxType * b, void *cl) { LayerType *layer = cl; TextType *text = (TextType *)b; int min_silk_line; if (TEST_FLAG (SELECTEDFLAG, text)) gui->graphics->set_color (Output.fgGC, layer->SelectedColor); else gui->graphics->set_color (Output.fgGC, layer->Color); if (layer == &PCB->Data->SILKLAYER || layer == &PCB->Data->BACKSILKLAYER) min_silk_line = PCB->minSlk; else min_silk_line = PCB->minWid; gui->graphics->draw_pcb_text (Output.fgGC, text, min_silk_line); return 1; } void DrawLayer (LayerType *Layer, const BoxType *screen) { struct poly_info info = {screen, Layer, 0}; /* draw the poly outlines */ r_search (Layer->polygon_tree, screen, NULL, poly_callback, &info); if (!TEST_FLAG (CHECKPLANESFLAG, PCB)) { /* draw all visible lines this layer */ r_search (Layer->line_tree, screen, NULL, line_callback, Layer); /* draw the layer arcs on screen */ r_search (Layer->arc_tree, screen, NULL, arc_callback, Layer); /* draw the layer text on screen */ r_search (Layer->text_tree, screen, NULL, text_callback, Layer); /* We should check for gui->gui here, but it's kinda cool seeing the auto-outline magically disappear when you first add something to the "outline" layer. */ if (IsLayerEmpty (Layer) && (strcmp (Layer->Name, "outline") == 0 || strcmp (Layer->Name, "route") == 0)) { gui->graphics->set_color (Output.fgGC, Layer->Color); gui->graphics->set_line_width (Output.fgGC, PCB->minWid); gui->graphics->draw_rect (Output.fgGC, 0, 0, PCB->MaxWidth, PCB->MaxHeight); } } info.fill = 1; /* fill the polys */ r_search (Layer->polygon_tree, screen, NULL, poly_callback, &info); } /*! * \brief Draws one layer group. * * If the exporter is not a GUI, also draws the pins / pads / vias in * this layer group. */ void DrawLayerGroup (int group, const BoxType *drawn_area) { int i, rv = 1; int layernum; LayerType *Layer; int n_entries = PCB->LayerGroups.Number[group]; Cardinal *layers = PCB->LayerGroups.Entries[group]; for (i = n_entries - 1; i >= 0; i--) { layernum = layers[i]; Layer = PCB->Data->Layer + layers[i]; if (strcmp (Layer->Name, "outline") == 0 || strcmp (Layer->Name, "route") == 0) rv = 0; if (layernum < max_copper_layer && Layer->On) DrawLayer (Layer, drawn_area); } if (n_entries > 1) rv = 1; if (rv && !gui->gui) DrawPPV (group, drawn_area); } static void GatherPVName (PinType *Ptr) { BoxType box; bool vert = TEST_FLAG (EDGE2FLAG, Ptr); if (vert) { box.X1 = Ptr->X - Ptr->Thickness / 2 + Settings.PinoutTextOffsetY; box.Y1 = Ptr->Y - Ptr->DrillingHole / 2 - Settings.PinoutTextOffsetX; } else { box.X1 = Ptr->X + Ptr->DrillingHole / 2 + Settings.PinoutTextOffsetX; box.Y1 = Ptr->Y - Ptr->Thickness / 2 + Settings.PinoutTextOffsetY; } if (vert) { box.X2 = box.X1; box.Y2 = box.Y1; } else { box.X2 = box.X1; box.Y2 = box.Y1; } AddPart (&box); } static void GatherPadName (PadType *Pad) { BoxType box; bool vert; /* should text be vertical ? */ vert = (Pad->Point1.X == Pad->Point2.X); if (vert) { box.X1 = Pad->Point1.X - Pad->Thickness / 2; box.Y1 = MAX (Pad->Point1.Y, Pad->Point2.Y) + Pad->Thickness / 2; box.X1 += Settings.PinoutTextOffsetY; box.Y1 -= Settings.PinoutTextOffsetX; box.X2 = box.X1; box.Y2 = box.Y1; } else { box.X1 = MIN (Pad->Point1.X, Pad->Point2.X) - Pad->Thickness / 2; box.Y1 = Pad->Point1.Y - Pad->Thickness / 2; box.X1 += Settings.PinoutTextOffsetX; box.Y1 += Settings.PinoutTextOffsetY; box.X2 = box.X1; box.Y2 = box.Y1; } AddPart (&box); return; } /*! * \brief Draw a via object. */ void DrawVia (PinType *Via) { AddPart (Via); if (!TEST_FLAG (HOLEFLAG, Via) && TEST_FLAG (DISPLAYNAMEFLAG, Via)) DrawViaName (Via); } /*! * \brief Draws the name of a via. */ void DrawViaName (PinType *Via) { GatherPVName (Via); } /*! * \brief Draw a pin object. */ void DrawPin (PinType *Pin) { AddPart (Pin); if ((!TEST_FLAG (HOLEFLAG, Pin) && TEST_FLAG (DISPLAYNAMEFLAG, Pin)) || doing_pinout) DrawPinName (Pin); } /*! * \brief Draws the name of a pin. */ void DrawPinName (PinType *Pin) { GatherPVName (Pin); } /*! * \brief Draw a pad object. */ void DrawPad (PadType *Pad) { AddPart (Pad); if (doing_pinout || TEST_FLAG (DISPLAYNAMEFLAG, Pad)) DrawPadName (Pad); } /*! * \brief Draws the name of a pad. */ void DrawPadName (PadType *Pad) { GatherPadName (Pad); } /*! * \brief Draws a line on a layer. */ void DrawLine (LayerType *Layer, LineType *Line) { AddPart (Line); } /*! * \brief Draws a ratline. */ void DrawRat (RatType *Rat) { if (Settings.RatThickness < 100) Rat->Thickness = pixel_slop * Settings.RatThickness; /* rats.c set VIAFLAG if this rat goes to a containing poly: draw a donut */ if (TEST_FLAG(VIAFLAG, Rat)) { Coord w = Rat->Thickness; BoxType b; b.X1 = Rat->Point1.X - w * 2 - w / 2; b.X2 = Rat->Point1.X + w * 2 + w / 2; b.Y1 = Rat->Point1.Y - w * 2 - w / 2; b.Y2 = Rat->Point1.Y + w * 2 + w / 2; AddPart (&b); } else DrawLine (NULL, (LineType *)Rat); } /*! * \brief Draws an arc on a layer. */ void DrawArc (LayerType *Layer, ArcType *Arc) { AddPart (Arc); } /*! * \brief Draws a text on a layer. */ void DrawText (LayerType *Layer, TextType *Text) { AddPart (Text); } /*! * \brief Draws a polygon on a layer. */ void DrawPolygon (LayerType *Layer, PolygonType *Polygon) { AddPart (Polygon); } /*! * \brief Draws an element. */ void DrawElement (ElementType *Element) { DrawElementPackage (Element); DrawElementName (Element); DrawElementPinsAndPads (Element); } /*! * \brief Draws the name of an element. */ void DrawElementName (ElementType *Element) { if (TEST_FLAG (HIDENAMEFLAG, Element)) return; DrawText (NULL, &ELEMENT_TEXT (PCB, Element)); } /*! * \brief Draws the package of an element. */ void DrawElementPackage (ElementType *Element) { ELEMENTLINE_LOOP (Element); { DrawLine (NULL, line); } END_LOOP; ARC_LOOP (Element); { DrawArc (NULL, arc); } END_LOOP; } /*! * \brief Draw pins of an element. */ void DrawElementPinsAndPads (ElementType *Element) { PAD_LOOP (Element); { if (doing_pinout || doing_assy || FRONT (pad) || PCB->InvisibleObjectsOn) DrawPad (pad); } END_LOOP; PIN_LOOP (Element); { DrawPin (pin); } END_LOOP; } /*! * \brief Erase a via. */ void EraseVia (PinType *Via) { AddPart (Via); if (TEST_FLAG (DISPLAYNAMEFLAG, Via)) EraseViaName (Via); } /*! * \brief Erase a ratline. */ void EraseRat (RatType *Rat) { if (TEST_FLAG(VIAFLAG, Rat)) { Coord w = Rat->Thickness; BoxType b; b.X1 = Rat->Point1.X - w * 2 - w / 2; b.X2 = Rat->Point1.X + w * 2 + w / 2; b.Y1 = Rat->Point1.Y - w * 2 - w / 2; b.Y2 = Rat->Point1.Y + w * 2 + w / 2; AddPart (&b); } else EraseLine ((LineType *)Rat); } /*! * \brief Erase a via name. */ void EraseViaName (PinType *Via) { GatherPVName (Via); } /*! * \brief Erase a pad object. */ void ErasePad (PadType *Pad) { AddPart (Pad); if (TEST_FLAG (DISPLAYNAMEFLAG, Pad)) ErasePadName (Pad); } /*! * \brief Erase a pad name. */ void ErasePadName (PadType *Pad) { GatherPadName (Pad); } /*! * \brief Erase a pin object. */ void ErasePin (PinType *Pin) { AddPart (Pin); if (TEST_FLAG (DISPLAYNAMEFLAG, Pin)) ErasePinName (Pin); } /*! * \brief Erase a pin name. */ void ErasePinName (PinType *Pin) { GatherPVName (Pin); } /*! * \brief Erases a line on a layer. */ void EraseLine (LineType *Line) { AddPart (Line); } /*! * \brief Erases an arc on a layer. */ void EraseArc (ArcType *Arc) { if (!Arc->Thickness) return; AddPart (Arc); } /*! * \brief Erases a text on a layer. */ void EraseText (LayerType *Layer, TextType *Text) { /* r_delete_entry (Layer->text_tree, (BoxType *) Text); */ AddPart (Text); } /*! * \brief Erases a polygon on a layer. */ void ErasePolygon (PolygonType *Polygon) { AddPart (Polygon); } /*! * \brief Erases an element. */ void EraseElement (ElementType *Element) { ELEMENTLINE_LOOP (Element); { EraseLine (line); } END_LOOP; ARC_LOOP (Element); { EraseArc (arc); } END_LOOP; EraseElementName (Element); EraseElementPinsAndPads (Element); } /*! * \brief Erases all pins and pads of an element. */ void EraseElementPinsAndPads (ElementType *Element) { PIN_LOOP (Element); { ErasePin (pin); } END_LOOP; PAD_LOOP (Element); { ErasePad (pad); } END_LOOP; } /*! * \brief Erases the name of an element. */ void EraseElementName (ElementType *Element) { if (TEST_FLAG (HIDENAMEFLAG, Element)) return; EraseText (NULL, &ELEMENT_TEXT (PCB, Element));} void EraseObject (int type, void *lptr, void *ptr) { switch (type) { case VIA_TYPE: case PIN_TYPE: ErasePin ((PinType *) ptr); break; case TEXT_TYPE: EraseText ((LayerType *)lptr, (TextType *) ptr); break; case ELEMENTNAME_TYPE: EraseElementName ((ElementType *) ptr); break; case POLYGON_TYPE: ErasePolygon ((PolygonType *) ptr); break; case ELEMENT_TYPE: EraseElement ((ElementType *) ptr); break; case LINE_TYPE: case ELEMENTLINE_TYPE: case RATLINE_TYPE: EraseLine ((LineType *) ptr); break; case PAD_TYPE: ErasePad ((PadType *) ptr); break; case ARC_TYPE: case ELEMENTARC_TYPE: EraseArc ((ArcType *) ptr); break; default: Message ("hace: Internal ERROR, trying to erase an unknown type\n"); } } void DrawObject (int type, void *ptr1, void *ptr2) { switch (type) { case VIA_TYPE: if (PCB->ViaOn) DrawVia ((PinType *) ptr2); break; case LINE_TYPE: if (((LayerType *) ptr1)->On) DrawLine ((LayerType *) ptr1, (LineType *) ptr2); break; case ARC_TYPE: if (((LayerType *) ptr1)->On) DrawArc ((LayerType *) ptr1, (ArcType *) ptr2); break; case TEXT_TYPE: if (((LayerType *) ptr1)->On) DrawText ((LayerType *) ptr1, (TextType *) ptr2); break; case POLYGON_TYPE: if (((LayerType *) ptr1)->On) DrawPolygon ((LayerType *) ptr1, (PolygonType *) ptr2); break; case ELEMENT_TYPE: if (PCB->ElementOn && (FRONT ((ElementType *) ptr2) || PCB->InvisibleObjectsOn)) DrawElement ((ElementType *) ptr2); break; case RATLINE_TYPE: if (PCB->RatOn) DrawRat ((RatType *) ptr2); break; case PIN_TYPE: if (PCB->PinOn) DrawPin ((PinType *) ptr2); break; case PAD_TYPE: if (PCB->PinOn) DrawPad ((PadType *) ptr2); break; case ELEMENTNAME_TYPE: if (PCB->ElementOn && (FRONT ((ElementType *) ptr2) || PCB->InvisibleObjectsOn)) DrawElementName ((ElementType *) ptr1); break; } } static void draw_element (ElementType *element) { draw_element_package (element); draw_element_name (element); draw_element_pins_and_pads (element); } /*! * \brief HID drawing callback. */ void hid_expose_callback (HID * hid, BoxType * region, void *item) { HID *old_gui = gui; gui = hid; Output.fgGC = gui->graphics->make_gc (); Output.bgGC = gui->graphics->make_gc (); Output.pmGC = gui->graphics->make_gc (); hid->graphics->set_color (Output.pmGC, "erase"); hid->graphics->set_color (Output.bgGC, "drill"); if (item) { doing_pinout = true; draw_element ((ElementType *)item); doing_pinout = false; } else DrawEverything (region); gui->graphics->destroy_gc (Output.fgGC); gui->graphics->destroy_gc (Output.bgGC); gui->graphics->destroy_gc (Output.pmGC); gui = old_gui; } pcb-4.3.0/src/rotate.h0000664000175000017500000000474213773431044011460 00000000000000/*! * \file src/rotate.h * * \brief Prototypes for transform routines. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * * Thomas.Nau@rz.uni-ulm.de */ #ifndef PCB_ROTATE_H #define PCB_ROTATE_H #include "global.h" /* --------------------------------------------------------------------------- * some useful transformation macros and constants */ #define ROTATE(x,y,x0,y0,n) \ { \ Coord dx = (x)-(x0), \ dy = (y)-(y0); \ \ switch(n & 0x03) \ { \ case 1: (x)=(x0)+dy; (y)=(y0)-dx; \ break; \ case 2: (x)=(x0)-dx; (y)=(y0)-dy; \ break; \ case 3: (x)=(x0)-dy; (y)=(y0)+dx; \ break; \ default: break; \ } \ } #define ROTATE_VIA_LOWLEVEL(v,x0,y0,n) ROTATE((v)->X,(v)->Y,(x0),(y0),(n)) #define ROTATE_PIN_LOWLEVEL(p,x0,y0,n) ROTATE((p)->X,(p)->Y,(x0),(y0),(n)) #define ROTATE_PAD_LOWLEVEL(p,x0,y0,n) \ RotateLineLowLevel(((LineType *) (p)),(x0),(y0),(n)) #define ROTATE_TYPES (ELEMENT_TYPE | TEXT_TYPE | ELEMENTNAME_TYPE | ARC_TYPE) void RotateLineLowLevel (LineType *, Coord, Coord, unsigned); void RotateArcLowLevel (ArcType *, Coord, Coord, unsigned); void RotateBoxLowLevel (BoxType *, Coord, Coord, unsigned); void RotateTextLowLevel (TextType *, Coord, Coord, unsigned); void RotatePolygonLowLevel (PolygonType *, Coord, Coord, unsigned); void RotateElementLowLevel (DataType *, ElementType *, Coord, Coord, unsigned); void *RotateObject (int, void *, void *, void *, Coord, Coord, unsigned); void RotateScreenObject (Coord, Coord, unsigned); #endif pcb-4.3.0/src/toporouter.h0000664000175000017500000003107613773431044012404 00000000000000/*! * \file src/toporouter.h * * \brief Topological Autorouter for PCB. * *
* *

Copyright.

\n * * Topological Autorouter for * PCB, interactive printed circuit board design * * Copyright (C) 2009 Anthony Blake * * Copyright (C) 2009-2011 PCB Contributors (see ChangeLog for details) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for email: * Anthony Blake, tonyb33@gmail.com */ #ifndef PCB_TOPOROUTER_H #define PCB_TOPOROUTER_H #include #include "data.h" #include "macro.h" #include "autoroute.h" #include "box.h" #include "create.h" #include "draw.h" #include "error.h" #include "find.h" #include "heap.h" #include "rtree.h" #include "misc.h" #include "mymem.h" #include "polygon.h" #include "rats.h" #include "remove.h" #include "thermal.h" #include "undo.h" #include "global.h" #include "gts.h" #include #include #include #define TOPOROUTER_FLAG_VERBOSE (1<<0) #define TOPOROUTER_FLAG_HARDDEST (1<<1) #define TOPOROUTER_FLAG_HARDSRC (1<<2) #define TOPOROUTER_FLAG_MATCH (1<<3) #define TOPOROUTER_FLAG_LAYERHINT (1<<4) #define TOPOROUTER_FLAG_LEASTINVALID (1<<5) #define TOPOROUTER_FLAG_AFTERORDER (1<<6) #define TOPOROUTER_FLAG_AFTERRUBIX (1<<7) #define TOPOROUTER_FLAG_GOFAR (1<<8) #define TOPOROUTER_FLAG_DETOUR (1<<9) #if TOPO_OUTPUT_ENABLED #include #endif #define EPSILON 0.0001f //#define DEBUG_ROAR 1 #define tvdistance(a,b) hypot(vx(a)-vx(b),vy(a)-vy(b)) #define edge_v1(e) (GTS_SEGMENT(e)->v1) #define edge_v2(e) (GTS_SEGMENT(e)->v2) #define tedge_v1(e) (TOPOROUTER_VERTEX(GTS_SEGMENT(e)->v1)) #define tedge_v2(e) (TOPOROUTER_VERTEX(GTS_SEGMENT(e)->v2)) #define tedge(v1,v2) TOPOROUTER_EDGE(gts_vertices_are_connected(GTS_VERTEX(v1), GTS_VERTEX(v2))) #define edge_routing(e) (TOPOROUTER_IS_CONSTRAINT(e) ? TOPOROUTER_CONSTRAINT(e)->routing : e->routing) #define vrouting(v) (edge_routing(v->routingedge)) #define edge_routing_next(e,list) ((list->next) ? TOPOROUTER_VERTEX(list->next->data) : TOPOROUTER_VERTEX(edge_v2(e))) #define edge_routing_prev(e,list) ((list->prev) ? TOPOROUTER_VERTEX(list->prev->data) : TOPOROUTER_VERTEX(edge_v1(e))) #define vx(v) (GTS_POINT(v)->x) #define vy(v) (GTS_POINT(v)->y) #define vz(v) (GTS_POINT(v)->z) #define close_enough_xy(a,b) (vx(a) > vx(b) - EPSILON && vx(a) < vx(b) + EPSILON && vy(a) > vy(b) - EPSILON && vy(a) < vy(b) + EPSILON) #define tev1x(e) (vx(tedge_v1(e)) #define tev1y(e) (vy(tedge_v1(e)) #define tev1z(e) (vz(tedge_v1(e)) #define tev2x(e) (vx(tedge_v2(e)) #define tev2y(e) (vy(tedge_v2(e)) #define tev2z(e) (vz(tedge_v2(e)) #define tvertex_intersect(a,b,c,d) (TOPOROUTER_VERTEX(vertex_intersect(GTS_VERTEX(a),GTS_VERTEX(b),GTS_VERTEX(c),GTS_VERTEX(d)))) #define TOPOROUTER_IS_BBOX(obj) (gts_object_is_from_class (obj, toporouter_bbox_class ())) #define TOPOROUTER_BBOX(obj) GTS_OBJECT_CAST (obj, toporouter_bbox_t, toporouter_bbox_class ()) #define TOPOROUTER_BBOX_CLASS(klass) GTS_OBJECT_CLASS_CAST (klass, toporouter_bbox_class_t, toporouter_bbox_class ()) typedef enum { PAD, PIN, VIA, ARC, VIA_SHADOW, LINE, OTHER, BOARD, EXPANSION_AREA, POLYGON, TEMP } toporouter_term_t; struct _toporouter_bbox_t { GtsBBox b; toporouter_term_t type; void *data; int layer; GtsSurface *surface; GtsTriangle *enclosing; GList *constraints; GtsPoint *point, *realpoint; // char *netlist, *style; struct _toporouter_cluster_t *cluster; }; struct _toporouter_bbox_class_t { GtsBBoxClass parent_class; }; typedef struct _toporouter_bbox_t toporouter_bbox_t; typedef struct _toporouter_bbox_class_t toporouter_bbox_class_t; #define TOPOROUTER_IS_EDGE(obj) (gts_object_is_from_class (obj, toporouter_edge_class ())) #define TOPOROUTER_EDGE(obj) GTS_OBJECT_CAST (obj, toporouter_edge_t, toporouter_edge_class ()) #define TOPOROUTER_EDGE_CLASS(klass) GTS_OBJECT_CLASS_CAST (klass, toporouter_edge_class_t, toporouter_edge_class ()) #define EDGE_FLAG_DIRECTCONNECTION (1<<0) struct _toporouter_edge_t { GtsEdge e; //NetListType *netlist; guint flags; GList *routing; }; struct _toporouter_edge_class_t { GtsEdgeClass parent_class; }; typedef struct _toporouter_edge_t toporouter_edge_t; typedef struct _toporouter_edge_class_t toporouter_edge_class_t; #define TOPOROUTER_IS_VERTEX(obj) (gts_object_is_from_class (obj, toporouter_vertex_class ())) #define TOPOROUTER_VERTEX(obj) GTS_OBJECT_CAST (obj, toporouter_vertex_t, toporouter_vertex_class ()) #define TOPOROUTER_VERTEX_CLASS(klass) GTS_OBJECT_CLASS_CAST (klass, toporouter_vertex_class_t, toporouter_vertex_class ()) #define VERTEX_FLAG_VIZ (1<<1) #define VERTEX_FLAG_CCW (1<<2) #define VERTEX_FLAG_CW (1<<3) #define VERTEX_FLAG_RED (1<<4) #define VERTEX_FLAG_GREEN (1<<5) #define VERTEX_FLAG_BLUE (1<<6) #define VERTEX_FLAG_TEMP (1<<7) #define VERTEX_FLAG_ROUTE (1<<8) #define VERTEX_FLAG_FAKE (1<<10) #define VERTEX_FLAG_SPECCUT (1<<11) struct _toporouter_vertex_t { GtsVertex v; //GList *boxes; struct _toporouter_bbox_t *bbox; struct _toporouter_vertex_t *parent; struct _toporouter_vertex_t *child; toporouter_edge_t *routingedge; guint flags; gdouble gcost, hcost; guint gn; struct _toporouter_arc_t *arc; struct _toporouter_oproute_t *oproute; struct _toporouter_route_t *route; gdouble thickness; }; struct _toporouter_vertex_class_t { GtsVertexClass parent_class; }; typedef struct _toporouter_vertex_t toporouter_vertex_t; typedef struct _toporouter_vertex_class_t toporouter_vertex_class_t; #define TOPOROUTER_IS_CONSTRAINT(obj) (gts_object_is_from_class (obj, toporouter_constraint_class ())) #define TOPOROUTER_CONSTRAINT(obj) GTS_OBJECT_CAST (obj, toporouter_constraint_t, toporouter_constraint_class ()) #define TOPOROUTER_CONSTRAINT_CLASS(klass) GTS_OBJECT_CLASS_CAST (klass, toporouter_constraint_class_t, toporouter_constraint_class ()) struct _toporouter_constraint_t { GtsConstraint c; toporouter_bbox_t *box; GList *routing; }; struct _toporouter_constraint_class_t { GtsConstraintClass parent_class; }; typedef struct { gdouble x, y; } toporouter_spoint_t; typedef struct _toporouter_constraint_t toporouter_constraint_t; typedef struct _toporouter_constraint_class_t toporouter_constraint_class_t; typedef struct { GtsSurface *surface; // GtsTriangle *t; // GtsVertex *v1, *v2, *v3; GList *vertices; GList *constraints; GList *edges; } toporouter_layer_t; #define TOPOROUTER_VERTEX_REGION(x) ((toporouter_vertex_region_t *)x) typedef struct { GList *points; toporouter_vertex_t *v1, *v2; toporouter_vertex_t *origin; } toporouter_vertex_region_t; struct _toporouter_rubberband_arc_t { toporouter_vertex_t *pathv, *arcv; gdouble r, d; gint wind; GList *list; }; typedef struct _toporouter_rubberband_arc_t toporouter_rubberband_arc_t; #define TOPOROUTER_RUBBERBAND_ARC(x) ((toporouter_rubberband_arc_t *)x) struct _toporouter_route_t { struct _toporouter_netlist_t *netlist; struct _toporouter_cluster_t *src, *dest; struct _toporouter_cluster_t *psrc, *pdest; gdouble score, detourscore; toporouter_vertex_t *curpoint; GHashTable *alltemppoints; GList *path; guint flags; GList *destvertices, *srcvertices; GList *topopath; gdouble pscore; GList *ppath; gint *ppathindices; }; typedef struct _toporouter_route_t toporouter_route_t; #define TOPOROUTER_ROUTE(x) ((toporouter_route_t *)x) struct _toporouter_netlist_t { GPtrArray *clusters, *routes; char *netlist, *style; GList *routed; struct _toporouter_netlist_t *pair; }; typedef struct _toporouter_netlist_t toporouter_netlist_t; #define TOPOROUTER_NETLIST(x) ((toporouter_netlist_t *)x) struct _toporouter_cluster_t { gint c, pc; GPtrArray *boxes; toporouter_netlist_t *netlist; }; typedef struct _toporouter_cluster_t toporouter_cluster_t; #define TOPOROUTER_CLUSTER(x) ((toporouter_cluster_t *)x) #define TOPOROUTER_OPROUTE(x) ((toporouter_oproute_t *)x) #define oproute_next(a,b) (b->next ? TOPOROUTER_ARC(b->next->data) : a->term2) #define oproute_prev(a,b) (b->prev ? TOPOROUTER_ARC(b->prev->data) : a->term1) #define TOPOROUTER_SERPINTINE(x) ((toporouter_serpintine_t *)x) struct _toporouter_serpintine_t { GList *arcs; gdouble x, y; gdouble x0, y0, x1, y1; gpointer start; gdouble halfa, radius; guint nhalfcycles; }; typedef struct _toporouter_serpintine_t toporouter_serpintine_t; struct _toporouter_oproute_t { GList *arcs; toporouter_vertex_t *term1, *term2; char *style; char *netlist; guint layergroup; gdouble tof; GList *path; toporouter_serpintine_t *serp; }; typedef struct _toporouter_oproute_t toporouter_oproute_t; #define TOPOROUTER_IS_ARC(obj) (gts_object_is_from_class (obj, toporouter_arc_class())) #define TOPOROUTER_ARC(obj) GTS_OBJECT_CAST (obj, toporouter_arc_t, toporouter_arc_class()) #define TOPOROUTER_ARC_CLASS(klass) GTS_OBJECT_CLASS_CAST (klass, toporouter_arc_class_t, toporouter_arc_class()) struct _toporouter_arc_t { GtsObject object; gdouble x0, y0, x1, y1; toporouter_vertex_t *centre, *v; gdouble r; gint dir; GList *clearance; toporouter_oproute_t *oproute; toporouter_vertex_t *v1, *v2; }; struct _toporouter_arc_class_t { GtsObjectClass parent_class; gboolean binary; }; typedef struct _toporouter_arc_t toporouter_arc_t; typedef struct _toporouter_arc_class_t toporouter_arc_class_t; typedef struct _toporouter_t toporouter_t; typedef struct { guint id; guint *pairwise_nodetour; gdouble pairwise_detour_sum; gdouble score; guint pairwise_fails; toporouter_route_t *routedata; toporouter_t *r; } toporouter_netscore_t; #define TOPOROUTER_NETSCORE(x) ((toporouter_netscore_t *)x) struct _toporouter_t { GSList *bboxes; GNode *bboxtree; toporouter_layer_t *layers; GList *paths; GList *keepoutlayers; guint flags; GList *destboxes, *consumeddestboxes; /* settings: */ gdouble viacost; gdouble wiring_score; GPtrArray *routes; GPtrArray *netlists; GList *routednets, *failednets; gint (*netsort)(toporouter_netscore_t **, toporouter_netscore_t **); struct timeval starttime; FILE *debug; }; typedef gint (*oproute_adjseg_func) (toporouter_t *, GList **, GList **, guint *, gdouble, gdouble, gdouble, gdouble, toporouter_oproute_t *, toporouter_oproute_t *); typedef struct { #ifdef CAIRO_H cairo_t *cr; cairo_surface_t *surface; #endif double s; /*!< scale factor. */ int mode; void *data; char *filename; double iw; /*!< image width dimensions. */ double ih; /*!< image height dimensions. */ } drawing_context_t; #define FOREACH_CLUSTER(clusters) do { \ for(toporouter_cluster_t **i = ((toporouter_cluster_t **)clusters->pdata) + clusters->len - 1; i >= (toporouter_cluster_t **)clusters->pdata && clusters->len > 0; --i) { \ toporouter_cluster_t *cluster = *i; #define FOREACH_BBOX(boxes) do { \ for(toporouter_bbox_t **i = ((toporouter_bbox_t **)boxes->pdata) + boxes->len - 1; i >= (toporouter_bbox_t **)boxes->pdata && boxes->len > 0; --i) { \ toporouter_bbox_t *box = *i; #define FOREACH_ROUTE(routes) do { \ for(toporouter_route_t **i = ((toporouter_route_t **)routes->pdata) + routes->len - 1; i >= (toporouter_route_t **)routes->pdata && routes->len > 0; --i) { \ toporouter_route_t *routedata = *i; #define FOREACH_NETSCORE(netscores) do { \ for(toporouter_netscore_t **i = ((toporouter_netscore_t **)netscores->pdata) + netscores->len - 1; i >= (toporouter_netscore_t **)netscores->pdata && netscores->len > 0; --i) { \ toporouter_netscore_t *netscore = *i; #define FOREACH_NETLIST(netlists) do { \ for(toporouter_netlist_t **i = ((toporouter_netlist_t **)netlists->pdata) + netlists->len - 1; i >= (toporouter_netlist_t **)netlists->pdata && netlists->len > 0; --i) { \ toporouter_netlist_t *netlist = *i; #define FOREACH_END }} while(0) #endif /* PCB_TOPOROUTER_H */ pcb-4.3.0/src/undo.c0000664000175000017500000013270613773431044011124 00000000000000/*! * \file src/undo.c * * \brief Functions used to undo operations. * * Description: * * There are two lists which hold: * - information about a command * - data of removed objects * * Both lists are organized as first-in-last-out which means that the undo * list can always use the last entry of the remove list. * * A serial number is incremented whenever an operation is completed. * * An operation itself may consist of several basic instructions. * * E.g.: removing all selected objects is one operation with exactly one * serial number even if the remove function is called several times. * * \note A lock flag ensures that no infinite loops occur. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * * Thomas.Nau@rz.uni-ulm.de */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "global.h" #include "buffer.h" #include "change.h" #include "create.h" #include "data.h" #include "draw.h" #include "error.h" #include "flags.h" #include "insert.h" #include "misc.h" #include "mirror.h" #include "move.h" #include "mymem.h" #include "polygon.h" #include "remove.h" #include "rotate.h" #include "rtree.h" #include "search.h" #include "set.h" #include "undo.h" #include "strflags.h" #ifdef HAVE_LIBDMALLOC #include #endif static bool between_increment_and_restore = false; static bool added_undo_between_increment_and_restore = false; /* --------------------------------------------------------------------------- * some local data types */ /*! * \brief Information about a change command. */ typedef struct { char *Name; } ChangeNameType; /*! * \brief Information about a move command. */ typedef struct { Coord DX; /*!< movement vector. */ Coord DY; /*!< movement vector. */ } MoveType; /*! * \brief Information about removed polygon points. */ typedef struct { Coord X; /*!< Data. */ Coord Y; /*!< Data. */ int ID; Cardinal Index; /*!< Index in a polygons array of points. */ bool last_in_contour; /*!< Whether the point was the last in its contour. */ } RemovedPointType; /*! * \brief Information about rotation. */ typedef struct { Coord CenterX; /*!< Center of rotation. */ Coord CenterY; /*!< Center of rotation. */ Cardinal Steps; /*!< Number of steps. */ } RotateType; /*! * \brief Information about moves between layers. */ typedef struct { Cardinal OriginalLayer; /*!< The index of the original layer. */ } MoveToLayerType; /*! * \brief Information about layer changes. */ typedef struct { int old_index; int new_index; } LayerChangeType; /*! * \brief Information about layer changes. */ typedef struct { int from; int to; } SetViaLayersChangeType; /*! * \brief Information about poly clear/restore. */ typedef struct { bool Clear; /*!< true was clear, false was restore. */ LayerType *Layer; } ClearPolyType; /*! * \brief Information about netlist lib changes. */ typedef struct { LibraryType *old; LibraryType *lib; } NetlistChangeType; /*! * \brief Holds information about an operation. */ typedef struct { int Serial, /*!< Serial number of operation. */ Type, /*!< Type of operation. */ Kind, /*!< Type of object with given ID. */ ID; /*!< Object ID. */ union /* Some additional information. */ { ChangeNameType ChangeName; MoveType Move; RemovedPointType RemovedPoint; RotateType Rotate; MoveToLayerType MoveToLayer; FlagType Flags; Coord Size; int Scale; LayerChangeType LayerChange; ClearPolyType ClearPoly; NetlistChangeType NetlistChange; SetViaLayersChangeType SetViaLayersChange; long int CopyID; } Data; } UndoListType; /* --------------------------------------------------------------------------- * some local variables */ static DataType *RemoveList = NULL; /*!< List of removed objects. */ static UndoListType *UndoList = NULL; /*!< List of operations. */ static int Serial = 1; /*!< Serial number. */ static int SavedSerial; static size_t UndoN; /*!< Number of entries. */ static size_t RedoN; /*!< Number of entries. */ static size_t UndoMax; /*!< Number of entries. */ static bool Locked = false; /*!< Do not add entries if. */ static bool andDraw = true; /* flag is set; prevents from */ /* infinite loops */ /* --------------------------------------------------------------------------- * some local prototypes */ static UndoListType *GetUndoSlot (int, int, int); static void DrawRecoveredObject (int, void *, void *, void *); static bool UndoRotate (UndoListType *); static bool UndoChangeName (UndoListType *); static bool UndoCopyOrCreate (UndoListType *); static bool UndoMove (UndoListType *); static bool UndoRemove (UndoListType *); static bool UndoRemovePoint (UndoListType *); static bool UndoInsertPoint (UndoListType *); static bool UndoRemoveContour (UndoListType *); static bool UndoInsertContour (UndoListType *); static bool UndoMoveToLayer (UndoListType *); static bool UndoFlag (UndoListType *); static bool UndoMirror (UndoListType *); static bool UndoChangeSize (UndoListType *); static bool UndoChange2ndSize (UndoListType *); static bool UndoChangeAngles (UndoListType *); static bool UndoChangeClearSize (UndoListType *); static bool UndoChangeMaskSize (UndoListType *); static bool UndoClearPoly (UndoListType *); static bool UndoSetViaLayers (UndoListType *); static int PerformUndo (UndoListType *); /*! * \brief Adds a command plus some data to the undo list. */ static UndoListType * GetUndoSlot (int CommandType, int ID, int Kind) { UndoListType *ptr; void *ptr1, *ptr2, *ptr3; int type; static size_t limit = UNDO_WARNING_SIZE; #ifdef DEBUG_ID if (SearchObjectByID (PCB->Data, &ptr1, &ptr2, &ptr3, ID, Kind) == NO_TYPE) Message ("hace: ID (%d) and Type (%x) mismatch in AddObject...\n", ID, Kind); #endif /* allocate memory */ if (UndoN >= UndoMax) { size_t size; UndoMax += STEP_UNDOLIST; size = UndoMax * sizeof (UndoListType); UndoList = (UndoListType *) realloc (UndoList, size); memset (&UndoList[UndoN], 0, STEP_REMOVELIST * sizeof (UndoListType)); /* ask user to flush the table because of it's size */ if (size > limit) { limit = (size / UNDO_WARNING_SIZE + 1) * UNDO_WARNING_SIZE; Message (_("Size of 'undo-list' exceeds %li kb\n"), (long) (size >> 10)); } } /* free structures from the pruned redo list */ for (ptr = &UndoList[UndoN]; RedoN; ptr++, RedoN--) switch (ptr->Type) { case UNDO_CHANGENAME: free (ptr->Data.ChangeName.Name); break; case UNDO_REMOVE: type = SearchObjectByID (RemoveList, &ptr1, &ptr2, &ptr3, ptr->ID, ptr->Kind); if (type != NO_TYPE) { DestroyObject (RemoveList, type, ptr1, ptr2, ptr3); } break; default: break; } if (between_increment_and_restore) added_undo_between_increment_and_restore = true; /* copy typefield and serial number to the list */ ptr = &UndoList[UndoN++]; ptr->Type = CommandType; ptr->Kind = Kind; ptr->ID = ID; ptr->Serial = Serial; return (ptr); } /*! * \brief Redraws the recovered object. */ static void DrawRecoveredObject (int Type, void *Ptr1, void *Ptr2, void *Ptr3) { if (Type & (LINE_TYPE | TEXT_TYPE | POLYGON_TYPE | ARC_TYPE)) { LayerType *layer; layer = LAYER_PTR (GetLayerNumber (RemoveList, (LayerType *) Ptr1)); DrawObject (Type, (void *) layer, Ptr2); } else DrawObject (Type, Ptr1, Ptr2); } /*! * \brief Recovers an object from a 'rotate' operation. * * \return true if anything has been recovered. */ static bool UndoRotate (UndoListType *Entry) { void *ptr1, *ptr2, *ptr3; int type; /* lookup entry by it's ID */ type = SearchObjectByID (PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); if (type != NO_TYPE) { RotateObject (type, ptr1, ptr2, ptr3, Entry->Data.Rotate.CenterX, Entry->Data.Rotate.CenterY, (4 - Entry->Data.Rotate.Steps) & 0x03); Entry->Data.Rotate.Steps = (4 - Entry->Data.Rotate.Steps) & 0x03; return (true); } return (false); } /*! * \brief Recovers an object from a clear/restore poly operation. * * \return true if anything has been recovered. */ static bool UndoClearPoly (UndoListType *Entry) { void *ptr1, *ptr2, *ptr3; int type; type = SearchObjectByID (PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); if (type != NO_TYPE) { if (Entry->Data.ClearPoly.Clear) RestoreToPolygon (PCB->Data, type, Entry->Data.ClearPoly.Layer, ptr3); else ClearFromPolygon (PCB->Data, type, Entry->Data.ClearPoly.Layer, ptr3); Entry->Data.ClearPoly.Clear = !Entry->Data.ClearPoly.Clear; return true; } return false; } /*! * \brief Recovers an object from a 'change name' operation. * * \return true if anything has been recovered. */ static bool UndoChangeName (UndoListType *Entry) { void *ptr1, *ptr2, *ptr3; int type; /* lookup entry by it's ID */ type = SearchObjectByID (PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); if (type != NO_TYPE) { Entry->Data.ChangeName.Name = (char *)(ChangeObjectName (type, ptr1, ptr2, ptr3, Entry->Data.ChangeName.Name)); return (true); } return (false); } /*! * \brief Recovers an object from a 2ndSize change operation. */ static bool UndoChange2ndSize (UndoListType *Entry) { void *ptr1, *ptr2, *ptr3; int type; Coord swap; /* lookup entry by ID */ type = SearchObjectByID (PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); if (type != NO_TYPE) { swap = ((PinType *) ptr2)->DrillingHole; if (andDraw) EraseObject (type, ptr1, ptr2); ((PinType *) ptr2)->DrillingHole = Entry->Data.Size; Entry->Data.Size = swap; DrawObject (type, ptr1, ptr2); return (true); } return (false); } /*! * \brief Recovers an object from a ChangeAngles change operation. */ static bool UndoChangeAngles (UndoListType *Entry) { void *ptr1, *ptr2, *ptr3; int type; long int old_sa, old_da; /* lookup entry by ID */ type = SearchObjectByID (PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); if (type == ARC_TYPE) { LayerType *Layer = (LayerType *) ptr1; ArcType *a = (ArcType *) ptr2; r_delete_entry (Layer->arc_tree, (BoxType *) a); old_sa = a->StartAngle; old_da = a->Delta; if (andDraw) EraseObject (type, Layer, a); a->StartAngle = Entry->Data.Move.DX; a->Delta = Entry->Data.Move.DY; SetArcBoundingBox (a); r_insert_entry (Layer->arc_tree, (BoxType *) a, 0); Entry->Data.Move.DX = old_sa; Entry->Data.Move.DY = old_da;; DrawObject (type, ptr1, a); return (true); } return (false); } /*! * \brief Recovers an object from a clearance size change operation. */ static bool UndoChangeClearSize (UndoListType *Entry) { void *ptr1, *ptr2, *ptr3; int type; Coord swap; /* lookup entry by ID */ type = SearchObjectByID (PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); if (type != NO_TYPE) { swap = ((PinType *) ptr2)->Clearance; RestoreToPolygon (PCB->Data, type, ptr1, ptr2); if (andDraw) EraseObject (type, ptr1, ptr2); ((PinType *) ptr2)->Clearance = Entry->Data.Size; ClearFromPolygon (PCB->Data, type, ptr1, ptr2); Entry->Data.Size = swap; if (andDraw) DrawObject (type, ptr1, ptr2); return (true); } return (false); } /*! * \brief Recovers an object from a mask size change operation. */ static bool UndoChangeMaskSize (UndoListType *Entry) { void *ptr1, *ptr2, *ptr3; int type; Coord swap; /* lookup entry by ID */ type = SearchObjectByID (PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); if (type & (VIA_TYPE | PIN_TYPE | PAD_TYPE)) { swap = (type == PAD_TYPE ? ((PadType *) ptr2)->Mask : ((PinType *) ptr2)->Mask); if (andDraw) EraseObject (type, ptr1, ptr2); if (type == PAD_TYPE) ((PadType *) ptr2)->Mask = Entry->Data.Size; else ((PinType *) ptr2)->Mask = Entry->Data.Size; Entry->Data.Size = swap; if (andDraw) DrawObject (type, ptr1, ptr2); return (true); } return (false); } /*! * \brief Recovers an object from a Size change operation. */ static bool UndoChangeSize (UndoListType *Entry) { void *ptr1, *ptr2, *ptr3; int type, iswap = 0; Coord swap = 0; /* lookup entry by ID */ type = SearchObjectByID (PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); if (type != NO_TYPE) { /* Wow! can any object be treated as a pin type for size change?? */ /* pins, vias, lines, and arcs can. Text can't but it has it's own mechanism */ switch (type) { case PIN_TYPE: case VIA_TYPE: swap = ((PinType *) ptr2)->Thickness; break; case LINE_TYPE: case ELEMENTLINE_TYPE: swap = ((LineType *) ptr2)->Thickness; break; case TEXT_TYPE: case ELEMENTNAME_TYPE: iswap = ((TextType *) ptr2)->Scale; break; case PAD_TYPE: swap = ((PadType *) ptr2)->Thickness; break; case ARC_TYPE: case ELEMENTARC_TYPE: swap = ((ArcType *) ptr2)->Thickness; break; } RestoreToPolygon (PCB->Data, type, ptr1, ptr2); if (andDraw) EraseObject (type, ptr1, ptr2); switch (type) { case PIN_TYPE: case VIA_TYPE: ((PinType *) ptr2)->Thickness = Entry->Data.Size; Entry->Data.Size = swap; break; case LINE_TYPE: case ELEMENTLINE_TYPE: ((LineType *) ptr2)->Thickness = Entry->Data.Size; Entry->Data.Size = swap; break; case TEXT_TYPE: case ELEMENTNAME_TYPE: ((TextType *) ptr2)->Scale = Entry->Data.Scale; Entry->Data.Scale = iswap; break; case PAD_TYPE: ((PadType *) ptr2)->Thickness = Entry->Data.Size; Entry->Data.Size = swap; break; case ARC_TYPE: case ELEMENTARC_TYPE: ((ArcType *) ptr2)->Thickness = Entry->Data.Size; Entry->Data.Size = swap; break; } ClearFromPolygon (PCB->Data, type, ptr1, ptr2); if (andDraw) DrawObject (type, ptr1, ptr2); return (true); } return (false); } /*! * \brief Recovers an object from a FLAG change operation. */ static bool UndoFlag (UndoListType *Entry) { void *ptr1, *ptr2, *ptr3; int type; FlagType swap; int must_redraw; /* lookup entry by ID */ type = SearchObjectByID (PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); if (type != NO_TYPE) { FlagType f1, f2; PinType *pin = (PinType *) ptr2; swap = pin->Flags; must_redraw = 0; f1 = MaskFlags (pin->Flags, ~DRAW_FLAGS); f2 = MaskFlags (Entry->Data.Flags, ~DRAW_FLAGS); if (!FLAGS_EQUAL (f1, f2)) must_redraw = 1; if (andDraw && must_redraw) EraseObject (type, ptr1, ptr2); pin->Flags = Entry->Data.Flags; Entry->Data.Flags = swap; if (andDraw && must_redraw) DrawObject (type, ptr1, ptr2); return (true); } Message ("hace Internal error: Can't find ID %d type %08x\n", Entry->ID, Entry->Kind); Message ("for UndoFlag Operation. Previous flags: %s\n", flags_to_string (Entry->Data.Flags, 0)); return (false); } /*! * \brief Recovers an object from a mirror operation. * * \return true if anything has been recovered. */ static bool UndoMirror (UndoListType *Entry) { void *ptr1, *ptr2, *ptr3; int type; /* lookup entry by ID */ type = SearchObjectByID (PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); if (type == ELEMENT_TYPE) { ElementType *element = (ElementType *) ptr3; if (andDraw) EraseElement (element); MirrorElementCoordinates (PCB->Data, element, Entry->Data.Move.DY); if (andDraw) DrawElement (element); return (true); } Message ("hace Internal error: UndoMirror on object type %d\n", type); return (false); } /*! * \brief Recovers an object from a 'copy' or 'create' operation. * * \return true if anything has been recovered. */ static bool UndoCopyOrCreate (UndoListType *Entry) { void *ptr1, *ptr2, *ptr3; int type; /* lookup entry by it's ID */ type = SearchObjectByID (PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); if (type != NO_TYPE) { if (!RemoveList) RemoveList = CreateNewBuffer (); if (andDraw) EraseObject (type, ptr1, ptr2); /* in order to make this re-doable we move it to the RemoveList */ MoveObjectToBuffer (RemoveList, PCB->Data, type, ptr1, ptr2, ptr3); Entry->Type = UNDO_REMOVE; return (true); } return (false); } /*! * \brief Recovers an object from a 'move' operation. * * \return true if anything has been recovered. */ static bool UndoMove (UndoListType *Entry) { void *ptr1, *ptr2, *ptr3; int type; /* lookup entry by it's ID */ type = SearchObjectByID (PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); if (type != NO_TYPE) { MoveObject (type, ptr1, ptr2, ptr3, -Entry->Data.Move.DX, -Entry->Data.Move.DY); Entry->Data.Move.DX *= -1; Entry->Data.Move.DY *= -1; return (true); } return (false); } /*! * \brief Recovers an object from a 'remove' operation. * * \return true if anything has been recovered. */ static bool UndoRemove (UndoListType *Entry) { void *ptr1, *ptr2, *ptr3; int type; /* lookup entry by it's ID */ type = SearchObjectByID (RemoveList, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); if (type != NO_TYPE) { if (andDraw) DrawRecoveredObject (type, ptr1, ptr2, ptr3); MoveObjectToBuffer (PCB->Data, RemoveList, type, ptr1, ptr2, ptr3); Entry->Type = UNDO_CREATE; return (true); } return (false); } /*! * \brief Recovers an object from a 'move to another layer' operation. * * \return true if anything has been recovered. */ static bool UndoMoveToLayer (UndoListType *Entry) { void *ptr1, *ptr2, *ptr3; int type, swap; /* lookup entry by it's ID */ type = SearchObjectByID (PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); if (type != NO_TYPE) { swap = GetLayerNumber (PCB->Data, (LayerType *) ptr1); MoveObjectToLayer (type, ptr1, ptr2, ptr3, LAYER_PTR (Entry->Data. MoveToLayer.OriginalLayer), true); Entry->Data.MoveToLayer.OriginalLayer = swap; return (true); } return (false); } /*! * \brief Recovers a removed polygon point. * * \return true on success. */ static bool UndoRemovePoint (UndoListType *Entry) { LayerType *layer; PolygonType *polygon; void *ptr3; int type; /* lookup entry (polygon not point was saved) by it's ID */ assert (Entry->Kind == POLYGON_TYPE); type = SearchObjectByID (PCB->Data, (void **) &layer, (void **) &polygon, &ptr3, Entry->ID, Entry->Kind); switch (type) { case POLYGON_TYPE: /* restore the removed point */ { /* recover the point */ if (andDraw && layer->On) ErasePolygon (polygon); InsertPointIntoObject (POLYGON_TYPE, layer, polygon, &Entry->Data.RemovedPoint.Index, Entry->Data.RemovedPoint.X, Entry->Data.RemovedPoint.Y, true, Entry->Data.RemovedPoint.last_in_contour); polygon->Points[Entry->Data.RemovedPoint.Index].ID = Entry->Data.RemovedPoint.ID; if (andDraw && layer->On) DrawPolygon (layer, polygon); Entry->Type = UNDO_INSERT_POINT; Entry->ID = Entry->Data.RemovedPoint.ID; Entry->Kind = POLYGONPOINT_TYPE; return (true); } default: return (false); } } /*! * \brief Recovers an inserted polygon point. * * \return true on success. */ static bool UndoInsertPoint (UndoListType *Entry) { LayerType *layer; PolygonType *polygon; PointType *pnt; int type; Cardinal point_idx; Cardinal hole; bool last_in_contour = false; assert (Entry->Kind == POLYGONPOINT_TYPE); /* lookup entry by it's ID */ type = SearchObjectByID (PCB->Data, (void **) &layer, (void **) &polygon, (void **) &pnt, Entry->ID, Entry->Kind); switch (type) { case POLYGONPOINT_TYPE: /* removes an inserted polygon point */ { if (andDraw && layer->On) ErasePolygon (polygon); /* Check whether this point was at the end of its contour. * If so, we need to flag as such when re-adding the point * so it goes back in the correct place */ point_idx = polygon_point_idx (polygon, pnt); for (hole = 0; hole < polygon->HoleIndexN; hole++) if (point_idx == polygon->HoleIndex[hole] - 1) last_in_contour = true; if (point_idx == polygon->PointN - 1) last_in_contour = true; Entry->Data.RemovedPoint.last_in_contour = last_in_contour; Entry->Data.RemovedPoint.X = pnt->X; Entry->Data.RemovedPoint.Y = pnt->Y; Entry->Data.RemovedPoint.ID = pnt->ID; Entry->ID = polygon->ID; Entry->Kind = POLYGON_TYPE; Entry->Type = UNDO_REMOVE_POINT; Entry->Data.RemovedPoint.Index = point_idx; DestroyObject (PCB->Data, POLYGONPOINT_TYPE, layer, polygon, pnt); if (andDraw && layer->On) DrawPolygon (layer, polygon); return (true); } default: return (false); } } static bool UndoSwapCopiedObject (UndoListType *Entry) { void *ptr1, *ptr2, *ptr3; void *ptr1b, *ptr2b, *ptr3b; AnyObjectType *obj, *obj2; int type; long int swap_id; /* lookup entry by it's ID */ type = SearchObjectByID (RemoveList, &ptr1, &ptr2, &ptr3, Entry->Data.CopyID, Entry->Kind); if (type == NO_TYPE) return false; type = SearchObjectByID (PCB->Data, &ptr1b, &ptr2b, &ptr3b, Entry->ID, Entry->Kind); if (type == NO_TYPE) return FALSE; obj = (AnyObjectType *)ptr2; obj2 = (AnyObjectType *)ptr2b; swap_id = obj->ID; obj->ID = obj2->ID; obj2->ID = swap_id; MoveObjectToBuffer (RemoveList, PCB->Data, type, ptr1b, ptr2b, ptr3b); if (andDraw) DrawRecoveredObject (Entry->Kind, ptr1, ptr2, ptr3); obj = (AnyObjectType *)MoveObjectToBuffer (PCB->Data, RemoveList, type, ptr1, ptr2, ptr3); if (Entry->Kind == POLYGON_TYPE) InitClip (PCB->Data, (LayerType *)ptr1b, (PolygonType *)obj); return (true); } /*! * \brief Recovers an removed polygon point. * * \return true on success. */ static bool UndoRemoveContour (UndoListType *Entry) { assert (Entry->Kind == POLYGON_TYPE); return UndoSwapCopiedObject (Entry); } /*! * \brief Recovers an inserted polygon point. * * \return true on success. */ static bool UndoInsertContour (UndoListType *Entry) { assert (Entry->Kind == POLYGON_TYPE); return UndoSwapCopiedObject (Entry); } /*! * \brief Undo a layer change. * * \return true on success. */ static bool UndoLayerChange (UndoListType *Entry) { LayerChangeType *l = &Entry->Data.LayerChange; int tmp; tmp = l->new_index; l->new_index = l->old_index; l->old_index = tmp; if (MoveLayer (l->old_index, l->new_index)) return false; else return true; } /*! * \brief Undo a netlist change. * * \return true on success. */ static bool UndoNetlistChange (UndoListType *Entry) { NetlistChangeType *l = & Entry->Data.NetlistChange; unsigned int i, j; LibraryType *lib, *saved; lib = l->lib; saved = l->old; /* iterate over each net */ for (i = 0 ; i < lib->MenuN; i++) { if (lib->Menu[i].Name) free (lib->Menu[i].Name); if (lib->Menu[i].directory) free (lib->Menu[i].directory); if (lib->Menu[i].Style) free (lib->Menu[i].Style); /* iterate over each pin on the net */ for (j = 0; j < lib->Menu[i].EntryN; j++) { if (lib->Menu[i].Entry[j].ListEntry) free (lib->Menu[i].Entry[j].ListEntry); if (lib->Menu[i].Entry[j].AllocatedMemory) free (lib->Menu[i].Entry[j].AllocatedMemory); if (lib->Menu[i].Entry[j].Template) free (lib->Menu[i].Entry[j].Template); if (lib->Menu[i].Entry[j].Package) free (lib->Menu[i].Entry[j].Package); if (lib->Menu[i].Entry[j].Value) free (lib->Menu[i].Entry[j].Value); if (lib->Menu[i].Entry[j].Description) free (lib->Menu[i].Entry[j].Description); } } if (lib->Menu) free (lib->Menu); *lib = *saved; NetlistChanged (0); return true; } /*! * \brief Recovers an object from a Size change operation. */ static bool UndoSetViaLayers (UndoListType *Entry) { void *ptr1, *ptr2, *ptr3; int type; int from, to; /* lookup entry by ID */ type = SearchObjectByID (PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); if (type == VIA_TYPE) { from = ((PinType *) ptr2)->BuriedFrom; to = ((PinType *) ptr2)->BuriedTo; RestoreToPolygon (PCB->Data, type, ptr1, ptr2); if (andDraw) EraseObject (type, ptr1, ptr2); ((PinType *) ptr2)->BuriedFrom = Entry->Data.SetViaLayersChange.from; ((PinType *) ptr2)->BuriedTo = Entry->Data.SetViaLayersChange.to; Entry->Data.SetViaLayersChange.from = from; Entry->Data.SetViaLayersChange.to = to; ClearFromPolygon (PCB->Data, type, ptr1, ptr2); if (andDraw) DrawObject (type, ptr1, ptr2); return (true); } return (false); } /*! * \brief Undo of any 'hard to recover' operation. * * \return The bitfield for the types of operations that were undone. */ int Undo (bool draw) { UndoListType *ptr; int Types = 0; int unique; bool error_undoing = false; unique = TEST_FLAG (UNIQUENAMEFLAG, PCB); CLEAR_FLAG (UNIQUENAMEFLAG, PCB); andDraw = draw; if (Serial == 0) { Message (_("ERROR: Attempt to Undo() with Serial == 0\n" " Please save your work and report this bug.\n")); return 0; } if (UndoN == 0) { Message (_("Nothing to undo - buffer is empty\n")); return 0; } Serial --; ptr = &UndoList[UndoN - 1]; if (ptr->Serial > Serial) { Message (_("ERROR: Bad undo serial number %d in undo stack - expecting %d or lower\n" " Please save your work and report this bug.\n"), ptr->Serial, Serial); /* It is likely that the serial number got corrupted through some bad * use of the SaveUndoSerialNumber() / RestoreUndoSerialNumber() APIs. * * Reset the serial number to be consistent with that of the last * operation on the undo stack in the hope that this might clear * the problem and allow the user to hit Undo again. */ Serial = ptr->Serial + 1; return 0; } LockUndo (); /* lock undo module to prevent from loops */ /* Loop over all entries with the correct serial number */ for (; UndoN && ptr->Serial == Serial; ptr--, UndoN--, RedoN++) { int undid = PerformUndo (ptr); if (undid == 0) error_undoing = true; Types |= undid; } UnlockUndo (); if (error_undoing) Message (_("ERROR: Failed to undo some operations\n")); if (Types && andDraw) Draw (); /* restore the unique flag setting */ if (unique) SET_FLAG (UNIQUENAMEFLAG, PCB); return Types; } static int PerformUndo (UndoListType *ptr) { switch (ptr->Type) { case UNDO_CHANGENAME: if (UndoChangeName (ptr)) return (UNDO_CHANGENAME); break; case UNDO_CREATE: if (UndoCopyOrCreate (ptr)) return (UNDO_CREATE); break; case UNDO_MOVE: if (UndoMove (ptr)) return (UNDO_MOVE); break; case UNDO_REMOVE: if (UndoRemove (ptr)) return (UNDO_REMOVE); break; case UNDO_REMOVE_POINT: if (UndoRemovePoint (ptr)) return (UNDO_REMOVE_POINT); break; case UNDO_INSERT_POINT: if (UndoInsertPoint (ptr)) return (UNDO_INSERT_POINT); break; case UNDO_REMOVE_CONTOUR: if (UndoRemoveContour (ptr)) return (UNDO_REMOVE_CONTOUR); break; case UNDO_INSERT_CONTOUR: if (UndoInsertContour (ptr)) return (UNDO_INSERT_CONTOUR); break; case UNDO_ROTATE: if (UndoRotate (ptr)) return (UNDO_ROTATE); break; case UNDO_CLEAR: if (UndoClearPoly (ptr)) return (UNDO_CLEAR); break; case UNDO_MOVETOLAYER: if (UndoMoveToLayer (ptr)) return (UNDO_MOVETOLAYER); break; case UNDO_FLAG: if (UndoFlag (ptr)) return (UNDO_FLAG); break; case UNDO_CHANGESIZE: if (UndoChangeSize (ptr)) return (UNDO_CHANGESIZE); break; case UNDO_CHANGECLEARSIZE: if (UndoChangeClearSize (ptr)) return (UNDO_CHANGECLEARSIZE); break; case UNDO_CHANGEMASKSIZE: if (UndoChangeMaskSize (ptr)) return (UNDO_CHANGEMASKSIZE); break; case UNDO_CHANGE2NDSIZE: if (UndoChange2ndSize (ptr)) return (UNDO_CHANGE2NDSIZE); break; case UNDO_CHANGEANGLES: if (UndoChangeAngles (ptr)) return (UNDO_CHANGEANGLES); break; case UNDO_LAYERCHANGE: if (UndoLayerChange (ptr)) return (UNDO_LAYERCHANGE); break; case UNDO_NETLISTCHANGE: if (UndoNetlistChange (ptr)) return (UNDO_NETLISTCHANGE); break; case UNDO_MIRROR: if (UndoMirror (ptr)) return (UNDO_MIRROR); break; case UNDO_CHANGESETVIALAYERS: if (UndoSetViaLayers (ptr)) return (UNDO_CHANGESETVIALAYERS); break; } return 0; } /*! * \brief Redo of any 'hard to recover' operation. * * \return The number of operations redone. */ int Redo (bool draw) { UndoListType *ptr; int Types = 0; bool error_undoing = false; andDraw = draw; if (RedoN == 0) { Message (_("Nothing to redo. Perhaps changes have been made since last undo\n")); return 0; } ptr = &UndoList[UndoN]; if (ptr->Serial < Serial) { Message (_("ERROR: Bad undo serial number %d in redo stack - expecting %d or higher\n" " Please save your work and report this bug.\n"), ptr->Serial, Serial); /* It is likely that the serial number got corrupted through some bad * use of the SaveUndoSerialNumber() / RestoreUndoSerialNumber() APIs. * * Reset the serial number to be consistent with that of the first * operation on the redo stack in the hope that this might clear * the problem and allow the user to hit Redo again. */ Serial = ptr->Serial; return 0; } LockUndo (); /* lock undo module to prevent from loops */ /* and loop over all entries with the correct serial number */ for (; RedoN && ptr->Serial == Serial; ptr++, UndoN++, RedoN--) { int undid = PerformUndo (ptr); if (undid == 0) error_undoing = true; Types |= undid; } /* Make next serial number current */ Serial++; UnlockUndo (); if (error_undoing) Message (_("ERROR: Failed to redo some operations\n")); if (Types && andDraw) Draw (); return Types; } /*! * \brief Restores the serial number of the undo list. * * Returns the current undo serial number, after the restore. */ int RestoreUndoSerialNumber (void) { if (added_undo_between_increment_and_restore) Message (_("ERROR: Operations were added to the Undo stack with an incorrect serial number\n")); between_increment_and_restore = false; added_undo_between_increment_and_restore = false; Serial = SavedSerial; return Serial; } /*! * \brief Saves the serial number of the undo list. * * Returns the current undo serial number. */ int SaveUndoSerialNumber (void) { Bumped = false; between_increment_and_restore = false; added_undo_between_increment_and_restore = false; SavedSerial = Serial; return Serial; } /*! * \brief Increments the serial number of the undo list. * * It's not done automatically because some operations perform more * than one request with the same serial #. * * Returns the undo serial number after the increment. */ int IncrementUndoSerialNumber (void) { if (!Locked) { /* Set the changed flag if anything was added prior to this bump */ if (UndoN > 0 && UndoList[UndoN - 1].Serial == Serial) SetChangedFlag (true); Serial++; Bumped = true; between_increment_and_restore = true; return Serial; } return -1; } /*! * \brief Merge range of undo serial numbers into one. * * The purpose of this is to combine multiple undo operations into a * single one. * * Any undo operation that has a serial number inclusively in the * range (min, max) gets reassigned the number min. Everything > max is * shifted down so that the serial numbers remain contiguous. * * This should not interfere with operations that have added things to the * undo list but not yet incremented the serial number. * * Returns the current undo serial number, after the operations. */ int MergeUndoSerialRange(int min, int max) { size_t n; int dsn = max - min; /* delta serial number */ for(n = 0; n < UndoN; n++) { if (UndoList[n].Serial < min) continue; else if (UndoList[n].Serial <= max) UndoList[n].Serial = min; /* greater than max */ else UndoList[n].Serial -= dsn; } Serial -= dsn; return Serial; } /*! * \brief Releases memory of the undo- and remove list. */ void ClearUndoList (bool Force) { UndoListType *undo; if (UndoN && (Force || gui->confirm_dialog ("OK to clear 'undo' buffer?", 0))) { /* release memory allocated by objects in undo list */ for (undo = UndoList; UndoN; undo++, UndoN--) { if (undo->Type == UNDO_CHANGENAME) free (undo->Data.ChangeName.Name); } free (UndoList); UndoList = NULL; if (RemoveList) { FreeDataMemory (RemoveList); free (RemoveList); RemoveList = NULL; } /* reset some counters */ UndoN = UndoMax = RedoN = 0; } /* reset counter in any case */ Serial = 1; } /*! * \brief Adds an object to the list of clearpoly objects. */ void AddObjectToClearPolyUndoList (int Type, void *Ptr1, void *Ptr2, void *Ptr3, bool clear) { UndoListType *undo; if (!Locked) { undo = GetUndoSlot (UNDO_CLEAR, OBJECT_ID (Ptr3), Type); undo->Data.ClearPoly.Clear = clear; undo->Data.ClearPoly.Layer = (LayerType *) Ptr1; } } /*! * \brief Adds an object to the list of mirrored objects. */ void AddObjectToMirrorUndoList (int Type, void *Ptr1, void *Ptr2, void *Ptr3, Coord yoff) { UndoListType *undo; if (!Locked) { undo = GetUndoSlot (UNDO_MIRROR, OBJECT_ID (Ptr3), Type); undo->Data.Move.DY = yoff; } } /*! * \brief Adds an object to the list of rotated objects. */ void AddObjectToRotateUndoList (int Type, void *Ptr1, void *Ptr2, void *Ptr3, Coord CenterX, Coord CenterY, BYTE Steps) { UndoListType *undo; if (!Locked) { undo = GetUndoSlot (UNDO_ROTATE, OBJECT_ID (Ptr3), Type); undo->Data.Rotate.CenterX = CenterX; undo->Data.Rotate.CenterY = CenterY; undo->Data.Rotate.Steps = Steps; } } /*! * \brief Adds an object to the list of removed objects and removes it * from the current PCB. */ void MoveObjectToRemoveUndoList (int Type, void *Ptr1, void *Ptr2, void *Ptr3) { if (Locked) return; if (!RemoveList) RemoveList = CreateNewBuffer (); GetUndoSlot (UNDO_REMOVE, OBJECT_ID (Ptr3), Type); MoveObjectToBuffer (RemoveList, PCB->Data, Type, Ptr1, Ptr2, Ptr3); } /*! * \brief Adds an object to the list of removed polygon/... points. */ void AddObjectToRemovePointUndoList (int Type, void *Ptr1, void *Ptr2, Cardinal index) { UndoListType *undo; PolygonType *polygon = (PolygonType *) Ptr2; Cardinal hole; bool last_in_contour = false; if (!Locked) { switch (Type) { case POLYGONPOINT_TYPE: { /* save the ID of the parent object; else it will be * impossible to recover the point */ undo = GetUndoSlot (UNDO_REMOVE_POINT, OBJECT_ID (polygon), POLYGON_TYPE); undo->Data.RemovedPoint.X = polygon->Points[index].X; undo->Data.RemovedPoint.Y = polygon->Points[index].Y; undo->Data.RemovedPoint.ID = polygon->Points[index].ID; undo->Data.RemovedPoint.Index = index; /* Check whether this point was at the end of its contour. * If so, we need to flag as such when re-adding the point * so it goes back in the correct place */ for (hole = 0; hole < polygon->HoleIndexN; hole++) if (index == polygon->HoleIndex[hole] - 1) last_in_contour = true; if (index == polygon->PointN - 1) last_in_contour = true; undo->Data.RemovedPoint.last_in_contour = last_in_contour; } break; } } } /*! * \brief Adds an object to the list of inserted polygon/... points. */ void AddObjectToInsertPointUndoList (int Type, void *Ptr1, void *Ptr2, void *Ptr3) { if (!Locked) GetUndoSlot (UNDO_INSERT_POINT, OBJECT_ID (Ptr3), Type); } static void CopyObjectToUndoList (int undo_type, int Type, void *Ptr1, void *Ptr2, void *Ptr3) { UndoListType *undo; AnyObjectType *copy; if (Locked) return; if (!RemoveList) RemoveList = CreateNewBuffer (); undo = GetUndoSlot (undo_type, OBJECT_ID (Ptr2), Type); copy = (AnyObjectType *)CopyObjectToBuffer (RemoveList, PCB->Data, Type, Ptr1, Ptr2, Ptr3); undo->Data.CopyID = copy->ID; } /*! * \brief Adds an object to the list of removed contours. * * Actually just takes a copy of the whole polygon to restore. */ void AddObjectToRemoveContourUndoList (int Type, LayerType *Layer, PolygonType *Polygon) { CopyObjectToUndoList (UNDO_REMOVE_CONTOUR, Type, Layer, Polygon, NULL); } /*! * \brief Adds an object to the list of insert contours. * * Actually just takes a copy of the whole polygon to restore. */ void AddObjectToInsertContourUndoList (int Type, LayerType *Layer, PolygonType *Polygon) { CopyObjectToUndoList (UNDO_INSERT_CONTOUR, Type, Layer, Polygon, NULL); } /*! * \brief Adds an object to the list of moved objects. */ void AddObjectToMoveUndoList (int Type, void *Ptr1, void *Ptr2, void *Ptr3, Coord DX, Coord DY) { UndoListType *undo; if (!Locked) { undo = GetUndoSlot (UNDO_MOVE, OBJECT_ID (Ptr3), Type); undo->Data.Move.DX = DX; undo->Data.Move.DY = DY; } } /*! * \brief Adds an object to the list of objects with changed names. */ void AddObjectToChangeNameUndoList (int Type, void *Ptr1, void *Ptr2, void *Ptr3, char *OldName) { UndoListType *undo; if (!Locked) { undo = GetUndoSlot (UNDO_CHANGENAME, OBJECT_ID (Ptr3), Type); undo->Data.ChangeName.Name = OldName; } } /*! * \brief Adds an object to the list of objects moved to another layer. */ void AddObjectToMoveToLayerUndoList (int Type, void *Ptr1, void *Ptr2, void *Ptr3) { UndoListType *undo; if (!Locked) { undo = GetUndoSlot (UNDO_MOVETOLAYER, OBJECT_ID (Ptr3), Type); undo->Data.MoveToLayer.OriginalLayer = GetLayerNumber (PCB->Data, (LayerType *) Ptr1); } } /*! * \brief Adds an object to the list of created objects. */ void AddObjectToCreateUndoList (int Type, void *Ptr1, void *Ptr2, void *Ptr3) { if (!Locked) GetUndoSlot (UNDO_CREATE, OBJECT_ID (Ptr3), Type); ClearFromPolygon (PCB->Data, Type, Ptr1, Ptr2); } /*! * \brief Adds an object to the list of objects with flags changed. */ void AddObjectToFlagUndoList (int Type, void *Ptr1, void *Ptr2, void *Ptr3) { UndoListType *undo; if (!Locked) { undo = GetUndoSlot (UNDO_FLAG, OBJECT_ID (Ptr2), Type); undo->Data.Flags = ((PinType *) Ptr2)->Flags; } } /*! * \brief Adds an object to the list of objects with Size changes. */ void AddObjectToSizeUndoList (int Type, void *ptr1, void *ptr2, void *ptr3) { UndoListType *undo; if (!Locked) { undo = GetUndoSlot (UNDO_CHANGESIZE, OBJECT_ID (ptr2), Type); switch (Type) { case PIN_TYPE: case VIA_TYPE: undo->Data.Size = ((PinType *) ptr2)->Thickness; break; case LINE_TYPE: case ELEMENTLINE_TYPE: undo->Data.Size = ((LineType *) ptr2)->Thickness; break; case TEXT_TYPE: case ELEMENTNAME_TYPE: undo->Data.Scale = ((TextType *) ptr2)->Scale; break; case PAD_TYPE: undo->Data.Size = ((PadType *) ptr2)->Thickness; break; case ARC_TYPE: case ELEMENTARC_TYPE: undo->Data.Size = ((ArcType *) ptr2)->Thickness; break; } } } /*! * \brief Adds an object to the list of objects with Size changes. */ void AddObjectToClearSizeUndoList (int Type, void *ptr1, void *ptr2, void *ptr3) { UndoListType *undo; if (!Locked) { undo = GetUndoSlot (UNDO_CHANGECLEARSIZE, OBJECT_ID (ptr2), Type); switch (Type) { case PIN_TYPE: case VIA_TYPE: undo->Data.Size = ((PinType *) ptr2)->Clearance; break; case LINE_TYPE: undo->Data.Size = ((LineType *) ptr2)->Clearance; break; case PAD_TYPE: undo->Data.Size = ((PadType *) ptr2)->Clearance; break; case ARC_TYPE: undo->Data.Size = ((ArcType *) ptr2)->Clearance; break; } } } /*! * \brief Adds an object to the list of objects with Size changes. */ void AddObjectToMaskSizeUndoList (int Type, void *ptr1, void *ptr2, void *ptr3) { UndoListType *undo; if (!Locked) { undo = GetUndoSlot (UNDO_CHANGEMASKSIZE, OBJECT_ID (ptr2), Type); switch (Type) { case PIN_TYPE: case VIA_TYPE: undo->Data.Size = ((PinType *) ptr2)->Mask; break; case PAD_TYPE: undo->Data.Size = ((PadType *) ptr2)->Mask; break; } } } /*! * \brief Adds an object to the list of objects with 2ndSize changes. */ void AddObjectTo2ndSizeUndoList (int Type, void *ptr1, void *ptr2, void *ptr3) { UndoListType *undo; if (!Locked) { undo = GetUndoSlot (UNDO_CHANGE2NDSIZE, OBJECT_ID (ptr2), Type); if (Type == PIN_TYPE || Type == VIA_TYPE) undo->Data.Size = ((PinType *) ptr2)->DrillingHole; } } /*! * \brief Adds an object to the list of changed angles. * * \note You must call this before changing the angles, passing the new * start/delta. */ void AddObjectToChangeAnglesUndoList (int Type, void *Ptr1, void *Ptr2, void *Ptr3) { UndoListType *undo; ArcType *a = (ArcType *) Ptr3; if (!Locked) { undo = GetUndoSlot (UNDO_CHANGEANGLES, OBJECT_ID (Ptr3), Type); undo->Data.Move.DX = a->StartAngle; undo->Data.Move.DY = a->Delta; } } /*! * \brief Adds a layer change (new, delete, move) to the undo list. */ void AddLayerChangeToUndoList (int old_index, int new_index) { UndoListType *undo; if (!Locked) { undo = GetUndoSlot (UNDO_LAYERCHANGE, 0, 0); undo->Data.LayerChange.old_index = old_index; undo->Data.LayerChange.new_index = new_index; } } /*! * \brief Adds a netlist change to the undo list. */ void AddNetlistLibToUndoList (LibraryType *lib) { UndoListType *undo; unsigned int i, j; LibraryType *old; if (!Locked) { undo = GetUndoSlot (UNDO_NETLISTCHANGE, 0, 0); /* keep track of where the data needs to go */ undo->Data.NetlistChange.lib = lib; /* and what the old data is that we'll need to restore */ undo->Data.NetlistChange.old = (LibraryType *)malloc (sizeof (LibraryType)); old = undo->Data.NetlistChange.old; old->MenuN = lib->MenuN; old->MenuMax = lib->MenuMax; old->Menu = (LibraryMenuType *)malloc (old->MenuMax * sizeof (LibraryMenuType)); if (old->Menu == NULL) { fprintf (stderr, "malloc() failed in %s\n", __FUNCTION__); exit (1); } /* iterate over each net */ for (i = 0 ; i < lib->MenuN; i++) { old->Menu[i].EntryN = lib->Menu[i].EntryN; old->Menu[i].EntryMax = lib->Menu[i].EntryMax; old->Menu[i].Name = lib->Menu[i].Name ? strdup (lib->Menu[i].Name) : NULL; old->Menu[i].directory = lib->Menu[i].directory ? strdup (lib->Menu[i].directory) : NULL; old->Menu[i].Style = lib->Menu[i].Style ? strdup (lib->Menu[i].Style) : NULL; old->Menu[i].Entry = (LibraryEntryType *)malloc (old->Menu[i].EntryMax * sizeof (LibraryEntryType)); if (old->Menu[i].Entry == NULL) { fprintf (stderr, "malloc() failed in %s\n", __FUNCTION__); exit (1); } /* iterate over each pin on the net */ for (j = 0; j < lib->Menu[i].EntryN; j++) { old->Menu[i].Entry[j].ListEntry = lib->Menu[i].Entry[j].ListEntry ? strdup (lib->Menu[i].Entry[j].ListEntry) : NULL; old->Menu[i].Entry[j].AllocatedMemory = lib->Menu[i].Entry[j].AllocatedMemory ? strdup (lib->Menu[i].Entry[j].AllocatedMemory) : NULL; old->Menu[i].Entry[j].Template = lib->Menu[i].Entry[j].Template ? strdup (lib->Menu[i].Entry[j].Template) : NULL; old->Menu[i].Entry[j].Package = lib->Menu[i].Entry[j].Package ? strdup (lib->Menu[i].Entry[j].Package) : NULL; old->Menu[i].Entry[j].Value = lib->Menu[i].Entry[j].Value ? strdup (lib->Menu[i].Entry[j].Value) : NULL; old->Menu[i].Entry[j].Description = lib->Menu[i].Entry[j].Description ? strdup (lib->Menu[i].Entry[j].Description) : NULL; } } } } /*! * \brief Adds an object to the list of objects with buried info data. */ void AddObjectToSetViaLayersUndoList (void *ptr1, void *ptr2, void *ptr3) { UndoListType *undo; if (!Locked) { undo = GetUndoSlot (UNDO_CHANGESETVIALAYERS, OBJECT_ID (ptr2), VIA_TYPE); undo->Data.SetViaLayersChange.from = ((PinType *) ptr2)->BuriedFrom; undo->Data.SetViaLayersChange.to = ((PinType *) ptr2)->BuriedTo; } } /*! * \brief Set lock flag */ void LockUndo (void) { Locked = true; } /*! * \brief Reset lock flag. */ void UnlockUndo (void) { Locked = false; } /*! * \brief Return undo lock state. */ bool Undoing (void) { return (Locked); } pcb-4.3.0/src/polyarea.h0000664000175000017500000001215113773431044011767 00000000000000/*! * \file src/polyarea.h * * \brief poly_Boolean: a polygon clip library. * *
* *

Copyright.

\n * * Copyright (C) 1997 Alexey Nikitin, Michael Leonov * * leonov@propro.iis.nsk.su * * Copyright (C) 1997 Klamer Schutte (minor patches) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef PCB_POLYAREA_H #define PCB_POLYAREA_H #ifdef __cplusplus extern "C" { #endif typedef int BOOLp; #ifndef FALSE enum { FALSE = 0, TRUE = 1 }; #endif /* What do these stand for? */ #define PLF_DIR 1 #define PLF_INV 0 #define PLF_MARK 1 #ifndef min #define min(x, y) ((x) < (y) ? (x) : (y)) #endif #ifndef max #define max(x, y) ((x) > (y) ? (x) : (y)) #endif typedef Coord vertex[2]; /*!< longing point representation of coordinates. */ typedef vertex Vector; #define VertexEqu(a,b) (memcmp((a),(b),sizeof(Vector))==0) #define VertexCpy(a,b) memcpy((a),(b),sizeof(Vector)) extern Vector vect_zero; enum { err_no_memory = 2, err_bad_parm = 3, err_ok = 0 }; /* Cross Vertex Connectivity List */ typedef struct CVCList CVCList; typedef struct VNODE VNODE; struct CVCList { double angle; VNODE *parent; CVCList *prev, *next, *head; char poly, side; }; /* A node of a PLINE. * * A segment is defined by the current node and the next node. * */ struct VNODE { VNODE *next, *prev, *shared; struct { unsigned int status:3; unsigned int mark:1; } Flags; CVCList *cvc_prev; CVCList *cvc_next; Vector point; }; /* This structure defines a contour. The segments are comprise the * various VNODEs, which are organized in an ordered list. * * PLINEs have an orientation, positive or negative, depending on if the * VNODES of the contour are organized in a generally clockwise or counter * clockwise order. Positive contours define the perimeters of polygons, * negative contours define holes in contours. * */ typedef struct PLINE PLINE; struct PLINE { /* segment bounding box */ Coord xmin, ymin, xmax, ymax; PLINE *next; VNODE head; unsigned int Count; double area; rtree_t *tree; bool is_round; Coord cx, cy; Coord radius; struct { unsigned int status:3; unsigned int orient:1; } Flags; }; PLINE *poly_NewContour(Vector v); void poly_IniContour(PLINE * c); void poly_ClrContour(PLINE * c); /* clears list of vertices */ void poly_DelContour(PLINE ** c); BOOLp poly_CopyContour(PLINE ** dst, PLINE * src); void poly_PreContour(PLINE * c, BOOLp optimize); /* prepare contour */ void poly_InvContour(PLINE * c); /* invert contour */ VNODE *poly_CreateNode(Vector v); void poly_InclVertex(VNODE * after, VNODE * node); void poly_ExclVertex(VNODE * node); typedef struct POLYAREA POLYAREA; struct POLYAREA { /* this type is a double linked list, forward, backwards */ POLYAREA *f, *b; /* linked list of contours defining the perimeter and holes. */ PLINE *contours; /* rtree of segment bounding boxes, for faster searching */ rtree_t *contour_tree; }; BOOLp poly_M_Copy0(POLYAREA ** dst, const POLYAREA * srcfst); void poly_M_Incl(POLYAREA **list, POLYAREA *a); BOOLp poly_Copy0(POLYAREA **dst, const POLYAREA *src); BOOLp poly_Copy1(POLYAREA *dst, const POLYAREA *src); BOOLp poly_InclContour(POLYAREA * p, PLINE * c); BOOLp poly_ExclContour(POLYAREA * p, PLINE * c); BOOLp poly_ChkContour(PLINE * a); BOOLp poly_CheckInside(POLYAREA * c, Vector v0); BOOLp Touching(POLYAREA *p1, POLYAREA *p2); /* tools for clipping */ /*! * \brief Checks whether point lies within contour independently of its * orientation. */ int poly_InsideContour(PLINE *c, Vector v); int poly_ContourInContour(PLINE * poly, PLINE * inner); POLYAREA *poly_Create(void); void poly_Free(POLYAREA **p); void poly_Init(POLYAREA *p); void poly_FreeContours(PLINE **pl); BOOLp poly_Valid(POLYAREA *p); enum PolygonBooleanOperation { PBO_UNITE, PBO_ISECT, PBO_SUB, PBO_XOR }; double vect_dist2 (Vector v1, Vector v2); double vect_det2 (Vector v1, Vector v2); double vect_len2 (Vector v1); int vect_inters2 (Vector A, Vector B, Vector C, Vector D, Vector S1, Vector S2); int poly_Boolean(const POLYAREA * a, const POLYAREA * b, POLYAREA ** res, int action); int poly_Boolean_free(POLYAREA * a, POLYAREA * b, POLYAREA ** res, int action); int poly_AndSubtract_free(POLYAREA * a, POLYAREA * b, POLYAREA ** aandb, POLYAREA ** aminusb); int SavePOLYAREA( POLYAREA *PA, char * fname); #ifdef __cplusplus } #endif #endif /* PCB_POLYAREA_H */ pcb-4.3.0/src/rubberband.c0000664000175000017500000004161013773431044012256 00000000000000/*! * \file src/rubberband.c * * \brief Functions used by 'rubberband moves'. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * * Thomas.Nau@rz.uni-ulm.de */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #ifdef HAVE_STRING_H #include #endif #include #include #ifdef HAVE_UNISTD_H #include #endif #include "global.h" #include "create.h" #include "data.h" #include "error.h" #include "misc.h" #include "polygon.h" #include "rubberband.h" #include "rtree.h" #include "search.h" #ifdef HAVE_LIBDMALLOC #include #endif /* --------------------------------------------------------------------------- * some local prototypes */ static void CheckPadForRubberbandConnection (PadType *); static void CheckPinForRubberbandConnection (PinType *); static void CheckLinePointForRubberbandConnection (LayerType *, LineType *, PointType *, bool); static void CheckArcPointForRubberbandConnection (LayerType *Layer, ArcType *Arc, PointType *ArcPoint, bool Exact); static void CheckPolygonForRubberbandConnection (LayerType *, PolygonType *); static void CheckLinePointForRat (LayerType *, PointType *); static int rubber_callback (const BoxType * b, void *cl); struct rubber_info { Coord radius; Coord X, Y; LineType *line; BoxType box; LayerType *layer; }; static int rubber_callback (const BoxType * b, void *cl) { LineType *line = (LineType *) b; struct rubber_info *i = (struct rubber_info *) cl; double x, y, rad, dist1, dist2; Coord t; int touches = 0, n = 0 ; t = line->Thickness / 2; /* Check to see if the line is already in the rubberband list */ for (n = 0; n < Crosshair.AttachedObject.RubberbandN; n++) if (Crosshair.AttachedObject.Rubberband[n].Line == line) return 0; if (TEST_FLAG (LOCKFLAG, line)) return 0; if (line == i->line) return 0; /* * Check to see if the line touches a rectangular region. * To do this we need to look for the intersection of a circular * region and a rectangular region. */ if (i->radius == 0) { int found = 0; if (line->Point1.X + t >= i->box.X1 && line->Point1.X - t <= i->box.X2 && line->Point1.Y + t >= i->box.Y1 && line->Point1.Y - t <= i->box.Y2) { if (((i->box.X1 <= line->Point1.X) && (line->Point1.X <= i->box.X2)) || ((i->box.Y1 <= line->Point1.Y) && (line->Point1.Y <= i->box.Y2))) { /* * The circle is positioned such that the closest point * on the rectangular region boundary is not at a corner * of the rectangle. i.e. the shortest line from circle * center to rectangle intersects the rectangle at 90 * degrees. In this case our first test is sufficient */ touches = 1; } else { /* * Now we must check the distance from the center of the * circle to the corners of the rectangle since the * closest part of the rectangular region is the corner. */ x = MIN (abs (i->box.X1 - line->Point1.X), abs (i->box.X2 - line->Point1.X)); x *= x; y = MIN (abs (i->box.Y1 - line->Point1.Y), abs (i->box.Y2 - line->Point1.Y)); y *= y; x = x + y - (t * t); if (x <= 0) touches = 1; } if (touches) { CreateNewRubberbandEntry (i->layer, line, &line->Point1); found++; } } if (line->Point2.X + t >= i->box.X1 && line->Point2.X - t <= i->box.X2 && line->Point2.Y + t >= i->box.Y1 && line->Point2.Y - t <= i->box.Y2) { if (((i->box.X1 <= line->Point2.X) && (line->Point2.X <= i->box.X2)) || ((i->box.Y1 <= line->Point2.Y) && (line->Point2.Y <= i->box.Y2))) { touches = 1; } else { x = MIN (abs (i->box.X1 - line->Point2.X), abs (i->box.X2 - line->Point2.X)); x *= x; y = MIN (abs (i->box.Y1 - line->Point2.Y), abs (i->box.Y2 - line->Point2.Y)); y *= y; x = x + y - (t * t); if (x <= 0) touches = 1; } if (touches) { CreateNewRubberbandEntry (i->layer, line, &line->Point2); found++; } } return found; } /* circular search region */ if (i->radius < 0) rad = 0; /* require exact match */ else rad = SQUARE(i->radius + t); x = (i->X - line->Point1.X); x *= x; y = (i->Y - line->Point1.Y); y *= y; dist1 = x + y - rad; x = (i->X - line->Point2.X); x *= x; y = (i->Y - line->Point2.Y); y *= y; dist2 = x + y - rad; if (dist1 > 0 && dist2 > 0) return 0; #ifdef CLOSEST_ONLY /* keep this to remind me */ if (dist1 < dist2) CreateNewRubberbandEntry (i->layer, line, &line->Point1); else CreateNewRubberbandEntry (i->layer, line, &line->Point2); #else if (dist1 <= 0) CreateNewRubberbandEntry (i->layer, line, &line->Point1); if (dist2 <= 0) CreateNewRubberbandEntry (i->layer, line, &line->Point2); #endif return 1; } /*! * \brief Checks all visible lines which belong to the same layergroup * as the passed pad. * * If one of the endpoints of the line lays inside the pad, the line is * added to the 'rubberband' list. */ static void CheckPadForRubberbandConnection (PadType *Pad) { Coord half = Pad->Thickness / 2; Cardinal group; struct rubber_info info; info.box.X1 = MIN (Pad->Point1.X, Pad->Point2.X) - half; info.box.Y1 = MIN (Pad->Point1.Y, Pad->Point2.Y) - half; info.box.X2 = MAX (Pad->Point1.X, Pad->Point2.X) + half; info.box.Y2 = MAX (Pad->Point1.Y, Pad->Point2.Y) + half; info.radius = 0; info.line = NULL; group = GetLayerGroupNumberBySide ( TEST_FLAG (ONSOLDERFLAG, Pad) ? BOTTOM_SIDE : TOP_SIDE); /* check all visible layers in the same group */ GROUP_LOOP (PCB->Data, group); { /* check all visible lines of the group member */ info.layer = layer; if (info.layer->On) { r_search (info.layer->line_tree, &info.box, NULL, rubber_callback, &info); } } END_LOOP; } struct rinfo { int type; Cardinal group; PinType *pin; PadType *pad; PointType *point; }; static int rat_callback (const BoxType * box, void *cl) { RatType *rat = (RatType *) box; struct rinfo *i = (struct rinfo *) cl; switch (i->type) { case PIN_TYPE: if (rat->Point1.X == i->pin->X && rat->Point1.Y == i->pin->Y) CreateNewRubberbandEntry (NULL, (LineType *) rat, &rat->Point1); else if (rat->Point2.X == i->pin->X && rat->Point2.Y == i->pin->Y) CreateNewRubberbandEntry (NULL, (LineType *) rat, &rat->Point2); break; case PAD_TYPE: if (rat->Point1.X == i->pad->Point1.X && rat->Point1.Y == i->pad->Point1.Y && rat->group1 == i->group) CreateNewRubberbandEntry (NULL, (LineType *) rat, &rat->Point1); else if (rat->Point2.X == i->pad->Point1.X && rat->Point2.Y == i->pad->Point1.Y && rat->group2 == i->group) CreateNewRubberbandEntry (NULL, (LineType *) rat, &rat->Point2); else if (rat->Point1.X == i->pad->Point2.X && rat->Point1.Y == i->pad->Point2.Y && rat->group1 == i->group) CreateNewRubberbandEntry (NULL, (LineType *) rat, &rat->Point1); else if (rat->Point2.X == i->pad->Point2.X && rat->Point2.Y == i->pad->Point2.Y && rat->group2 == i->group) CreateNewRubberbandEntry (NULL, (LineType *) rat, &rat->Point2); else if (rat->Point1.X == (i->pad->Point1.X + i->pad->Point2.X) / 2 && rat->Point1.Y == (i->pad->Point1.Y + i->pad->Point2.Y) / 2 && rat->group1 == i->group) CreateNewRubberbandEntry (NULL, (LineType *) rat, &rat->Point1); else if (rat->Point2.X == (i->pad->Point1.X + i->pad->Point2.X) / 2 && rat->Point2.Y == (i->pad->Point1.Y + i->pad->Point2.Y) / 2 && rat->group2 == i->group) CreateNewRubberbandEntry (NULL, (LineType *) rat, &rat->Point2); break; case LINEPOINT_TYPE: if (rat->group1 == i->group && rat->Point1.X == i->point->X && rat->Point1.Y == i->point->Y) CreateNewRubberbandEntry (NULL, (LineType *) rat, &rat->Point1); else if (rat->group2 == i->group && rat->Point2.X == i->point->X && rat->Point2.Y == i->point->Y) CreateNewRubberbandEntry (NULL, (LineType *) rat, &rat->Point2); break; default: Message ("hace: bad rubber-rat lookup callback\n"); } return 0; } static void CheckPadForRat (PadType *Pad) { struct rinfo info; info.group = GetLayerGroupNumberBySide ( TEST_FLAG (ONSOLDERFLAG, Pad) ? BOTTOM_SIDE : TOP_SIDE); info.pad = Pad; info.type = PAD_TYPE; r_search (PCB->Data->rat_tree, &Pad->BoundingBox, NULL, rat_callback, &info); } static void CheckPinForRat (PinType *Pin) { struct rinfo info; info.type = PIN_TYPE; info.pin = Pin; r_search (PCB->Data->rat_tree, &Pin->BoundingBox, NULL, rat_callback, &info); } static void CheckLinePointForRat (LayerType *Layer, PointType *Point) { struct rinfo info; info.group = GetLayerGroupNumberByPointer (Layer); info.point = Point; info.type = LINEPOINT_TYPE; r_search (PCB->Data->rat_tree, (BoxType *) Point, NULL, rat_callback, &info); } /*! * \brief Checks all visible lines. * * If one of the endpoints of the line lays inside the pin, the line is * added to the 'rubberband' list. * * Square pins are handled as if they were round. * * Speed and readability is more important then the few % of failures * that are immediately recognized. */ static void CheckPinForRubberbandConnection (PinType *Pin) { struct rubber_info info; Cardinal n; Coord t = Pin->Thickness / 2; info.box.X1 = Pin->X - t; info.box.X2 = Pin->X + t; info.box.Y1 = Pin->Y - t; info.box.Y2 = Pin->Y + t; info.line = NULL; if (TEST_FLAG (SQUAREFLAG, Pin)) info.radius = 0; else { info.radius = t; info.X = Pin->X; info.Y = Pin->Y; } for (n = 0; n < max_copper_layer; n++) { info.layer = LAYER_PTR (n); r_search (info.layer->line_tree, &info.box, NULL, rubber_callback, &info); } } /*! * \brief Checks all visible lines which belong to the same group as the * passed line. * * If one of the endpoints of the line lays * inside the passed line, * the scanned line is added to the 'rubberband' list. */ static void CheckLinePointForRubberbandConnection (LayerType *Layer, LineType *Line, PointType *LinePoint, bool Exact) { Cardinal group; struct rubber_info info; Coord t = Line->Thickness / 2; /* lookup layergroup and check all visible lines in this group */ info.radius = Exact ? -1 : MAX(Line->Thickness / 2, 1); info.box.X1 = LinePoint->X - t; info.box.X2 = LinePoint->X + t; info.box.Y1 = LinePoint->Y - t; info.box.Y2 = LinePoint->Y + t; info.line = Line; info.X = LinePoint->X; info.Y = LinePoint->Y; group = GetLayerGroupNumberByPointer (Layer); GROUP_LOOP (PCB->Data, group); { /* check all visible lines of the group member */ if (layer->On) { info.layer = layer; r_search (layer->line_tree, &info.box, NULL, rubber_callback, &info); } } END_LOOP; } /*! * \brief Checks all visible lines which belong to the same group as the * passed arc. * * If one of the endpoints of the line lays inside the passed arc, * the scanned line is added to the 'rubberband' list */ static void CheckArcPointForRubberbandConnection (LayerType *Layer, ArcType *Arc, PointType *ArcPoint, bool Exact) { Cardinal group; struct rubber_info info; Coord t = Arc->Thickness / 2; /* lookup layergroup and check all visible lines in this group */ info.radius = Exact ? -1 : MAX(Arc->Thickness / 2, 1); info.box.X1 = ArcPoint->X - t; info.box.X2 = ArcPoint->X + t; info.box.Y1 = ArcPoint->Y - t; info.box.Y2 = ArcPoint->Y + t; info.line = NULL; info.X = ArcPoint->X; info.Y = ArcPoint->Y; group = GetLayerGroupNumberByPointer (Layer); GROUP_LOOP (PCB->Data, group); { /* check all visible lines of the group member */ if (layer->On) { info.layer = layer; r_search (layer->line_tree, &info.box, NULL, rubber_callback, &info); } } END_LOOP; } /* --------------------------------------------------------------------------- * checks all visible lines which belong to the same group as the passed polygon. * If one of the endpoints of the line lays inside the passed polygon, * the scanned line is added to the 'rubberband' list. */ static void CheckPolygonForRubberbandConnection (LayerType *Layer, PolygonType *Polygon) { Cardinal group; /* lookup layergroup and check all visible lines in this group */ group = GetLayerGroupNumberByPointer (Layer); GROUP_LOOP (PCB->Data, group); { if (layer->On) { Coord thick; /* the following code just stupidly compares the endpoints * of the lines */ LINE_LOOP (layer); { if (TEST_FLAG (LOCKFLAG, line)) continue; if (TEST_FLAG (CLEARLINEFLAG, line)) continue; thick = (line->Thickness + 1) / 2; if (IsPointInPolygon (line->Point1.X, line->Point1.Y, thick, Polygon)) CreateNewRubberbandEntry (layer, line, &line->Point1); if (IsPointInPolygon (line->Point2.X, line->Point2.Y, thick, Polygon)) CreateNewRubberbandEntry (layer, line, &line->Point2); } END_LOOP; } } END_LOOP; } /*! * \brief Lookup all lines that are connected to an object and save the * data to 'Crosshair.AttachedObject.Rubberband'. * * Lookup is only done for visible layers. */ void LookupRubberbandLines (int Type, void *Ptr1, void *Ptr2, void *Ptr3) { /* the function is only supported for some types * check all visible lines; * it is only necessary to check if one of the endpoints * is connected */ switch (Type) { case ELEMENT_TYPE: { ElementType *element = (ElementType *) Ptr1; /* square pins are handled as if they are round. Speed * and readability is more important then the few % * of failures that are immediately recognized */ PIN_LOOP (element); { CheckPinForRubberbandConnection (pin); } END_LOOP; PAD_LOOP (element); { CheckPadForRubberbandConnection (pad); } END_LOOP; break; } case LINE_TYPE: { LayerType *layer = (LayerType *) Ptr1; LineType *line = (LineType *) Ptr2; if (GetLayerNumber (PCB->Data, layer) < max_copper_layer) { CheckLinePointForRubberbandConnection (layer, line, &line->Point1, false); CheckLinePointForRubberbandConnection (layer, line, &line->Point2, false); } break; } case LINEPOINT_TYPE: if (GetLayerNumber (PCB->Data, (LayerType *) Ptr1) < max_copper_layer) CheckLinePointForRubberbandConnection ((LayerType *) Ptr1, (LineType *) Ptr2, (PointType *) Ptr3, true); break; case ARC_TYPE: { LayerType *layer = (LayerType *) Ptr1; ArcType *arc = (ArcType *) Ptr2; if (GetLayerNumber (PCB->Data, layer) < max_copper_layer) { CheckArcPointForRubberbandConnection (layer, arc, &arc->Point1, false); CheckArcPointForRubberbandConnection (layer, arc, &arc->Point2, false); } break; } case VIA_TYPE: CheckPinForRubberbandConnection ((PinType *) Ptr1); break; case POLYGON_TYPE: if (GetLayerNumber (PCB->Data, (LayerType *) Ptr1) < max_copper_layer) CheckPolygonForRubberbandConnection ((LayerType *) Ptr1, (PolygonType *) Ptr2); break; } } void LookupRatLines (int Type, void *Ptr1, void *Ptr2, void *Ptr3) { switch (Type) { case ELEMENT_TYPE: { ElementType *element = (ElementType *) Ptr1; PIN_LOOP (element); { CheckPinForRat (pin); } END_LOOP; PAD_LOOP (element); { CheckPadForRat (pad); } END_LOOP; break; } case LINE_TYPE: { LayerType *layer = (LayerType *) Ptr1; LineType *line = (LineType *) Ptr2; CheckLinePointForRat (layer, &line->Point1); CheckLinePointForRat (layer, &line->Point2); break; } case LINEPOINT_TYPE: CheckLinePointForRat ((LayerType *) Ptr1, (PointType *) Ptr3); break; case VIA_TYPE: CheckPinForRat ((PinType *) Ptr1); break; } } pcb-4.3.0/src/heap.h0000664000175000017500000000345413773431044011076 00000000000000/*! * \file src/heap.h * * \brief Prototypes for heap routines. * * This file, heap.h, was written and is * * Copyright (c) 2001 C. Scott Ananian * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * Copyright (C) 1998,1999,2000,2001 harry eaton * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA * haceaton@aplcomm.jhuapl.edu */ #ifndef PCB_HEAP_H #define PCB_HEAP_H #include "global.h" /*! * \brief Type of heap costs. */ typedef double cost_t; /*! * \brief What a heap looks like. */ typedef struct heap_struct heap_t; heap_t *heap_create (); void heap_destroy (heap_t ** heap); void heap_free (heap_t * heap, void (*funcfree) (void *)); /* -- mutation -- */ void heap_insert (heap_t * heap, cost_t cost, void *data); void *heap_remove_smallest (heap_t * heap); void *heap_replace (heap_t * heap, cost_t cost, void *data); /* -- interrogation -- */ int heap_is_empty (heap_t * heap); int heap_size (heap_t * heap); #endif /* PCB_HEAP_H */ pcb-4.3.0/src/mirror.h0000664000175000017500000000266213773431044011473 00000000000000/*! * \file src/mirror.h * * \brief Prototypes to change objects mirror flag. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * * Thomas.Nau@rz.uni-ulm.de */ #ifndef PCB_MIRROR_H #define PCB_MIRROR_H #include "global.h" /* --------------------------------------------------------------------------- * some useful macros and defines */ #define MIRROR(object) TOGGLE_FLAG(MIRRORFLAG, (object)) #define MIRROR_TYPES (TEXT_TYPE | ELEMENTNAME_TYPE) void MirrorElementCoordinates (DataType *, ElementType *, Coord); #endif pcb-4.3.0/src/print.c0000664000175000017500000002735013773431044011311 00000000000000/*! * \file src/print.c * * \brief Printing routines. * * \note Change History:\n * 10/11/96 11:37 AJF Added support for a Text() driver function.\n * This was done out of a pressing need to force text to be printed on * the silkscreen layer.\n * Perhaps the design is not the best. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996, 2003 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * * Thomas.Nau@rz.uni-ulm.de */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "global.h" #include "hid_draw.h" #include #ifdef HAVE_UNISTD_H #include #endif #if defined(ENABLE_NLS) && defined(HAVE_LOCALE_H) #include #endif #include "data.h" #include "draw.h" #include "drill.h" #include "file.h" #include "find.h" #include "error.h" #include "misc.h" #include "print.h" #include "polygon.h" #include "rtree.h" #include "search.h" #include "hid.h" #ifdef HAVE_LIBDMALLOC #include #endif /* --------------------------------------------------------------------------- * prints a FAB drawing. */ #define TEXT_SIZE MIL_TO_COORD(150) #define TEXT_LINE MIL_TO_COORD(150) #define DRILL_MARK_SIZE MIL_TO_COORD(16) #define FAB_LINE_W MIL_TO_COORD(8) static void fab_line (hidGC gc, int x1, int y1, int x2, int y2) { gui->graphics->draw_line (gc, x1, y1, x2, y2); } static void fab_circle (hidGC gc, int x, int y, int r) { gui->graphics->draw_arc (gc, x, y, r, r, 0, 180); gui->graphics->draw_arc (gc, x, y, r, r, 180, 180); } /*! * \brief Align text ? * * align is 0=left, 1=center, 2=right, add 8 for underline. */ static void text_at (hidGC gc, int x, int y, int align, char *fmt, ...) { char tmp[512]; int w = 0, i; TextType t; va_list a; FontType *font = &PCB->Font; va_start (a, fmt); vsprintf (tmp, fmt, a); va_end (a); t.Direction = 0; t.TextString = tmp; t.Scale = COORD_TO_MIL(TEXT_SIZE); /* pcnt of 100mil base height */ t.Flags = NoFlags (); t.X = x; t.Y = y; for (i = 0; tmp[i]; i++) w += (font->Symbol[(int) tmp[i]].Width + font->Symbol[(int) tmp[i]].Delta); w = SCALE_TEXT (w, t.Scale); t.X -= w * (align & 3) / 2; if (t.X < 0) t.X = 0; gui->graphics->draw_pcb_text (gc, &t, 0); if (align & 8) fab_line (gc, t.X, t.Y + SCALE_TEXT (font->MaxHeight, t.Scale) + MIL_TO_COORD(10), t.X + w, t.Y + SCALE_TEXT (font->MaxHeight, t.Scale) + MIL_TO_COORD(10)); } /*! * \brief . * * Y, +, X, circle, square. */ static void drill_sym (hidGC gc, int idx, int x, int y) { int type = idx % 5; int size = idx / 5; int s2 = (size + 1) * DRILL_MARK_SIZE; int i; switch (type) { case 0: /* Y */ ; fab_line (gc, x, y, x, y + s2); fab_line (gc, x, y, x + s2 * 13 / 15, y - s2 / 2); fab_line (gc, x, y, x - s2 * 13 / 15, y - s2 / 2); for (i = 1; i <= size; i++) fab_circle (gc, x, y, i * DRILL_MARK_SIZE); break; case 1: /* + */ ; fab_line (gc, x, y - s2, x, y + s2); fab_line (gc, x - s2, y, x + s2, y); for (i = 1; i <= size; i++) { fab_line (gc, x - i * DRILL_MARK_SIZE, y - i * DRILL_MARK_SIZE, x + i * DRILL_MARK_SIZE, y - i * DRILL_MARK_SIZE); fab_line (gc, x - i * DRILL_MARK_SIZE, y - i * DRILL_MARK_SIZE, x - i * DRILL_MARK_SIZE, y + i * DRILL_MARK_SIZE); fab_line (gc, x - i * DRILL_MARK_SIZE, y + i * DRILL_MARK_SIZE, x + i * DRILL_MARK_SIZE, y + i * DRILL_MARK_SIZE); fab_line (gc, x + i * DRILL_MARK_SIZE, y - i * DRILL_MARK_SIZE, x + i * DRILL_MARK_SIZE, y + i * DRILL_MARK_SIZE); } break; case 2: /* X */ ; fab_line (gc, x - s2 * 3 / 4, y - s2 * 3 / 4, x + s2 * 3 / 4, y + s2 * 3 / 4); fab_line (gc, x - s2 * 3 / 4, y + s2 * 3 / 4, x + s2 * 3 / 4, y - s2 * 3 / 4); for (i = 1; i <= size; i++) { fab_line (gc, x - i * DRILL_MARK_SIZE, y - i * DRILL_MARK_SIZE, x + i * DRILL_MARK_SIZE, y - i * DRILL_MARK_SIZE); fab_line (gc, x - i * DRILL_MARK_SIZE, y - i * DRILL_MARK_SIZE, x - i * DRILL_MARK_SIZE, y + i * DRILL_MARK_SIZE); fab_line (gc, x - i * DRILL_MARK_SIZE, y + i * DRILL_MARK_SIZE, x + i * DRILL_MARK_SIZE, y + i * DRILL_MARK_SIZE); fab_line (gc, x + i * DRILL_MARK_SIZE, y - i * DRILL_MARK_SIZE, x + i * DRILL_MARK_SIZE, y + i * DRILL_MARK_SIZE); } break; case 3: /* circle */ ; for (i = 0; i <= size; i++) fab_circle (gc, x, y, (i + 1) * DRILL_MARK_SIZE - DRILL_MARK_SIZE / 2); break; case 4: /* square */ for (i = 1; i <= size + 1; i++) { fab_line (gc, x - i * DRILL_MARK_SIZE, y - i * DRILL_MARK_SIZE, x + i * DRILL_MARK_SIZE, y - i * DRILL_MARK_SIZE); fab_line (gc, x - i * DRILL_MARK_SIZE, y - i * DRILL_MARK_SIZE, x - i * DRILL_MARK_SIZE, y + i * DRILL_MARK_SIZE); fab_line (gc, x - i * DRILL_MARK_SIZE, y + i * DRILL_MARK_SIZE, x + i * DRILL_MARK_SIZE, y + i * DRILL_MARK_SIZE); fab_line (gc, x + i * DRILL_MARK_SIZE, y - i * DRILL_MARK_SIZE, x + i * DRILL_MARK_SIZE, y + i * DRILL_MARK_SIZE); } break; } } static int count_drill_lines (DrillInfoType *AllDrills) { int n, ds = 0; for (n = AllDrills->DrillN - 1; n >= 0; n--) { DrillType *drill = &(AllDrills->Drill[n]); if (drill->PinCount + drill->ViaCount > drill->UnplatedCount) ds++; if (drill->UnplatedCount) ds++; } return ds; } int PrintFab_overhang (void) { DrillInfoType *AllDrills = GetDrillInfo (PCB->Data); int ds = count_drill_lines (AllDrills); if (ds < 4) ds = 4; return (ds + 2) * TEXT_LINE; } void PrintFab (hidGC gc) { DrillInfoType *AllDrills; int i, n, yoff, total_drills = 0, ds = 0; time_t currenttime; const char *utcFmt = "%c UTC"; char utcTime[64]; #ifdef ENABLE_NLS char *oldlocale; #endif AllDrills = GetDrillInfo (PCB->Data); yoff = -TEXT_LINE; /* count how many drill description lines will be needed */ ds = count_drill_lines (AllDrills); /* * When we only have a few drill sizes we need to make sure the * drill table header doesn't fall on top of the board info * section. */ if (ds < 4) { yoff -= (4 - ds) * TEXT_LINE; } gui->graphics->set_line_width (gc, FAB_LINE_W); for (n = AllDrills->DrillN - 1; n >= 0; n--) { int plated_sym = -1, unplated_sym = -1; DrillType *drill = &(AllDrills->Drill[n]); if (drill->PinCount + drill->ViaCount > drill->UnplatedCount) plated_sym = --ds; if (drill->UnplatedCount) unplated_sym = --ds; gui->graphics->set_color (gc, PCB->PinColor); for (i = 0; i < drill->PinN; i++) drill_sym (gc, TEST_FLAG (HOLEFLAG, drill->Pin[i]) ? unplated_sym : plated_sym, drill->Pin[i]->X, drill->Pin[i]->Y); if (plated_sym != -1) { drill_sym (gc, plated_sym, TEXT_SIZE, yoff + TEXT_SIZE / 4); text_at (gc, MIL_TO_COORD(1350), yoff, MIL_TO_COORD(2), "YES"); text_at (gc, MIL_TO_COORD(980), yoff, MIL_TO_COORD(2), "%d", drill->PinCount + drill->ViaCount - drill->UnplatedCount); if (unplated_sym != -1) yoff -= TEXT_LINE; } if (unplated_sym != -1) { drill_sym (gc, unplated_sym, TEXT_SIZE, yoff + TEXT_SIZE / 4); text_at (gc, MIL_TO_COORD(1400), yoff, MIL_TO_COORD(2), "NO"); text_at (gc, MIL_TO_COORD(980), yoff, MIL_TO_COORD(2), "%d", drill->UnplatedCount); } gui->graphics->set_color (gc, PCB->ElementColor); text_at (gc, MIL_TO_COORD(450), yoff, MIL_TO_COORD(2), "%0.3f", COORD_TO_INCH(drill->DrillSize)); if (plated_sym != -1 && unplated_sym != -1) text_at (gc, MIL_TO_COORD(450), yoff + TEXT_LINE, MIL_TO_COORD(2), "%0.3f", COORD_TO_INCH(drill->DrillSize)); yoff -= TEXT_LINE; total_drills += drill->PinCount; total_drills += drill->ViaCount; } gui->graphics->set_color (gc, PCB->ElementColor); text_at (gc, 0, yoff, MIL_TO_COORD(9), "Symbol"); text_at (gc, MIL_TO_COORD(410), yoff, MIL_TO_COORD(9), "Diam. (Inch)"); text_at (gc, MIL_TO_COORD(950), yoff, MIL_TO_COORD(9), "Count"); text_at (gc, MIL_TO_COORD(1300), yoff, MIL_TO_COORD(9), "Plated?"); yoff -= TEXT_LINE; text_at (gc, 0, yoff, 0, "There are %d different drill sizes used in this layout, %d holes total", AllDrills->DrillN, total_drills); /* Create a portable timestamp. */ #ifdef ENABLE_NLS oldlocale = setlocale (LC_TIME, "C"); #endif currenttime = time (NULL); strftime (utcTime, sizeof utcTime, utcFmt, gmtime (¤ttime)); #ifdef ENABLE_NLS setlocale (LC_TIME, oldlocale); #endif yoff = -TEXT_LINE; for (i = 0; i < max_copper_layer; i++) { LayerType *l = LAYER_PTR (i); if (l->Name && (l->LineN || l->ArcN)) { if (strcmp ("route", l->Name) == 0) break; if (strcmp ("outline", l->Name) == 0) break; } } if (i == max_copper_layer) { gui->graphics->set_line_width (gc, MIL_TO_COORD(10)); gui->graphics->draw_line (gc, 0, 0, PCB->MaxWidth, 0); gui->graphics->draw_line (gc, 0, 0, 0, PCB->MaxHeight); gui->graphics->draw_line (gc, PCB->MaxWidth, 0, PCB->MaxWidth, PCB->MaxHeight); gui->graphics->draw_line (gc, 0, PCB->MaxHeight, PCB->MaxWidth, PCB->MaxHeight); /*FPrintOutline (); */ gui->graphics->set_line_width (gc, FAB_LINE_W); text_at (gc, MIL_TO_COORD(2000), yoff, 0, "Maximum Dimensions: %f mils wide, %f mils high", COORD_TO_MIL(PCB->MaxWidth), COORD_TO_MIL(PCB->MaxHeight)); text_at (gc, PCB->MaxWidth / 2, PCB->MaxHeight + MIL_TO_COORD(20), 1, "Board outline is the centerline of this %f mil" " rectangle - 0,0 to %f,%f mils", COORD_TO_MIL(FAB_LINE_W), COORD_TO_MIL(PCB->MaxWidth), COORD_TO_MIL(PCB->MaxHeight)); } else { LayerType *layer = LAYER_PTR (i); gui->graphics->set_line_width (gc, MIL_TO_COORD(10)); LINE_LOOP (layer); { gui->graphics->draw_line (gc, line->Point1.X, line->Point1.Y, line->Point2.X, line->Point2.Y); } END_LOOP; ARC_LOOP (layer); { gui->graphics->draw_arc (gc, arc->X, arc->Y, arc->Width, arc->Height, arc->StartAngle, arc->Delta); } END_LOOP; TEXT_LOOP (layer); { gui->graphics->draw_pcb_text (gc, text, 0); } END_LOOP; gui->graphics->set_line_width (gc, FAB_LINE_W); text_at (gc, PCB->MaxWidth / 2, PCB->MaxHeight + MIL_TO_COORD(20), 1, "Board outline is the centerline of this path"); } yoff -= TEXT_LINE; text_at (gc, MIL_TO_COORD(2000), yoff, 0, "Date: %s", utcTime); yoff -= TEXT_LINE; text_at (gc, MIL_TO_COORD(2000), yoff, 0, "Author: %s", pcb_author ()); yoff -= TEXT_LINE; text_at (gc, MIL_TO_COORD(2000), yoff, 0, "Title: %s - Fabrication Drawing", UNKNOWN (PCB->Name)); } pcb-4.3.0/src/hid/0000775000175000017500000000000014017001275010615 500000000000000pcb-4.3.0/src/hid/hidint.h0000664000175000017500000000720613773431044012203 00000000000000/*! * \file src/hid/hidint.h * * \brief HID internal interfaces. * * These may ONLY be called from the HID modules, not from the common * PCB code. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 2006 DJ Delorie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Contact addresses for paper mail and Email: * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * Thomas.Nau@rz.uni-ulm.de */ /* These decode the set_layer index. */ #define SL_TYPE(x) ((x) < 0 ? (x) & 0x0f0 : 0) #define SL_SIDE(x) ((x) & 0x00f) #define SL_MYSIDE(x) ((((x) & SL_BOTTOM_SIDE)!=0) == (SWAP_IDENT != 0)) /*! * \brief Called by the init funcs, used to set up hid_list. */ extern void hid_register_hid (HID * hid); /*! * \brief NULL terminated list of all static HID structures. * * Built by hid_register_hid, used by hid_find_*() and hid_enumerate(). * The order in this list is the same as the order of hid_register_hid * calls. */ extern HID **hid_list; /*! * \brief Count of entries in the above. */ extern int hid_num_hids; /*! * \brief Used to cache color lookups. * * If set is zero, it looks up the name and if found sets val and * returns nonzero. If not found, it returns zero. If set is nonzero, * name/val is added to the cache. */ int hid_cache_color (int set, const char *name, hidval * val, void **cache); typedef struct HID_AttrNode { struct HID_AttrNode *next; HID_Attribute *attributes; int n; } HID_AttrNode; extern HID_AttrNode *hid_attr_nodes; HID_Action *hid_find_action (const char *name); HID_Flag *hid_find_flag (const char *name); /*! * \brief A HID may use this if it does not need command line arguments * in any special format. * * For example, the Lesstif HID needs to use the Xt parser, but the * Postscript HID can use this function. */ void hid_parse_command_line (int *argc, char ***argv); /*! * \brief Use this to temporarily enable all layers, so that they can be * exported even if they're not currently visible. * * save_array must be MAX_ALL_LAYER big. */ void hid_save_and_show_layer_ons (int *save_array); /*! * \brief Use this to restore them. */ void hid_restore_layer_ons (int *save_array); enum File_Name_Style { FNS_fixed, /*!< Files for copper layers are named top, groupN, bottom. */ FNS_single, /*!< Groups with multiple layers are named as above, else the single layer name is used. */ FNS_first, /*!< The name of the first layer in each group is used. */ }; /* Returns a filename base that can be used to output the layer. */ const char *layer_type_to_file_name (int idx, int style); const char *layer_type_to_file_name_ex (int idx, int style, const char *layer_name); /*! * \brief Convenience function that calls the expose callback for the * item, and returns the extents of what was drawn. */ BoxType *hid_get_extents (void *item); void derive_default_filename(const char *pcbfile, HID_Attribute *filename_attrib, const char *suffix, char **memory); pcb-4.3.0/src/hid/ipcd356/0000775000175000017500000000000014017001275011772 500000000000000pcb-4.3.0/src/hid/ipcd356/hid.conf0000664000175000017500000000001413773431044013331 00000000000000type=export pcb-4.3.0/src/hid/ipcd356/ipcd356.c0000664000175000017500000004445013773431044013253 00000000000000/*! * \file src/hid/ipcd356/ipcd356.c * * \brief IPC-D-356 Netlist export. * * \author Copyright (C) 2012 Jerome Marchand (Jerome.Marchand@gmail.com) * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * * Thomas.Nau@rz.uni-ulm.de */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "data.h" #include "config.h" #include "global.h" #include "rats.h" #include "error.h" #include "find.h" #include "flags.h" #include "misc.h" #include "pcb-printf.h" #include "hid.h" #include "hid/common/hidnogui.h" #include "../hidint.h" #ifdef HAVE_LIBDMALLOC #include #endif static HID_Attribute IPCD356_options[] = { /* %start-doc options "95 IPC-D-356 Netlist Export" @ftable @code @item --netlist-file Name of the IPC-D-356 Netlist output file. Parameter @code{} can include a path. @end ftable %end-doc */ { "netlistfile", "Name of the IPC-D-356 Netlist output file", HID_String, 0, 0, {0, 0, 0}, 0, 0 }, #define HA_IPCD356_filename 0 }; #define NUM_OPTIONS (sizeof(IPCD356_options)/sizeof(IPCD356_options[0])) static HID_Attr_Val IPCD356_values[NUM_OPTIONS]; const char *IPCD356_filename; typedef struct { char NName[16]; char NetName[256]; } IPCD356_Alias; typedef struct { int AliasN; /*!< Number of entries. */ IPCD356_Alias *Alias; } IPCD356_AliasList; void IPCD356_WriteNet (FILE *, char *); void IPCD356_WriteHeader (FILE *); void IPCD356_End (FILE *); int IPCD356_Netlist (void); int IPCD356_WriteAliases (FILE *, IPCD356_AliasList *); void ResetVisitPinsViasAndPads (void); void CheckNetLength (char *, IPCD356_AliasList *); IPCD356_AliasList *CreateAliasList (void); IPCD356_AliasList *AddAliasToList (IPCD356_AliasList *); int IPCD356_SanityCheck (void); static HID_Attribute * IPCD356_get_export_options (int *n) { static char *last_IPCD356_filename = 0; if (PCB) { derive_default_filename (PCB->Filename, &IPCD356_options[HA_IPCD356_filename], ".net", &last_IPCD356_filename); } if (n) *n = NUM_OPTIONS; return IPCD356_options; } /*! * \brief Writes the IPC-D-356 Header to the file provided. * * The JOB name is the PCB Name (if set), otherwise the filename * (including the path) is used. * * The units used for the netlist depends on what is set (mils or mm). */ void IPCD356_WriteHeader (FILE * fd) { time_t currenttime; char utcTime[64]; const char *fmt = "%c UTC"; currenttime = time (NULL); strftime (utcTime, sizeof utcTime, fmt, gmtime (¤ttime)); fprintf (fd, "C IPC-D-356 Netlist generated by gEDA PCB " VERSION "\nC \n"); fprintf (fd, "C File created on %s\nC \n", utcTime); if (PCB->Name == NULL) { fprintf (fd, "P JOB %s\n", PCB->Filename); /* Use the file name if the PCB name in not set. */ } else { fprintf (fd, "P JOB %s\n", PCB->Name); } fprintf (fd, "P CODE 00\n"); if (strcmp (Settings.grid_unit->suffix,"mil") == 0) /* Use whatever unit is currently in use (mil or mm). */ { fprintf (fd, "P UNITS CUST 0\n"); } else { fprintf (fd, "P UNITS CUST 1\n"); } fprintf (fd, "P DIM N\n"); fprintf (fd, "P VER IPC-D-356\n"); fprintf (fd, "P IMAGE PRIMARY\nC \n"); } /*! * \brief Writes a net to the file provided. * * The net name is passed through the "net" and should be 14 characters * max.\n * The function scans through pads, pins and vias and looks for the * \c FOUNDFLAG.\n * Once the object has been added to the net list the \c VISITFLAG is * set on that object. * * \todo 1) The bottom layer is always written as layer #2 (A02).\n * It could output the actual layer number (example: A06 on a * 6 layer board).\n * But I could not find an easy way to do this... * * \todo 2) Objects with mutiple connections could have the "M" * (column 32) field written to indicate a Mid Net Point. */ void IPCD356_WriteNet (FILE * fd, char *net) { int padx, pady, tmp; ELEMENT_LOOP (PCB->Data); PAD_LOOP (element); if (TEST_FLAG (FOUNDFLAG, pad)) { fprintf (fd, "327%-17.14s", net); /* Net Name. */ fprintf (fd, "%-6.6s", element->Name[1].TextString); /* Refdes. */ fprintf (fd, "-%-4.4s", pad->Number); /* pin number. */ fprintf (fd, " "); /*! \todo Midpoint indicator (M). */ fprintf (fd, " "); /* Drilled hole Id (blank for pads). */ if (TEST_FLAG (ONSOLDERFLAG, pad) == true) { fprintf (fd, "A02"); /*! \todo Put actual layer # for bottom side. */ } else { fprintf (fd, "A01"); /* Top side. */ } padx = (pad->Point1.X + pad->Point2.X) / 2; /* X location in PCB units. */ pady = (PCB->MaxHeight - ((pad->Point1.Y + pad->Point2.Y) / 2)); /* Y location in PCB units. */ if (strcmp (Settings.grid_unit->suffix, "mil") == 0) { padx = padx / 2540; /* X location in 0.0001". */ pady = pady / 2540; /* Y location in 0.0001". */ } else { padx = padx / 1000; /* X location in 0.001 mm. */ pady = pady / 1000; /* Y location in 0.001 mm. */ } fprintf (fd, "X%+6.6d", padx); /* X Pad center. */ fprintf (fd, "Y%+6.6d", pady); /* Y pad center. */ padx = (pad->Thickness + (pad->Point2.X - pad->Point1.X)); /* Pad dimension X in PCB units. */ pady = (pad->Thickness + (pad->Point2.Y - pad->Point1.Y)); /* Pad dimension Y in PCB units. */ if (strcmp(Settings.grid_unit->suffix, "mil") == 0) { padx = padx / 2540; /* X location in 0.0001". */ pady = pady / 2540; /* Y location in 0.0001". */ } else { padx = padx / 1000; // X location in 0.001mm pady = pady / 1000; // Y location in 0.001mm } fprintf (fd, "X%4.4d", padx); fprintf (fd, "Y%4.4d", pady); fprintf (fd, "R000"); /* Rotation (0 degrees). */ fprintf (fd, " "); /* Column 72 should be left blank. */ if (pad->Mask > 0) { if (TEST_FLAG (ONSOLDERFLAG, pad) == true) { fprintf(fd, "S2"); /* Soldermask on bottom side. */ } else { fprintf(fd, "S1"); /* SolderMask on top side. */ } } else { fprintf(fd, "S3"); /* No soldermask. */ } fprintf (fd, " "); /* Padding. */ fprintf (fd, "\n"); SET_FLAG (VISITFLAG, pad); } END_LOOP; /* Pad. */ PIN_LOOP (element); if (TEST_FLAG (FOUNDFLAG, pin)) { if (TEST_FLAG (HOLEFLAG, pin)) /* Non plated? */ { fprintf (fd, "367%-17.14s", net); /* Net Name. */ } else { fprintf (fd, "317%-17.14s", net); /* Net Name. */ } fprintf (fd, "%-6.6s", element->Name[1].TextString); /* Refdes. */ fprintf (fd, "-%-4.4s", pin->Number); /* Pin number. */ fprintf (fd, " "); /*! \todo Midpoint indicator (M). */ tmp = pin->DrillingHole; if (strcmp (Settings.grid_unit->suffix, "mil") == 0) { tmp = tmp / 2540; /* 0.0001". */ } else { tmp = tmp / 1000; /* 0.001 mm. */ } if (TEST_FLAG (HOLEFLAG, pin)) { fprintf (fd, "D%-4.4dU", tmp); /* Unplated Drilled hole Id. */ } else { fprintf (fd, "D%-4.4dP", tmp); /* Plated drill hole. */ } fprintf (fd, "A00"); /* Accessible from both sides. */ padx = pin->X; /* X location in PCB units. */ pady = (PCB->MaxHeight - pin->Y); /* Y location in PCB units.*/ if (strcmp (Settings.grid_unit->suffix, "mil") == 0) { padx = padx / 2540; /* X location in 0.0001". */ pady = pady / 2540; /* Y location in 0.0001". */ } else { padx = padx / 1000; /* X location in 0.001 mm. */ pady = pady / 1000; /* Y location in 0.001 mm. */ } fprintf (fd, "X%+6.6d", padx); /* X Pad center. */ fprintf (fd, "Y%+6.6d", pady); /* Y pad center. */ padx = pin->Thickness; if (strcmp (Settings.grid_unit->suffix, "mil") == 0) { padx = padx / 2540; /* X location in 0.0001". */ } else { padx = padx / 1000; /* X location in 0.001 mm. */ } fprintf (fd, "X%4.4d", padx); /* Pad dimension X. */ if (TEST_FLAG (SQUAREFLAG, pin)) { fprintf (fd, "Y%4.4d", padx); /* Pad dimension Y. */ } else { fprintf (fd, "Y0000"); /* Y is 0 for round pins. */ } fprintf (fd, "R000"); /* Rotation (0 degrees). */ fprintf (fd, " "); /* Column 72 should be left blank.*/ if (pin->Mask > 0) { fprintf(fd, "S0"); /* No Soldermask. */ } else { fprintf(fd, "S3"); /* Soldermask on both sides. */ } fprintf (fd, " "); /* Padding. */ fprintf (fd, "\n"); SET_FLAG (VISITFLAG, pin); } END_LOOP; /* Pin. */ END_LOOP; /* Element */ VIA_LOOP (PCB->Data); if (TEST_FLAG (FOUNDFLAG, via)) { if (TEST_FLAG (HOLEFLAG, via)) /* Non plated ? */ { fprintf (fd, "367%-17.14s", net); /* Net Name. */ } else { fprintf (fd, "317%-17.14s", net); /* Net Name. */ } fprintf (fd, "VIA "); /* Refdes. */ fprintf (fd, "- "); /* Pin number. */ fprintf (fd, " "); /*! \todo Midpoint indicator (M). */ tmp = via->DrillingHole; if (strcmp (Settings.grid_unit->suffix, "mil") == 0) { tmp = tmp / 2540; /* 0.0001". */ } else { tmp = tmp / 1000; /* 0.001 mm. */ } if (TEST_FLAG (HOLEFLAG, via)) { fprintf (fd, "D%-4.4dU", tmp); /* Unplated Drilled hole Id. */ } else { fprintf (fd, "D%-4.4dP", tmp); /* Plated drill hole. */ } fprintf (fd, "A00"); /* Accessible from both sides. */ padx = via->X; /* X location in PCB units. */ pady = (PCB->MaxHeight - via->Y); /* Y location in PCB units. */ if (strcmp (Settings.grid_unit->suffix, "mil") == 0) { padx = padx / 2540; /* X location in 0.0001". */ pady = pady / 2540; /* Y location in 0.0001". */ } else { padx = padx / 1000; /* X location in 0.001 mm. */ pady = pady / 1000; /* Y location in 0.001 mm. */ } fprintf (fd, "X%+6.6d", padx); /* X Pad center. */ fprintf (fd, "Y%+6.6d", pady); /* Y pad center. */ padx = via->Thickness; if (strcmp (Settings.grid_unit->suffix, "mil") == 0) { padx = padx / 2540; /* X location in 0.0001". */ } else { padx = padx / 1000; /* X location in 0.001 mm. */ } fprintf (fd, "X%4.4d", padx); /* Pad dimension X. */ fprintf (fd, "Y0000"); /* Y is 0 for round pins (vias always round?). */ fprintf (fd, "R000"); /* Rotation (0 degrees). */ fprintf (fd, " "); /* Column 72 should be left blank. */ if (via->Mask > 0) { fprintf(fd, "S0"); /* No Soldermask. */ } else { fprintf(fd, "S3"); /* Soldermask on both sides. */ } fprintf (fd, " "); /* Padding. */ fprintf (fd, "\n"); SET_FLAG (VISITFLAG, via); } END_LOOP; /* Via. */ } /*! * \brief The main IPC-D-356 function. * * Gets the filename for the netlist from the dialog. */ int IPCD356_Netlist (void) { FILE *fp; char nodename[256]; char net[256]; LibraryMenuType *netname; IPCD356_AliasList * aliaslist; if (IPCD356_SanityCheck()) /* Check for invalid names + numbers. */ { Message ("Aborting.\n"); return(1); } sprintf (net, "%s.ipc", PCB->Name); if (IPCD356_filename == NULL) return 1; fp = fopen (IPCD356_filename, "wb+"); if (fp == NULL) { Message ("error opening %s\n", IPCD356_filename); return 1; } /* free (IPCD356_filename); */ IPCD356_WriteHeader (fp); aliaslist = CreateAliasList (); if (aliaslist == NULL) { Message ("Error Aloccating memory for IPC-D-356 AliasList\n"); return 1; } if (IPCD356_WriteAliases (fp, aliaslist)) { Message ("Error Writing IPC-D-356 AliasList\n"); return 1; } ELEMENT_LOOP (PCB->Data); PIN_LOOP (element); if (!TEST_FLAG (VISITFLAG, pin)) { ClearFlagOnAllObjects(FOUNDFLAG, true); LookupConnectionByPin (PIN_TYPE, pin); sprintf (nodename, "%s-%s", element->Name[1].TextString, pin->Number); netname = netnode_to_netname (nodename); /* Message("Netname: %s\n", netname->Name +2); */ if (netname) { strcpy (net, &netname->Name[2]); CheckNetLength (net, aliaslist); } else { strcpy (net, "N/C"); } IPCD356_WriteNet (fp, net); } END_LOOP; /* Pin. */ PAD_LOOP (element); if (!TEST_FLAG (VISITFLAG, pad)) { ClearFlagOnAllObjects(FOUNDFLAG, true); LookupConnectionByPin (PAD_TYPE, pad); sprintf (nodename, "%s-%s", element->Name[1].TextString, pad->Number); netname = netnode_to_netname (nodename); /* Message("Netname: %s\n", netname->Name +2); */ if (netname) { strcpy (net, &netname->Name[2]); CheckNetLength (net, aliaslist); } else { strcpy (net, "N/C"); } IPCD356_WriteNet (fp, net); } END_LOOP; /* Pad. */ END_LOOP; /* Element. */ VIA_LOOP (PCB->Data); if (!TEST_FLAG (VISITFLAG, via)) { ClearFlagOnAllObjects(FOUNDFLAG, true); LookupConnectionByPin (PIN_TYPE, via); strcpy (net, "N/C"); IPCD356_WriteNet (fp, net); } END_LOOP; /* Via. */ IPCD356_End (fp); fclose (fp); free (aliaslist); ResetVisitPinsViasAndPads (); ClearFlagOnAllObjects(FOUNDFLAG, true); return 0; } void IPCD356_End (FILE * fd) { fprintf (fd, "999\n"); } void ResetVisitPinsViasAndPads () { VIA_LOOP (PCB->Data); CLEAR_FLAG (VISITFLAG, via); END_LOOP; /* Via. */ ELEMENT_LOOP (PCB->Data); PIN_LOOP (element); CLEAR_FLAG (VISITFLAG, pin); END_LOOP; /* Pin. */ PAD_LOOP (element); CLEAR_FLAG (VISITFLAG, pad); END_LOOP; /* Pad. */ END_LOOP; /* Element. */ } int IPCD356_WriteAliases (FILE * fd, IPCD356_AliasList * aliaslist) { int index; int i; index = 1; for (i = 0; i < PCB->NetlistLib.MenuN; i++) { if (strlen (PCB->NetlistLib.Menu[i].Name + 2) > 14) { if (index == 1) { fprintf (fd, "C Netname Aliases Section\n"); } aliaslist = AddAliasToList (aliaslist); if (aliaslist == NULL) { return 1; } sprintf (aliaslist->Alias[index].NName, "NNAME%-5.5d", index); strcpy (aliaslist->Alias[index].NetName, PCB->NetlistLib.Menu[i].Name + 2); fprintf (fd, "P %s %-58.58s\n", aliaslist->Alias[index].NName, aliaslist->Alias[index].NetName); index++; } } if (index > 1) { fprintf (fd, "C End Netname Aliases Section\nC \n"); } return 0; } IPCD356_AliasList * CreateAliasList () { IPCD356_AliasList * aliaslist; aliaslist = malloc (sizeof (IPCD356_AliasList)); /* Create an alias list. */ aliaslist->AliasN = 0; /* Initialize Number of Alias. */ return aliaslist; } IPCD356_AliasList * AddAliasToList (IPCD356_AliasList * aliaslist) { aliaslist->AliasN++; aliaslist->Alias = realloc (aliaslist->Alias, sizeof (IPCD356_Alias) * (aliaslist->AliasN + 1)); if (aliaslist->Alias == NULL) { return NULL; } return aliaslist; } void CheckNetLength (char *net, IPCD356_AliasList * aliaslist) { int i; if (strlen (net) > 14) { for (i = 1; i <= aliaslist->AliasN; i++) { if (strcmp (net, aliaslist->Alias[i].NetName) == 0) { strcpy (net, aliaslist->Alias[i].NName); } } } } int IPCD356_SanityCheck() { ELEMENT_LOOP (PCB->Data); if (element->Name[1].TextString == NULL || strlen(element->Name[1].TextString)==0) { Message("Error: Found unnamed element. All elements need to be named to create an IPC-D-356 netlist.\n"); return(1); } END_LOOP; /* Element. */ return(0); } static void IPCD356_do_export (HID_Attr_Val * options) { int i; if (!options) { IPCD356_get_export_options (0); for (i = 0; i < NUM_OPTIONS; i++) IPCD356_values[i] = IPCD356_options[i].default_val; options = IPCD356_values; } IPCD356_filename = options[HA_IPCD356_filename].str_value; if (!IPCD356_filename) IPCD356_filename = "pcb-out.net"; IPCD356_Netlist (); } static void IPCD356_parse_arguments (int *argc, char ***argv) { hid_register_attributes (IPCD356_options, sizeof (IPCD356_options) / sizeof (IPCD356_options[0])); hid_parse_command_line (argc, argv); } HID IPCD356_hid; void hid_ipcd356_init () { memset (&IPCD356_hid, 0, sizeof (HID)); common_nogui_init (&IPCD356_hid); IPCD356_hid.struct_size = sizeof (HID); IPCD356_hid.name = "IPC-D-356"; IPCD356_hid.description = "Exports a IPC-D-356 Netlist"; IPCD356_hid.exporter = 1; IPCD356_hid.get_export_options = IPCD356_get_export_options; IPCD356_hid.do_export = IPCD356_do_export; IPCD356_hid.parse_arguments = IPCD356_parse_arguments; hid_register_hid (&IPCD356_hid); } /* EOF */ pcb-4.3.0/src/hid/gerber/0000775000175000017500000000000014017001275012063 500000000000000pcb-4.3.0/src/hid/gerber/gerber.c0000664000175000017500000011176613773431044013442 00000000000000#ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #ifdef HAVE_PWD_H #include #endif #include #include "config.h" #include "global.h" #include "data.h" #include "misc.h" #include "error.h" #include "draw.h" #include "pcb-printf.h" #include "hid.h" #include "hid_draw.h" #include "../hidint.h" #include "hid/common/hidnogui.h" #include "hid/common/draw_helpers.h" #include "hid/common/hidinit.h" #ifdef HAVE_LIBDMALLOC #include #endif #define CRASH fprintf(stderr, "HID error: pcb called unimplemented Gerber function %s.\n", __FUNCTION__); abort() /*----------------------------------------------------------------------------*/ /* Function prototypes */ /*----------------------------------------------------------------------------*/ static HID_Attribute * gerber_get_export_options (int *n); static void gerber_do_export (HID_Attr_Val * options); static void gerber_parse_arguments (int *argc, char ***argv); static int gerber_set_layer (const char *name, int group, int empty); static hidGC gerber_make_gc (void); static void gerber_destroy_gc (hidGC gc); static void gerber_use_mask (enum mask_mode mode); static void gerber_set_color (hidGC gc, const char *name); static void gerber_set_line_cap (hidGC gc, EndCapStyle style); static void gerber_set_line_width (hidGC gc, Coord width); static void gerber_set_draw_xor (hidGC gc, int _xor); static void gerber_draw_line (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2); static void gerber_draw_arc (hidGC gc, Coord cx, Coord cy, Coord width, Coord height, Angle start_angle, Angle delta_angle); static void gerber_draw_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2); static void gerber_fill_circle (hidGC gc, Coord cx, Coord cy, Coord radius); static void gerber_fill_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2); static void gerber_calibrate (double xval, double yval); static void gerber_set_crosshair (int x, int y, int action); static void gerber_fill_polygon (hidGC gc, int n_coords, Coord *x, Coord *y); /*----------------------------------------------------------------------------*/ /* Utility routines */ /*----------------------------------------------------------------------------*/ /* These are for films */ #define gerberX(pcb, x) ((Coord) (x)) #define gerberY(pcb, y) ((Coord) ((pcb)->MaxHeight - (y))) #define gerberXOffset(pcb, x) ((Coord) (x)) #define gerberYOffset(pcb, y) ((Coord) (-(y))) /* These are for drills */ #define gerberDrX(pcb, x) ((Coord) (x)) #define gerberDrY(pcb, y) ((Coord) ((pcb)->MaxHeight - (y))) /*----------------------------------------------------------------------------*/ /* Private data structures */ /*----------------------------------------------------------------------------*/ static int verbose; static int all_layers; static int metric; static char *x_convspec, *y_convspec; static int is_mask, was_drill; static int is_drill; static enum mask_mode current_mask; static int flash_drills; static int copy_outline_mode; static int name_style; static LayerType *outline_layer; #define print_xcoord(file, pcb, val)\ pcb_fprintf(file, x_convspec, gerberX(pcb, val)) #define print_ycoord(file, pcb, val)\ pcb_fprintf(file, y_convspec, gerberY(pcb, val)) enum ApertureShape { ROUND, /* Shaped like a circle */ OCTAGON, /* octagonal shape */ SQUARE, /* Shaped like a square */ ROUNDCLEAR, /* clearance in negatives */ SQUARECLEAR, THERMAL /* negative thermal relief */ }; typedef enum ApertureShape ApertureShape; /* This is added to the global aperture array indexes to get gerber dcode and macro numbers. */ #define DCODE_BASE 11 typedef struct aperture { int dCode; /* The RS-274X D code */ Coord width; /* Size in pcb units */ ApertureShape shape; /* ROUND/SQUARE etc */ struct aperture *next; } Aperture; typedef struct { Aperture *data; int count; } ApertureList; static ApertureList *layer_aptr_list; static ApertureList *curr_aptr_list; static int layer_list_max; static int layer_list_idx; typedef struct { Coord diam; Coord x; Coord y; } PendingDrills; PendingDrills *pending_drills = NULL; int n_pending_drills = 0, max_pending_drills = 0; /*----------------------------------------------------------------------------*/ /* Defined Constants */ /*----------------------------------------------------------------------------*/ #define AUTO_OUTLINE_WIDTH MIL_TO_COORD(8) /* Auto-geneated outline width of 8 mils */ /*----------------------------------------------------------------------------*/ /* Aperture Routines */ /*----------------------------------------------------------------------------*/ /* Initialize aperture list */ static void initApertureList (ApertureList *list) { list->data = NULL; list->count = 0; } static void deinitApertureList (ApertureList *list) { Aperture *search = list->data; Aperture *next; while (search) { next = search->next; free(search); search = next; } initApertureList (list); } static int aperture_count; static void resetApertures() { int i; for (i = 0; i < layer_list_max; ++i) deinitApertureList (&layer_aptr_list[i]); free (layer_aptr_list); layer_aptr_list = NULL; curr_aptr_list = NULL; layer_list_max = 0; layer_list_idx = 0; aperture_count = 0; } /* Create and add a new aperture to the list */ static Aperture * addAperture (ApertureList *list, Coord width, ApertureShape shape) { Aperture *app = (Aperture *) malloc (sizeof *app); if (app == NULL) return NULL; app->width = width; app->shape = shape; app->dCode = DCODE_BASE + aperture_count++; app->next = list->data; list->data = app; ++list->count; return app; } /* Fetch an aperture from the list with the specified * width/shape, creating a new one if none exists */ static Aperture * findAperture (ApertureList *list, Coord width, ApertureShape shape) { Aperture *search; /* we never draw zero-width lines */ if (width == 0) return NULL; /* Search for an appropriate aperture. */ for (search = list->data; search; search = search->next) if (search->width == width && search->shape == shape) return search; /* Failing that, create a new one */ return addAperture (list, width, shape); } /* Output aperture data to the file */ static void fprintAperture (FILE *f, Aperture *aptr) { switch (aptr->shape) { case ROUND: pcb_fprintf (f, metric ? "%%ADD%dC,%.3`mm*%%\r\n" : "%%ADD%dC,%.4`mi*%%\r\n", aptr->dCode, aptr->width); break; case SQUARE: pcb_fprintf (f, metric ? "%%ADD%dR,%.3`mmX%.3`mm*%%\r\n" : "%%ADD%dR,%.4`miX%.4`mi*%%\r\n", aptr->dCode, aptr->width, aptr->width); break; case OCTAGON: pcb_fprintf (f, metric ? "%%AMOCT%d*5,0,8,0,0,%.3`mm,22.5*%%\r\n" "%%ADD%dOCT%d*%%\r\n" : "%%AMOCT%d*5,0,8,0,0,%.3`mm,22.5*%%\r\n" "%%ADD%dOCT%d*%%\r\n", aptr->dCode, (Coord) ((double) aptr->width / COS_22_5_DEGREE), aptr->dCode, aptr->dCode); break; #if 0 case THERMAL: fprintf (f, "%%AMTHERM%d*7,0,0,%.4f,%.4f,%.4f,45*%%\r\n" "%%ADD%dTHERM%d*%%\r\n", dCode, gap / 100000.0, width / 100000.0, finger / 100000.0, dCode, dCode); break; case ROUNDCLEAR: fprintf (f, "%%ADD%dC,%.4fX%.4f*%%\r\n", dCode, gap / 100000.0, width / 100000.0); break; case SQUARECLEAR: fprintf (f, "%%ADD%dR,%.4fX%.4fX%.4fX%.4f*%%\r\n", dCode, gap / 100000.0, gap / 100000.0, width / 100000.0, width / 100000.0); break; #else default: break; #endif } } /* Set the aperture list for the current layer, * expanding the list buffer if needed */ static ApertureList * setLayerApertureList (int layer_idx) { if (layer_idx >= layer_list_max) { int i = layer_list_max; layer_list_max = 2 * (layer_idx + 1); layer_aptr_list = (ApertureList *) realloc (layer_aptr_list, layer_list_max * sizeof (*layer_aptr_list)); for (; i < layer_list_max; ++i) initApertureList (&layer_aptr_list[i]); } curr_aptr_list = &layer_aptr_list[layer_idx]; return curr_aptr_list; } /* --------------------------------------------------------------------------- */ static HID gerber_hid; static HID_DRAW gerber_graphics; typedef struct hid_gc_struct { EndCapStyle cap; int width; int color; int erase; int drill; } hid_gc_struct; static FILE *f = NULL; static char *filename = NULL; static char *filesuff = NULL; static char *layername = NULL; static int lncount = 0; static int finding_apertures = 0; static int pagecount = 0; static int linewidth = -1; static int lastgroup = -1; static int lastcap = -1; static int print_group[MAX_GROUP]; static int print_layer[MAX_ALL_LAYER]; static int lastX, lastY; /* the last X and Y coordinate */ static const char *copy_outline_names[] = { #define COPY_OUTLINE_NONE 0 "none", #define COPY_OUTLINE_MASK 1 "mask", #define COPY_OUTLINE_SILK 2 "silk", #define COPY_OUTLINE_ALL 3 "all", NULL }; static const char *name_style_names[] = { #define NAME_STYLE_FIXED 0 "fixed", #define NAME_STYLE_SINGLE 1 "single", #define NAME_STYLE_FIRST 2 "first", #define NAME_STYLE_EAGLE 3 "eagle", #define NAME_STYLE_HACKVANA 4 "hackvana", #define NAME_STYLE_OSHPARK 5 "oshpark", NULL }; static HID_Attribute gerber_options[] = { /* %start-doc options "90 Gerber Export" @ftable @code @item --gerberfile Gerber output file prefix. Parameter @code{} can include a path. @end ftable %end-doc */ {"gerberfile", "Gerber output file base", HID_String, 0, 0, {0, 0, 0}, 0, 0}, #define HA_gerberfile 0 /* %start-doc options "90 Gerber Export" @ftable @code @item --all-layers Output contains all layers, even empty ones. @end ftable %end-doc */ {"all-layers", "Output all layers, even empty ones", HID_Boolean, 0, 0, {0, 0, 0}, 0, 0}, #define HA_all_layers 1 /* %start-doc options "90 Gerber Export" @ftable @code @item --verbose Print file names and aperture counts on stdout. @end ftable %end-doc */ {"verbose", "Print file names and aperture counts on stdout", HID_Boolean, 0, 0, {0, 0, 0}, 0, 0}, #define HA_verbose 2 /* %start-doc options "90 Gerber Export" @ftable @code @item --metric Generate metric Gerber and drill files @end ftable %end-doc */ {"metric", "Generate metric Gerber and drill files", HID_Boolean, 0, 0, {0, 0, 0}, 0, 0}, #define HA_metric 3 /* %start-doc options "90 Gerber Export" @ftable @code @item --copy-outline Copy the outline onto other layers. Parameter @code{} can be @samp{none}, @samp{mask}, @samp{silk} or @samp{all}. @end ftable %end-doc */ {"copy-outline", "Copy outline onto other layers", HID_Enum, 0, 0, {0, 0, 0}, copy_outline_names, 0}, #define HA_copy_outline 4 /* %start-doc options "90 Gerber Export" @ftable @code @item --name-style Naming style for individual gerber files. Parameter @code{} can be @samp{fixed}, @samp{single}, @samp{first}, @samp{eagle}, @samp{hackvana} or @samp{oshpark}. @end ftable %end-doc */ {"name-style", "Naming style for individual gerber files", HID_Enum, 0, 0, {0, 0, 0}, name_style_names, 0}, #define HA_name_style 5 }; #define NUM_OPTIONS (sizeof(gerber_options)/sizeof(gerber_options[0])) static HID_Attr_Val gerber_values[NUM_OPTIONS]; static HID_Attribute * gerber_get_export_options (int *n) { static char *last_made_filename = NULL; if (PCB) derive_default_filename(PCB->Filename, &gerber_options[HA_gerberfile], "", &last_made_filename); if (n) *n = NUM_OPTIONS; return gerber_options; } static int layer_stack_sort (const void *va, const void *vb) { int a_layer = *(int *) va; int b_layer = *(int *) vb; int a_group = GetLayerGroupNumberByNumber (a_layer); int b_group = GetLayerGroupNumberByNumber (b_layer); if (b_group != a_group) return b_group - a_group; return b_layer - a_layer; } static void maybe_close_f (FILE *f) { if (f) { if (was_drill) fprintf (f, "M30\r\n"); else fprintf (f, "M02*\r\n"); fclose (f); } } static BoxType region; /* Very similar to layer_type_to_file_name() but appends only a three-character suffix compatible with Eagle's defaults. */ static void assign_eagle_file_suffix (char *dest, int idx) { int group; int nlayers; char *suff = "out"; switch (idx) { case SL (SILK, TOP): suff = "plc"; break; case SL (SILK, BOTTOM): suff = "pls"; break; case SL (MASK, TOP): suff = "stc"; break; case SL (MASK, BOTTOM): suff = "sts"; break; case SL (PDRILL, 0): suff = "drd"; break; case SL (UDRILL, 0): suff = "dru"; break; case SL (PASTE, TOP): suff = "crc"; break; case SL (PASTE, BOTTOM): suff = "crs"; break; case SL (INVISIBLE, 0): suff = "inv"; break; case SL (FAB, 0): suff = "fab"; break; case SL (ASSY, TOP): suff = "ast"; break; case SL (ASSY, BOTTOM): suff = "asb"; break; default: group = GetLayerGroupNumberByNumber(idx); nlayers = PCB->LayerGroups.Number[group]; if (group == GetLayerGroupNumberBySide(TOP_SIDE)) /* Component */ { suff = "cmp"; } else if (group == GetLayerGroupNumberBySide(BOTTOM_SIDE)) /* Solder */ { suff = "sol"; } else if (nlayers == 1 && (strcmp (PCB->Data->Layer[idx].Name, "route") == 0 || strcmp (PCB->Data->Layer[idx].Name, "outline") == 0)) { suff = "oln"; } else { static char buf[20]; sprintf (buf, "ly%d", group); suff = buf; } break; } strcpy (dest, suff); } /* Very similar to layer_type_to_file_name() but appends only a three-character suffix compatible with Hackvana's naming requirements */ static void assign_hackvana_file_suffix (char *dest, int idx) { int group; int nlayers; char *suff = "defau.out"; switch (idx) { case SL (SILK, TOP): suff = "gto"; break; case SL (SILK, BOTTOM): suff = "gbo"; break; case SL (MASK, TOP): suff = "gts"; break; case SL (MASK, BOTTOM): suff = "gbs"; break; case SL (PDRILL, 0): suff = "drl"; break; case SL (UDRILL, 0): suff = "_NPTH.drl"; break; case SL (PASTE, TOP): suff = "gtp"; break; case SL (PASTE, BOTTOM): suff = "gbp"; break; case SL (INVISIBLE, 0): suff = "inv"; break; case SL (FAB, 0): suff = "fab"; break; case SL (ASSY, TOP): suff = "ast"; break; case SL (ASSY, BOTTOM): suff = "asb"; break; default: group = GetLayerGroupNumberByNumber(idx); nlayers = PCB->LayerGroups.Number[group]; if (group == GetLayerGroupNumberBySide(TOP_SIDE)) { suff = "gtl"; } else if (group == GetLayerGroupNumberBySide(BOTTOM_SIDE)) { suff = "gbl"; } else if (nlayers == 1 && (strcmp (PCB->Data->Layer[idx].Name, "route") == 0 || strcmp (PCB->Data->Layer[idx].Name, "outline") == 0)) { suff = "gm1"; } else { static char buf[20]; sprintf (buf, "g%d", group); suff = buf; } break; } strcpy (dest, suff); } /*! * \brief Very similar to layer_type_to_file_name() but appends only a * three-character suffix compatible with OSH Park's naming requirements. * * \note The unplated drill file with the ".TXT" extension will be * merged when the zip file is processed by OSH Park (after uploading). * * \warning Blind and buried vias are not supported by OSH Park. * * \warning Currently 4 layer boards is the maximum OSH Park supports. */ static void assign_oshpark_file_suffix (char *dest, int idx) { int group; int nlayers; char *suff = "default.out"; switch (idx) { case SL (SILK, TOP): suff = "GTO"; break; case SL (SILK, BOTTOM): suff = "GBO"; break; case SL (MASK, TOP): suff = "GTS"; break; case SL (MASK, BOTTOM): suff = "GBS"; break; case SL (PDRILL, 0): suff = "XLN"; break; case SL (UDRILL, 0): suff = "TXT"; break; case SL (PASTE, TOP): suff = "gtp"; break; case SL (PASTE, BOTTOM): suff = "gbp"; break; case SL (INVISIBLE, 0): suff = "inv"; break; case SL (FAB, 0): suff = "fab"; break; case SL (ASSY, TOP): suff = "ast"; break; case SL (ASSY, BOTTOM): suff = "asb"; break; default: group = GetLayerGroupNumberByNumber(idx); nlayers = PCB->LayerGroups.Number[group]; if (group == GetLayerGroupNumberBySide(TOP_SIDE)) { suff = "GTL"; } else if (group == GetLayerGroupNumberBySide(BOTTOM_SIDE)) { suff = "GBL"; } else if (nlayers == 1 && (strcmp (PCB->Data->Layer[idx].Name, "route") == 0 || strcmp (PCB->Data->Layer[idx].Name, "outline") == 0)) { suff = "GKO"; } else { static char buf[20]; sprintf (buf, "G%dL", group); suff = buf; } break; } strcpy (dest, suff); } static void assign_file_suffix (char *dest, int idx, const char *layer_name) { int fns_style; const char *sext = ".gbr"; switch (name_style) { default: case NAME_STYLE_FIXED: fns_style = FNS_fixed; break; case NAME_STYLE_SINGLE: fns_style = FNS_single; break; case NAME_STYLE_FIRST: fns_style = FNS_first; break; case NAME_STYLE_EAGLE: assign_eagle_file_suffix (dest, idx); return; case NAME_STYLE_HACKVANA: assign_hackvana_file_suffix (dest, idx); return; case NAME_STYLE_OSHPARK: assign_oshpark_file_suffix (dest, idx); return; } switch (idx) { case SL (PDRILL, 0): sext = ".cnc"; break; case SL (UDRILL, 0): sext = ".cnc"; break; } strcpy (dest, layer_type_to_file_name_ex (idx, fns_style, layer_name)); strcat (dest, sext); } static void gerber_do_export (HID_Attr_Val * options) { const char *fnbase; int i; static int saved_layer_stack[MAX_LAYER]; int save_ons[MAX_ALL_LAYER]; FlagType save_thindraw; save_thindraw = PCB->Flags; CLEAR_FLAG(THINDRAWFLAG, PCB); CLEAR_FLAG(THINDRAWPOLYFLAG, PCB); CLEAR_FLAG(CHECKPLANESFLAG, PCB); if (!options) { gerber_get_export_options (NULL); for (i = 0; i < NUM_OPTIONS; i++) gerber_values[i] = gerber_options[i].default_val; options = gerber_values; } fnbase = options[HA_gerberfile].str_value; if (!fnbase) fnbase = "pcb-out"; verbose = options[HA_verbose].int_value; metric = options[HA_metric].int_value; if (metric) { x_convspec = "X%.0mu"; y_convspec = "Y%.0mu"; } else { x_convspec = "X%.0mc"; y_convspec = "Y%.0mc"; } all_layers = options[HA_all_layers].int_value; copy_outline_mode = options[HA_copy_outline].int_value; name_style = options[HA_name_style].int_value; outline_layer = NULL; for (i = 0; i < max_copper_layer; i++) { LayerType *layer = PCB->Data->Layer + i; if (strcmp (layer->Name, "outline") == 0 || strcmp (layer->Name, "route") == 0) { outline_layer = layer; } } i = strlen (fnbase); filename = (char *)realloc (filename, i + 40); strcpy (filename, fnbase); strcat (filename, "."); filesuff = filename + strlen (filename); if (all_layers) { memset (print_group, 1, sizeof (print_group)); memset (print_layer, 1, sizeof (print_layer)); } else { memset (print_group, 0, sizeof (print_group)); memset (print_layer, 0, sizeof (print_layer)); } hid_save_and_show_layer_ons (save_ons); for (i = 0; i < max_copper_layer; i++) { LayerType *layer = PCB->Data->Layer + i; if (layer->LineN || layer->TextN || layer->ArcN || layer->PolygonN) print_group[GetLayerGroupNumberByNumber (i)] = 1; } print_group[GetLayerGroupNumberBySide (BOTTOM_SIDE)] = 1; print_group[GetLayerGroupNumberBySide (TOP_SIDE)] = 1; for (i = 0; i < max_copper_layer; i++) if (print_group[GetLayerGroupNumberByNumber (i)]) print_layer[i] = 1; memcpy (saved_layer_stack, LayerStack, sizeof (LayerStack)); qsort (LayerStack, max_copper_layer, sizeof (LayerStack[0]), layer_stack_sort); linewidth = -1; lastcap = -1; lastgroup = -1; region.X1 = 0; region.Y1 = 0; region.X2 = PCB->MaxWidth; region.Y2 = PCB->MaxHeight; pagecount = 1; resetApertures (); lastgroup = -1; layer_list_idx = 0; finding_apertures = 1; hid_expose_callback (&gerber_hid, ®ion, 0); layer_list_idx = 0; finding_apertures = 0; hid_expose_callback (&gerber_hid, ®ion, 0); memcpy (LayerStack, saved_layer_stack, sizeof (LayerStack)); maybe_close_f (f); f = NULL; hid_restore_layer_ons (save_ons); PCB->Flags = save_thindraw; } static void gerber_parse_arguments (int *argc, char ***argv) { hid_register_attributes (gerber_options, NUM_OPTIONS); hid_parse_command_line (argc, argv); } static int drill_sort (const void *va, const void *vb) { PendingDrills *a = (PendingDrills *) va; PendingDrills *b = (PendingDrills *) vb; if (a->diam != b->diam) return a->diam - b->diam; if (a->x != b->x) return a->x - b->x; return a->y - b->y; } static int gerber_set_layer (const char *name, int group, int empty) { int want_outline; char *cp; int idx = (group >= 0 && group < max_group) ? PCB->LayerGroups.Entries[group][0] : group; if (name == NULL) name = PCB->Data->Layer[idx].Name; if (idx >= 0 && idx < max_copper_layer && !print_layer[idx]) return 0; if (strcmp (name, "invisible") == 0) return 0; if (SL_TYPE (idx) == SL_ASSY) return 0; flash_drills = 0; if (strcmp (name, "outline") == 0 || strcmp (name, "route") == 0) flash_drills = 1; if (is_drill && n_pending_drills) { int i; /* dump pending drills in sequence */ qsort (pending_drills, n_pending_drills, sizeof (pending_drills[0]), drill_sort); for (i = 0; i < n_pending_drills; i++) { if (i == 0 || pending_drills[i].diam != pending_drills[i - 1].diam) { Aperture *ap = findAperture (curr_aptr_list, pending_drills[i].diam, ROUND); fprintf (f, "T%02d\r\n", ap->dCode); } pcb_fprintf (f, metric ? "X%06.0muY%06.0mu\r\n" : "X%06.0mtY%06.0mt\r\n", gerberDrX (PCB, pending_drills[i].x), gerberDrY (PCB, pending_drills[i].y)); } free (pending_drills); n_pending_drills = max_pending_drills = 0; pending_drills = NULL; } is_drill = (SL_TYPE (idx) == SL_PDRILL || SL_TYPE (idx) == SL_UDRILL); is_mask = (SL_TYPE (idx) == SL_MASK); current_mask = HID_MASK_OFF; #if 0 printf ("Layer %s group %d drill %d mask %d\n", name, group, is_drill, is_mask); #endif if (group < 0 || group != lastgroup) { time_t currenttime; char utcTime[64]; #ifdef HAVE_GETPWUID struct passwd *pwentry; #endif ApertureList *aptr_list; Aperture *search; lastgroup = group; lastX = -1; lastY = -1; linewidth = -1; lastcap = -1; aptr_list = setLayerApertureList (layer_list_idx++); if (finding_apertures) goto emit_outline; if (aptr_list->count == 0 && !all_layers) return 0; maybe_close_f (f); f = NULL; pagecount++; assign_file_suffix (filesuff, idx, name); f = fopen (filename, "wb"); /* Binary needed to force CR-LF */ if (f == NULL) { Message ( "Error: Could not open %s for writing.\n", filename); return 1; } was_drill = is_drill; if (verbose) { int c = aptr_list->count; printf ("Gerber: %d aperture%s in %s\n", c, c == 1 ? "" : "s", filename); } if (is_drill) { /* We omit the ,TZ here because we are not omitting trailing zeros. Our format is always six-digit 0.1 mil or µm resolution (i.e. 001100 = 0.11" or 1.1mm)*/ fprintf (f, "M48\r\n"); fprintf (f, metric ? "METRIC,000.000\r\n" : "INCH\r\n"); for (search = aptr_list->data; search; search = search->next) pcb_fprintf (f, metric ? "T%02dC%.3`mm\r\n" : "T%02dC%.3`mi\r\n", search->dCode, search->width); fprintf (f, "%%\r\n"); /* FIXME */ return 1; } fprintf (f, "G04 start of page %d for group %d idx %d *\r\n", pagecount, group, idx); /* Create a portable timestamp. */ currenttime = time (NULL); { /* avoid gcc complaints */ const char *fmt = "%c UTC"; strftime (utcTime, sizeof utcTime, fmt, gmtime (¤ttime)); } /* Print a cute file header at the beginning of each file. */ fprintf (f, "G04 Title: %s, %s *\r\n", UNKNOWN (PCB->Name), UNKNOWN (name)); fprintf (f, "G04 Creator: %s " VERSION " *\r\n", Progname); fprintf (f, "G04 CreationDate: %s *\r\n", utcTime); #ifdef HAVE_GETPWUID /* ID the user. */ pwentry = getpwuid (getuid ()); fprintf (f, "G04 For: %s *\r\n", pwentry->pw_name); #endif fprintf (f, "G04 Format: Gerber/RS-274X *\r\n"); pcb_fprintf (f, metric ? "G04 PCB-Dimensions (mm): %.2mm %.2mm *\r\n" : "G04 PCB-Dimensions (mil): %.2ml %.2ml *\r\n", PCB->MaxWidth, PCB->MaxHeight); fprintf (f, "G04 PCB-Coordinate-Origin: lower left *\r\n"); /* Signal data in inches. */ fprintf (f, metric ? "%%MOMM*%%\r\n" : "%%MOIN*%%\r\n"); /* Signal Leading zero suppression, Absolute Data, 2.5 format in inch, 4.3 in mm */ fprintf (f, metric ? "%%FSLAX43Y43*%%\r\n" : "%%FSLAX25Y25*%%\r\n"); /* build a legal identifier. */ if (layername) free (layername); layername = strdup (filesuff); if (strrchr (layername, '.')) * strrchr (layername, '.') = 0; for (cp=layername; *cp; cp++) { if (isalnum((int) *cp)) *cp = toupper((int) *cp); else *cp = '_'; } fprintf (f, "%%LN%s*%%\r\n", layername); lncount = 1; for (search = aptr_list->data; search; search = search->next) fprintAperture(f, search); if (aptr_list->count == 0) /* We need to put *something* in the file to make it be parsed as RS-274X instead of RS-274D. */ fprintf (f, "%%ADD11C,0.0100*%%\r\n"); } emit_outline: /* If we're printing a copper layer other than the outline layer, and we want to "print outlines", and we have an outline layer, print the outline layer on this layer also. */ want_outline = 0; if (copy_outline_mode == COPY_OUTLINE_MASK && SL_TYPE (idx) == SL_MASK) want_outline = 1; if (copy_outline_mode == COPY_OUTLINE_SILK && SL_TYPE (idx) == SL_SILK) want_outline = 1; if (copy_outline_mode == COPY_OUTLINE_ALL && (SL_TYPE (idx) == SL_SILK || SL_TYPE (idx) == SL_MASK || SL_TYPE (idx) == SL_FAB || SL_TYPE (idx) == SL_ASSY || SL_TYPE (idx) == 0)) want_outline = 1; if (want_outline && strcmp (name, "outline") && strcmp (name, "route")) { if (outline_layer && outline_layer != PCB->Data->Layer+idx) DrawLayer (outline_layer, ®ion); else if (!outline_layer) { hidGC gc = gui->graphics->make_gc (); printf("name %s idx %d\n", name, idx); if (SL_TYPE (idx) == SL_SILK) gui->graphics->set_line_width (gc, PCB->minSlk); else if (group >= 0) gui->graphics->set_line_width (gc, PCB->minWid); else gui->graphics->set_line_width (gc, AUTO_OUTLINE_WIDTH); gui->graphics->draw_line (gc, 0, 0, PCB->MaxWidth, 0); gui->graphics->draw_line (gc, 0, 0, 0, PCB->MaxHeight); gui->graphics->draw_line (gc, PCB->MaxWidth, 0, PCB->MaxWidth, PCB->MaxHeight); gui->graphics->draw_line (gc, 0, PCB->MaxHeight, PCB->MaxWidth, PCB->MaxHeight); gui->graphics->destroy_gc (gc); } } return 1; } static hidGC gerber_make_gc (void) { hidGC rv = (hidGC) calloc (1, sizeof (*rv)); rv->cap = Trace_Cap; return rv; } static void gerber_destroy_gc (hidGC gc) { free (gc); } static void gerber_use_mask (enum mask_mode mode) { current_mask = mode; } static void gerber_set_color (hidGC gc, const char *name) { if (strcmp (name, "erase") == 0) { gc->color = 1; gc->erase = 1; gc->drill = 0; } else if (strcmp (name, "drill") == 0) { gc->color = 1; gc->erase = 0; gc->drill = 1; } else { gc->color = 0; gc->erase = 0; gc->drill = 0; } } static void gerber_set_line_cap (hidGC gc, EndCapStyle style) { gc->cap = style; } static void gerber_set_line_width (hidGC gc, Coord width) { gc->width = width; } static void gerber_set_draw_xor (hidGC gc, int xor_) { ; } static void use_gc (hidGC gc, int radius) { if (radius) { radius *= 2; if (radius != linewidth || lastcap != Round_Cap) { Aperture *aptr = findAperture (curr_aptr_list, radius, ROUND); if (aptr == NULL) pcb_fprintf (stderr, "error: aperture for radius %$mS type ROUND is null\n", radius); else if (f && !is_drill) fprintf (f, "G54D%d*", aptr->dCode); linewidth = radius; lastcap = Round_Cap; } } else if (linewidth != gc->width || lastcap != gc->cap) { Aperture *aptr; ApertureShape shape; linewidth = gc->width; lastcap = gc->cap; switch (gc->cap) { case Round_Cap: case Trace_Cap: shape = ROUND; break; default: case Square_Cap: shape = SQUARE; break; } aptr = findAperture (curr_aptr_list, linewidth, shape); if (aptr == NULL) pcb_fprintf (stderr, "error: aperture for width %$mS type %s is null\n", linewidth, shape == ROUND ? "ROUND" : "SQUARE"); else if (f) fprintf (f, "G54D%d*", aptr->dCode); } } static void gerber_draw_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2) { gerber_draw_line (gc, x1, y1, x1, y2); gerber_draw_line (gc, x1, y1, x2, y1); gerber_draw_line (gc, x1, y2, x2, y2); gerber_draw_line (gc, x2, y1, x2, y2); } static void gerber_draw_line (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2) { bool m = false; if (x1 != x2 && y1 != y2 && gc->cap == Square_Cap) { Coord x[5], y[5]; double tx, ty, theta; theta = atan2 (y2-y1, x2-x1); /* T is a vector half a thickness long, in the direction of one of the corners. */ tx = gc->width / 2.0 * cos (theta + M_PI/4) * sqrt(2.0); ty = gc->width / 2.0 * sin (theta + M_PI/4) * sqrt(2.0); x[0] = x1 - tx; y[0] = y1 - ty; x[1] = x2 + ty; y[1] = y2 - tx; x[2] = x2 + tx; y[2] = y2 + ty; x[3] = x1 - ty; y[3] = y1 + tx; x[4] = x[0]; y[4] = y[0]; gerber_fill_polygon (gc, 5, x, y); return; } use_gc (gc, 0); if (!f) return; if (x1 != lastX) { m = true; lastX = x1; print_xcoord (f, PCB, lastX); } if (y1 != lastY) { m = true; lastY = y1; print_ycoord (f, PCB, lastY); } if ((x1 == x2) && (y1 == y2)) fprintf (f, "D03*\r\n"); else { if (m) fprintf (f, "D02*"); if (x2 != lastX) { lastX = x2; print_xcoord (f, PCB, lastX); } if (y2 != lastY) { lastY = y2; print_ycoord (f, PCB, lastY); } fprintf (f, "D01*\r\n"); } } static void gerber_draw_arc (hidGC gc, Coord cx, Coord cy, Coord width, Coord height, Angle start_angle, Angle delta_angle) { bool m = false; double arcStartX, arcStopX, arcStartY, arcStopY; /* we never draw zero-width lines */ if (gc->width == 0) return; use_gc (gc, 0); if (!f) return; arcStartX = cx - width * cos (TO_RADIANS (start_angle)); arcStartY = cy + height * sin (TO_RADIANS (start_angle)); /* I checked three different gerber viewers, and they all disagreed on how ellipses should be drawn. The spec just calls G74/G75 "circular interpolation" so there's a chance it just doesn't support ellipses at all. Thus, we draw them out with line segments. Note that most arcs in pcb are circles anyway. */ if (width != height) { double step, angle; Coord max = width > height ? width : height; Coord minr = max - gc->width / 10; int nsteps; Coord x0, y0, x1, y1; if (minr >= max) minr = max - 1; step = acos((double)minr/(double)max) * 180.0/M_PI; if (step > 5) step = 5; nsteps = abs(delta_angle) / step + 1; step = (double)delta_angle / nsteps; x0 = arcStartX; y0 = arcStartY; angle = start_angle; while (nsteps > 0) { nsteps --; x1 = cx - width * cos (TO_RADIANS (angle+step)); y1 = cy + height * sin (TO_RADIANS (angle+step)); gerber_draw_line (gc, x0, y0, x1, y1); x0 = x1; y0 = y1; angle += step; } return; } arcStopX = cx - width * cos (TO_RADIANS (start_angle + delta_angle)); arcStopY = cy + height * sin (TO_RADIANS (start_angle + delta_angle)); if (arcStartX != lastX) { m = true; lastX = arcStartX; print_xcoord (f, PCB, lastX); } if (arcStartY != lastY) { m = true; lastY = arcStartY; print_ycoord (f, PCB, lastY); } if (m) fprintf (f, "D02*"); pcb_fprintf (f, metric ? "G75*G0%1dX%.0muY%.0muI%.0muJ%.0muD01*G01*\r\n" : "G75*G0%1dX%.0mcY%.0mcI%.0mcJ%.0mcD01*G01*\r\n", (delta_angle < 0) ? 2 : 3, gerberX (PCB, arcStopX), gerberY (PCB, arcStopY), gerberXOffset (PCB, cx - arcStartX), gerberYOffset (PCB, cy - arcStartY)); lastX = arcStopX; lastY = arcStopY; } static void gerber_fill_circle (hidGC gc, Coord cx, Coord cy, Coord radius) { if (radius <= 0) return; if (is_drill) radius = 50 * round (radius / 50.0); use_gc (gc, radius); if (!f) return; if (is_drill) { if (n_pending_drills >= max_pending_drills) { max_pending_drills += 100; pending_drills = (PendingDrills *) realloc(pending_drills, max_pending_drills * sizeof (pending_drills[0])); } pending_drills[n_pending_drills].x = cx; pending_drills[n_pending_drills].y = cy; pending_drills[n_pending_drills].diam = radius * 2; n_pending_drills++; return; } else if (gc->drill && !flash_drills) return; if (cx != lastX) { lastX = cx; print_xcoord (f, PCB, lastX); } if (cy != lastY) { lastY = cy; print_ycoord (f, PCB, lastY); } fprintf (f, "D03*\r\n"); } static void gerber_fill_polygon (hidGC gc, int n_coords, Coord *x, Coord *y) { bool m = false; int i; int firstTime = 1; Coord startX = 0, startY = 0; if (is_mask && current_mask == HID_MASK_BEFORE) return; use_gc (gc, 10 * 100); if (!f) return; fprintf (f, "G36*\r\n"); for (i = 0; i < n_coords; i++) { if (x[i] != lastX) { m = true; lastX = x[i]; print_xcoord (f, PCB, lastX); } if (y[i] != lastY) { m = true; lastY = y[i]; print_ycoord (f, PCB, lastY); } if (firstTime) { firstTime = 0; startX = x[i]; startY = y[i]; if (m) fprintf (f, "D02*"); } else if (m) fprintf (f, "D01*\r\n"); m = false; } if (startX != lastX) { m = true; lastX = startX; print_xcoord (f, PCB, startX); } if (startY != lastY) { m = true; lastY = startY; print_ycoord (f, PCB, lastY); } if (m) fprintf (f, "D01*\r\n"); fprintf (f, "G37*\r\n"); } static void gerber_fill_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2) { Coord x[5]; Coord y[5]; x[0] = x[4] = x1; y[0] = y[4] = y1; x[1] = x1; y[1] = y2; x[2] = x2; y[2] = y2; x[3] = x2; y[3] = y1; gerber_fill_polygon (gc, 5, x, y); } static void gerber_calibrate (double xval, double yval) { CRASH; } static void gerber_set_crosshair (int x, int y, int action) { } void hid_gerber_init () { memset (&gerber_hid, 0, sizeof (gerber_hid)); memset (&gerber_graphics, 0, sizeof (gerber_graphics)); common_nogui_init (&gerber_hid); common_draw_helpers_init (&gerber_graphics); gerber_hid.struct_size = sizeof (gerber_hid); gerber_hid.name = "gerber"; gerber_hid.description = "RS-274X (Gerber) export"; gerber_hid.exporter = 1; gerber_hid.get_export_options = gerber_get_export_options; gerber_hid.do_export = gerber_do_export; gerber_hid.parse_arguments = gerber_parse_arguments; gerber_hid.set_layer = gerber_set_layer; gerber_hid.calibrate = gerber_calibrate; gerber_hid.set_crosshair = gerber_set_crosshair; gerber_hid.graphics = &gerber_graphics; gerber_graphics.make_gc = gerber_make_gc; gerber_graphics.destroy_gc = gerber_destroy_gc; gerber_graphics.use_mask = gerber_use_mask; gerber_graphics.set_color = gerber_set_color; gerber_graphics.set_line_cap = gerber_set_line_cap; gerber_graphics.set_line_width = gerber_set_line_width; gerber_graphics.set_draw_xor = gerber_set_draw_xor; gerber_graphics.draw_line = gerber_draw_line; gerber_graphics.draw_arc = gerber_draw_arc; gerber_graphics.draw_rect = gerber_draw_rect; gerber_graphics.fill_circle = gerber_fill_circle; gerber_graphics.fill_polygon = gerber_fill_polygon; gerber_graphics.fill_rect = gerber_fill_rect; hid_register_hid (&gerber_hid); } pcb-4.3.0/src/hid/gerber/hid.conf0000664000175000017500000000001413773431044013422 00000000000000type=export pcb-4.3.0/src/hid/nelma/0000775000175000017500000000000014017001275011711 500000000000000pcb-4.3.0/src/hid/nelma/nelma.c0000664000175000017500000006075013773431044013112 00000000000000/* * COPYRIGHT * * PCB, interactive printed circuit board design * * NELMA (Numerical capacitance calculator) export HID * Copyright (C) 2006 Tomaz Solc (tomaz.solc@tablix.org) * * PNG export code is based on the PNG export HID * Copyright (C) 2006 Dan McMahill * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ /* * This HID exports a PCB layout into: o One layer mask file (PNG format) per * copper layer. o Nelma configuration file that contains netlist and pin * information. */ /* * FIXME: * * If you have a section of a net that does not contain any pins then that * section will be missing from the Nelma's copper geometry. * * For example: * * this section will be ignored by Nelma | | * * || ||=======|| || component layer || * || || || ||=============|| ||============|| * solder layer * * pin1 via via pin2 * * Single layer layouts are always exported correctly. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include "global.h" #include "error.h" /* Message() */ #include "data.h" #include "misc.h" #include "rats.h" #include "hid.h" #include "hid_draw.h" #include "../hidint.h" #include "hid/common/hidnogui.h" #include "hid/common/draw_helpers.h" #include #include "hid/common/hidinit.h" #ifdef HAVE_LIBDMALLOC #include #endif #define CRASH fprintf(stderr, "HID error: pcb called unimplemented PNG function %s.\n", __FUNCTION__); abort() /* Needed for PNG export */ struct color_struct { /* the descriptor used by the gd library */ int c; /* so I can figure out what rgb value c refers to */ unsigned int r, g, b; }; struct hid_gc_struct { HID *me_pointer; EndCapStyle cap; Coord width; unsigned char r, g, b; int erase; struct color_struct *color; gdImagePtr brush; }; static HID nelma_hid; static HID_DRAW nelma_graphics; static struct color_struct *black = NULL, *white = NULL; static Coord linewidth = -1; static gdImagePtr lastbrush = (gdImagePtr)((void *) -1); /* gd image and file for PNG export */ static gdImagePtr nelma_im = NULL; static FILE *nelma_f = NULL; static int is_mask; static int is_drill; /* * Which groups of layers to export into PNG layer masks. 1 means export, 0 * means do not export. */ static int nelma_export_group[MAX_GROUP]; /* Group that is currently exported. */ static int nelma_cur_group; /* Filename prefix that will be used when saving files. */ static const char *nelma_basename = NULL; /* Horizontal DPI (grid points per inch) */ static int nelma_dpi = -1; /* Height of the copper layers in micrometers. */ /* * The height of the copper layer is currently taken as the vertical grid * step, since this is the smallest vertical feature in the layout. */ static int nelma_copperh = -1; /* Height of the substrate layers in micrometers. */ static int nelma_substrateh = -1; /* Relative permittivity of the substrate. */ static double nelma_substratee = -1; /* Permittivity of empty space (As/Vm) */ static const double nelma_air_epsilon = 8.85e-12; HID_Attribute nelma_attribute_list[] = { /* other HIDs expect this to be first. */ /* %start-doc options "94 Nelma Options" @ftable @code @item --basename File name prefix. @end ftable %end-doc */ {"basename", "File name prefix", HID_String, 0, 0, {0, 0, 0}, 0, 0}, #define HA_basename 0 /* %start-doc options "94 Nelma Options" @ftable @code @item --dpi Horizontal scale factor (grid points/inch). @end ftable %end-doc */ {"dpi", "Horizontal scale factor (grid points/inch)", HID_Integer, 0, 1000, {100, 0, 0}, 0, 0}, #define HA_dpi 1 /* %start-doc options "94 Nelma Options" @ftable @code @item --copper-height Copper layer height (um). @end ftable %end-doc */ {"copper-height", "Copper layer height (um)", HID_Integer, 0, 200, {100, 0, 0}, 0, 0}, #define HA_copperh 2 /* %start-doc options "94 Nelma Options" @ftable @code @item --substrate-height Substrate layer height (um). @end ftable %end-doc */ {"substrate-height", "Substrate layer height (um)", HID_Integer, 0, 10000, {2000, 0, 0}, 0, 0}, #define HA_substrateh 3 /* %start-doc options "94 Nelma Options" @ftable @code @item --substrate-epsilon Substrate relative epsilon. @end ftable %end-doc */ {"substrate-epsilon", "Substrate relative epsilon", HID_Real, 0, 100, {0, 0, 4.0}, 0, 0}, #define HA_substratee 4 }; #define NUM_OPTIONS (sizeof(nelma_attribute_list)/sizeof(nelma_attribute_list[0])) REGISTER_ATTRIBUTES(nelma_attribute_list) static HID_Attr_Val nelma_values[NUM_OPTIONS]; /* *** Utility funcions **************************************************** */ /* convert from default PCB units to nelma units */ static int pcb_to_nelma (Coord pcb) { return COORD_TO_INCH(pcb) * nelma_dpi; } static char * nelma_get_png_name(const char *basename, const char *suffix) { char *buf; int len; len = strlen(basename) + strlen(suffix) + 6; buf = (char *)malloc(sizeof(*buf) * len); sprintf(buf, "%s.%s.png", basename, suffix); return buf; } /* Retrieves coordinates (in default PCB units) of a pin or pad. */ /* Copied from netlist.c */ static int pin_name_to_xy (LibraryEntryType * pin, Coord *x, Coord *y) { ConnectionType conn; if (!SeekPad(pin, &conn, false)) return 1; switch (conn.type) { case PIN_TYPE: *x = ((PinType *) (conn.ptr2))->X; *y = ((PinType *) (conn.ptr2))->Y; return 0; case PAD_TYPE: *x = ((PadType *) (conn.ptr2))->Point1.X; *y = ((PadType *) (conn.ptr2))->Point1.Y; return 0; } return 1; } /* *** Exporting netlist data and geometry to the nelma config file ******** */ static void nelma_write_space(FILE * out) { double xh, zh; int z; int i, idx; const char *ext; xh = 2.54e-2 / ((double) nelma_dpi); zh = nelma_copperh * 1e-6; fprintf(out, "\n/* **** Space **** */\n\n"); fprintf(out, "space pcb {\n"); fprintf(out, "\tstep = { %e, %e, %e }\n", xh, xh, zh); fprintf(out, "\tlayers = {\n"); fprintf(out, "\t\t\"air-top\",\n"); fprintf(out, "\t\t\"air-bottom\""); z = 10; for (i = 0; i < MAX_GROUP; i++) if (nelma_export_group[i]) { idx = (i >= 0 && i < max_group) ? PCB->LayerGroups.Entries[i][0] : i; ext = layer_type_to_file_name(idx, FNS_fixed); if (z != 10) { fprintf(out, ",\n"); fprintf(out, "\t\t\"substrate-%d\"", z); z++; } fprintf(out, ",\n"); fprintf(out, "\t\t\"%s\"", ext); z++; } fprintf(out, "\n\t}\n"); fprintf(out, "}\n"); } static void nelma_write_material(FILE * out, char *name, char *type, double e) { fprintf(out, "material %s {\n", name); fprintf(out, "\ttype = \"%s\"\n", type); fprintf(out, "\tpermittivity = %e\n", e); fprintf(out, "\tconductivity = 0.0\n"); fprintf(out, "\tpermeability = 0.0\n"); fprintf(out, "}\n"); } static void nelma_write_materials(FILE * out) { fprintf(out, "\n/* **** Materials **** */\n\n"); nelma_write_material(out, "copper", "metal", nelma_air_epsilon); nelma_write_material(out, "air", "dielectric", nelma_air_epsilon); nelma_write_material(out, "composite", "dielectric", nelma_air_epsilon * nelma_substratee); } static void nelma_write_nets(FILE * out) { LibraryType netlist; LibraryMenuType *net; LibraryEntryType *pin; int n, m, i, idx; const char *ext; netlist = PCB->NetlistLib; fprintf(out, "\n/* **** Nets **** */\n\n"); for (n = 0; n < netlist.MenuN; n++) { net = &netlist.Menu[n]; /* Weird, but correct */ fprintf(out, "net %s {\n", &net->Name[2]); fprintf(out, "\tobjects = {\n"); for (m = 0; m < net->EntryN; m++) { pin = &net->Entry[m]; /* pin_name_to_xy(pin, &x, &y); */ for (i = 0; i < MAX_GROUP; i++) if (nelma_export_group[i]) { idx = (i >= 0 && i < max_group) ? PCB->LayerGroups.Entries[i][0] : i; ext = layer_type_to_file_name(idx, FNS_fixed); if (m != 0 || i != 0) fprintf(out, ",\n"); fprintf(out, "\t\t\"%s-%s\"", pin->ListEntry, ext); } } fprintf(out, "\n"); fprintf(out, "\t}\n"); fprintf(out, "}\n"); } } static void nelma_write_layer(FILE * out, int z, int h, const char *name, int full, char *mat) { LibraryType netlist; LibraryMenuType *net; LibraryEntryType *pin; int n, m; fprintf(out, "layer %s {\n", name); fprintf(out, "\theight = %d\n", h); fprintf(out, "\tz-order = %d\n", z); fprintf(out, "\tmaterial = \"%s\"\n", mat); if (full) { fprintf(out, "\tobjects = {\n"); netlist = PCB->NetlistLib; for (n = 0; n < netlist.MenuN; n++) { net = &netlist.Menu[n]; for (m = 0; m < net->EntryN; m++) { pin = &net->Entry[m]; if (m != 0 || n != 0) fprintf(out, ",\n"); fprintf(out, "\t\t\"%s-%s\"", pin->ListEntry, name); } } fprintf(out, "\n\t}\n"); } fprintf(out, "}\n"); } static void nelma_write_layers(FILE * out) { int i, idx; int z; const char *ext; char buf[100]; int subh; subh = nelma_substrateh / nelma_copperh; fprintf(out, "\n/* **** Layers **** */\n\n"); /* Air layers on top and bottom of the stack */ /* Their height is double substrate height. */ nelma_write_layer(out, 1, 2 * subh, "air-top", 0, "air"); nelma_write_layer(out, 1000, 2 * subh, "air-bottom", 0, "air"); z = 10; for (i = 0; i < MAX_GROUP; i++) if (nelma_export_group[i]) { idx = (i >= 0 && i < max_group) ? PCB->LayerGroups.Entries[i][0] : i; ext = layer_type_to_file_name(idx, FNS_fixed); if (z != 10) { sprintf(buf, "substrate-%d", z); nelma_write_layer(out, z, subh, buf, 0, "composite"); z++; } /* * FIXME: for layers that are not on top or bottom, * the material should be "composite" */ nelma_write_layer(out, z, 1, ext, 1, "air"); z++; } } static void nelma_write_object(FILE * out, LibraryEntryType *pin) { int i, idx; Coord px = 0, py = 0; int x, y; char *f; const char *ext; pin_name_to_xy (pin, &px, &py); x = pcb_to_nelma (px); y = pcb_to_nelma (py); for (i = 0; i < MAX_GROUP; i++) if (nelma_export_group[i]) { idx = (i >= 0 && i < max_group) ? PCB->LayerGroups.Entries[i][0] : i; ext = layer_type_to_file_name(idx, FNS_fixed); fprintf(out, "object %s-%s {\n", pin->ListEntry, ext); fprintf(out, "\tposition = { 0, 0 }\n"); fprintf(out, "\tmaterial = \"copper\"\n"); fprintf(out, "\ttype = \"image\"\n"); fprintf(out, "\trole = \"net\"\n"); f = nelma_get_png_name(nelma_basename, ext); fprintf(out, "\tfile = \"%s\"\n", f); free(f); fprintf(out, "\tfile-pos = { %d, %d }\n", x, y); fprintf(out, "}\n"); } } static void nelma_write_objects(FILE * out) { LibraryType netlist; LibraryMenuType *net; LibraryEntryType *pin; int n, m; netlist = PCB->NetlistLib; fprintf(out, "\n/* **** Objects **** */\n\n"); for (n = 0; n < netlist.MenuN; n++) { net = &netlist.Menu[n]; for (m = 0; m < net->EntryN; m++) { pin = &net->Entry[m]; nelma_write_object(out, pin); } } } /* *** Main export callback ************************************************ */ static void nelma_parse_arguments(int *argc, char ***argv) { hid_register_attributes(nelma_attribute_list, sizeof(nelma_attribute_list) / sizeof(nelma_attribute_list[0])); hid_parse_command_line(argc, argv); } static HID_Attribute * nelma_get_export_options(int *n) { static char *last_made_filename = 0; if (PCB) { derive_default_filename(PCB->Filename, &nelma_attribute_list[HA_basename], ".nelma", &last_made_filename); } if (n) { *n = NUM_OPTIONS; } return nelma_attribute_list; } /* Populates nelma_export_group array */ void nelma_choose_groups() { int n, m; LayerType *layer; /* Set entire array to 0 (don't export any layer groups by default */ memset(nelma_export_group, 0, sizeof(nelma_export_group)); for (n = 0; n < max_copper_layer; n++) { layer = &PCB->Data->Layer[n]; if (layer->LineN || layer->TextN || layer->ArcN || layer->PolygonN) { /* layer isn't empty */ /* * is this check necessary? It seems that special * layers have negative indexes? */ if (SL_TYPE(n) == 0) { /* layer is a copper layer */ m = GetLayerGroupNumberByNumber(n); /* the export layer */ nelma_export_group[m] = 1; } } } } static void nelma_alloc_colors() { /* * Allocate white and black -- the first color allocated becomes the * background color */ white = (struct color_struct *) malloc(sizeof(*white)); white->r = white->g = white->b = 255; white->c = gdImageColorAllocate(nelma_im, white->r, white->g, white->b); black = (struct color_struct *) malloc(sizeof(*black)); black->r = black->g = black->b = 0; black->c = gdImageColorAllocate(nelma_im, black->r, black->g, black->b); } static void nelma_start_png(const char *basename, const char *suffix) { int h, w; char *buf; buf = nelma_get_png_name(basename, suffix); h = pcb_to_nelma(PCB->MaxHeight); w = pcb_to_nelma(PCB->MaxWidth); /* nelma_im = gdImageCreate (w, h); */ /* Nelma only works with true color images */ nelma_im = gdImageCreate(w, h); nelma_f = fopen(buf, "wb"); nelma_alloc_colors(); free(buf); } static void nelma_finish_png() { #ifdef HAVE_GDIMAGEPNG gdImagePng(nelma_im, nelma_f); #else Message("NELMA: PNG not supported by gd. Can't write layer mask.\n"); #endif gdImageDestroy(nelma_im); fclose(nelma_f); free(white); free(black); nelma_im = NULL; nelma_f = NULL; } void nelma_start_png_export() { BoxType region; region.X1 = 0; region.Y1 = 0; region.X2 = PCB->MaxWidth; region.Y2 = PCB->MaxHeight; linewidth = -1; lastbrush = (gdImagePtr)((void *) -1); hid_expose_callback(&nelma_hid, ®ion, 0); } static void nelma_do_export(HID_Attr_Val * options) { int save_ons[MAX_ALL_LAYER]; int i, idx; FILE *nelma_config; char *buf; int len; time_t t; if (!options) { nelma_get_export_options(0); for (i = 0; i < NUM_OPTIONS; i++) { nelma_values[i] = nelma_attribute_list[i].default_val; } options = nelma_values; } nelma_basename = options[HA_basename].str_value; if (!nelma_basename) { nelma_basename = "pcb-out"; } nelma_dpi = options[HA_dpi].int_value; if (nelma_dpi < 0) { fprintf(stderr, "ERROR: dpi may not be < 0\n"); return; } nelma_copperh = options[HA_copperh].int_value; nelma_substrateh = options[HA_substrateh].int_value; nelma_substratee = options[HA_substratee].real_value; nelma_choose_groups(); for (i = 0; i < MAX_GROUP; i++) { if (nelma_export_group[i]) { nelma_cur_group = i; /* magic */ idx = (i >= 0 && i < max_group) ? PCB->LayerGroups.Entries[i][0] : i; nelma_start_png(nelma_basename, layer_type_to_file_name(idx, FNS_fixed)); hid_save_and_show_layer_ons(save_ons); nelma_start_png_export(); hid_restore_layer_ons(save_ons); nelma_finish_png(); } } len = strlen(nelma_basename) + 4; buf = (char *)malloc(sizeof(*buf) * len); sprintf(buf, "%s.em", nelma_basename); nelma_config = fopen(buf, "wb"); free(buf); fprintf(nelma_config, "/* Made with PCB Nelma export HID */"); t = time(NULL); fprintf(nelma_config, "/* %s */", ctime(&t)); nelma_write_nets(nelma_config); nelma_write_objects(nelma_config); nelma_write_layers(nelma_config); nelma_write_materials(nelma_config); nelma_write_space(nelma_config); fclose(nelma_config); } /* *** PNG export (slightly modified code from PNG export HID) ************* */ static int nelma_set_layer(const char *name, int group, int empty) { int idx = (group >= 0 && group < max_group) ? PCB->LayerGroups.Entries[group][0] : group; if (name == 0) { name = PCB->Data->Layer[idx].Name; } if (strcmp(name, "invisible") == 0) { return 0; } is_drill = (SL_TYPE(idx) == SL_PDRILL || SL_TYPE(idx) == SL_UDRILL); is_mask = (SL_TYPE(idx) == SL_MASK); if (is_mask) { /* Don't print masks */ return 0; } if (is_drill) { /* * Print 'holes', so that we can fill gaps in the copper * layer */ return 1; } if (group == nelma_cur_group) { return 1; } return 0; } static hidGC nelma_make_gc(void) { hidGC rv = (hidGC) malloc(sizeof(struct hid_gc_struct)); rv->me_pointer = &nelma_hid; rv->cap = Trace_Cap; rv->width = 1; rv->color = (struct color_struct *) malloc(sizeof(*rv->color)); rv->color->r = rv->color->g = rv->color->b = 0; rv->color->c = 0; return rv; } static void nelma_destroy_gc(hidGC gc) { free(gc); } static void nelma_use_mask(enum mask_mode mode) { /* does nothing */ } static void nelma_set_color(hidGC gc, const char *name) { if (nelma_im == NULL) { return; } if (name == NULL) { name = "#ff0000"; } if (!strcmp(name, "drill")) { gc->color = black; gc->erase = 0; return; } if (!strcmp(name, "erase")) { /* FIXME -- should be background, not white */ gc->color = white; gc->erase = 1; return; } gc->color = black; gc->erase = 0; return; } static void nelma_set_line_cap(hidGC gc, EndCapStyle style) { gc->cap = style; } static void nelma_set_line_width(hidGC gc, Coord width) { gc->width = width; } static void nelma_set_draw_xor(hidGC gc, int xor_) { ; } static void nelma_set_draw_faded(hidGC gc, int faded) { } static void use_gc(hidGC gc) { int need_brush = 0; if (gc->me_pointer != &nelma_hid) { fprintf(stderr, "Fatal: GC from another HID passed to nelma HID\n"); abort(); } if (linewidth != gc->width) { /* Make sure the scaling doesn't erase lines completely */ /* if (SCALE (gc->width) == 0 && gc->width > 0) gdImageSetThickness (im, 1); else */ gdImageSetThickness(nelma_im, pcb_to_nelma(gc->width)); linewidth = gc->width; need_brush = 1; } if (lastbrush != gc->brush || need_brush) { static void *bcache = 0; hidval bval; char name[256]; char type; int r; switch (gc->cap) { case Round_Cap: case Trace_Cap: type = 'C'; r = pcb_to_nelma(gc->width / 2); break; default: case Square_Cap: r = pcb_to_nelma(gc->width); type = 'S'; break; } sprintf(name, "#%.2x%.2x%.2x_%c_%d", gc->color->r, gc->color->g, gc->color->b, type, r); if (hid_cache_color(0, name, &bval, &bcache)) { gc->brush = (gdImagePtr)bval.ptr; } else { int bg, fg; if (type == 'C') gc->brush = gdImageCreate(2 * r + 1, 2 * r + 1); else gc->brush = gdImageCreate(r + 1, r + 1); bg = gdImageColorAllocate(gc->brush, 255, 255, 255); fg = gdImageColorAllocate(gc->brush, gc->color->r, gc->color->g, gc->color->b); gdImageColorTransparent(gc->brush, bg); /* * if we shrunk to a radius/box width of zero, then just use * a single pixel to draw with. */ if (r == 0) gdImageFilledRectangle(gc->brush, 0, 0, 0, 0, fg); else { if (type == 'C') gdImageFilledEllipse(gc->brush, r, r, 2 * r, 2 * r, fg); else gdImageFilledRectangle(gc->brush, 0, 0, r, r, fg); } bval.ptr = gc->brush; hid_cache_color(1, name, &bval, &bcache); } gdImageSetBrush(nelma_im, gc->brush); lastbrush = gc->brush; } } static void nelma_draw_rect(hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2) { use_gc(gc); gdImageRectangle(nelma_im, pcb_to_nelma(x1), pcb_to_nelma(y1), pcb_to_nelma(x2), pcb_to_nelma(y2), gc->color->c); } static void nelma_fill_rect(hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2) { use_gc(gc); gdImageSetThickness(nelma_im, 0); linewidth = 0; gdImageFilledRectangle(nelma_im, pcb_to_nelma(x1), pcb_to_nelma(y1), pcb_to_nelma(x2), pcb_to_nelma(y2), gc->color->c); } static void nelma_draw_line(hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2) { if (x1 == x2 && y1 == y2) { Coord w = gc->width / 2; nelma_fill_rect(gc, x1 - w, y1 - w, x1 + w, y1 + w); return; } use_gc(gc); gdImageSetThickness(nelma_im, 0); linewidth = 0; gdImageLine(nelma_im, pcb_to_nelma(x1), pcb_to_nelma(y1), pcb_to_nelma(x2), pcb_to_nelma(y2), gdBrushed); } static void nelma_draw_arc(hidGC gc, Coord cx, Coord cy, Coord width, Coord height, Angle start_angle, Angle delta_angle) { Angle sa, ea; /* * in gdImageArc, 0 degrees is to the right and +90 degrees is down * in pcb, 0 degrees is to the left and +90 degrees is down */ start_angle = 180 - start_angle; delta_angle = -delta_angle; if (delta_angle > 0) { sa = start_angle; ea = start_angle + delta_angle; } else { sa = start_angle + delta_angle; ea = start_angle; } /* * make sure we start between 0 and 360 otherwise gd does strange * things */ sa = NormalizeAngle (sa); ea = NormalizeAngle (ea); #if 0 printf("draw_arc %d,%d %dx%d %d..%d %d..%d\n", cx, cy, width, height, start_angle, delta_angle, sa, ea); printf("gdImageArc (%p, %d, %d, %d, %d, %d, %d, %d)\n", im, SCALE_X(cx), SCALE_Y(cy), SCALE(width), SCALE(height), sa, ea, gc->color->c); #endif use_gc(gc); gdImageSetThickness(nelma_im, 0); linewidth = 0; gdImageArc(nelma_im, pcb_to_nelma(cx), pcb_to_nelma(cy), pcb_to_nelma(2 * width), pcb_to_nelma(2 * height), sa, ea, gdBrushed); } static void nelma_fill_circle(hidGC gc, Coord cx, Coord cy, Coord radius) { use_gc(gc); gdImageSetThickness(nelma_im, 0); linewidth = 0; gdImageFilledEllipse(nelma_im, pcb_to_nelma(cx), pcb_to_nelma(cy), pcb_to_nelma(2 * radius), pcb_to_nelma(2 * radius), gc->color->c); } static void nelma_fill_polygon(hidGC gc, int n_coords, Coord *x, Coord *y) { int i; gdPoint *points; points = (gdPoint *) malloc(n_coords * sizeof(gdPoint)); if (points == NULL) { fprintf(stderr, "ERROR: nelma_fill_polygon(): malloc failed\n"); exit(1); } use_gc(gc); for (i = 0; i < n_coords; i++) { points[i].x = pcb_to_nelma(x[i]); points[i].y = pcb_to_nelma(y[i]); } gdImageSetThickness(nelma_im, 0); linewidth = 0; gdImageFilledPolygon(nelma_im, points, n_coords, gc->color->c); free(points); } static void nelma_calibrate(double xval, double yval) { CRASH; } static void nelma_set_crosshair(int x, int y, int a) { } /* *** Miscellaneous ******************************************************* */ #include "dolists.h" void hid_nelma_init() { memset (&nelma_hid, 0, sizeof (HID)); memset (&nelma_graphics, 0, sizeof (HID_DRAW)); common_nogui_init (&nelma_hid); common_draw_helpers_init (&nelma_graphics); nelma_hid.struct_size = sizeof (HID); nelma_hid.name = "nelma"; nelma_hid.description = "Numerical analysis package export"; nelma_hid.exporter = 1; nelma_hid.poly_before = 1; nelma_hid.get_export_options = nelma_get_export_options; nelma_hid.do_export = nelma_do_export; nelma_hid.parse_arguments = nelma_parse_arguments; nelma_hid.set_layer = nelma_set_layer; nelma_hid.calibrate = nelma_calibrate; nelma_hid.set_crosshair = nelma_set_crosshair; nelma_hid.graphics = &nelma_graphics; nelma_graphics.make_gc = nelma_make_gc; nelma_graphics.destroy_gc = nelma_destroy_gc; nelma_graphics.use_mask = nelma_use_mask; nelma_graphics.set_color = nelma_set_color; nelma_graphics.set_line_cap = nelma_set_line_cap; nelma_graphics.set_line_width = nelma_set_line_width; nelma_graphics.set_draw_xor = nelma_set_draw_xor; nelma_graphics.set_draw_faded = nelma_set_draw_faded; nelma_graphics.draw_line = nelma_draw_line; nelma_graphics.draw_arc = nelma_draw_arc; nelma_graphics.draw_rect = nelma_draw_rect; nelma_graphics.fill_circle = nelma_fill_circle; nelma_graphics.fill_polygon = nelma_fill_polygon; nelma_graphics.fill_rect = nelma_fill_rect; hid_register_hid (&nelma_hid); #include "nelma_lists.h" } pcb-4.3.0/src/hid/nelma/nelma_lists.h0000664000175000017500000000005214017001022014277 00000000000000REGISTER_ATTRIBUTES(nelma_attribute_list) pcb-4.3.0/src/hid/nelma/hid.conf0000664000175000017500000000001413773431044013250 00000000000000type=export pcb-4.3.0/src/hid/bom/0000775000175000017500000000000014017001275011372 500000000000000pcb-4.3.0/src/hid/bom/bom.c0000664000175000017500000004722213773431044012253 00000000000000/*! * \file src/hid/bom/bom.c * * \brief Prints a centroid file in a format which includes data needed * by a pick and place machine. * * Further formatting for a particular factory setup can easily be * generated with awk or perl. * In addition, a bill of materials file is generated which can be used * for checking stock and purchasing needed materials. * returns != zero on error. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 2006 DJ Delorie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Contact addresses for paper mail and Email: * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * Thomas.Nau@rz.uni-ulm.de * *
*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "global.h" #include "data.h" #include "error.h" #include "misc.h" #include "pcb-printf.h" #include "hid.h" #include "hid/common/hidnogui.h" #include "../hidint.h" #ifdef HAVE_LIBDMALLOC #include #endif static HID_Attribute bom_options[] = { /* %start-doc options "80 BOM Creation" @ftable @code @item --bomfile Name of the BOM output file. Parameter @code{} can include a path. @end ftable %end-doc */ {"bomfile", "Name of the BOM output file", HID_String, 0, 0, {0, 0, 0}, 0, 0}, #define HA_bomfile 0 /* %start-doc options "80 BOM Creation" @ftable @code @item --xyfile Name of the XY output file. Parameter @code{} can include a path. @end ftable %end-doc */ {"xyfile", "Name of the XY output file", HID_String, 0, 0, {0, 0, 0}, 0, 0}, #define HA_xyfile 1 /* %start-doc options "80 BOM Creation" @ftable @code @item --attrs Name of the attributes input file. Parameter @code{} can include a path. The input file can be any path, the format matches what gschem uses. One attribute per line, and whitespace is ignored. Example: @example device manufacturer manufacturer_part_number vendor vendor_part_number @end example @end ftable %end-doc */ {"attrs", "Name of the attributes input file", HID_String, 0, 0, {0, 0, 0}, 0, 0}, #define HA_attrs 2 /* %start-doc options "80 BOM Creation" @ftable @code @item --xy-unit Unit of XY dimensions. Defaults to mil. Parameter @code{} can be @samp{km}, @samp{m}, @samp{cm}, @samp{mm}, @samp{um}, @samp{nm}, @samp{px}, @samp{in}, @samp{mil}, @samp{dmil}, @samp{cmil}, or @samp{inch}. @end ftable %end-doc */ {"xy-unit", "XY units", HID_Unit, 0, 0, {-1, 0, 0}, NULL, 0}, #define HA_unit 3 {"xy-in-mm", ATTR_UNDOCUMENTED, HID_Boolean, 0, 0, {0, 0, 0}, 0, 0}, #define HA_xymm 4 }; #define NUM_OPTIONS (sizeof(bom_options)/sizeof(bom_options[0])) static HID_Attr_Val bom_values[NUM_OPTIONS]; static const char *bom_filename; static const char *xy_filename; static const Unit *xy_unit; static char **attr_list = NULL; static int attr_count = 0; static int attr_max = 0; typedef struct _StringList { char *str; struct _StringList *next; } StringList; typedef struct _BomList { char *descr; char *value; int num; StringList *refdes; char **attrs; struct _BomList *next; } BomList; static HID_Attribute * bom_get_export_options (int *n) { static char *last_bom_filename = 0; static char *last_xy_filename = 0; static int last_unit_value = -1; if (bom_options[HA_unit].default_val.int_value == last_unit_value) { if (Settings.grid_unit) bom_options[HA_unit].default_val.int_value = Settings.grid_unit->index; else bom_options[HA_unit].default_val.int_value = get_unit_struct ("mil")->index; last_unit_value = bom_options[HA_unit].default_val.int_value; } if (PCB) { derive_default_filename(PCB->Filename, &bom_options[HA_bomfile], ".bom", &last_bom_filename); derive_default_filename(PCB->Filename, &bom_options[HA_xyfile ], ".xy" , &last_xy_filename ); } if (!bom_options[HA_attrs].default_val.str_value) bom_options[HA_attrs].default_val.str_value = strdup("attribs"); if (n) *n = NUM_OPTIONS; return bom_options; } static char * CleanBOMString (char *in) { char *out; int i; if ((out = (char *)malloc ((strlen (in) + 1) * sizeof (char))) == NULL) { fprintf (stderr, "Error: CleanBOMString() malloc() failed\n"); exit (1); } /* * copy over in to out with some character conversions. * Go all the way to then end to get the terminating \0 */ for (i = 0; i <= strlen (in); i++) { switch (in[i]) { case '"': out[i] = '\''; break; default: out[i] = in[i]; } } return out; } static double xyToAngle (double x, double y, bool morethan2pins) { double d = atan2 (-y, x) * 180.0 / M_PI; /* IPC 7351 defines different rules for 2 pin elements */ if (morethan2pins) { /* Multi pin case: * Output 0 degrees if pin1 in is top left or top, i.e. between angles of * 80 to 170 degrees. * Pin #1 can be at dead top (e.g. certain PLCCs) or anywhere in the top * left. */ if (d < -100) return 90; /* -180 to -100 */ else if (d < -10) return 180; /* -100 to -10 */ else if (d < 80) return 270; /* -10 to 80 */ else if (d < 170) return 0; /* 80 to 170 */ else return 90; /* 170 to 180 */ } else { /* 2 pin element: * Output 0 degrees if pin #1 is in top left or left, i.e. in sector * between angles of 95 and 185 degrees. */ if (d < -175) return 0; /* -180 to -175 */ else if (d < -85) return 90; /* -175 to -85 */ else if (d < 5) return 180; /* -85 to 5 */ else if (d < 95) return 270; /* 5 to 95 */ else return 0; /* 95 to 180 */ } } static StringList * string_insert (char *str, StringList * list) { StringList *newlist, *cur; if ((newlist = (StringList *) malloc (sizeof (StringList))) == NULL) { fprintf (stderr, "malloc() failed in string_insert()\n"); exit (1); } newlist->next = NULL; newlist->str = strdup (str); if (list == NULL) return (newlist); cur = list; while (cur->next != NULL) cur = cur->next; cur->next = newlist; return (list); } static BomList * bom_insert (char *refdes, char *descr, char *value, ElementType *e, BomList * bom) { BomList *newlist = NULL, *cur = NULL, *prev = NULL; int i; char *val; if (bom != NULL) { /* search and see if we already have used one of these components */ cur = bom; while (cur != NULL) { int attr_mismatch = 0; for (i=0; iattrs[i]) != 0) attr_mismatch = 1; } if ((NSTRCMP (descr, cur->descr) == 0) && (NSTRCMP (value, cur->value) == 0) && ! attr_mismatch) { cur->num++; cur->refdes = string_insert (refdes, cur->refdes); return (bom); } prev = cur; cur = cur->next; } } if ((newlist = (BomList *) malloc (sizeof (BomList))) == NULL) { fprintf (stderr, "malloc() failed in bom_insert()\n"); exit (1); } if (prev) prev->next = newlist; newlist->next = NULL; newlist->descr = strdup (descr); newlist->value = strdup (value); newlist->num = 1; newlist->refdes = string_insert (refdes, NULL); if ((newlist->attrs = (char **) malloc (attr_count * sizeof (char *))) == NULL) { fprintf (stderr, "malloc() failed in bom_insert()\n"); exit (1); } for (i=0; iattrs[i] = val ? val : ""; } if (bom == NULL) bom = newlist; return (bom); } /*! * \brief If \c fp is not NULL then print out the bill of materials * contained in \c bom. * Either way, free all memory which has been allocated for bom. */ static void print_and_free (FILE *fp, BomList *bom) { BomList *lastb; StringList *lasts; char *descr, *value; while (bom != NULL) { if (fp) { descr = CleanBOMString (bom->descr); value = CleanBOMString (bom->value); fprintf (fp, "%d,\"%s\",\"%s\",", bom->num, descr, value); free (descr); free (value); } while (bom->refdes != NULL) { if (fp) { fprintf (fp, "%s ", bom->refdes->str); } free (bom->refdes->str); lasts = bom->refdes; bom->refdes = bom->refdes->next; free (lasts); } if (fp) { int i; for (i=0; iattrs[i]); fprintf (fp, "\n"); } free (bom->attrs); lastb = bom; bom = bom->next; free (lastb); } } static void fetch_attr_list () { int i; FILE *f; char buf[1024]; char *fname; if (attr_list != NULL) { for (i=0; i= buf && isspace (*c)) *c-- = 0; c = buf; while (*c && isspace (*c)) c++; if (*c) { if (attr_count == attr_max) { attr_max += 10; attr_list = (char **) realloc (attr_list, attr_max * sizeof (char *)); } attr_list[attr_count++] = strdup (c); } } fclose (f); } /*! * Maximum length of following list. */ #define MAXREFPINS 32 /*! * \brief Includes numbered and BGA pins. * * In order of preference. * Possibly BGA pins can be missing, so we add a few to try. */ static char *reference_pin_names[] = {"1", "2", "A1", "A2", "B1", "B2", 0}; static int PrintBOM (void) { char utcTime[64]; Coord x, y; double theta = 0.0; double sumx, sumy; int pinfound[MAXREFPINS]; double pinx[MAXREFPINS]; double piny[MAXREFPINS]; double pinangle[MAXREFPINS]; double padcentrex, padcentrey; double centroidx, centroidy; double pin1x, pin1y; int pin_cnt; int found_any_not_at_centroid; int found_any; time_t currenttime; FILE *fp; BomList *bom = NULL; char *name, *descr, *value,*fixed_rotation; int rpindex; int i; char fmt[256]; sprintf(fmt, "%%s,\"%%s\",\"%%s\",%%.2`m%c,%%.2`m%c,%%g,%%s\n", xy_unit->printf_code, xy_unit->printf_code); fp = fopen (xy_filename, "wb"); if (!fp) { gui->log ("Cannot open file %s for writing\n", xy_filename); return 1; } fetch_attr_list (); /* Create a portable timestamp. */ currenttime = time (NULL); { /* avoid gcc complaints */ const char *fmt = "%c UTC"; strftime (utcTime, sizeof (utcTime), fmt, gmtime (¤ttime)); } fprintf (fp, "# PcbXY Version 1.0\n"); fprintf (fp, "# Date: %s\n", utcTime); fprintf (fp, "# Author: %s\n", pcb_author ()); fprintf (fp, "# Title: %s - PCB X-Y\n", UNKNOWN (PCB->Name)); fprintf (fp, "# RefDes, Description, Value, X, Y, rotation, top/bottom\n"); /* don't use localized xy_unit->in_suffix here since */ /* the line itself is not localized and not for GUI */ fprintf (fp, "# X,Y in %s. rotation in degrees.\n", xy_unit->suffix); fprintf (fp, "# --------------------------------------------\n"); /* * For each element we calculate the centroid of the footprint. * In addition, we need to extract some notion of rotation. * While here generate the BOM list */ ELEMENT_LOOP (PCB->Data); { /* Initialize our pin count and our totals for finding the centroid. */ pin_cnt = 0; sumx = 0.0; sumy = 0.0; for (rpindex = 0; rpindex < MAXREFPINS; rpindex++) pinfound[rpindex] = 0; /* Insert this component into the bill of materials list. */ bom = bom_insert ((char *)UNKNOWN (NAMEONPCB_NAME (element)), (char *)UNKNOWN (DESCRIPTION_NAME (element)), (char *)UNKNOWN (VALUE_NAME (element)), element, bom); /* * Iterate over the pins and pads keeping a running count of how * many pins/pads total and the sum of x and y coordinates * * While we're at it, store the location of pin/pad #1 and #2 if * we can find them. */ PIN_LOOP (element); { sumx += (double) pin->X; sumy += (double) pin->Y; pin_cnt++; for (rpindex = 0; reference_pin_names[rpindex]; rpindex++) { if (NSTRCMP (pin->Number, reference_pin_names[rpindex]) == 0) { pinx[rpindex] = (double) pin->X; piny[rpindex] = (double) pin->Y; pinangle[rpindex] = 0.0; /* pins have no notion of angle */ pinfound[rpindex] = 1; } } } END_LOOP; PAD_LOOP (element); { sumx += (pad->Point1.X + pad->Point2.X) / 2.0; sumy += (pad->Point1.Y + pad->Point2.Y) / 2.0; pin_cnt++; for (rpindex = 0; reference_pin_names[rpindex]; rpindex++) { if (NSTRCMP (pad->Number, reference_pin_names[rpindex]) == 0) { padcentrex = (double) (pad->Point1.X + pad->Point2.X) / 2.0; padcentrey = (double) (pad->Point1.Y + pad->Point2.Y) / 2.0; pinx[rpindex] = padcentrex; piny[rpindex] = padcentrey; /* * NOTE: We swap the Y points because in PCB, the Y-axis * is inverted. Increasing Y moves down. We want to deal * in the usual increasing Y moves up coordinates though. */ pinangle[rpindex] = (180.0 / M_PI) * atan2 (pad->Point1.Y - pad->Point2.Y, pad->Point2.X - pad->Point1.X); pinfound[rpindex]=1; } } } END_LOOP; if (pin_cnt > 0) { centroidx = sumx / (double) pin_cnt; centroidy = sumy / (double) pin_cnt; if (NSTRCMP( AttributeGetFromList (&element->Attributes,"xy-centre"), "origin") == 0 ) { x = element->MarkX; y = element->MarkY; } else { x = centroidx; y = centroidy; } fixed_rotation = AttributeGetFromList (&element->Attributes, "xy-fixed-rotation"); if (fixed_rotation) { /* The user specified a fixed rotation */ theta = atof (fixed_rotation); found_any_not_at_centroid = 1; found_any = 1; } else { /* Find first reference pin not at the centroid */ found_any_not_at_centroid = 0; found_any = 0; theta = 0.0; for (rpindex = 0; reference_pin_names[rpindex] && !found_any_not_at_centroid; rpindex++) { if (pinfound[rpindex]) { found_any = 1; /* Recenter pin "#1" onto the axis which cross at the part centroid */ pin1x = pinx[rpindex] - x; pin1y = piny[rpindex] - y; /* flip x, to reverse rotation for elements on back */ if (FRONT (element) != 1) pin1x = -pin1x; /* if only 1 pin, use pin 1's angle */ if (pin_cnt == 1) { theta = pinangle[rpindex]; found_any_not_at_centroid = 1; } else if ((pin1x != 0.0) || (pin1y != 0.0)) { theta = xyToAngle (pin1x, pin1y, pin_cnt > 2); found_any_not_at_centroid = 1; } } } if (!found_any) { Message ("PrintBOM(): unable to figure out angle because I could\n" " not find a suitable reference pin of element %s\n" " Setting to %g degrees\n", UNKNOWN (NAMEONPCB_NAME (element)), theta); } else if (!found_any_not_at_centroid) { Message ("PrintBOM(): unable to figure out angle of element\n" " %s because the reference pin(s) are at the centroid of the part.\n" " Setting to %g degrees\n", UNKNOWN (NAMEONPCB_NAME (element)), theta); } } name = CleanBOMString ((char *)UNKNOWN (NAMEONPCB_NAME (element))); descr = CleanBOMString ((char *)UNKNOWN (DESCRIPTION_NAME (element))); value = CleanBOMString ((char *)UNKNOWN (VALUE_NAME (element))); y = PCB->MaxHeight - y; //pcb_fprintf (fp, "%m+%s,\"%s\",\"%s\",%.2`mS,%.2`mS,%g,%s\n", pcb_fprintf (fp, fmt, name, descr, value, x, y, theta, FRONT (element) == 1 ? "top" : "bottom"); free (name); free (descr); free (value); } } END_LOOP; fclose (fp); /* Now print out a Bill of Materials file */ fp = fopen (bom_filename, "wb"); if (!fp) { gui->log ("Cannot open file %s for writing\n", bom_filename); print_and_free (NULL, bom); return 1; } fprintf (fp, "# PcbBOM Version 1.0\n"); fprintf (fp, "# Date: %s\n", utcTime); fprintf (fp, "# Author: %s\n", pcb_author ()); fprintf (fp, "# Title: %s - PCB BOM\n", UNKNOWN (PCB->Name)); fprintf (fp, "# Quantity, Description, Value, RefDes"); for (i=0; i struct s_xmlout { FILE* fd; int count; }; struct s_xmlout xmlout; char* indent[] = { "\n", "\n\t", "\n\t\t", "\n\t\t\t", "\n\t\t\t\t", "\n\t\t\t\t\t", "\n\t\t\t\t\t\t", "\n\t\t\t\t\t\t\t" }; #define XPUTS fputs #define XPRINTF fprintf #define XNEWLINE indent[xmlout.count] #define XOUT_DETENT() if(xmlout.count) xmlout.count-- #define XOUT_INDENT() xmlout.count++ #define XOUT_ELEMENT_2ATTR_START(name, id1, val1, id2, val2) XPRINTF(xmlout.fd, "<%s %s=\"%s\" %s=\"%s\">", name, id1, val1, id2, val2); #define XOUT_ELEMENT_ATTR_START(name, id, val) XPRINTF(xmlout.fd, "<%s %s=\"%s\">", name, id, val); #define XOUT_ELEMENT_START(name) XPRINTF(xmlout.fd, "<%s>", name); #define XOUT_ELEMENT_END(name) XPRINTF(xmlout.fd, "", name); #define XOUT_ELEMENT_EMPTY(name) XPRINTF(xmlout.fd, "<%s/>", name) #define XOUT_ELEMENT_ATTR_EMPTY(name, id, val) XPRINTF(xmlout.fd, "<%s %s=\"%s\"/>", name, id, val) #define XOUT_ELEMENT_DATA(data) XPRINTF(xmlout.fd, "%s", data) #define XOUT_NEWLINE() XPUTS( XNEWLINE, xmlout.fd) #define XOUT_ELEMENT(name, data) XOUT_ELEMENT_START(name);\ XOUT_ELEMENT_DATA(data);\ XOUT_ELEMENT_END(name); #define XOUT_ELEMENT_ATTR(name, id, val, data) XOUT_ELEMENT_ATTR_START(name, id, val);\ XOUT_ELEMENT_DATA(data);\ XOUT_ELEMENT_END(name); #define XOUT_HEADER() XPRINTF(xmlout.fd, ""); #define XOUT_INIT(filename) xmlout.count=0;\ xmlout.fd = fopen(filename, "w") #define XOUT_CLOSE() xmlout.count=0;\ fclose(xmlout.fd); \ xmlout.fd = NULL #endif pcb-4.3.0/src/hid/gsvit/hid.conf0000664000175000017500000000001413773431044013310 00000000000000type=export pcb-4.3.0/src/hid/gsvit/gsvit.c0000664000175000017500000013602013773431044013204 00000000000000/*! * \file src/hid/gsvit/gsvit.c * * \brief HID exporter for gsvit. * * This HID exports a PCB layout into: * - One layer mask file (PNG format) per copper layer. * - a gsvit configuration file that contains netlist and pin * information. * * \bug If you have a section of a net that does not contain any pins * then that section will be missing from the gsvit's copper geometry.\n * * \note Single layer layouts are always exported correctly. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994, 1995, 1996, 2004 Thomas Nau * * Based on the NELMA (Numerical capacitance calculator) export HID * Copyright (C) 2006 Tomaz Solc (tomaz.solc@tablix.org) * * PNG export code is based on the PNG export HID * Copyright (C) 2006 Dan McMahill * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Contact addresses for paper mail and Email: * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * Thomas.Nau@rz.uni-ulm.de * *
*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include "global.h" #include "error.h" /* Message() */ #include "data.h" #include "misc.h" #include "rats.h" #include "find.h" #include "flags.h" #include "hid.h" #include "hid_draw.h" #include "../hidint.h" #include "hid/common/hidnogui.h" #include "hid/common/draw_helpers.h" #include #include "xmlout.h" #include "hid/common/hidinit.h" #include "pcb-printf.h" #ifdef HAVE_LIBDMALLOC #include #endif #define CRASH fprintf(stderr, "HID error: pcb called unimplemented PNG function %s.\n", __FUNCTION__); abort() #define MAXREFPINS 32 /* max length of following list */ static char *reference_pin_names[] = {"1", "2", "A1", "A2", "B1", "B2", 0}; /* Needed for PNG export */ struct color_struct { /* the descriptor used by the gd library */ int c; /* so I can figure out what rgb value c refers to */ unsigned int r, g, b; }; struct hid_gc_struct { HID *me_pointer; EndCapStyle cap; Coord width; unsigned char r, g, b; int erase; struct color_struct *color; gdImagePtr brush; }; struct gsvit_net_layer { GList *Line; GList *Arc; GList *Polygon; }; struct gsvit_netlist { char* name; GList *Pin; GList *Via; GList *Pad; struct gsvit_net_layer layer[MAX_LAYER]; struct color_struct color; int colorIndex; }; /*! * \brief Structure to represent a single hole. */ struct drill_hole { int cx; int cy; int is_plated; }; /*! * \brief Structure to represent all holes of a given size. */ struct single_size_drills { double diameter_inches; Coord radius; int n_holes; int n_holes_allocated; struct drill_hole* holes; }; static struct single_size_drills* drills = NULL; typedef struct _StringList { char *str; struct _StringList *next; } StringList; typedef struct _BomList { char *descr; char *value; int num; StringList *refdes; struct _BomList *next; } BomList; static int n_drills = 0; /*!< At the start we have no drills at all */ static int n_drills_allocated = 0; static int save_drill = 0; static int is_plated = 0; struct gsvit_netlist* gsvit_netlist = NULL; int hashColor = gdBrushed; static struct color_struct* color_array[0x100]; static HID gsvit_hid; static HID_DRAW gsvit_graphics; static struct color_struct *black = NULL, *white = NULL; static Coord linewidth = -1; static gdImagePtr lastbrush = (gdImagePtr)((void *) -1); /*! * \brief gd image for PNG export. */ static gdImagePtr gsvit_im = NULL; /*! * \brief file for PNG export. */ static FILE *gsvit_f = NULL; static int is_mask; static int is_drill; /*! * \brief Which groups of layers to export into PNG layer masks. * * 1 means export; 0 means do not export. */ static int gsvit_export_group[MAX_GROUP]; /*! * \brief Group that is currently exported. */ static int gsvit_cur_group; /*! * \brief Filename prefix that will be used when saving files. */ static const char *gsvit_basename = NULL; /*! * \brief Horizontal DPI (grid points per inch). */ static int gsvit_dpi = -1; HID_Attribute gsvit_attribute_list[] = { /* other HIDs expect this to be first. */ /* %start-doc options "96 gsvit Options" @ftable @code @item -- basename File name prefix. @end ftable %end-doc */ {"basename", "File name prefix", HID_String, 0, 0, {0, 0, 0}, 0, 0}, #define HA_basename 0 /* %start-doc options "96 gsvit Options" @ftable @code @item --dpi Horizontal scale factor (grid points/inch). @end ftable %end-doc */ {"dpi", "Horizontal scale factor (grid points/inch)", HID_Integer, 0, 1000, {1000, 0, 0}, 0, 0}, /* 1000 --> 1 mil (25.4 um) resolution */ #define HA_dpi 1 }; #define NUM_OPTIONS (sizeof (gsvit_attribute_list) / sizeof (gsvit_attribute_list[0])) REGISTER_ATTRIBUTES(gsvit_attribute_list) static HID_Attr_Val gsvit_values[NUM_OPTIONS]; void gsvit_create_netlist (void); void gsvit_destroy_netlist (void); static void gsvit_xml_out (char* gsvit_basename); static void gsvit_build_net_from_selected (struct gsvit_netlist* currNet); static void gsvit_fill_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2); static void gsvit_write_xnets (void); /*! * \brief Convert HSL to RGB. * * From http://www.rapidtables.com/convert/color/hsl-to-rgb.htm * * Converts from (H)ue (S)aturation and (L)ightness to (R)ed, (G)reen * and (B)lue. * * h range 0 - 365 degrees * * s range 0 - 255 * * l range 0 - 255 * * \return rgb array of chars in range of 0-255 0-->R, 1-->G, 2-->B. * * \note Always returns a result, wraps 'h' if > 360 degrees. */ char * hslToRgb (int h, uint8_t s, uint8_t l) { static char rgb[3]; float H = fmod ((float)(h), 360.0); float S = s; float L = l; int sect; float C, X; float m; float Rp, Gp, Bp; L /= 255.0; S /= 255.0; sect = h / 60; C = (1.0 - fabs (2 * L - 1.0)) * S; X = C * (1.0 - fabs (fmod ((H / 60.0), 2.0) - 1.0)); m = L - C / 2.0; switch (sect) { case 0: Rp = C; Gp = X; Bp = 0.0; break; case 1: Rp = X; Gp = C; Bp = 0.0; break; case 2: Rp = 0.0; Gp = C; Bp = X; break; case 3: Rp = 0.0; Gp = X; Bp = C; break; case 4: Rp = X; Gp = 0.0; Bp = C; break; case 5: Rp = C; Gp = 0.0; Bp = X; break; default: Rp = 0.0; Gp = 0.0; Bp = 0.0; break; } rgb[0] = (Rp + m) * 0xFF; rgb[1] = (Gp + m) * 0xFF; rgb[2] = (Bp + m) * 0xFF; return (rgb); } void gsvit_build_net_from_selected (struct gsvit_netlist* currNet) { COPPERLINE_LOOP (PCB->Data); { if (TEST_FLAG (SELECTEDFLAG, line)) { currNet->layer[l].Line = g_list_prepend(currNet->layer[l].Line, line); } } ENDALL_LOOP; COPPERARC_LOOP (PCB->Data); { if (TEST_FLAG (SELECTEDFLAG, arc)) { currNet->layer[l].Arc = g_list_prepend (currNet->layer[l].Arc, arc); } } ENDALL_LOOP; COPPERPOLYGON_LOOP (PCB->Data); { if (TEST_FLAG (SELECTEDFLAG, polygon)) { currNet->layer[l].Polygon = g_list_prepend (currNet->layer[l].Polygon, polygon); } } ENDALL_LOOP; ALLPAD_LOOP (PCB->Data); { if (TEST_FLAG (SELECTEDFLAG, pad)) { currNet->Pad = g_list_prepend (currNet->Pad, pad); } } ENDALL_LOOP; ALLPIN_LOOP (PCB->Data); { if (TEST_FLAG (SELECTEDFLAG, pin)) { currNet->Pin = g_list_prepend (currNet->Pin, pin); } } ENDALL_LOOP; VIA_LOOP (PCB->Data); { if (TEST_FLAG (SELECTEDFLAG, via)) { currNet->Via = g_list_prepend(currNet->Via, via); } } END_LOOP; } void gsvit_create_netlist (void) { int i; int numNets = PCB->NetlistLib.MenuN; gsvit_netlist = (struct gsvit_netlist*) malloc (sizeof (struct gsvit_netlist) * numNets); memset (gsvit_netlist, 0, sizeof (struct gsvit_netlist) * numNets); for (i = 0; i < numNets; i++) { /* For each net in the netlist. */ int j; LibraryEntryType* entry; ConnectionType conn; struct gsvit_netlist* currNet = &gsvit_netlist[i]; currNet->name = PCB->NetlistLib.Menu[i].Name + 2; /*! \todo Add fancy color attachment here. */ InitConnectionLookup (); ClearFlagOnAllObjects (FOUNDFLAG | SELECTEDFLAG, false); for (j = PCB->NetlistLib.Menu[i].EntryN, entry = PCB->NetlistLib.Menu[i].Entry; j; j--, entry++) { /* For each component (pin/pad) in the net. */ if (SeekPad(entry, &conn, false)) { RatFindHook(conn.type, conn.ptr1, conn.ptr2, conn.ptr2, false, SELECTEDFLAG, false); } } /* The conn should now contain a list of all elements that are part * of the net. * Now build a database of all things selected as part of this net. */ gsvit_build_net_from_selected (currNet); ClearFlagOnAllObjects (FOUNDFLAG | SELECTEDFLAG, false); FreeConnectionLookupMemory (); } /* Assign colors to nets. */ for (i = 0; i < numNets; i++) { char *rgb = NULL; char name[0x100]; int j; int phase = (360 * i) / numNets; for (j = 0; gsvit_netlist[i].name[j]; j++) { name[j] = tolower (gsvit_netlist[i].name[j]); } name[j] = 0; /*! \todo Probably a '\0' character is better code. */ if (strstr (name, "gnd") || strstr (name, "ground")) { /* Make gnd nets darker. */ rgb = hslToRgb (phase, (70 * 256) / 100, (20 * 256) / 100); } else if (strstr (name, "unnamed")) {/* Make unnamed nets grayer. */ rgb = hslToRgb (phase, (15 * 256) / 100, (40 * 256) / 100); } else rgb = hslToRgb (phase, (70 * 256) / 100, (50 * 256) / 100); gsvit_netlist[i].color.r = rgb[0]; gsvit_netlist[i].color.g = rgb[1]; gsvit_netlist[i].color.b = rgb[2]; } } void gsvit_destroy_netlist (void) { int i; for (i = 0; i < PCB->NetlistLib.MenuN; i++) { /* For each net in the netlist. */ struct gsvit_netlist* currNet = &gsvit_netlist[i]; int j; for (j = 0; j < MAX_LAYER; j++) { g_list_free (currNet->layer[j].Line); g_list_free (currNet->layer[j].Arc); g_list_free (currNet->layer[j].Polygon); } g_list_free (currNet->Pad); g_list_free (currNet->Pin); g_list_free (currNet->Via); } free (gsvit_netlist); } /*! * \brief Convert from default PCB units to gsvit units. */ static int pcb_to_gsvit (Coord pcb) { return COORD_TO_INCH (pcb) * gsvit_dpi; } static char * gsvit_get_png_name (const char *basename, const char *suffix) { char *buf; int len; len = strlen (basename) + strlen(suffix) + 6; buf = (char *) malloc (sizeof (*buf) * len); sprintf (buf, "%s.%s.png", basename, suffix); return buf; } static void gsvit_write_xspace (void) { double xh; uint32_t h; uint32_t w; char buff[0x100]; int i, idx; const char *ext; char *src; xh = (1000.0* 2.54e-2) / ((double) gsvit_dpi); /* Units are in mm. */ h = (uint32_t) pcb_to_gsvit (PCB->MaxHeight); /* Units are in counts. */ w = (uint32_t) pcb_to_gsvit (PCB->MaxWidth); sprintf (buff, "%f", xh); XOUT_ELEMENT_START ("space"); XOUT_INDENT (); XOUT_NEWLINE (); XOUT_ELEMENT ("comment", "***** Space *****"); XOUT_NEWLINE (); XOUT_ELEMENT_ATTR ("resolution", "units", "mm", buff); XOUT_NEWLINE (); sprintf (buff, "%d", (int) w); XOUT_ELEMENT ("width", buff); XOUT_NEWLINE (); sprintf (buff, "%d", (int) h); XOUT_ELEMENT ("height", buff); XOUT_NEWLINE (); XOUT_ELEMENT_START ("layers"); XOUT_INDENT (); for (i = 0; i < MAX_GROUP; i++) if (gsvit_export_group[i]) { idx = (i >= 0 && i < max_group) ? PCB->LayerGroups.Entries[i][0] : i; ext = layer_type_to_file_name (idx, FNS_fixed); src = gsvit_get_png_name (gsvit_basename, ext); XOUT_NEWLINE (); XOUT_ELEMENT_ATTR ("layer", "name", ext, src); } XOUT_DETENT (); XOUT_NEWLINE (); XOUT_ELEMENT_END ("layers"); XOUT_DETENT (); XOUT_NEWLINE (); XOUT_ELEMENT_END ("space"); XOUT_DETENT (); } static void gsvit_write_xnets (void) { LibraryType netlist; LibraryMenuType *net; LibraryEntryType *pin; int n, m, i, idx; netlist = PCB->NetlistLib; XOUT_INDENT (); XOUT_NEWLINE (); XOUT_ELEMENT_START ("nets"); XOUT_INDENT (); XOUT_NEWLINE (); XOUT_ELEMENT ("comment", "***** Nets *****"); XOUT_NEWLINE (); for (n = 0; n < netlist.MenuN; n++) { char buff[0x100]; net = &netlist.Menu[n]; /* Weird, but correct */ XOUT_ELEMENT_ATTR_START ("net", "name", &net->Name[2]); // snprintf(buff, 0x100, "%d,%d,%d", net->color.r, net->color.g, net->color.b); // XOUT_ELEMENT_2ATTR_START("net", "name", &net->Name[2], "color", buff ); for (m = 0; m < net->EntryN; m++) { pin = &net->Entry[m]; /* pin_name_to_xy(pin, &x, &y); */ for (i = 0; i < MAX_GROUP; i++) if (gsvit_export_group[i]) { idx = (i >= 0 && i < max_group) ? PCB->LayerGroups.Entries[i][0] : i; layer_type_to_file_name (idx, FNS_fixed); if (m != 0 || i != 0) XOUT_ELEMENT_DATA (", "); snprintf (buff, 0x100, "%s", pin->ListEntry); { char* src = buff; while (*src) { if (*src == '-') *src = '.'; src++; } } XOUT_ELEMENT_DATA (buff); break; } } XOUT_ELEMENT_END ("net"); if (n+1 >= netlist.MenuN) XOUT_DETENT (); XOUT_NEWLINE (); } XOUT_ELEMENT_END ("nets"); XOUT_DETENT (); } static StringList * string_insert (char *str, StringList *list) { StringList *newlist, *cur; if ((newlist = (StringList *) malloc (sizeof (StringList))) == NULL) { fprintf (stderr, "malloc() failed in string_insert()\n"); exit (1); } newlist->next = NULL; newlist->str = strdup (str); if (list == NULL) return (newlist); cur = list; while (cur->next != NULL) cur = cur->next; cur->next = newlist; return (list); } static BomList * bom_insert (char *refdes, char *descr, char *value, BomList * bom) { BomList *newlist, *cur, *prev = NULL; if (bom == NULL) { /* this is the first element so automatically create an entry */ if ((newlist = (BomList *) malloc (sizeof (BomList))) == NULL) { fprintf (stderr, "malloc() failed in bom_insert()\n"); exit (1); } newlist->next = NULL; newlist->descr = strdup (descr); newlist->value = strdup (value); newlist->num = 1; newlist->refdes = string_insert (refdes, NULL); return (newlist); } /* search and see if we already have used one of these components */ cur = bom; while (cur != NULL) { if ((NSTRCMP (descr, cur->descr) == 0) && (NSTRCMP (value, cur->value) == 0)) { cur->num++; cur->refdes = string_insert (refdes, cur->refdes); break; } prev = cur; cur = cur->next; } if (cur == NULL) { if ((newlist = (BomList *) malloc (sizeof (BomList))) == NULL) { fprintf (stderr, "malloc() failed in bom_insert()\n"); exit (1); } prev->next = newlist; newlist->next = NULL; newlist->descr = strdup (descr); newlist->value = strdup (value); newlist->num = 1; newlist->refdes = string_insert (refdes, NULL); } return (bom); } static double xyToAngle (double x, double y, bool morethan2pins) { double d = atan2 (-y, x) * 180.0 / M_PI; /* IPC 7351 defines different rules for 2 pin elements */ if (morethan2pins) { /* Multi pin case: * Output 0 degrees if pin1 in is top left or top, i.e. between angles of * 80 to 170 degrees. * Pin #1 can be at dead top (e.g. certain PLCCs) or anywhere in the top * left. */ if (d < -100) return 90; /* -180 to -100 */ else if (d < -10) return 180; /* -100 to -10 */ else if (d < 80) return 270; /* -10 to 80 */ else if (d < 170) return 0; /* 80 to 170 */ else return 90; /* 170 to 180 */ } else { /* 2 pin element: * Output 0 degrees if pin #1 is in top left or left, i.e. in sector * between angles of 95 and 185 degrees. */ if (d < -175) return 0; /* -180 to -175 */ else if (d < -85) return 90; /* -175 to -85 */ else if (d < 5) return 180; /* -85 to 5 */ else if (d < 95) return 270; /* 5 to 95 */ else return 0; /* 95 to 180 */ } } /*! * \brief Main export callback. */ static void gsvit_parse_arguments (int *argc, char ***argv) { hid_register_attributes (gsvit_attribute_list, sizeof (gsvit_attribute_list) / sizeof (gsvit_attribute_list[0])); hid_parse_command_line(argc, argv); } static HID_Attribute * gsvit_get_export_options (int *n) { static char *last_made_filename = 0; if (PCB) { derive_default_filename (PCB->Filename, &gsvit_attribute_list[HA_basename], ".gsvit", &last_made_filename); } if (n) { *n = NUM_OPTIONS; } return gsvit_attribute_list; } static char* CleanXBOMString (char *in) { char *out; // int i; char* src; char* dest; if ((out = (char *)malloc ((strlen (in) + 1+0x40) * sizeof (char))) == NULL) { fprintf (stderr, "Error: CleanBOMString() malloc() failed\n"); exit (1); } dest = out; src = in; while(*src != '\0') { switch (*src) { case '<': *dest++ = '&'; *dest++ = 'l'; *dest++ = 't'; *dest = ';'; break; case '&': *dest++ = '&'; *dest++ = 'a'; *dest++ = 'm'; *dest++ = 'p'; *dest = ';'; break; default: *dest = *src; } src++; dest++; } return out; } static void gsvit_write_xdrills (void) { int i = 0; int j; char buff[0x100]; XOUT_NEWLINE (); XOUT_ELEMENT_START ("drills"); XOUT_INDENT (); XOUT_NEWLINE (); XOUT_ELEMENT ("comment", "***** Drills *****"); for (i = 0; i < n_drills; i++) { snprintf (buff, 0x100, "D%d", i); XOUT_NEWLINE (); XOUT_ELEMENT_ATTR_START ("drill", "id", buff); XOUT_INDENT (); snprintf (buff, 0x100, "%g", drills[i].diameter_inches); XOUT_NEWLINE (); XOUT_ELEMENT ("dia_inches", buff); snprintf (buff, 0x100, "%d", pcb_to_gsvit(drills[i].radius)); XOUT_NEWLINE (); XOUT_ELEMENT ("radius", buff); for (j = 0; j < drills[i].n_holes; j++) { snprintf (buff, 0x100, "%d,%d", drills[i].holes[j].cx, drills[i].holes[j].cy); XOUT_NEWLINE (); if (drills[i].holes[j].is_plated) { XOUT_ELEMENT_ATTR_START ("pos", "type", "plated"); } else { XOUT_ELEMENT_ATTR_START ("pos", "type", "unplated"); } XOUT_ELEMENT_DATA (buff); XOUT_ELEMENT_END ("pos"); } XOUT_DETENT (); XOUT_NEWLINE (); XOUT_ELEMENT_END ("drill"); } // if (drills[i].diameter_inches >= diameter_inches) // break; XOUT_DETENT (); XOUT_NEWLINE (); XOUT_ELEMENT_END ("drills"); XOUT_DETENT (); XOUT_NEWLINE (); } static void gsvit_write_xcentroids (void) { char buff[0x100]; Coord x, y; double theta = 0.0; double sumx, sumy; int pinfound[MAXREFPINS]; double pinx[MAXREFPINS]; double piny[MAXREFPINS]; double pinangle[MAXREFPINS]; double padcentrex, padcentrey; double centroidx, centroidy; double pin1x, pin1y; int pin_cnt; int found_any_not_at_centroid; int found_any; BomList *bom = NULL; char *name, *descr, *value,*fixed_rotation; int rpindex; XOUT_INDENT (); XOUT_NEWLINE (); XOUT_ELEMENT_START ("centroids"); XOUT_INDENT (); XOUT_NEWLINE (); XOUT_ELEMENT ("comment", "***** Centroids *****"); /* * For each element we calculate the centroid of the footprint. * In addition, we need to extract some notion of rotation. * While here generate the BOM list */ ELEMENT_LOOP (PCB->Data); { /* Initialize our pin count and our totals for finding the centroid. */ pin_cnt = 0; sumx = 0.0; sumy = 0.0; for (rpindex = 0; rpindex < MAXREFPINS; rpindex++) pinfound[rpindex] = 0; /* Insert this component into the bill of materials list. */ bom = bom_insert ((char *)UNKNOWN (NAMEONPCB_NAME (element)), (char *)UNKNOWN (DESCRIPTION_NAME (element)), (char *)UNKNOWN (VALUE_NAME (element)), bom); /* * Iterate over the pins and pads keeping a running count of how * many pins/pads total and the sum of x and y coordinates * * While we're at it, store the location of pin/pad #1 and #2 if * we can find them. */ PIN_LOOP (element); { sumx += (double) pin->X; sumy += (double) pin->Y; pin_cnt++; for (rpindex = 0; reference_pin_names[rpindex]; rpindex++) { if (NSTRCMP (pin->Number, reference_pin_names[rpindex]) == 0){ pinx[rpindex] = (double) pin->X; piny[rpindex] = (double) pin->Y; pinangle[rpindex] = 0.0; /* pins have no notion of angle */ pinfound[rpindex] = 1; } } } END_LOOP; PAD_LOOP (element); { sumx += (pad->Point1.X + pad->Point2.X) / 2.0; sumy += (pad->Point1.Y + pad->Point2.Y) / 2.0; pin_cnt++; for (rpindex = 0; reference_pin_names[rpindex]; rpindex++) { if (NSTRCMP (pad->Number, reference_pin_names[rpindex]) == 0) { padcentrex = (double) (pad->Point1.X + pad->Point2.X) / 2.0; padcentrey = (double) (pad->Point1.Y + pad->Point2.Y) / 2.0; pinx[rpindex] = padcentrex; piny[rpindex] = padcentrey; /* * NOTE: We swap the Y points because in PCB, the Y-axis * is inverted. Increasing Y moves down. We want to deal * in the usual increasing Y moves up coordinates though. */ pinangle[rpindex] = (180.0 / M_PI) * atan2 (pad->Point1.Y - pad->Point2.Y, pad->Point2.X - pad->Point1.X); pinfound[rpindex]=1; } } } END_LOOP; if (pin_cnt > 0) { centroidx = sumx / (double) pin_cnt; centroidy = sumy / (double) pin_cnt; if (NSTRCMP (AttributeGetFromList (&element->Attributes,"xy-centre"), "origin") == 0 ) { x = element->MarkX; y = element->MarkY; } else { x = centroidx; y = centroidy; } fixed_rotation = AttributeGetFromList (&element->Attributes, "xy-fixed-rotation"); if (fixed_rotation) { /* The user specified a fixed rotation */ theta = atof (fixed_rotation); found_any_not_at_centroid = 1; found_any = 1; } else { /* Find first reference pin not at the centroid */ found_any_not_at_centroid = 0; found_any = 0; theta = 0.0; for (rpindex = 0; reference_pin_names[rpindex] && !found_any_not_at_centroid; rpindex++) { if (pinfound[rpindex]) { found_any = 1; /* Recenter pin "#1" onto the axis which cross at the part * centroid. */ pin1x = pinx[rpindex] - x; pin1y = piny[rpindex] - y; /* flip x, to reverse rotation for elements on back. */ if (FRONT (element) != 1) pin1x = -pin1x; /* if only 1 pin, use pin 1's angle */ if (pin_cnt == 1) { theta = pinangle[rpindex]; found_any_not_at_centroid = 1; } else if ((pin1x != 0.0) || (pin1y != 0.0)) { theta = xyToAngle (pin1x, pin1y, pin_cnt > 2); found_any_not_at_centroid = 1; } } } if (!found_any) { Message ("PrintBOM(): unable to figure out angle because I could\n" " not find a suitable reference pin of element %s\n" " Setting to %g degrees\n", UNKNOWN (NAMEONPCB_NAME (element)), theta); } else if (!found_any_not_at_centroid) { Message ("PrintBOM(): unable to figure out angle of element\n" " %s because the reference pin(s) are at the centroid of the part.\n" " Setting to %g degrees\n", UNKNOWN (NAMEONPCB_NAME (element)), theta); } } name = CleanXBOMString ((char *)UNKNOWN (NAMEONPCB_NAME (element))); descr = CleanXBOMString ((char *)UNKNOWN (DESCRIPTION_NAME (element))); value = CleanXBOMString ((char *)UNKNOWN (VALUE_NAME (element))); y = PCB->MaxHeight - y; XOUT_NEWLINE (); XOUT_ELEMENT_ATTR_START ("xy", "name", name); XOUT_INDENT (); XOUT_NEWLINE (); XOUT_ELEMENT ("description", descr); XOUT_NEWLINE (); XOUT_ELEMENT ("value", value); XOUT_NEWLINE (); snprintf (buff, 0x100, "%d,%d", pcb_to_gsvit(x), pcb_to_gsvit(y)); XOUT_ELEMENT ("pos", buff); XOUT_NEWLINE (); pcb_snprintf (buff, 0x100, "%g", theta); XOUT_ELEMENT ("rotation", buff); XOUT_NEWLINE (); XOUT_ELEMENT ("side", FRONT (element) == 1 ? "top" : "bottom"); XOUT_DETENT (); XOUT_NEWLINE (); XOUT_ELEMENT_END ("xy"); free (name); free (descr); free (value); } } END_LOOP; XOUT_DETENT (); XOUT_NEWLINE (); XOUT_ELEMENT_END ("centroids"); } /*! * \brief Populates gsvit_export_group array. */ void gsvit_choose_groups () { int n, m; LayerType *layer; /* Set entire array to 0 (don't export any layer groups by default */ memset (gsvit_export_group, 0, sizeof (gsvit_export_group)); for (n = 0; n < max_copper_layer; n++) { layer = &PCB->Data->Layer[n]; if (layer->LineN || layer->TextN || layer->ArcN || layer->PolygonN) { /* Layer isn't empty. */ /*! \todo Is this check necessary? It seems that special layers * have negative indexes? */ if (SL_TYPE(n) == 0) { /* Layer is a copper layer. */ m = GetLayerGroupNumberByNumber (n); /* The export layer. */ gsvit_export_group[m] = 1; } } } } /*! * \brief Allocate colors. * * White and black, the first color allocated becomes the background * color. */ static void gsvit_alloc_colors () { int i; int numNets = PCB->NetlistLib.MenuN; char *rgb; white = (struct color_struct *) malloc (sizeof (*white)); white->r = white->g = white->b = 255; white->c = gdImageColorAllocate (gsvit_im, white->r, white->g, white->b); black = (struct color_struct *) malloc (sizeof (*black)); black->r = black->g = black->b = 0; black->c = gdImageColorAllocate (gsvit_im, black->r, black->g, black->b); for (i = 0; i < numNets; i++) { gsvit_netlist[i].colorIndex = i; color_array[i] = malloc (sizeof (*white)); color_array[i]->r = gsvit_netlist[i].color.r; color_array[i]->g = gsvit_netlist[i].color.g; color_array[i]->b = gsvit_netlist[i].color.b; color_array[i]->c = gdImageColorAllocate (gsvit_im, color_array[i]->r, color_array[i]->g, color_array[i]->b); } color_array[i] = malloc (sizeof (*white)); rgb = hslToRgb (128, (20 * 256) / 100, (20 * 256) / 100); color_array[i]->r = rgb[0]; color_array[i]->g = rgb[1]; color_array[i]->b = rgb[2]; color_array[i]->c = gdImageColorAllocate (gsvit_im, color_array[i]->r, color_array[i]->g, color_array[i]->b); printf ("%d colors allocated\n", numNets); } static void gsvit_start_png (const char *basename, const char *suffix) { int h, w; char *buf; buf = gsvit_get_png_name (basename, suffix); h = pcb_to_gsvit (PCB->MaxHeight); w = pcb_to_gsvit (PCB->MaxWidth); /* gsvit only works with true color images. */ gsvit_im = gdImageCreate (w, h); gsvit_f = fopen (buf, "wb"); gsvit_alloc_colors (); free (buf); } static void gsvit_finish_png () { int i; #ifdef HAVE_GDIMAGEPNG gdImagePng (gsvit_im, gsvit_f); #else Message ("gsvit: PNG not supported by gd. Can't write layer mask.\n"); #endif gdImageDestroy (gsvit_im); fclose (gsvit_f); for (i = 0; i < 0x100; i++) { free (color_array[i]); } gsvit_im = NULL; gsvit_f = NULL; } void gsvit_start_png_export () { BoxType region; region.X1 = 0; region.Y1 = 0; region.X2 = PCB->MaxWidth; region.Y2 = PCB->MaxHeight; linewidth = -1; lastbrush = (gdImagePtr)((void *) -1); hid_expose_callback (&gsvit_hid, ®ion, 0); } static void gsvit_do_export (HID_Attr_Val *options) { int save_ons[MAX_ALL_LAYER]; int i, idx; char *buf; int len; if (!options) { gsvit_get_export_options(0); for (i = 0; i < NUM_OPTIONS; i++) { gsvit_values[i] = gsvit_attribute_list[i].default_val; } options = gsvit_values; } gsvit_basename = options[HA_basename].str_value; if (!gsvit_basename) { gsvit_basename = "pcb-out"; } gsvit_dpi = options[HA_dpi].int_value; if (gsvit_dpi < 0) { fprintf (stderr, "ERROR: dpi may not be < 0\n"); return; } gsvit_create_netlist (); gsvit_choose_groups (); for (i = 0; i < MAX_GROUP; i++) { if (gsvit_export_group[i]) { gsvit_cur_group = i; /* Magic. */ idx = (i >= 0 && i < max_group) ? PCB->LayerGroups.Entries[i][0] : i; save_drill = (GetLayerGroupNumberByNumber (idx) == GetLayerGroupNumberBySide (BOTTOM_SIDE)) ? 1 : 0; /* save drills for one layer only */ gsvit_start_png (gsvit_basename, layer_type_to_file_name (idx, FNS_fixed)); hid_save_and_show_layer_ons (save_ons); gsvit_start_png_export (); hid_restore_layer_ons (save_ons); gsvit_finish_png (); } } len = strlen (gsvit_basename) + 4; buf = (char *) malloc (sizeof (*buf) * len); gsvit_xml_out ((char*) gsvit_basename); gsvit_destroy_netlist (); } void gsvit_xml_out (char *gsvit_basename) { char *buf; int len; time_t t; len = strlen (gsvit_basename) + 4; buf = (char *) malloc (sizeof (*buf) * len); sprintf (buf, "%s.xem", gsvit_basename); XOUT_INIT (buf); free (buf); XOUT_HEADER (); XOUT_NEWLINE (); XOUT_ELEMENT_START ("gsvit"); XOUT_INDENT (); XOUT_NEWLINE (); XOUT_ELEMENT ("comment", "Made with PCB gsvit export HID"); XOUT_NEWLINE (); { char buff[0x100 + 1]; char* src = buff; t = time (NULL); strncpy (buff, ctime(&t), 0x100); while (*src) { if ((*src =='\r') || (*src =='\n')) { *src = 0; break; } src++; } XOUT_ELEMENT ("genTime", buff); XOUT_NEWLINE (); } gsvit_write_xspace (); gsvit_write_xnets (); gsvit_write_xcentroids(); gsvit_write_xdrills(); XOUT_ELEMENT_END ("gsvit"); XOUT_NEWLINE (); XOUT_CLOSE (); } /* *** PNG export (slightly modified code from PNG export HID) ************* */ static int gsvit_set_layer (const char *name, int group, int empty) { int idx = (group >= 0 && group < max_group) ? PCB->LayerGroups.Entries[group][0] : group; if (name == 0) { name = PCB->Data->Layer[idx].Name; } if (strcmp(name, "invisible") == 0) { return 0; } is_drill = (SL_TYPE (idx) == SL_PDRILL || SL_TYPE (idx) == SL_UDRILL); is_mask = (SL_TYPE (idx) == SL_MASK); if (is_mask) { /* Don't print masks. */ return 0; } if (is_drill) { if (SL_TYPE(idx) == SL_PDRILL) is_plated =1; else if (SL_TYPE(idx) == SL_UDRILL) is_plated =0; /* Print 'holes', so that we can fill gaps in the copper layer. */ return 1; } if (group == gsvit_cur_group) { return 1; } return 0; } static hidGC gsvit_make_gc (void) { hidGC rv = (hidGC) malloc (sizeof (struct hid_gc_struct)); rv->me_pointer = &gsvit_hid; rv->cap = Trace_Cap; rv->width = 1; rv->color = (struct color_struct *) malloc (sizeof (*rv->color)); rv->color->r = rv->color->g = rv->color->b = 0; rv->color->c = 0; return rv; } static void gsvit_destroy_gc (hidGC gc) { free (gc); } static void gsvit_use_mask (enum mask_mode mode) { /* Do nothing. */ } static void gsvit_set_color (hidGC gc, const char *name) { if (gsvit_im == NULL) { return; } if (name == NULL) { name = "#ff0000"; } if (!strcmp(name, "drill")) { gc->color = black; gc->erase = 0; return; } if (!strcmp(name, "erase")) { /*! \todo Should be background, not white. */ gc->color = white; gc->erase = 1; return; } gc->color = black; gc->erase = 0; return; } static void gsvit_set_line_cap (hidGC gc, EndCapStyle style) { gc->cap = style; } static void gsvit_set_line_width (hidGC gc, Coord width) { gc->width = width; } static void gsvit_set_draw_xor (hidGC gc, int xor_) { /* Do nothing. */ } static void gsvit_set_draw_faded (hidGC gc, int faded) { /* Do nothing. */ } static void use_gc (hidGC gc) { int need_brush = 0; if (gc->me_pointer != &gsvit_hid) { fprintf (stderr, "Fatal: GC from another HID passed to gsvit HID\n"); abort (); } if (hashColor != gdBrushed) { need_brush = 1; } if (linewidth != gc->width) { /* Make sure the scaling doesn't erase lines completely */ /* if (SCALE (gc->width) == 0 && gc->width > 0) gdImageSetThickness (im, 1); else */ gdImageSetThickness (gsvit_im, pcb_to_gsvit (gc->width)); linewidth = gc->width; need_brush = 1; } if (lastbrush != gc->brush || need_brush) { static void *bcache = 0; hidval bval; char name[256]; char type; int r; switch (gc->cap) { case Round_Cap: case Trace_Cap: type = 'C'; r = pcb_to_gsvit (gc->width / 2); break; default: case Square_Cap: r = pcb_to_gsvit(gc->width); type = 'S'; break; } sprintf (name, "#%.2x%.2x%.2x_%c_%d", gc->color->r, gc->color->g, gc->color->b, type, r); /* if (hid_cache_color(0, name, &bval, &bcache)) { gc->brush = (gdImagePtr) bval.ptr; } else { */ { int bg, fg; if (type == 'C') gc->brush = gdImageCreate (2 * r + 1, 2 * r + 1); else gc->brush = gdImageCreate (r + 1, r + 1); bg = gdImageColorAllocate (gc->brush, 255, 255, 255); if (hashColor != gdBrushed) { /* printf ("hash:%d\n",hashColor); */ fg = gdImageColorAllocate (gc->brush, color_array[hashColor]->r,color_array[hashColor]->g,color_array[hashColor]->b); } else { fg = gdImageColorAllocate (gc->brush, gc->color->r, gc->color->g, gc->color->b); } gdImageColorTransparent (gc->brush, bg); /* If we shrunk to a radius/box width of zero, then just use a * single pixel to draw with. */ if (r == 0) { gdImageFilledRectangle (gc->brush, 0, 0, 0, 0, fg); } else { if (type == 'C') gdImageFilledEllipse (gc->brush, r, r, 2 * r, 2 * r, fg); else gdImageFilledRectangle (gc->brush, 0, 0, r, r, fg); } bval.ptr = gc->brush; hid_cache_color (1, name, &bval, &bcache); } gdImageSetBrush (gsvit_im, gc->brush); lastbrush = gc->brush; } } static void gsvit_draw_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2) { use_gc (gc); gdImageRectangle (gsvit_im, pcb_to_gsvit (x1), pcb_to_gsvit (y1), pcb_to_gsvit (x2), pcb_to_gsvit (y2), gc->color->c); } static void gsvit_fill_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2) { use_gc (gc); gdImageSetThickness (gsvit_im, 0); linewidth = 0; gdImageFilledRectangle (gsvit_im, pcb_to_gsvit (x1), pcb_to_gsvit (y1), pcb_to_gsvit (x2), pcb_to_gsvit (y2), gc->color->c); } struct gsvit_netlist * gsvit_lookup_net_from_arc (ArcType *targetArc) { int i; for (i = 0; i < PCB->NetlistLib.MenuN; i++) { /* For each net in the netlist. */ struct gsvit_netlist *currNet = &gsvit_netlist[i]; int j; for (j = 0; j < PCB->LayerGroups.Number[gsvit_cur_group]; j++) { /* For each layer of the current group. */ int layer = PCB->LayerGroups.Entries[gsvit_cur_group][j]; ARC_LOOP (&(currNet->layer[layer])); { if (targetArc == arc) return (currNet); } END_LOOP; } } return (NULL); } struct gsvit_netlist * gsvit_lookup_net_from_line (LineType *targetLine) { int i; for (i = 0; i < PCB->NetlistLib.MenuN; i++) { /* For each net in the netlist. */ struct gsvit_netlist* currNet = &gsvit_netlist[i]; int j; for (j = 0; j < PCB->LayerGroups.Number[gsvit_cur_group]; j++) { /* For each layer of the current group. */ int layer = PCB->LayerGroups.Entries[gsvit_cur_group][j]; LINE_LOOP (&(currNet->layer[layer])); { if (targetLine == line) return (currNet); } END_LOOP; } } return (NULL); } struct gsvit_netlist * gsvit_lookup_net_from_polygon (PolygonType *targetPolygon) { int i; for (i = 0; i < PCB->NetlistLib.MenuN; i++) { /* For each net in the netlist. */ struct gsvit_netlist* currNet = &gsvit_netlist[i]; int j; for (j = 0; j < PCB->LayerGroups.Number[gsvit_cur_group]; j++) { /* For each layer of the current group. */ int layer = PCB->LayerGroups.Entries[gsvit_cur_group][j]; POLYGON_LOOP (&(currNet->layer[layer])); { if (targetPolygon == polygon) return (currNet); } END_LOOP; } } return (NULL); } struct gsvit_netlist * gsvit_lookup_net_from_pad (PadType *targetPad) { int i; for (i = 0; i < PCB->NetlistLib.MenuN; i++) { /* For each net in the netlist. */ struct gsvit_netlist* currNet = &gsvit_netlist[i]; PAD_LOOP (currNet); { if (targetPad == pad) return (currNet); } END_LOOP; } return (NULL); } struct gsvit_netlist * gsvit_lookup_net_from_pv (PinType *targetPv) { int i; for (i = 0; i < PCB->NetlistLib.MenuN; i++) { /* For each net in the netlist. */ struct gsvit_netlist* currNet = &gsvit_netlist[i]; PIN_LOOP (currNet); { if (targetPv == pin) return (currNet); } END_LOOP; VIA_LOOP (currNet); { if (targetPv == via) return (currNet); } END_LOOP; } return (NULL); } static void add_hole (struct single_size_drills* drill, int cx, int cy) { if (drill->n_holes == drill->n_holes_allocated) { drill->n_holes_allocated += 100; drill->holes = (struct drill_hole *) realloc (drill->holes,drill->n_holes_allocated *sizeof (struct drill_hole)); } drill->holes[drill->n_holes].cx = cx; drill->holes[drill->n_holes].cy = cy; drill->holes[drill->n_holes].is_plated = is_plated; drill->n_holes++; printf ("holes %d\n", drill->n_holes); } /*! * \brief Given a hole size, return the structure that currently holds * the data for that hole size. * * If there isn't one, make it. */ static int _drill_size_comparator (const void* _size0, const void* _size1) { double size0 = ((const struct single_size_drills*)_size0)->diameter_inches; double size1 = ((const struct single_size_drills*)_size1)->diameter_inches; if (size0 == size1) return 0; if (size0 < size1) return -1; return 1; } static struct single_size_drills * get_drill (double diameter_inches, Coord radius) { /* See if we already have this size. If so, return that structure. */ struct single_size_drills* drill = bsearch (&diameter_inches, drills, n_drills, sizeof (drills[0]), _drill_size_comparator); if (drill != NULL) return( drill); /* Haven't seen this hole size before, so make a new structure for it. */ if (n_drills == n_drills_allocated) { n_drills_allocated += 100; drills = (struct single_size_drills *) realloc (drills, n_drills_allocated * sizeof (struct single_size_drills)); } /* I now add the structure to the list, making sure to keep the list * sorted. Ideally the bsearch() call above would have given me the location * to insert this element while keeping things sorted, but it doesn't. For * simplicity I manually lsearch() to find this location myself */ { int i = 0; for (i = 0; i= diameter_inches) break; if (n_drills != i) memmove (&drills[i+1], &drills[i], (n_drills-i) * sizeof (struct single_size_drills)); drills[i].diameter_inches = diameter_inches; drills[i].radius = radius; drills[i].n_holes = 0; drills[i].n_holes_allocated = 0; drills[i].holes = NULL; n_drills++; return &drills[i]; } } static void gsvit_draw_line (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2) { if (x1 == x2 && y1 == y2) { Coord w = gc->width / 2; gsvit_fill_rect (gc, x1 - w, y1 - w, x1 + w, y1 + w); return; } linewidth = -1; use_gc (gc); linewidth = -1; gdImageSetThickness (gsvit_im, 0); linewidth = 0; gdImageLine (gsvit_im, pcb_to_gsvit (x1), pcb_to_gsvit (y1), pcb_to_gsvit (x2), pcb_to_gsvit (y2), gdBrushed); } static void gsvit_draw_arc (hidGC gc, Coord cx, Coord cy, Coord width, Coord height, Angle start_angle, Angle delta_angle) { Angle sa, ea; /* In gdImageArc, 0 degrees is to the right and +90 degrees is down. * in pcb, 0 degrees is to the left and +90 degrees is down. */ start_angle = 180 - start_angle; delta_angle = -delta_angle; if (delta_angle > 0) { sa = start_angle; ea = start_angle + delta_angle; } else { sa = start_angle + delta_angle; ea = start_angle; } /* Make sure we start between 0 and 360 otherwise gd does strange * things. */ sa = NormalizeAngle (sa); ea = NormalizeAngle (ea); #if 0 printf("draw_arc %d,%d %dx%d %d..%d %d..%d\n", cx, cy, width, height, start_angle, delta_angle, sa, ea); printf("gdImageArc (%p, %d, %d, %d, %d, %d, %d, %d)\n", im, SCALE_X (cx), SCALE_Y (cy), SCALE (width), SCALE (height), sa, ea, gc->color->c); #endif use_gc (gc); gdImageSetThickness (gsvit_im, 0); linewidth = 0; gdImageArc (gsvit_im, pcb_to_gsvit (cx), pcb_to_gsvit (cy), pcb_to_gsvit (2 * width), pcb_to_gsvit (2 * height), sa, ea, gdBrushed); } static void gsvit_fill_circle (hidGC gc, Coord cx, Coord cy, Coord radius) { use_gc (gc); gdImageSetThickness (gsvit_im, 0); linewidth = 0; gdImageFilledEllipse (gsvit_im, pcb_to_gsvit (cx), pcb_to_gsvit (cy), pcb_to_gsvit (2 * radius), pcb_to_gsvit (2 * radius), color_array[hashColor]->c); if (save_drill && is_drill) { double diameter_inches = COORD_TO_INCH(radius*2); struct single_size_drills* drill = get_drill (diameter_inches, radius); add_hole(drill, pcb_to_gsvit(cx), pcb_to_gsvit(cy)); /* convert to inch, flip: will drill from bottom side */ // COORD_TO_INCH(PCB->MaxWidth - cx), /* PCB reverses y axis */ // COORD_TO_INCH(PCB->MaxHeight - cy)); } } static void gsvit_fill_polygon (hidGC gc, int n_coords, Coord *x, Coord *y) { int i; gdPoint *points; points = (gdPoint *) malloc (n_coords * sizeof (gdPoint)); if (points == NULL) { fprintf (stderr, "ERROR: gsvit_fill_polygon(): malloc failed\n"); exit (1); } use_gc (gc); for (i = 0; i < n_coords; i++) { points[i].x = pcb_to_gsvit (x[i]); points[i].y = pcb_to_gsvit (y[i]); } gdImageSetThickness (gsvit_im, 0); linewidth = 0; gdImageFilledPolygon (gsvit_im, points, n_coords, color_array[hashColor]->c); free (points); } static void gsvit_calibrate (double xval, double yval) { CRASH; } static void gsvit_set_crosshair (int x, int y, int a) { /* Do nothing. */ } static void gsvit_draw_pcb_arc (hidGC gc, ArcType *arc) { struct gsvit_netlist *net; net = gsvit_lookup_net_from_arc (arc); if (net) { hashColor = net->colorIndex; } else { hashColor = PCB->NetlistLib.MenuN; } common_draw_pcb_arc (gc, arc); hashColor = PCB->NetlistLib.MenuN; } static void gsvit_draw_pcb_line (hidGC gc, LineType *line) { struct gsvit_netlist *net; net = gsvit_lookup_net_from_line (line); if (net) { hashColor = net->colorIndex; } else { hashColor = PCB->NetlistLib.MenuN; } common_draw_pcb_line (gc, line); hashColor = PCB->NetlistLib.MenuN; } void gsvit_fill_pcb_polygon (hidGC gc, PolygonType *poly, const BoxType *clip_box) { /* Hijack the fill_pcb_polygon function to get *poly, then proceed * with the default handler. */ struct gsvit_netlist *net; net = gsvit_lookup_net_from_polygon (poly); if (net) { hashColor = net->colorIndex; } else { hashColor = PCB->NetlistLib.MenuN; } common_fill_pcb_polygon (gc, poly, clip_box); hashColor = PCB->NetlistLib.MenuN; } void gsvit_fill_pcb_pad (hidGC gc, PadType *pad, bool clear, bool mask) { struct gsvit_netlist *net = NULL; net = gsvit_lookup_net_from_pad(pad); if (net) { hashColor = net->colorIndex; } else { hashColor = PCB->NetlistLib.MenuN; } common_fill_pcb_pad (gc, pad, clear, mask); hashColor = PCB->NetlistLib.MenuN; } void gsvit_fill_pcb_pv (hidGC fg_gc, hidGC bg_gc, PinType *pv, bool drawHole, bool mask) { struct gsvit_netlist *net = NULL; net = gsvit_lookup_net_from_pv (pv); if (net) { hashColor = net->colorIndex; } else { hashColor = PCB->NetlistLib.MenuN; } common_fill_pcb_pv (fg_gc, bg_gc, pv, drawHole, mask); hashColor = PCB->NetlistLib.MenuN; } #include "dolists.h" void hid_gsvit_init () { memset (&gsvit_hid, 0, sizeof (HID)); memset (&gsvit_graphics, 0, sizeof (HID_DRAW)); common_nogui_init (&gsvit_hid); common_draw_helpers_init (&gsvit_graphics); //hid_gtk_init(); gsvit_hid.struct_size = sizeof (HID); gsvit_hid.name = "gsvit"; gsvit_hid.description = "Numerical analysis package export"; gsvit_hid.exporter = 1; gsvit_hid.poly_before = 1; gsvit_hid.get_export_options = gsvit_get_export_options; gsvit_hid.do_export = gsvit_do_export; gsvit_hid.parse_arguments = gsvit_parse_arguments; gsvit_hid.set_layer = gsvit_set_layer; gsvit_hid.calibrate = gsvit_calibrate; gsvit_hid.set_crosshair = gsvit_set_crosshair; gsvit_hid.graphics = &gsvit_graphics; gsvit_graphics.make_gc = gsvit_make_gc; gsvit_graphics.destroy_gc = gsvit_destroy_gc; gsvit_graphics.use_mask = gsvit_use_mask; gsvit_graphics.set_color = gsvit_set_color; gsvit_graphics.set_line_cap = gsvit_set_line_cap; gsvit_graphics.set_line_width = gsvit_set_line_width; gsvit_graphics.set_draw_xor = gsvit_set_draw_xor; gsvit_graphics.set_draw_faded = gsvit_set_draw_faded; gsvit_graphics.draw_line = gsvit_draw_line; gsvit_graphics.draw_arc = gsvit_draw_arc; gsvit_graphics.draw_rect = gsvit_draw_rect; gsvit_graphics.fill_circle = gsvit_fill_circle; gsvit_graphics.fill_polygon = gsvit_fill_polygon; gsvit_graphics.fill_rect = gsvit_fill_rect; /* Hijack these functions because what is passed to fill_polygon is a * series of polygons (for holes,...). */ gsvit_graphics.draw_pcb_line = gsvit_draw_pcb_line; gsvit_graphics.draw_pcb_arc = gsvit_draw_pcb_arc; gsvit_graphics.draw_pcb_polygon = gsvit_fill_pcb_polygon; gsvit_graphics.fill_pcb_polygon = gsvit_fill_pcb_polygon; gsvit_graphics.fill_pcb_pad = gsvit_fill_pcb_pad; gsvit_graphics.fill_pcb_pv = gsvit_fill_pcb_pv; hid_register_hid (&gsvit_hid); #include "gsvit_lists.h" } pcb-4.3.0/src/hid/common/0000775000175000017500000000000014017001275012105 500000000000000pcb-4.3.0/src/hid/common/draw_helpers.c0000664000175000017500000004657113773431044014676 00000000000000#include "global.h" #include "hid.h" #include "hid_draw.h" #include "data.h" /* For global "PCB" variable */ #include "rotate.h" /* For RotateLineLowLevel() */ #include "polygon.h" #include "draw_helpers.h" void common_draw_pcb_line (hidGC gc, LineType *line) { gui->graphics->set_line_cap (gc, Trace_Cap); if (TEST_FLAG (THINDRAWFLAG, PCB)) gui->graphics->set_line_width (gc, 0); else gui->graphics->set_line_width (gc, line->Thickness); gui->graphics->draw_line (gc, line->Point1.X, line->Point1.Y, line->Point2.X, line->Point2.Y); } void common_draw_pcb_arc (hidGC gc, ArcType *arc) { if (!arc->Thickness) return; if (TEST_FLAG (THINDRAWFLAG, PCB)) gui->graphics->set_line_width (gc, 0); else gui->graphics->set_line_width (gc, arc->Thickness); gui->graphics->set_line_cap (gc, Trace_Cap); gui->graphics->draw_arc (gc, arc->X, arc->Y, arc->Width, arc->Height, arc->StartAngle, arc->Delta); } /* --------------------------------------------------------------------------- * drawing routine for text objects */ static void common_draw_pcb_text (hidGC gc, TextType *Text, Coord min_line_width) { Coord x = 0; unsigned char *string = (unsigned char *) Text->TextString; Cardinal n; FontType *font = &PCB->Font; while (string && *string) { /* draw lines if symbol is valid and data is present */ if (*string <= MAX_FONTPOSITION && font->Symbol[*string].Valid) { LineType *line = font->Symbol[*string].Line; LineType newline; for (n = font->Symbol[*string].LineN; n; n--, line++) { /* create one line, scale, move, rotate and swap it */ newline = *line; newline.Point1.X = SCALE_TEXT (newline.Point1.X + x, Text->Scale); newline.Point1.Y = SCALE_TEXT (newline.Point1.Y, Text->Scale); newline.Point2.X = SCALE_TEXT (newline.Point2.X + x, Text->Scale); newline.Point2.Y = SCALE_TEXT (newline.Point2.Y, Text->Scale); newline.Thickness = SCALE_TEXT (newline.Thickness, Text->Scale / 2); if (newline.Thickness < min_line_width) newline.Thickness = min_line_width; RotateLineLowLevel (&newline, 0, 0, Text->Direction); /* the labels of SMD objects on the bottom * side haven't been swapped yet, only their offset */ if (TEST_FLAG (ONSOLDERFLAG, Text)) { newline.Point1.X = SWAP_SIGN_X (newline.Point1.X); newline.Point1.Y = SWAP_SIGN_Y (newline.Point1.Y); newline.Point2.X = SWAP_SIGN_X (newline.Point2.X); newline.Point2.Y = SWAP_SIGN_Y (newline.Point2.Y); } /* add offset and draw line */ newline.Point1.X += Text->X; newline.Point1.Y += Text->Y; newline.Point2.X += Text->X; newline.Point2.Y += Text->Y; gui->graphics->draw_pcb_line (gc, &newline); } /* move on to next cursor position */ x += (font->Symbol[*string].Width + font->Symbol[*string].Delta); } else { /* the default symbol is a filled box */ BoxType defaultsymbol = PCB->Font.DefaultSymbol; Coord size = (defaultsymbol.X2 - defaultsymbol.X1) * 6 / 5; defaultsymbol.X1 = SCALE_TEXT (defaultsymbol.X1 + x, Text->Scale); defaultsymbol.Y1 = SCALE_TEXT (defaultsymbol.Y1, Text->Scale); defaultsymbol.X2 = SCALE_TEXT (defaultsymbol.X2 + x, Text->Scale); defaultsymbol.Y2 = SCALE_TEXT (defaultsymbol.Y2, Text->Scale); RotateBoxLowLevel (&defaultsymbol, 0, 0, Text->Direction); /* add offset and draw box */ defaultsymbol.X1 += Text->X; defaultsymbol.Y1 += Text->Y; defaultsymbol.X2 += Text->X; defaultsymbol.Y2 += Text->Y; gui->graphics->fill_rect (gc, defaultsymbol.X1, defaultsymbol.Y1, defaultsymbol.X2, defaultsymbol.Y2); /* move on to next cursor position */ x += size; } string++; } } static void fill_contour (hidGC gc, PLINE *pl) { Coord *x, *y, n, i = 0; VNODE *v; n = pl->Count; x = (Coord *)malloc (n * sizeof (*x)); y = (Coord *)malloc (n * sizeof (*y)); for (v = &pl->head; i < n; v = v->next) { x[i] = v->point[0]; y[i++] = v->point[1]; } gui->graphics->fill_polygon (gc, n, x, y); free (x); free (y); } static void thindraw_contour (hidGC gc, PLINE *pl) { VNODE *v; Coord last_x, last_y; Coord this_x, this_y; gui->graphics->set_line_width (gc, 0); gui->graphics->set_line_cap (gc, Round_Cap); /* If the contour is round, use an arc drawing routine. */ if (pl->is_round) { gui->graphics->draw_arc (gc, pl->cx, pl->cy, pl->radius, pl->radius, 0, 360); return; } /* Need at least two points in the contour */ if (pl->head.next == NULL) return; last_x = pl->head.point[0]; last_y = pl->head.point[1]; v = pl->head.next; do { this_x = v->point[0]; this_y = v->point[1]; gui->graphics->draw_line (gc, last_x, last_y, this_x, this_y); // gui->graphics->fill_circle (gc, this_x, this_y, 30); last_x = this_x; last_y = this_y; } while ((v = v->next) != pl->head.next); } static void fill_contour_cb (PLINE *pl, void *user_data) { hidGC gc = (hidGC)user_data; PLINE *local_pl = pl; fill_contour (gc, pl); poly_FreeContours (&local_pl); } static void fill_clipped_contour (hidGC gc, PLINE *pl, const BoxType *clip_box) { PLINE *pl_copy; POLYAREA *clip_poly; POLYAREA *piece_poly; POLYAREA *clipped_pieces; POLYAREA *draw_piece; int x; clip_poly = RectPoly (clip_box->X1, clip_box->X2, clip_box->Y1, clip_box->Y2); poly_CopyContour (&pl_copy, pl); piece_poly = poly_Create (); poly_InclContour (piece_poly, pl_copy); x = poly_Boolean_free (piece_poly, clip_poly, &clipped_pieces, PBO_ISECT); if (x != err_ok || clipped_pieces == NULL) return; draw_piece = clipped_pieces; do { /* NB: The polygon won't have any holes in it */ fill_contour (gc, draw_piece->contours); } while ((draw_piece = draw_piece->f) != clipped_pieces); poly_Free (&clipped_pieces); } /* If at least 50% of the bounding box of the polygon is on the screen, * lets compute the complete no-holes polygon. */ #define BOUNDS_INSIDE_CLIP_THRESHOLD 0.5 static int should_compute_no_holes (PolygonType *poly, const BoxType *clip_box) { Coord x1, x2, y1, y2; double poly_bounding_area; double clipped_poly_area; /* If there is no passed clip box, compute the whole thing */ if (clip_box == NULL) return 1; x1 = MAX (poly->BoundingBox.X1, clip_box->X1); x2 = MIN (poly->BoundingBox.X2, clip_box->X2); y1 = MAX (poly->BoundingBox.Y1, clip_box->Y1); y2 = MIN (poly->BoundingBox.Y2, clip_box->Y2); /* Check if the polygon is outside the clip box */ if ((x2 <= x1) || (y2 <= y1)) return 0; poly_bounding_area = (double)(poly->BoundingBox.X2 - poly->BoundingBox.X1) * (double)(poly->BoundingBox.Y2 - poly->BoundingBox.Y1); clipped_poly_area = (double)(x2 - x1) * (double)(y2 - y1); if (clipped_poly_area / poly_bounding_area >= BOUNDS_INSIDE_CLIP_THRESHOLD) return 1; return 0; } #undef BOUNDS_INSIDE_CLIP_THRESHOLD void common_gui_draw_pcb_polygon (hidGC gc, PolygonType *polygon, const BoxType *clip_box) { if (polygon->Clipped == NULL) return; if (TEST_FLAG (THINDRAWFLAG, PCB) || TEST_FLAG (THINDRAWPOLYFLAG, PCB)) gui->graphics->thindraw_pcb_polygon (gc, polygon, clip_box); else gui->graphics->fill_pcb_polygon (gc, polygon, clip_box); /* If checking planes, thin-draw any pieces which have been clipped away */ if (TEST_FLAG (CHECKPLANESFLAG, PCB) && !TEST_FLAG (FULLPOLYFLAG, polygon)) { PolygonType poly = *polygon; for (poly.Clipped = polygon->Clipped->f; poly.Clipped != polygon->Clipped; poly.Clipped = poly.Clipped->f) gui->graphics->thindraw_pcb_polygon (gc, &poly, clip_box); } } void common_fill_pcb_polygon (hidGC gc, PolygonType *poly, const BoxType *clip_box) { if (poly->Clipped == NULL) return; if (!poly->NoHolesValid) { /* If enough of the polygon is on-screen, compute the entire * NoHoles version and cache it for later rendering, otherwise * just compute what we need to render now. */ if (should_compute_no_holes (poly, clip_box)) ComputeNoHoles (poly); else NoHolesPolygonDicer (poly, clip_box, fill_contour_cb, gc); } if (poly->NoHolesValid && poly->NoHoles) { PLINE *pl; for (pl = poly->NoHoles; pl != NULL; pl = pl->next) { if (clip_box == NULL) fill_contour (gc, pl); else fill_clipped_contour (gc, pl, clip_box); } } /* Draw other parts of the polygon if fullpoly flag is set */ /* NB: No "NoHoles" cache for these */ if (TEST_FLAG (FULLPOLYFLAG, poly)) { PolygonType p = *poly; for (p.Clipped = poly->Clipped->f; p.Clipped != poly->Clipped; p.Clipped = p.Clipped->f) NoHolesPolygonDicer (&p, clip_box, fill_contour_cb, gc); } } static int thindraw_hole_cb (PLINE *pl, void *user_data) { hidGC gc = (hidGC)user_data; thindraw_contour (gc, pl); return 0; } void common_thindraw_pcb_polygon (hidGC gc, PolygonType *poly, const BoxType *clip_box) { if (poly->Clipped == NULL) return; thindraw_contour (gc, poly->Clipped->contours); PolygonHoles (poly, clip_box, thindraw_hole_cb, gc); /* Draw other parts of the polygon if fullpoly flag is set */ if (TEST_FLAG (FULLPOLYFLAG, poly)) { PolygonType p = *poly; for (p.Clipped = poly->Clipped->f; p.Clipped != poly->Clipped; p.Clipped = p.Clipped->f) { thindraw_contour (gc, p.Clipped->contours); PolygonHoles (&p, clip_box, thindraw_hole_cb, gc); } } } void common_thindraw_pcb_pad (hidGC gc, PadType *pad, bool clear, bool mask) { Coord w = clear ? (mask ? pad->Mask : pad->Thickness + pad->Clearance) : pad->Thickness; Coord x1, y1, x2, y2; Coord t = w / 2; x1 = pad->Point1.X; y1 = pad->Point1.Y; x2 = pad->Point2.X; y2 = pad->Point2.Y; if (x1 > x2 || y1 > y2) { Coord temp_x = x1; Coord temp_y = y1; x1 = x2; x2 = temp_x; y1 = y2; y2 = temp_y; } gui->graphics->set_line_cap (gc, Round_Cap); gui->graphics->set_line_width (gc, 0); if (TEST_FLAG (SQUAREFLAG, pad)) { /* slanted square pad */ double tx, ty, theta; if (x1 == x2 && y1 == y2) theta = 0; else theta = atan2 (y2 - y1, x2 - x1); /* T is a vector half a thickness long, in the direction of one of the corners. */ tx = t * cos (theta + M_PI / 4) * sqrt (2.0); ty = t * sin (theta + M_PI / 4) * sqrt (2.0); gui->graphics->draw_line (gc, x1 - tx, y1 - ty, x2 + ty, y2 - tx); gui->graphics->draw_line (gc, x2 + ty, y2 - tx, x2 + tx, y2 + ty); gui->graphics->draw_line (gc, x2 + tx, y2 + ty, x1 - ty, y1 + tx); gui->graphics->draw_line (gc, x1 - ty, y1 + tx, x1 - tx, y1 - ty); } else if (x1 == x2 && y1 == y2) { gui->graphics->draw_arc (gc, x1, y1, t, t, 0, 360); } else { /* Slanted round-end pads. */ Coord dx, dy, ox, oy; double h; dx = x2 - x1; dy = y2 - y1; h = t / hypot (dx, dy); ox = dy * h + 0.5 * SGN (dy); oy = -(dx * h + 0.5 * SGN (dx)); gui->graphics->draw_line (gc, x1 + ox, y1 + oy, x2 + ox, y2 + oy); if (abs (ox) >= pixel_slop || abs (oy) >= pixel_slop) { Angle angle = atan2 (dx, dy) * 57.295779; gui->graphics->draw_line (gc, x1 - ox, y1 - oy, x2 - ox, y2 - oy); gui->graphics->draw_arc (gc, x1, y1, t, t, angle - 180, 180); gui->graphics->draw_arc (gc, x2, y2, t, t, angle, 180); } } } /* Computes the coordinates of the corners of a squared pad. */ static void common_get_pad_polygon(Coord x[4], Coord y[4], const PadType *l, int w) { Coord dX, dY; double dwx, dwy; Coord x1, y1, x2, y2; x1 = l->Point1.X; y1 = l->Point1.Y; x2 = l->Point2.X; y2 = l->Point2.Y; if (x1 > x2 || y1 > y2) { Coord temp_x = x1; Coord temp_y = y1; x1 = x2; x2 = temp_x; y1 = y2; y2 = temp_y; } dX = x2 - x1; dY = y2 - y1; if (dY == 0) { dwx = w / 2; dwy = 0; } else if (dX == 0) { dwx = 0; dwy = w / 2; } else { double r; r = hypot (dX, dY) * 2; dwx = w / r * dX; dwy = w / r * dY; } x[0] = x1 - dwx + dwy; y[0] = y1 - dwy - dwx; x[1] = x1 - dwx - dwy; y[1] = y1 - dwy + dwx; x[2] = x2 + dwx - dwy; y[2] = y2 + dwy + dwx; x[3] = x2 + dwx + dwy; y[3] = y2 + dwy - dwx; } void common_fill_pcb_pad (hidGC gc, PadType *pad, bool clear, bool mask) { Coord w = clear ? (mask ? pad->Mask : pad->Thickness + pad->Clearance) : pad->Thickness; if (pad->Point1.X == pad->Point2.X && pad->Point1.Y == pad->Point2.Y) { if (TEST_FLAG (SQUAREFLAG, pad)) { Coord l, r, t, b; l = pad->Point1.X - w / 2; b = pad->Point1.Y - w / 2; r = l + w; t = b + w; gui->graphics->fill_rect (gc, l, b, r, t); } else { gui->graphics->fill_circle (gc, pad->Point1.X, pad->Point1.Y, w / 2); } } else { gui->graphics->set_line_cap (gc, TEST_FLAG (SQUAREFLAG, pad) ? Square_Cap : Round_Cap); gui->graphics->set_line_width (gc, w); if (TEST_FLAG (SQUAREFLAG, pad)) { Coord x[4], y[4]; common_get_pad_polygon (x, y, pad, w); gui->graphics->fill_polygon (gc, 4, x, y); } else gui->graphics->draw_line (gc, pad->Point1.X, pad->Point1.Y, pad->Point2.X, pad->Point2.Y); } } /* --------------------------------------------------------------------------- * draws one polygon * x and y are already in display coordinates * the points are numbered: * * 5 --- 6 * / \ * 4 7 * | | * 3 0 * \ / * 2 --- 1 */ typedef struct { double X, Y; } FloatPolyType; static void draw_octagon_poly (hidGC gc, Coord X, Coord Y, Coord Thickness, bool thin_draw) { static FloatPolyType p[8] = { { 0.5, -TAN_22_5_DEGREE_2}, { TAN_22_5_DEGREE_2, -0.5 }, {-TAN_22_5_DEGREE_2, -0.5 }, {-0.5, -TAN_22_5_DEGREE_2}, {-0.5, TAN_22_5_DEGREE_2}, {-TAN_22_5_DEGREE_2, 0.5 }, { TAN_22_5_DEGREE_2, 0.5 }, { 0.5, TAN_22_5_DEGREE_2} }; static int special_size = 0; static int scaled_x[8]; static int scaled_y[8]; Coord polygon_x[9]; Coord polygon_y[9]; int i; if (Thickness != special_size) { special_size = Thickness; for (i = 0; i < 8; i++) { scaled_x[i] = p[i].X * special_size; scaled_y[i] = p[i].Y * special_size; } } /* add line offset */ for (i = 0; i < 8; i++) { polygon_x[i] = X + scaled_x[i]; polygon_y[i] = Y + scaled_y[i]; } if (thin_draw) { int i; gui->graphics->set_line_cap (gc, Round_Cap); gui->graphics->set_line_width (gc, 0); polygon_x[8] = X + scaled_x[0]; polygon_y[8] = Y + scaled_y[0]; for (i = 0; i < 8; i++) gui->graphics->draw_line (gc, polygon_x[i ], polygon_y[i ], polygon_x[i + 1], polygon_y[i + 1]); } else gui->graphics->fill_polygon (gc, 8, polygon_x, polygon_y); } void common_fill_pcb_pv (hidGC fg_gc, hidGC bg_gc, PinType *pv, bool drawHole, bool mask) { Coord w = mask ? pv->Mask : pv->Thickness; Coord r = w / 2; if (TEST_FLAG (HOLEFLAG, pv)) { if (mask) gui->graphics->fill_circle (bg_gc, pv->X, pv->Y, r); if (drawHole) { gui->graphics->fill_circle (bg_gc, pv->X, pv->Y, r); gui->graphics->set_line_cap (fg_gc, Round_Cap); gui->graphics->set_line_width (fg_gc, 0); gui->graphics->draw_arc (fg_gc, pv->X, pv->Y, r, r, 0, 360); } return; } if (TEST_FLAG (SQUAREFLAG, pv)) { Coord l = pv->X - r; Coord b = pv->Y - r; Coord r = l + w; Coord t = b + w; gui->graphics->fill_rect (fg_gc, l, b, r, t); } else if (TEST_FLAG (OCTAGONFLAG, pv)) draw_octagon_poly (fg_gc, pv->X, pv->Y, w, false); else /* draw a round pin or via */ gui->graphics->fill_circle (fg_gc, pv->X, pv->Y, r); /* and the drilling hole (which is always round) */ if (drawHole) gui->graphics->fill_circle (bg_gc, pv->X, pv->Y, pv->DrillingHole / 2); } void common_thindraw_pcb_pv (hidGC fg_gc, hidGC bg_gc, PinType *pv, bool drawHole, bool mask) { Coord w = mask ? pv->Mask : pv->Thickness; Coord r = w / 2; if (TEST_FLAG (HOLEFLAG, pv)) { if (mask) gui->graphics->draw_arc (fg_gc, pv->X, pv->Y, r, r, 0, 360); if (drawHole) { r = pv->DrillingHole / 2; gui->graphics->set_line_cap (bg_gc, Round_Cap); gui->graphics->set_line_width (bg_gc, 0); gui->graphics->draw_arc (bg_gc, pv->X, pv->Y, r, r, 0, 360); } return; } if (TEST_FLAG (SQUAREFLAG, pv)) { Coord l = pv->X - r; Coord b = pv->Y - r; Coord r = l + w; Coord t = b + w; gui->graphics->set_line_cap (fg_gc, Round_Cap); gui->graphics->set_line_width (fg_gc, 0); gui->graphics->draw_line (fg_gc, r, t, r, b); gui->graphics->draw_line (fg_gc, l, t, l, b); gui->graphics->draw_line (fg_gc, r, t, l, t); gui->graphics->draw_line (fg_gc, r, b, l, b); } else if (TEST_FLAG (OCTAGONFLAG, pv)) { draw_octagon_poly (fg_gc, pv->X, pv->Y, w, true); } else /* draw a round pin or via */ { gui->graphics->set_line_cap (fg_gc, Round_Cap); gui->graphics->set_line_width (fg_gc, 0); gui->graphics->draw_arc (fg_gc, pv->X, pv->Y, r, r, 0, 360); } /* and the drilling hole (which is always round */ if (drawHole) { gui->graphics->set_line_cap (bg_gc, Round_Cap); gui->graphics->set_line_width (bg_gc, 0); gui->graphics->draw_arc (bg_gc, pv->X, pv->Y, pv->DrillingHole / 2, pv->DrillingHole / 2, 0, 360); } } void common_draw_helpers_init (HID_DRAW *graphics) { graphics->draw_pcb_line = common_draw_pcb_line; graphics->draw_pcb_arc = common_draw_pcb_arc; graphics->draw_pcb_text = common_draw_pcb_text; graphics->draw_pcb_polygon = common_fill_pcb_polygon; /* Default is the non-GUI case */ graphics->fill_pcb_polygon = common_fill_pcb_polygon; graphics->thindraw_pcb_polygon = common_thindraw_pcb_polygon; graphics->fill_pcb_pad = common_fill_pcb_pad; graphics->thindraw_pcb_pad = common_thindraw_pcb_pad; graphics->fill_pcb_pv = common_fill_pcb_pv; graphics->thindraw_pcb_pv = common_thindraw_pcb_pv; } pcb-4.3.0/src/hid/common/hid_resource.h0000664000175000017500000000060013773431044014656 00000000000000 #ifndef PCB_HID_COMMON_HID_RESOURCE_H #define PCB_HID_COMMON_HID_RESOURCE_H #include "resource.h" #define M_Shift 1 #define M_Ctrl 2 #define M_Mod(n) (1<<(n+1)) #define M_Alt M_Mod(1) #define M_Multi M_Mod(2) #define M_Release (~((unsigned)-1>>1)) // set the top bit void load_mouse_resource (const Resource *res); void do_mouse_action (int button, int mods); #endif pcb-4.3.0/src/hid/common/draw_helpers.h0000664000175000017500000000136613773431044014674 00000000000000void common_draw_pcb_line (hidGC gc, LineType *line); void common_draw_pcb_arc (hidGC gc, ArcType *arc); void common_gui_draw_pcb_polygon (hidGC gc, PolygonType *poly, const BoxType *clip_box); void common_fill_pcb_polygon (hidGC gc, PolygonType *poly, const BoxType *clip_box); void common_thindraw_pcb_polygon (hidGC gc, PolygonType *poly, const BoxType *clip_box); void common_fill_pcb_pad (hidGC gc, PadType *pad, bool clear, bool mask); void common_thindraw_pcb_pad (hidGC gc, PadType *pad, bool clear, bool mask); void common_fill_pcb_pv (hidGC fg_gc, hidGC bg_gc, PinType *pv, bool drawHole, bool mask); void common_thindraw_pcb_pv (hidGC fg_gc, hidGC bg_gc, PinType *pv, bool drawHole, bool mask); void common_draw_helpers_init (HID_DRAW *graphics); pcb-4.3.0/src/hid/common/actions.c0000664000175000017500000002406413773431044013650 00000000000000#ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "global.h" #include "data.h" #include "error.h" #include "hid.h" #include "../hidint.h" #ifdef HAVE_LIBDMALLOC #include #endif static HID_Action **all_actions = 0; static int all_actions_sorted = 0; static int n_actions = 0; HID_Action *current_action = NULL; static const char * check_action_name (const char *s) { while (*s) if (isspace ((int) *s++) || *s == '(') return (s-1); return NULL; } void hid_register_actions (HID_Action * a, int n) { int i, count = 0; all_actions = (HID_Action **)realloc (all_actions, (n_actions + n) * sizeof (HID_Action*)); for (i = 0; i < n; i++) { if (check_action_name (a[i].name)) { Message (_("ERROR! Invalid action name, " "action \"%s\" not registered.\n"), a[i].name); continue; } all_actions[n_actions + count++] = a + i; } n_actions += count; all_actions_sorted = 0; } void hid_register_action (HID_Action * a) { hid_register_actions (a, 1); } static int action_sort_compar (const void *va, const void *vb) { HID_Action *a = *(HID_Action **) va; HID_Action *b = *(HID_Action **) vb; return strcmp (a->name, b->name); } static void sort_actions () { qsort (all_actions, n_actions, sizeof (HID_Action*), action_sort_compar); all_actions_sorted = 1; } static int action_search_compar (const void *va, const void *vb) { char *name = (char*)va; HID_Action *action = *(HID_Action**)vb; return strcmp (name, action->name); } HID_Action * hid_find_action (const char *name) { HID_Action **action; int i; if (name == NULL) return 0; if (!all_actions_sorted) sort_actions (); action = (HID_Action **)bsearch (name, all_actions, n_actions, sizeof (HID_Action*), action_search_compar); if (action) return *action; for (i = 0; i < n_actions; i++) if (strcasecmp (all_actions[i]->name, name) == 0) return all_actions[i]; printf ("unknown action `%s'\n", name); return 0; } void print_actions () { int i; if (!all_actions_sorted) sort_actions (); fprintf (stderr, "Registered Actions:\n"); for (i = 0; i < n_actions; i++) { if (all_actions[i]->description) fprintf (stderr, " %s - %s\n", all_actions[i]->name, all_actions[i]->description); else fprintf (stderr, " %s\n", all_actions[i]->name); if (all_actions[i]->syntax) { const char *bb, *eb; bb = eb = all_actions[i]->syntax; while (1) { for (eb = bb; *eb && *eb != '\n'; eb++) ; fwrite (" ", 4, 1, stderr); fwrite (bb, eb - bb, 1, stderr); fputc ('\n', stderr); if (*eb == 0) break; bb = eb + 1; } } } } static void dump_string (char prefix, const char *str) { int eol = 1; while (*str) { if (eol) { putchar (prefix); eol = 0; } putchar (*str); if (*str == '\n') eol = 1; str ++; } if (!eol) putchar ('\n'); } void dump_actions () { int i; if (!all_actions_sorted) sort_actions (); for (i = 0; i < n_actions; i++) { const char *desc = all_actions[i]->description; const char *synt = all_actions[i]->syntax; desc = desc ? desc : ""; synt = synt ? synt : ""; printf ("A%s\n", all_actions[i]->name); dump_string ('D', desc); dump_string ('S', synt); } } int hid_action (const char *name) { return hid_actionv (name, 0, 0); } int hid_actionl (const char *name, ...) { char *argv[20]; int argc = 0; va_list ap; char *arg; va_start (ap, name); while ((arg = va_arg (ap, char *)) != 0) argv[argc++] = arg; va_end (ap); return hid_actionv (name, argc, argv); } int hid_actionv (const char *name, int argc, char **argv) { Coord x = 0, y = 0; int i, ret; HID_Action *a, *old_action; if (!name) return 1; a = hid_find_action (name); if (!a) { int i; Message (_("no action %s("), name); for (i = 0; i < argc; i++) Message ("%s%s", i ? ", " : "", argv[i]); Message (")\n"); return 1; } if (a->need_coord_msg) gui->get_coords (_(a->need_coord_msg), &x, &y); if (Settings.verbose) { printf ("Action: \033[34m%s(", name); for (i = 0; i < argc; i++) printf ("%s%s", i ? "," : "", argv[i]); printf (")\033[0m\n"); } old_action = current_action; current_action = a; ret = current_action->trigger_cb (argc, argv, x, y); current_action = old_action; return ret; } static int hid_parse_actionstring (const char *rstr, char require_parens) { char **list = NULL; int max = 0; int num; char *str = NULL; const char *sp; char *cp, *aname, *cp2; int maybe_empty = 0; char in_quotes = 0; char parens = 0; int retcode = 0; /*fprintf(stderr, "invoke: `%s'\n", rstr);*/ sp = rstr; str = (char *)malloc(strlen(rstr)+1); another: num = 0; cp = str; /* eat leading spaces and tabs */ while (*sp && isspace ((int) *sp)) sp++; if (!*sp) { retcode = 0; goto cleanup; } aname = cp; /* copy the action name, assumes name does not have a space or '(' * in its name */ while (*sp && !isspace ((int) *sp) && *sp != '(') *cp++ = *sp++; *cp++ = 0; /* skip whitespace */ while (*sp && isspace ((int) *sp)) sp++; /* * we only have an action name, so invoke the action * with no parameters or event. */ if (!*sp) { retcode = hid_actionv (aname, 0, 0); goto cleanup; } /* are we using parenthesis? */ if (*sp == '(') { parens = 1; sp++; } else if (require_parens) { Message (_("Syntax error: %s\n"), rstr); Message (_(" expected: Action(arg1, arg2)")); retcode = 1; goto cleanup; } /* get the parameters to pass to the action */ while (1) { /* * maybe_empty == 0 means that the last char examined was not a * "," */ if (!maybe_empty && ((parens && *sp == ')') || (!parens && !*sp))) { retcode = hid_actionv (aname, num, list); if (retcode) goto cleanup; /* strip any white space or ';' following the action */ if (parens) sp++; while (*sp && (isspace ((int) *sp) || *sp == ';')) sp++; goto another; } else if (*sp == 0 && !maybe_empty) break; else { maybe_empty = 0; in_quotes = 0; /* * if we have more parameters than memory in our array of * pointers, then either allocate some or grow the array */ if (num >= max) { max += 10; if (list) list = (char **) realloc (list, max * sizeof (char *)); else list = (char **) malloc (max * sizeof (char *)); } /* Strip leading whitespace. */ while (*sp && isspace ((int) *sp)) sp++; list[num++] = cp; /* search for the end of the argument, we want to keep going * if we are in quotes or the char is not a delimiter */ while (*sp && (in_quotes || ((*sp != ',') && (!parens || *sp != ')') && (parens || !isspace ((int) *sp))))) { /* * single quotes give literal value inside, including '\'. * you can't have a single inside single quotes. * doubles quotes gives literal value inside, but allows escape. */ if ((*sp == '"' || *sp == '\'') && (!in_quotes || *sp == in_quotes)) { in_quotes = in_quotes ? 0 : *sp; sp++; continue; } /* unless within single quotes, \ will just be */ else if (*sp == '\\' && in_quotes != '\'') sp++; *cp++ = *sp++; } cp2 = cp - 1; *cp++ = 0; if (*sp == ',' || (!parens && isspace ((int) *sp))) { maybe_empty = 1; sp++; } /* Strip trailing whitespace. */ for (; isspace ((int) *cp2) && cp2 >= list[num - 1]; cp2--) *cp2 = 0; } } cleanup: if (list != NULL) free(list); if (str != NULL) free (str); return retcode; } int hid_parse_command (const char *str_) { return hid_parse_actionstring (str_, FALSE); } int hid_parse_actions (const char *str_) { return hid_parse_actionstring (str_, TRUE); } /* trick for the doc extractor */ #define static /* %start-doc actions 00macros @macro hidaction This is one of a number of actions which are part of the HID interface. The core functions use these actions to tell the current GUI when to change the presented information in response to changes that the GUI may not know about. The user normally does not invoke these directly. @end macro %end-doc */ static const char pcbchanged_syntax[] = "PCBChanged([revert])"; static const char pcbchanged_help[] = "Tells the GUI that the whole PCB has changed. The optional \"revert\"" "parameter can be used as a hint to the GUI that the same design is being" "reloaded, and that it might keep some viewport settings"; /* %start-doc actions PCBChanged @hidaction %end-doc */ static const char routestyleschanged_syntax[] = "RouteStylesChanged()"; static const char routestyleschanged_help[] = "Tells the GUI that the routing styles have changed."; /* %start-doc actions RouteStylesChanged @hidaction %end-doc */ static const char netlistchanged_syntax[] = "NetlistChanged()"; static const char netlistchanged_help[] = "Tells the GUI that the netlist has changed."; /* %start-doc actions NetlistChanged @hidaction %end-doc */ static const char layerschanged_syntax[] = "LayersChanged()"; static const char layerschanged_help[] = "Tells the GUI that the layers have changed."; /* %start-doc actions LayersChanged This includes layer names, colors, stacking order, visibility, etc. @hidaction %end-doc */ static const char librarychanged_syntax[] = "LibraryChanged()"; static const char librarychanged_help[] = "Tells the GUI that the libraries have changed."; /* %start-doc actions LibraryChanged @hidaction %end-doc */ pcb-4.3.0/src/hid/common/hidgl.h0000664000175000017500000000666513773431044013313 00000000000000/* * COPYRIGHT * * PCB, interactive printed circuit board design * Copyright (C) 2009-2011 PCB Contributors (See ChangeLog for details). * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #ifndef PCB_HID_COMMON_HIDGL_H #define PCB_HID_COMMON_HIDGL_H #ifdef WIN32 #define _GLUfuncptr void * #endif #define TRIANGLE_ARRAY_SIZE 5461 typedef struct { GLfloat triangle_array [3 * 3 * TRIANGLE_ARRAY_SIZE]; unsigned int triangle_count; unsigned int coord_comp_count; } triangle_buffer; extern triangle_buffer buffer; extern float global_depth; void hidgl_flush_triangles (triangle_buffer *buffer); void hidgl_ensure_triangle_space (triangle_buffer *buffer, int count); static inline void hidgl_add_triangle_3D (triangle_buffer *buffer, GLfloat x1, GLfloat y1, GLfloat z1, GLfloat x2, GLfloat y2, GLfloat z2, GLfloat x3, GLfloat y3, GLfloat z3) { buffer->triangle_array [buffer->coord_comp_count++] = x1; buffer->triangle_array [buffer->coord_comp_count++] = y1; buffer->triangle_array [buffer->coord_comp_count++] = z1; buffer->triangle_array [buffer->coord_comp_count++] = x2; buffer->triangle_array [buffer->coord_comp_count++] = y2; buffer->triangle_array [buffer->coord_comp_count++] = z2; buffer->triangle_array [buffer->coord_comp_count++] = x3; buffer->triangle_array [buffer->coord_comp_count++] = y3; buffer->triangle_array [buffer->coord_comp_count++] = z3; buffer->triangle_count++; } static inline void hidgl_add_triangle (triangle_buffer *buffer, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2, GLfloat x3, GLfloat y3) { hidgl_add_triangle_3D (buffer, x1, y1, global_depth, x2, y2, global_depth, x3, y3, global_depth); } void hidgl_draw_grid (BoxType *drawn_area); void hidgl_set_depth (float depth); void hidgl_draw_line (int cap, Coord width, Coord x1, Coord y1, Coord x2, Coord y2, double scale); void hidgl_draw_arc (Coord width, Coord vx, Coord vy, Coord vrx, Coord vry, Angle start_angle, Angle delta_angle, double scale); void hidgl_draw_rect (Coord x1, Coord y1, Coord x2, Coord y2); void hidgl_fill_circle (Coord vx, Coord vy, Coord vr, double scale); void hidgl_fill_polygon (int n_coords, Coord *x, Coord *y); void hidgl_fill_pcb_polygon (PolygonType *poly, const BoxType *clip_box, double scale); void hidgl_fill_rect (Coord x1, Coord y1, Coord x2, Coord y2); void hidgl_init (void); void hidgl_start_render (void); void hidgl_finish_render (void); int hidgl_stencil_bits (void); int hidgl_assign_clear_stencil_bit (void); void hidgl_return_stencil_bit (int bit); void hidgl_reset_stencil_usage (void); #endif /* PCB_HID_COMMON_HIDGL_H */ pcb-4.3.0/src/hid/common/hidnogui.c0000664000175000017500000002422713773431044014017 00000000000000#ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "global.h" #include "hid.h" #include "hid_draw.h" #ifdef HAVE_LIBDMALLOC #include #endif /* This is the "gui" that is installed at startup, and is used when there is no other real GUI to use. For the most part, it just stops the application from (1) crashing randomly, and (2) doing gui-specific things when it shouldn't. */ #define CRASH fprintf(stderr, "HID error: pcb called GUI function %s without having a GUI available.\n", __FUNCTION__); abort() typedef struct hid_gc_struct { int nothing_interesting_here; } hid_gc_struct; static HID_Attribute * nogui_get_export_options (int *n_ret) { CRASH; return 0; } static void nogui_do_export (HID_Attr_Val * options) { CRASH; } static void nogui_parse_arguments (int *argc, char ***argv) { CRASH; } static void nogui_invalidate_lr (Coord l, Coord r, Coord t, Coord b) { printf("pcb: invalidate_lr() called without a GUI\n"); printf("This is ok, if you run an action script\n"); } static void nogui_invalidate_all (void) { CRASH; } static int nogui_set_layer (const char *name, int idx, int empty) { CRASH; return 0; } static void nogui_end_layer (void) { } static hidGC nogui_make_gc (void) { return 0; } static void nogui_destroy_gc (hidGC gc) { } static void nogui_use_mask (enum mask_mode mode) { CRASH; } static void nogui_set_color (hidGC gc, const char *name) { CRASH; } static void nogui_set_line_cap (hidGC gc, EndCapStyle style) { CRASH; } static void nogui_set_line_width (hidGC gc, Coord width) { CRASH; } static void nogui_set_draw_xor (hidGC gc, int xor_) { CRASH; } static void nogui_set_draw_faded (hidGC gc, int faded) { } static void nogui_draw_line (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2) { CRASH; } static void nogui_draw_arc (hidGC gc, Coord cx, Coord cy, Coord width, Coord height, Angle start_angle, Angle end_angle) { CRASH; } static void nogui_draw_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2) { CRASH; } static void nogui_fill_circle (hidGC gc, Coord cx, Coord cy, Coord radius) { CRASH; } static void nogui_fill_polygon (hidGC gc, int n_coords, Coord *x, Coord *y) { CRASH; } static void nogui_draw_pcb_polygon (hidGC gc, PolygonType *poly, const BoxType *clip_box) { CRASH; } static void nogui_fill_pcb_pad (hidGC gc, PadType *pad, bool clear, bool mask) { CRASH; } static void nogui_thindraw_pcb_pad (hidGC gc, PadType *pad, bool clear, bool mask) { CRASH; } static void nogui_fill_pcb_pv (hidGC fg_gc, hidGC bg_gc, PinType *pad, bool drawHole, bool mask) { CRASH; } static void nogui_thindraw_pcb_pv (hidGC fg_gc, hidGC bg_gc, PinType *pad, bool drawHole, bool mask) { CRASH; } static void nogui_fill_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2) { CRASH; } static void nogui_calibrate (double xval, double yval) { CRASH; } static int nogui_shift_is_pressed (void) { /* This is called from FitCrosshairIntoGrid() when the board is loaded. */ return 0; } static int nogui_control_is_pressed (void) { CRASH; return 0; } static int nogui_mod1_is_pressed (void) { CRASH; return 0; } static void nogui_get_coords (const char *msg, Coord *x, Coord *y) { CRASH; } static void nogui_set_crosshair (int x, int y, int action) { } static hidval nogui_add_timer (void (*func) (hidval user_data), unsigned long milliseconds, hidval user_data) { hidval rv; CRASH; rv.lval = 0; return rv; } static void nogui_stop_timer (hidval timer) { CRASH; } static hidval nogui_watch_file (int fd, unsigned int condition, void (*func) (hidval watch, int fd, unsigned int condition, hidval user_data), hidval user_data) { hidval rv; CRASH; rv.lval = 0; return rv; } static void nogui_unwatch_file (hidval watch) { CRASH; } static hidval nogui_add_block_hook (void (*func) (hidval data), hidval data) { hidval rv; CRASH; rv.ptr = NULL; return rv; } static void nogui_stop_block_hook (hidval block_hook) { CRASH; } static void nogui_log (const char *fmt, ...) { va_list ap; va_start (ap, fmt); vprintf (fmt, ap); va_end (ap); } static void nogui_logv (const char *fmt, va_list ap) { vprintf (fmt, ap); } /* Return a line of user input text, stripped of any newline characters. * Returns NULL if the user simply presses enter, or otherwise gives no input. */ #define MAX_LINE_LENGTH 1024 static char * read_stdin_line (void) { static char buf[MAX_LINE_LENGTH]; char *s; int i; s = fgets (buf, MAX_LINE_LENGTH, stdin); if (s == NULL) { printf ("\n"); return NULL; } /* Strip any trailing newline characters */ for (i = strlen (s) - 1; i >= 0; i--) if (s[i] == '\r' || s[i] == '\n') s[i] = '\0'; if (s[0] == '\0') return NULL; return strdup (s); } #undef MAX_LINE_LENGTH static int nogui_confirm_dialog (char *msg, ...) { char *answer; int ret = 0; bool valid_answer = false; va_list args; do { va_start (args, msg); vprintf (msg, args); va_end (args); printf (" ? 0=cancel 1 = ok : "); answer = read_stdin_line (); if (answer == NULL) continue; if (answer[0] == '0' && answer[1] == '\0') { ret = 0; valid_answer = true; } if (answer[0] == '1' && answer[1] == '\0') { ret = 1; valid_answer = true; } free (answer); } while (!valid_answer); return ret; } static int nogui_close_confirm_dialog () { return nogui_confirm_dialog (_("OK to lose data ?"), NULL); } static void nogui_report_dialog (char *title, char *msg) { printf ("--- %s ---\n%s\n", title, msg); } static char * nogui_prompt_for (const char *msg, const char *default_string) { char *answer; if (default_string) printf ("%s [%s] : ", msg, default_string); else printf ("%s : ", msg); answer = read_stdin_line (); if (answer == NULL) return strdup ((default_string != NULL) ? default_string : ""); else return answer; } /* FIXME - this could use some enhancement to actually use the other args */ static char * nogui_fileselect (const char *title, const char *descr, char *default_file, char *default_ext, const char *history_tag, int flags) { char *answer; if (default_file) printf ("%s [%s] : ", title, default_file); else printf ("%s : ", title); answer = read_stdin_line (); if (answer == NULL) return (default_file != NULL) ? strdup (default_file) : NULL; else return answer; } static int nogui_attribute_dialog (HID_Attribute * attrs, int n_attrs, HID_Attr_Val * results, const char * title, const char * descr) { CRASH; } static void nogui_show_item (void *item) { CRASH; } static void nogui_beep (void) { putchar (7); fflush (stdout); } static int nogui_progress (int so_far, int total, const char *message) { return 0; } static HID_DRAW * nogui_request_debug_draw (void) { return NULL; } static void nogui_flush_debug_draw (void) { } static void nogui_finish_debug_draw (void) { } void common_nogui_init (HID *hid) { hid->get_export_options = nogui_get_export_options; hid->do_export = nogui_do_export; hid->parse_arguments = nogui_parse_arguments; hid->invalidate_lr = nogui_invalidate_lr; hid->invalidate_all = nogui_invalidate_all; hid->set_layer = nogui_set_layer; hid->end_layer = nogui_end_layer; hid->calibrate = nogui_calibrate; hid->shift_is_pressed = nogui_shift_is_pressed; hid->control_is_pressed = nogui_control_is_pressed; hid->mod1_is_pressed = nogui_mod1_is_pressed; hid->get_coords = nogui_get_coords; hid->set_crosshair = nogui_set_crosshair; hid->add_timer = nogui_add_timer; hid->stop_timer = nogui_stop_timer; hid->watch_file = nogui_watch_file; hid->unwatch_file = nogui_unwatch_file; hid->add_block_hook = nogui_add_block_hook; hid->stop_block_hook = nogui_stop_block_hook; hid->log = nogui_log; hid->logv = nogui_logv; hid->confirm_dialog = nogui_confirm_dialog; hid->close_confirm_dialog = nogui_close_confirm_dialog; hid->report_dialog = nogui_report_dialog; hid->prompt_for = nogui_prompt_for; hid->fileselect = nogui_fileselect; hid->attribute_dialog = nogui_attribute_dialog; hid->show_item = nogui_show_item; hid->beep = nogui_beep; hid->progress = nogui_progress; hid->request_debug_draw = nogui_request_debug_draw; hid->flush_debug_draw = nogui_flush_debug_draw; hid->finish_debug_draw = nogui_finish_debug_draw; } void common_nogui_graphics_init (HID_DRAW *graphics) { graphics->make_gc = nogui_make_gc; graphics->destroy_gc = nogui_destroy_gc; graphics->use_mask = nogui_use_mask; graphics->set_color = nogui_set_color; graphics->set_line_cap = nogui_set_line_cap; graphics->set_line_width = nogui_set_line_width; graphics->set_draw_xor = nogui_set_draw_xor; graphics->set_draw_faded = nogui_set_draw_faded; graphics->draw_line = nogui_draw_line; graphics->draw_arc = nogui_draw_arc; graphics->draw_rect = nogui_draw_rect; graphics->fill_circle = nogui_fill_circle; graphics->fill_polygon = nogui_fill_polygon; graphics->fill_rect = nogui_fill_rect; graphics->draw_pcb_polygon = nogui_draw_pcb_polygon; graphics->fill_pcb_pad = nogui_fill_pcb_pad; graphics->thindraw_pcb_pad = nogui_thindraw_pcb_pad; graphics->fill_pcb_pv = nogui_fill_pcb_pv; graphics->thindraw_pcb_pv = nogui_thindraw_pcb_pv; } static HID nogui_hid; static HID_DRAW nogui_graphics; HID * hid_nogui_get_hid (void) { memset (&nogui_hid, 0, sizeof (HID)); memset (&nogui_graphics, 0, sizeof (HID_DRAW)); nogui_hid.struct_size = sizeof (HID); nogui_hid.name = "nogui"; nogui_hid.description = "Default GUI when no other GUI is present. " "Does nothing."; nogui_hid.graphics = &nogui_graphics; common_nogui_init (&nogui_hid); common_nogui_graphics_init (&nogui_graphics); return &nogui_hid; } pcb-4.3.0/src/hid/common/actions.h0000664000175000017500000000014713773431044013651 00000000000000 #ifndef PCB_HID_COMMON_ACTIONS_H #define PCB_HID_COMMON_ACTIONS_H void print_actions (void); #endif pcb-4.3.0/src/hid/common/flags.c0000664000175000017500000001116013773431044013275 00000000000000#ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "global.h" #include "data.h" #include "misc.h" #include "hid.h" #include "../hidint.h" #ifdef HAVE_LIBDMALLOC #include #endif typedef struct HID_FlagNode { struct HID_FlagNode *next; HID_Flag *flags; int n; } HID_FlagNode; HID_FlagNode *hid_flag_nodes = 0; static int n_flags = 0; static HID_Flag *all_flags = 0; void hid_register_flags (HID_Flag * a, int n) { HID_FlagNode *ha; /* printf("%d flag%s registered\n", n, n==1 ? "" : "s"); */ ha = (HID_FlagNode *) malloc (sizeof (HID_FlagNode)); ha->next = hid_flag_nodes; hid_flag_nodes = ha; ha->flags = a; ha->n = n; n_flags += n; if (all_flags) { free (all_flags); all_flags = 0; } } static int flag_sort (const void *va, const void *vb) { HID_Flag *a = (HID_Flag *) va; HID_Flag *b = (HID_Flag *) vb; return strcmp (a->name, b->name); } HID_Flag * hid_find_flag (const char *name) { HID_FlagNode *hf; int i, n, lower, upper; if (all_flags == 0) { n = 0; all_flags = (HID_Flag *)malloc (n_flags * sizeof (HID_Flag)); for (hf = hid_flag_nodes; hf; hf = hf->next) for (i = 0; i < hf->n; i++) all_flags[n++] = hf->flags[i]; qsort (all_flags, n_flags, sizeof (HID_Flag), flag_sort); } lower = -1; upper = n_flags + 1; /*printf("search flag %s\n", name); */ while (lower < upper - 1) { i = (lower + upper) / 2; n = strcmp (all_flags[i].name, name); /*printf("try [%d].%s, cmp %d\n", i, all_flags[i].name, n); */ if (n == 0) return all_flags + i; if (n > 0) upper = i; else lower = i; } printf ("unknown flag `%s'\n", name); return 0; } int hid_get_flag (const char *name) { static char *buf = 0; static int nbuf = 0; const char *cp; HID_Flag *f; cp = strchr (name, ','); if (cp) { int wv; if (nbuf < (cp - name + 1)) { nbuf = cp - name + 10; buf = (char *)realloc (buf, nbuf); } memcpy (buf, name, cp - name); buf[cp - name] = 0; /* A number without units is just a number. */ wv = GetValueEx (cp + 1, NULL, NULL, NULL, NULL); f = hid_find_flag (buf); if (!f) return 0; return f->function (f->parm) == wv; } f = hid_find_flag (name); if (!f) return 0; return f->function (f->parm); } void hid_save_and_show_layer_ons (int *save_array) { int i; for (i = 0; i < max_copper_layer + SILK_LAYER; i++) { save_array[i] = PCB->Data->Layer[i].On; PCB->Data->Layer[i].On = 1; } } void hid_restore_layer_ons (int *save_array) { int i; for (i = 0; i < max_copper_layer + SILK_LAYER; i++) PCB->Data->Layer[i].On = save_array[i]; } const char * layer_type_to_file_name (int idx, int style) { int group; int nlayers; const char *single_name; switch (idx) { case SL (SILK, TOP): return "topsilk"; case SL (SILK, BOTTOM): return "bottomsilk"; case SL (MASK, TOP): return "topmask"; case SL (MASK, BOTTOM): return "bottommask"; case SL (PDRILL, 0): return "plated-drill"; case SL (UDRILL, 0): return "unplated-drill"; case SL (PASTE, TOP): return "toppaste"; case SL (PASTE, BOTTOM): return "bottompaste"; case SL (INVISIBLE, 0): return "invisible"; case SL (FAB, 0): return "fab"; case SL (ASSY, TOP): return "topassembly"; case SL (ASSY, BOTTOM): return "bottomassembly"; default: group = GetLayerGroupNumberByNumber(idx); nlayers = PCB->LayerGroups.Number[group]; single_name = PCB->Data->Layer[idx].Name; if (group == GetLayerGroupNumberBySide(TOP_SIDE)) { if (style == FNS_first || (style == FNS_single && nlayers == 2)) return single_name; return "top"; } else if (group == GetLayerGroupNumberBySide(BOTTOM_SIDE)) { if (style == FNS_first || (style == FNS_single && nlayers == 2)) return single_name; return "bottom"; } else if (nlayers == 1 && (strcmp (PCB->Data->Layer[idx].Name, "route") == 0 || strcmp (PCB->Data->Layer[idx].Name, "outline") == 0)) { return "outline"; } else { static char buf[20]; if (style == FNS_first || (style == FNS_single && nlayers == 1)) return single_name; sprintf (buf, "group%d", group); return buf; } break; } } const char * layer_type_to_file_name_ex (int idx, int style, const char *layer_name) { if (idx == SL (PDRILL, 0) || idx == SL (UDRILL, 0)) return layer_name; else return layer_type_to_file_name (idx, style); } pcb-4.3.0/src/hid/common/trackball.c0000664000175000017500000002053013773431044014141 00000000000000/* * (c) Copyright 1993, 1994, Silicon Graphics, Inc. * ALL RIGHTS RESERVED * Permission to use, copy, modify, and distribute this software for * any purpose and without fee is hereby granted, provided that the above * copyright notice appear in all copies and that both the copyright notice * and this permission notice appear in supporting documentation, and that * the name of Silicon Graphics, Inc. not be used in advertising * or publicity pertaining to distribution of the software without specific, * written prior permission. * * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN PAD_CONNECTION WITH THE * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE. * * US Government Users Restricted Rights * Use, duplication, or disclosure by the Government is subject to * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph * (c)(1)(ii) of the Rights in Technical Data and Computer Software * clause at DFARS 252.227-7013 and/or in similar or successor * clauses in the FAR or the DOD or NASA FAR Supplement. * Unpublished-- rights reserved under the copyright laws of the * United States. Contractor/manufacturer is Silicon Graphics, * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311. * * OpenGL(TM) is a trademark of Silicon Graphics, Inc. */ /* * Trackball code: * * Implementation of a virtual trackball. * Implemented by Gavin Bell, lots of ideas from Thant Tessman and * the August '88 issue of Siggraph's "Computer Graphics," pp. 121-129. * * Vector manip code: * * Original code from: * David M. Ciemiewicz, Mark Grossman, Henry Moreton, and Paul Haeberli * * Much mucking with by: * Gavin Bell */ #include #include "trackball.h" /* * This size should really be based on the distance from the center of * rotation to the point on the object underneath the mouse. That * point would then track the mouse as closely as possible. This is a * simple example, though, so that is left as an Exercise for the * Programmer. */ #define TRACKBALLSIZE (0.8f) /* * Local function prototypes (not defined in trackball.h) */ static float tb_project_to_sphere(float, float, float); static void normalize_quat(float [4]); void vzero(float *v) { v[0] = 0.0; v[1] = 0.0; v[2] = 0.0; } void vset(float *v, float x, float y, float z) { v[0] = x; v[1] = y; v[2] = z; } void vsub(const float *src1, const float *src2, float *dst) { dst[0] = src1[0] - src2[0]; dst[1] = src1[1] - src2[1]; dst[2] = src1[2] - src2[2]; } void vcopy(const float *v1, float *v2) { register int i; for (i = 0 ; i < 3 ; i++) v2[i] = v1[i]; } void vcross(const float *v1, const float *v2, float *cross) { float temp[3]; temp[0] = (v1[1] * v2[2]) - (v1[2] * v2[1]); temp[1] = (v1[2] * v2[0]) - (v1[0] * v2[2]); temp[2] = (v1[0] * v2[1]) - (v1[1] * v2[0]); vcopy(temp, cross); } float vlength(const float *v) { return (float) sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); } void vscale(float *v, float div) { v[0] *= div; v[1] *= div; v[2] *= div; } void vnormal(float *v) { vscale(v, 1.0f/vlength(v)); } float vdot(const float *v1, const float *v2) { return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; } void vadd(const float *src1, const float *src2, float *dst) { dst[0] = src1[0] + src2[0]; dst[1] = src1[1] + src2[1]; dst[2] = src1[2] + src2[2]; } /* * Ok, simulate a track-ball. Project the points onto the virtual * trackball, then figure out the axis of rotation, which is the cross * product of P1 P2 and O P1 (O is the center of the ball, 0,0,0) * Note: This is a deformed trackball-- is a trackball in the center, * but is deformed into a hyperbolic sheet of rotation away from the * center. This particular function was chosen after trying out * several variations. * * It is assumed that the arguments to this routine are in the range * (-1.0 ... 1.0) */ void trackball(float q[4], float p1x, float p1y, float p2x, float p2y) { float a[3]; /* Axis of rotation */ float phi; /* how much to rotate about axis */ float p1[3], p2[3], d[3]; float t; if (p1x == p2x && p1y == p2y) { /* Zero rotation */ vzero(q); q[3] = 1.0; return; } /* * First, figure out z-coordinates for projection of P1 and P2 to * deformed sphere */ vset(p1, p1x, p1y, tb_project_to_sphere(TRACKBALLSIZE, p1x, p1y)); vset(p2, p2x, p2y, tb_project_to_sphere(TRACKBALLSIZE, p2x, p2y)); /* * Now, we want the cross product of P1 and P2 */ vcross(p2,p1,a); /* * Figure out how much to rotate around that axis. */ vsub(p1, p2, d); t = vlength(d) / (2.0f*TRACKBALLSIZE); /* * Avoid problems with out-of-control values... */ if (t > 1.0) t = 1.0; if (t < -1.0) t = -1.0; phi = 2.0f * (float) asin(t); axis_to_quat(a,phi,q); } /* * Given an axis and angle, compute quaternion. */ void axis_to_quat(float a[3], float phi, float q[4]) { vnormal(a); vcopy(a, q); vscale(q, (float) sin(phi/2.0)); q[3] = (float) cos(phi/2.0); } /* * Project an x,y pair onto a sphere of radius r OR a hyperbolic sheet * if we are away from the center of the sphere. */ static float tb_project_to_sphere(float r, float x, float y) { float d, t, z; d = hypotf(x, y); if (d < r * 0.70710678118654752440) { /* Inside sphere */ z = (float) sqrt(r*r - d*d); } else { /* On hyperbola */ t = r / 1.41421356237309504880f; z = t*t / d; } return z; } /* * Given two rotations, e1 and e2, expressed as quaternion rotations, * figure out the equivalent single rotation and stuff it into dest. * * This routine also normalizes the result every RENORMCOUNT times it is * called, to keep error from creeping in. * * NOTE: This routine is written so that q1 or q2 may be the same * as dest (or each other). */ #define RENORMCOUNT 97 void add_quats(float q1[4], float q2[4], float dest[4]) { static int count=0; float t1[4], t2[4], t3[4]; float tf[4]; vcopy(q1,t1); vscale(t1,q2[3]); vcopy(q2,t2); vscale(t2,q1[3]); vcross(q2,q1,t3); vadd(t1,t2,tf); vadd(t3,tf,tf); tf[3] = q1[3] * q2[3] - vdot(q1,q2); dest[0] = tf[0]; dest[1] = tf[1]; dest[2] = tf[2]; dest[3] = tf[3]; if (++count > RENORMCOUNT) { count = 0; normalize_quat(dest); } } /* * Quaternions always obey: a^2 + b^2 + c^2 + d^2 = 1.0 * If they don't add up to 1.0, dividing by their magnitued will * renormalize them. * * Note: See the following for more information on quaternions: * * - Shoemake, K., Animating rotation with quaternion curves, Computer * Graphics 19, No 3 (Proc. SIGGRAPH'85), 245-254, 1985. * - Pletinckx, D., Quaternion calculus as a basic tool in computer * graphics, The Visual Computer 5, 2-13, 1989. */ static void normalize_quat(float q[4]) { int i; float mag; mag = (q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]); for (i = 0; i < 4; i++) q[i] /= mag; } /* * Build a rotation matrix, given a quaternion rotation. * */ void build_rotmatrix(float m[4][4], float q[4]) { m[0][0] = 1.0f - 2.0f * (q[1] * q[1] + q[2] * q[2]); m[0][1] = 2.0f * (q[0] * q[1] - q[2] * q[3]); m[0][2] = 2.0f * (q[2] * q[0] + q[1] * q[3]); m[0][3] = 0.0f; m[1][0] = 2.0f * (q[0] * q[1] + q[2] * q[3]); m[1][1]= 1.0f - 2.0f * (q[2] * q[2] + q[0] * q[0]); m[1][2] = 2.0f * (q[1] * q[2] - q[0] * q[3]); m[1][3] = 0.0f; m[2][0] = 2.0f * (q[2] * q[0] - q[1] * q[3]); m[2][1] = 2.0f * (q[1] * q[2] + q[0] * q[3]); m[2][2] = 1.0f - 2.0f * (q[1] * q[1] + q[0] * q[0]); m[2][3] = 0.0f; m[3][0] = 0.0f; m[3][1] = 0.0f; m[3][2] = 0.0f; m[3][3] = 1.0f; } pcb-4.3.0/src/hid/common/hidgl.c0000664000175000017500000005455013773431044013302 00000000000000/* * COPYRIGHT * * PCB, interactive printed circuit board design * Copyright (C) 2009-2011 PCB Contributers (See ChangeLog for details) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #ifdef HAVE_STRING_H #include #endif #include #include /* The Linux OpenGL ABI 1.0 spec requires that we define * GL_GLEXT_PROTOTYPES before including gl.h or glx.h for extensions * in order to get prototypes: * http://www.opengl.org/registry/ABI/ */ #define GL_GLEXT_PROTOTYPES 1 /* This follows autoconf's recommendation for the AX_CHECK_GL macro https://www.gnu.org/software/autoconf-archive/ax_check_gl.html */ #if defined HAVE_WINDOWS_H && defined _WIN32 # include #endif #if defined HAVE_GL_GL_H # include #elif defined HAVE_OPENGL_GL_H # include #else # error autoconf couldnt find gl.h #endif /* This follows autoconf's recommendation for the AX_CHECK_GLU macro https://www.gnu.org/software/autoconf-archive/ax_check_glu.html */ #if defined HAVE_GL_GLU_H # include #elif defined HAVE_OPENGL_GLU_H # include #else # error autoconf couldnt find glu.h #endif #include "action.h" #include "crosshair.h" #include "data.h" #include "error.h" #include "global.h" #include "mymem.h" #include "clip.h" #include "hid.h" #include "hidgl.h" #include "rtree.h" #ifdef HAVE_LIBDMALLOC #include #endif triangle_buffer buffer; float global_depth = 0; static void hidgl_init_triangle_array (triangle_buffer *buffer) { buffer->triangle_count = 0; buffer->coord_comp_count = 0; } void hidgl_flush_triangles (triangle_buffer *buffer) { if (buffer->triangle_count == 0) return; glEnableClientState (GL_VERTEX_ARRAY); glVertexPointer (3, GL_FLOAT, 0, buffer->triangle_array); glDrawArrays (GL_TRIANGLES, 0, buffer->triangle_count * 3); glDisableClientState (GL_VERTEX_ARRAY); buffer->triangle_count = 0; buffer->coord_comp_count = 0; } void hidgl_ensure_triangle_space (triangle_buffer *buffer, int count) { if (count > TRIANGLE_ARRAY_SIZE) { fprintf (stderr, "Not enough space in vertex buffer\n"); fprintf (stderr, "Requested %i triangles, %i available\n", count, TRIANGLE_ARRAY_SIZE); exit (1); } if (count > TRIANGLE_ARRAY_SIZE - buffer->triangle_count) hidgl_flush_triangles (buffer); } void hidgl_set_depth (float depth) { global_depth = depth; } /*! * \brief Draw the grid on the 3D canvas */ void hidgl_draw_grid (BoxType *drawn_area) { static GLfloat *points = 0; static int npoints = 0; Coord x1, y1, x2, y2, n, i; double x, y; if (!Settings.DrawGrid) return; /* grid hidden */ /* Find the bounding grid points, all others lay between them */ x1 = GridFit (MAX (0, drawn_area->X1), PCB->Grid, PCB->GridOffsetX); y1 = GridFit (MAX (0, drawn_area->Y1), PCB->Grid, PCB->GridOffsetY); x2 = GridFit (MIN (PCB->MaxWidth, drawn_area->X2), PCB->Grid, PCB->GridOffsetX); y2 = GridFit (MIN (PCB->MaxHeight, drawn_area->Y2), PCB->Grid, PCB->GridOffsetY); if (x1 > x2) { Coord tmp = x1; x1 = x2; x2 = tmp; } if (y1 > y2) { Coord tmp = y1; y1 = y2; y2 = tmp; } n = (int) ((x2 - x1) / PCB->Grid + 0.5) + 1; /* Number of points in one row */ if (n > npoints) { /* [n]points are static, reallocate if we need more memory */ npoints = n + 10; points = realloc (points, npoints * 3 * sizeof (GLfloat)); } glEnableClientState (GL_VERTEX_ARRAY); glVertexPointer (3, GL_FLOAT, 0, points); n = 0; for (x = x1; x <= x2; x += PCB->Grid) { /* compute all the x coordinates */ points[3 * n + 0] = x; points[3 * n + 2] = global_depth; n++; } for (y = y1; y <= y2; y += PCB->Grid) { /* reuse the row of points at each y */ for (i = 0; i < n; i++) points[3 * i + 1] = y; /* draw all the points in a row for a given y */ glDrawArrays (GL_POINTS, 0, n); } glDisableClientState (GL_VERTEX_ARRAY); } #define MAX_PIXELS_ARC_TO_CHORD 0.5 #define MIN_SLICES 6 int calc_slices (float pix_radius, float sweep_angle) { float slices; if (pix_radius <= MAX_PIXELS_ARC_TO_CHORD) return MIN_SLICES; slices = sweep_angle / acosf (1 - MAX_PIXELS_ARC_TO_CHORD / pix_radius) / 2.; return (int)ceilf (slices); } #define MIN_TRIANGLES_PER_CAP 3 #define MAX_TRIANGLES_PER_CAP 90 static void draw_cap (Coord width, Coord x, Coord y, Angle angle, double scale) { float last_capx, last_capy; float capx, capy; float radius = width / 2.; int slices = calc_slices (radius / scale, M_PI); int i; if (slices < MIN_TRIANGLES_PER_CAP) slices = MIN_TRIANGLES_PER_CAP; if (slices > MAX_TRIANGLES_PER_CAP) slices = MAX_TRIANGLES_PER_CAP; hidgl_ensure_triangle_space (&buffer, slices); last_capx = radius * cosf (angle * M_PI / 180.) + x; last_capy = -radius * sinf (angle * M_PI / 180.) + y; for (i = 0; i < slices; i++) { capx = radius * cosf (angle * M_PI / 180. + ((float)(i + 1)) * M_PI / (float)slices) + x; capy = -radius * sinf (angle * M_PI / 180. + ((float)(i + 1)) * M_PI / (float)slices) + y; hidgl_add_triangle (&buffer, last_capx, last_capy, capx, capy, x, y); last_capx = capx; last_capy = capy; } } void hidgl_draw_line (int cap, Coord width, Coord x1, Coord y1, Coord x2, Coord y2, double scale) { double angle; double deltax, deltay, length; float wdx, wdy; int circular_caps = 0; int hairline = 0; if (width == 0.0) hairline = 1; if (width < scale) width = scale; deltax = x2 - x1; deltay = y2 - y1; length = hypot (deltax, deltay); if (length == 0) { /* Assume the orientation of the line is horizontal */ wdx = -width / 2.; wdy = 0; length = 1.; deltax = 1.; deltay = 0.; } else { wdy = deltax * width / 2. / length; wdx = -deltay * width / 2. / length; } angle = -180. / M_PI * atan2 (deltay, deltax); switch (cap) { case Trace_Cap: case Round_Cap: circular_caps = 1; break; case Square_Cap: case Beveled_Cap: x1 -= deltax * width / 2. / length; y1 -= deltay * width / 2. / length; x2 += deltax * width / 2. / length; y2 += deltay * width / 2. / length; break; } hidgl_ensure_triangle_space (&buffer, 2); hidgl_add_triangle (&buffer, x1 - wdx, y1 - wdy, x2 - wdx, y2 - wdy, x2 + wdx, y2 + wdy); hidgl_add_triangle (&buffer, x1 - wdx, y1 - wdy, x2 + wdx, y2 + wdy, x1 + wdx, y1 + wdy); /* Don't bother capping hairlines */ if (circular_caps && !hairline) { draw_cap (width, x1, y1, angle + 90., scale); draw_cap (width, x2, y2, angle - 90., scale); } } #define MIN_SLICES_PER_ARC 6 #define MAX_SLICES_PER_ARC 360 void hidgl_draw_arc (Coord width, Coord x, Coord y, Coord rx, Coord ry, Angle start_angle, Angle delta_angle, double scale) { float last_inner_x, last_inner_y; float last_outer_x, last_outer_y; float inner_x, inner_y; float outer_x, outer_y; float inner_r; float outer_r; float cos_ang, sin_ang; float start_angle_rad; float delta_angle_rad; float angle_incr_rad; int slices; int i; int hairline = 0; if (width == 0.0) hairline = 1; if (width < scale) width = scale; inner_r = rx - width / 2.; outer_r = rx + width / 2.; if (delta_angle < 0) { start_angle += delta_angle; delta_angle = - delta_angle; } start_angle_rad = start_angle * M_PI / 180.; delta_angle_rad = delta_angle * M_PI / 180.; slices = calc_slices ((rx + width / 2.) / scale, delta_angle_rad); if (slices < MIN_SLICES_PER_ARC) slices = MIN_SLICES_PER_ARC; if (slices > MAX_SLICES_PER_ARC) slices = MAX_SLICES_PER_ARC; hidgl_ensure_triangle_space (&buffer, 2 * slices); angle_incr_rad = delta_angle_rad / (float)slices; cos_ang = cosf (start_angle_rad); sin_ang = sinf (start_angle_rad); last_inner_x = -inner_r * cos_ang + x; last_inner_y = inner_r * sin_ang + y; last_outer_x = -outer_r * cos_ang + x; last_outer_y = outer_r * sin_ang + y; for (i = 1; i <= slices; i++) { cos_ang = cosf (start_angle_rad + ((float)(i)) * angle_incr_rad); sin_ang = sinf (start_angle_rad + ((float)(i)) * angle_incr_rad); inner_x = -inner_r * cos_ang + x; inner_y = inner_r * sin_ang + y; outer_x = -outer_r * cos_ang + x; outer_y = outer_r * sin_ang + y; hidgl_add_triangle (&buffer, last_inner_x, last_inner_y, last_outer_x, last_outer_y, outer_x, outer_y); hidgl_add_triangle (&buffer, last_inner_x, last_inner_y, inner_x, inner_y, outer_x, outer_y); last_inner_x = inner_x; last_inner_y = inner_y; last_outer_x = outer_x; last_outer_y = outer_y; } /* Don't bother capping hairlines */ if (hairline) return; draw_cap (width, x + rx * -cosf (start_angle_rad), y + rx * sinf (start_angle_rad), start_angle, scale); draw_cap (width, x + rx * -cosf (start_angle_rad + delta_angle_rad), y + rx * sinf (start_angle_rad + delta_angle_rad), start_angle + delta_angle + 180., scale); } void hidgl_draw_rect (Coord x1, Coord y1, Coord x2, Coord y2) { glBegin (GL_LINE_LOOP); glVertex3f (x1, y1, global_depth); glVertex3f (x1, y2, global_depth); glVertex3f (x2, y2, global_depth); glVertex3f (x2, y1, global_depth); glEnd (); } void hidgl_fill_circle (Coord vx, Coord vy, Coord vr, double scale) { #define MIN_TRIANGLES_PER_CIRCLE 6 #define MAX_TRIANGLES_PER_CIRCLE 360 float last_x, last_y; float radius = vr; int slices; int i; slices = calc_slices (vr / scale, 2 * M_PI); if (slices < MIN_TRIANGLES_PER_CIRCLE) slices = MIN_TRIANGLES_PER_CIRCLE; if (slices > MAX_TRIANGLES_PER_CIRCLE) slices = MAX_TRIANGLES_PER_CIRCLE; hidgl_ensure_triangle_space (&buffer, slices); last_x = vx + vr; last_y = vy; for (i = 0; i < slices; i++) { float x, y; x = radius * cosf (((float)(i + 1)) * 2. * M_PI / (float)slices) + vx; y = radius * sinf (((float)(i + 1)) * 2. * M_PI / (float)slices) + vy; hidgl_add_triangle (&buffer, vx, vy, last_x, last_y, x, y); last_x = x; last_y = y; } } #define MAX_COMBINED_MALLOCS 2500 static void *combined_to_free [MAX_COMBINED_MALLOCS]; static int combined_num_to_free = 0; static GLenum tessVertexType; static int stashed_vertices; static int triangle_comp_idx; #ifndef CALLBACK #define CALLBACK #endif static void CALLBACK myError (GLenum errno) { printf ("gluTess error: %s\n", gluErrorString (errno)); } static void CALLBACK myCombine ( GLdouble coords[3], void *vertex_data[4], GLfloat weight[4], void **dataOut ) { #define MAX_COMBINED_VERTICES 2500 static GLdouble combined_vertices [3 * MAX_COMBINED_VERTICES]; static int num_combined_vertices = 0; GLdouble *new_vertex; if (num_combined_vertices < MAX_COMBINED_VERTICES) { new_vertex = &combined_vertices [3 * num_combined_vertices]; num_combined_vertices ++; } else { new_vertex = malloc (3 * sizeof (GLdouble)); if (combined_num_to_free < MAX_COMBINED_MALLOCS) combined_to_free [combined_num_to_free ++] = new_vertex; else printf ("myCombine leaking %lu bytes of memory\n", (unsigned long)3 * sizeof (GLdouble)); } new_vertex[0] = coords[0]; new_vertex[1] = coords[1]; new_vertex[2] = coords[2]; *dataOut = new_vertex; } static void CALLBACK myBegin (GLenum type) { tessVertexType = type; stashed_vertices = 0; triangle_comp_idx = 0; } static double global_scale; static void CALLBACK myVertex (GLdouble *vertex_data) { static GLfloat triangle_vertices [2 * 3]; if (tessVertexType == GL_TRIANGLE_STRIP || tessVertexType == GL_TRIANGLE_FAN) { if (stashed_vertices < 2) { triangle_vertices [triangle_comp_idx ++] = vertex_data [0]; triangle_vertices [triangle_comp_idx ++] = vertex_data [1]; stashed_vertices ++; } else { hidgl_ensure_triangle_space (&buffer, 1); hidgl_add_triangle (&buffer, triangle_vertices [0], triangle_vertices [1], triangle_vertices [2], triangle_vertices [3], vertex_data [0], vertex_data [1]); if (tessVertexType == GL_TRIANGLE_STRIP) { /* STRIP saves the last two vertices for re-use in the next triangle */ triangle_vertices [0] = triangle_vertices [2]; triangle_vertices [1] = triangle_vertices [3]; } /* Both FAN and STRIP save the last vertex for re-use in the next triangle */ triangle_vertices [2] = vertex_data [0]; triangle_vertices [3] = vertex_data [1]; } } else if (tessVertexType == GL_TRIANGLES) { triangle_vertices [triangle_comp_idx ++] = vertex_data [0]; triangle_vertices [triangle_comp_idx ++] = vertex_data [1]; stashed_vertices ++; if (stashed_vertices == 3) { hidgl_ensure_triangle_space (&buffer, 1); hidgl_add_triangle (&buffer, triangle_vertices [0], triangle_vertices [1], triangle_vertices [2], triangle_vertices [3], triangle_vertices [4], triangle_vertices [5]); triangle_comp_idx = 0; stashed_vertices = 0; } } else printf ("Vertex received with unknown type\n"); } static void myFreeCombined () { while (combined_num_to_free) free (combined_to_free [-- combined_num_to_free]); } void hidgl_fill_polygon (int n_coords, Coord *x, Coord *y) { int i; GLUtesselator *tobj; GLdouble *vertices; assert (n_coords > 0); vertices = malloc (sizeof(GLdouble) * n_coords * 3); tobj = gluNewTess (); gluTessCallback(tobj, GLU_TESS_BEGIN, (_GLUfuncptr)myBegin); gluTessCallback(tobj, GLU_TESS_VERTEX, (_GLUfuncptr)myVertex); gluTessCallback(tobj, GLU_TESS_COMBINE, (_GLUfuncptr)myCombine); gluTessCallback(tobj, GLU_TESS_ERROR, (_GLUfuncptr)myError); gluTessBeginPolygon (tobj, NULL); gluTessBeginContour (tobj); for (i = 0; i < n_coords; i++) { vertices [0 + i * 3] = x[i]; vertices [1 + i * 3] = y[i]; vertices [2 + i * 3] = 0.; gluTessVertex (tobj, &vertices [i * 3], &vertices [i * 3]); } gluTessEndContour (tobj); gluTessEndPolygon (tobj); gluDeleteTess (tobj); myFreeCombined (); free (vertices); } void tesselate_contour (GLUtesselator *tobj, PLINE *contour, GLdouble *vertices, double scale) { VNODE *vn = &contour->head; int offset = 0; /* If the contour is round, and hidgl_fill_circle would use * less slices than we have vertices to draw it, then call * hidgl_fill_circle to draw this contour. */ if (contour->is_round) { double slices = calc_slices (contour->radius / scale, 2 * M_PI); if (slices < contour->Count) { hidgl_fill_circle (contour->cx, contour->cy, contour->radius, scale); return; } } gluTessBeginPolygon (tobj, NULL); gluTessBeginContour (tobj); do { vertices [0 + offset] = vn->point[0]; vertices [1 + offset] = vn->point[1]; vertices [2 + offset] = 0.; gluTessVertex (tobj, &vertices [offset], &vertices [offset]); offset += 3; } while ((vn = vn->next) != &contour->head); gluTessEndContour (tobj); gluTessEndPolygon (tobj); } struct do_hole_info { GLUtesselator *tobj; GLdouble *vertices; double scale; }; static int do_hole (const BoxType *b, void *cl) { struct do_hole_info *info = cl; PLINE *curc = (PLINE *) b; /* Ignore the outer contour - we draw it first explicitly*/ if (curc->Flags.orient == PLF_DIR) { return 0; } tesselate_contour (info->tobj, curc, info->vertices, info->scale); return 1; } static GLint stencil_bits; static int dirty_bits = 0; static int assigned_bits = 0; static void fill_polyarea (POLYAREA *pa, const BoxType *clip_box, double scale) { int vertex_count = 0; PLINE *contour; struct do_hole_info info; int stencil_bit; info.scale = scale; global_scale = scale; stencil_bit = hidgl_assign_clear_stencil_bit (); if (!stencil_bit) { printf ("hidgl_fill_pcb_polygon: No free stencil bits, aborting polygon\n"); return; } /* Flush out any existing geoemtry to be rendered */ hidgl_flush_triangles (&buffer); /* Walk the polygon structure, counting vertices */ /* This gives an upper bound on the amount of storage required */ for (contour = pa->contours; contour != NULL; contour = contour->next) vertex_count = MAX (vertex_count, contour->Count); info.vertices = malloc (sizeof(GLdouble) * vertex_count * 3); info.tobj = gluNewTess (); gluTessCallback(info.tobj, GLU_TESS_BEGIN, (_GLUfuncptr)myBegin); gluTessCallback(info.tobj, GLU_TESS_VERTEX, (_GLUfuncptr)myVertex); gluTessCallback(info.tobj, GLU_TESS_COMBINE, (_GLUfuncptr)myCombine); gluTessCallback(info.tobj, GLU_TESS_ERROR, (_GLUfuncptr)myError); glPushAttrib (GL_STENCIL_BUFFER_BIT); /* Save the write mask etc.. for final restore */ glEnable (GL_STENCIL_TEST); glPushAttrib (GL_STENCIL_BUFFER_BIT | /* Resave the stencil write-mask etc.., and */ GL_COLOR_BUFFER_BIT); /* the colour buffer write mask etc.. for part way restore */ glStencilMask (stencil_bit); /* Only write to our stencil bit */ glStencilFunc (GL_ALWAYS, stencil_bit, stencil_bit); /* Always pass stencil test, ref value is our bit */ glColorMask (0, 0, 0, 0); /* Disable writting in color buffer */ glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); /* Stencil pass => replace stencil value */ /* Drawing operations now set our reference bit in the stencil buffer */ r_search (pa->contour_tree, clip_box, NULL, do_hole, &info); hidgl_flush_triangles (&buffer); glPopAttrib (); /* Restore the colour and stencil buffer write-mask etc.. */ glStencilOp (GL_KEEP, GL_KEEP, GL_INVERT); /* This allows us to toggle the bit on any subcompositing bitplane */ /* If the stencil test has passed, we know that bit is 0, so we're */ /* effectively just setting it to 1. */ glStencilFunc (GL_GEQUAL, 0, assigned_bits); /* Pass stencil test if all assigned bits clear, */ /* reference is all assigned bits so we set */ /* any bits permitted by the stencil writemask */ /* Drawing operations as masked to areas where the stencil buffer is '0' */ /* Draw the polygon outer */ tesselate_contour (info.tobj, pa->contours, info.vertices, scale); hidgl_flush_triangles (&buffer); /* Unassign our stencil buffer bit */ hidgl_return_stencil_bit (stencil_bit); glPopAttrib (); /* Restore the stencil buffer write-mask etc.. */ gluDeleteTess (info.tobj); myFreeCombined (); free (info.vertices); } void hidgl_fill_pcb_polygon (PolygonType *poly, const BoxType *clip_box, double scale) { if (poly->Clipped == NULL) return; fill_polyarea (poly->Clipped, clip_box, scale); if (TEST_FLAG (FULLPOLYFLAG, poly)) { POLYAREA *pa; for (pa = poly->Clipped->f; pa != poly->Clipped; pa = pa->f) fill_polyarea (pa, clip_box, scale); } } void hidgl_fill_rect (Coord x1, Coord y1, Coord x2, Coord y2) { hidgl_ensure_triangle_space (&buffer, 2); hidgl_add_triangle (&buffer, x1, y1, x1, y2, x2, y2); hidgl_add_triangle (&buffer, x2, y1, x2, y2, x1, y1); } void hidgl_init (void) { glGetIntegerv (GL_STENCIL_BITS, &stencil_bits); if (stencil_bits == 0) { printf ("No stencil bits available.\n" "Cannot mask polygon holes or subcomposite layers\n"); /* TODO: Flag this to the HID so it can revert to the dicer? */ } else if (stencil_bits == 1) { printf ("Only one stencil bitplane available\n" "Cannot use stencil buffer to sub-composite layers.\n"); /* Do we need to disable that somewhere? */ } } void hidgl_start_render (void) { hidgl_init (); hidgl_init_triangle_array (&buffer); } void hidgl_finish_render (void) { } int hidgl_stencil_bits (void) { return stencil_bits; } static void hidgl_clean_unassigned_stencil (void) { glPushAttrib (GL_STENCIL_BUFFER_BIT); glStencilMask (~assigned_bits); glClearStencil (0); glClear (GL_STENCIL_BUFFER_BIT); glPopAttrib (); } int hidgl_assign_clear_stencil_bit (void) { int stencil_bitmask = (1 << stencil_bits) - 1; int test; int first_dirty = 0; if (assigned_bits == stencil_bitmask) { printf ("No more stencil bits available, total of %i already assigned\n", stencil_bits); return 0; } /* Look for a bitplane we don't have to clear */ for (test = 1; test & stencil_bitmask; test <<= 1) { if (!(test & dirty_bits)) { assigned_bits |= test; dirty_bits |= test; return test; } else if (!first_dirty && !(test & assigned_bits)) { first_dirty = test; } } /* Didn't find any non dirty planes. Clear those dirty ones which aren't in use */ hidgl_clean_unassigned_stencil (); assigned_bits |= first_dirty; dirty_bits = assigned_bits; return first_dirty; } void hidgl_return_stencil_bit (int bit) { assigned_bits &= ~bit; } void hidgl_reset_stencil_usage (void) { assigned_bits = 0; dirty_bits = 0; } pcb-4.3.0/src/hid/common/hidinit.c0000664000175000017500000004541413773431044013642 00000000000000/*! * \file src/common/hidinit.c * * \brief General initialization routines for HIDs. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996 Thomas Nau * * Copyright (C) 1998,1999,2000,2001 harry eaton * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA * haceaton@aplcomm.jhuapl.edu */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifdef HAVE_DLFCN_H #include #endif #include #include #include #include #if defined(WIN32) && defined(HAVE_WINDOWS_H) #define WIN32_LEAN_AND_MEAN #include #endif #include "global.h" #include "hid.h" #include "hidnogui.h" #include "../hidint.h" /* for dlopen() and friends on windows */ #include "compat.h" #include "error.h" #include "global.h" #include "misc.h" #include "pcb-printf.h" #ifdef HAVE_LIBDMALLOC #include #endif #define HID_DEF(x) extern void hid_ ## x ## _init(void); #include "hid/common/hidlist.h" #undef HID_DEF HID **hid_list = 0; int hid_num_hids = 0; HID *gui = NULL; HID *exporter = NULL; int pixel_slop = 1; /*! * \brief Search a directory for plugins and load them if found * * The specified path is searched for shared library objects and dynamic link * libraries. If any are found, check their symbols for a "hid_x_init" (where * x is the basename of the library file) or a pcb_plugin_init, and call it as * a function if found. * * \todo the MacOS .dylib should be added to this list * */ static void hid_load_dir (char *dirname) { DIR *dir; struct dirent *de; dir = opendir (dirname); if (!dir) { free (dirname); return; } while ((de = readdir (dir)) != NULL) { void *sym; void (*symv)(); void *so; char *basename, *path, *symname; struct stat st; basename = strdup (de->d_name); if (strlen (basename) > 3 && strcasecmp (basename+strlen(basename)-3, ".so") == 0) basename[strlen(basename)-3] = 0; else if (strlen (basename) > 4 && strcasecmp (basename+strlen(basename)-4, ".dll") == 0) basename[strlen(basename)-4] = 0; path = Concat (dirname, PCB_DIR_SEPARATOR_S, de->d_name, NULL); if (stat (path, &st) == 0 && ( /* mingw and win32 do not support S_IXGRP or S_IXOTH */ #if defined(S_IXGRP) (st.st_mode & S_IXGRP) || #endif #if defined(S_IXOTH) (st.st_mode & S_IXOTH) || #endif (st.st_mode & S_IXUSR) ) && S_ISREG (st.st_mode)) { if ((so = dlopen (path, RTLD_NOW | RTLD_GLOBAL)) == NULL) { fprintf(stderr, "dl_error: %s\n", dlerror ()); } else { symname = Concat ("hid_", basename, "_init", NULL); if ((sym = dlsym (so, symname)) != NULL) { symv = (void (*)()) sym; symv(); } else if ((sym = dlsym (so, "pcb_plugin_init")) != NULL) { symv = (void (*)()) sym; symv(); } free (symname); } } free (basename); free (path); } free (dirname); closedir (dir); } /*! * \brief Initialize the available hids and load plugins * * The file hid/common/hidlist.h contains a list of HID_DEF statements, compiled * by the build system. The HID_DEF macro is redefined here to call the init * function for each of those hids. */ void hid_init () { /* Setup a "nogui" default HID */ gui = hid_nogui_get_hid (); /* Call all of the hid initialization functions */ #define HID_DEF(x) hid_ ## x ## _init(); #include "hid/common/hidlist.h" #undef HID_DEF /* Search the exec_prefix for plugins and load them */ hid_load_dir (Concat (exec_prefix, PCB_DIR_SEPARATOR_S, "lib", PCB_DIR_SEPARATOR_S, "pcb", PCB_DIR_SEPARATOR_S, "plugins", PCB_DIR_SEPARATOR_S, HOST, NULL)); hid_load_dir (Concat (exec_prefix, PCB_DIR_SEPARATOR_S, "lib", PCB_DIR_SEPARATOR_S, "pcb", PCB_DIR_SEPARATOR_S, "plugins", NULL)); /* Search homedir for plugins and load them. homedir is set by the core * immediately on startup */ if (homedir != NULL) { hid_load_dir (Concat (homedir, PCB_DIR_SEPARATOR_S, ".pcb", PCB_DIR_SEPARATOR_S, "plugins", PCB_DIR_SEPARATOR_S, HOST, NULL)); hid_load_dir (Concat (homedir, PCB_DIR_SEPARATOR_S, ".pcb", PCB_DIR_SEPARATOR_S, "plugins", NULL)); } hid_load_dir (Concat ("plugins", PCB_DIR_SEPARATOR_S, HOST, NULL)); hid_load_dir (Concat ("plugins", NULL)); } void hid_uninit (void) { } /*! * \brief Add an HID to the list of HIDs. */ void hid_register_hid (HID * hid) { int i; int sz = (hid_num_hids + 2) * sizeof (HID *); if (hid->struct_size != sizeof (HID)) { fprintf (stderr, "Warning: hid \"%s\" has an incompatible ABI.\n", hid->name); return; } for (i=0; iprinter && !hid_list[i]->exporter) return hid_list[i]; fprintf (stderr, "Error: No GUI available.\n"); exit (1); } HID * hid_find_printer () { int i; for (i = 0; i < hid_num_hids; i++) if (hid_list[i]->printer) return hid_list[i]; return 0; } HID * hid_find_exporter (const char *which) { int i; for (i = 0; i < hid_num_hids; i++) if (hid_list[i]->exporter && strcmp (which, hid_list[i]->name) == 0) return hid_list[i]; fprintf (stderr, "Invalid exporter %s, available ones:", which); for (i = 0; i < hid_num_hids; i++) if (hid_list[i]->exporter) fprintf (stderr, " %s", hid_list[i]->name); fprintf (stderr, "\n"); return 0; } HID ** hid_enumerate () { return hid_list; } HID_AttrNode *hid_attr_nodes = 0; void hid_register_attributes (HID_Attribute * a, int n) { HID_AttrNode *ha; /* printf("%d attributes registered\n", n); */ ha = (HID_AttrNode *) malloc (sizeof (HID_AttrNode)); ha->next = hid_attr_nodes; hid_attr_nodes = ha; ha->attributes = a; ha->n = n; } void hid_parse_command_line (int *argc, char ***argv) { HID_AttrNode *ha; int i, e, ok; (*argc)--; (*argv)++; for (ha = hid_attr_nodes; ha; ha = ha->next) for (i = 0; i < ha->n; i++) { HID_Attribute *a = ha->attributes + i; switch (a->type) { case HID_Label: break; case HID_Integer: if (a->value) *(int *) a->value = a->default_val.int_value; break; case HID_Coord: if (a->value) *(Coord *) a->value = a->default_val.coord_value; break; case HID_Boolean: if (a->value) *(char *) a->value = a->default_val.int_value; break; case HID_Real: if (a->value) *(double *) a->value = a->default_val.real_value; break; case HID_String: if (a->value) *(const char **) a->value = a->default_val.str_value; break; case HID_Enum: if (a->value) *(int *) a->value = a->default_val.int_value; break; case HID_Mixed: if (a->value) { *(HID_Attr_Val *) a->value = a->default_val; case HID_Unit: if (a->value) *(int *) a->value = a->default_val.int_value; break; } break; default: abort (); } } while (*argc && (*argv)[0][0] == '-' && (*argv)[0][1] == '-') { int bool_val; int arg_ofs; bool_val = 1; arg_ofs = 2; try_no_arg: for (ha = hid_attr_nodes; ha; ha = ha->next) for (i = 0; i < ha->n; i++) if (strcmp ((*argv)[0] + arg_ofs, ha->attributes[i].name) == 0) { HID_Attribute *a = ha->attributes + i; char *ep; const Unit *unit; switch (ha->attributes[i].type) { case HID_Label: break; case HID_Integer: if (a->value) *(int *) a->value = strtol ((*argv)[1], 0, 0); else a->default_val.int_value = strtol ((*argv)[1], 0, 0); (*argc)--; (*argv)++; break; case HID_Coord: if (a->value) *(Coord *) a->value = GetValue ((*argv)[1], NULL, NULL); else a->default_val.coord_value = GetValue ((*argv)[1], NULL, NULL); (*argc)--; (*argv)++; break; case HID_Real: if (a->value) *(double *) a->value = strtod ((*argv)[1], 0); else a->default_val.real_value = strtod ((*argv)[1], 0); (*argc)--; (*argv)++; break; case HID_String: if (a->value) *(char **) a->value = (*argv)[1]; else a->default_val.str_value = (*argv)[1]; (*argc)--; (*argv)++; break; case HID_Boolean: if (a->value) *(char *) a->value = bool_val; else a->default_val.int_value = bool_val; break; case HID_Mixed: a->default_val.real_value = strtod ((*argv)[1], &ep); goto do_enum; case HID_Enum: ep = (*argv)[1]; do_enum: ok = 0; for (e = 0; a->enumerations[e]; e++) if (strcmp (a->enumerations[e], ep) == 0) { ok = 1; a->default_val.int_value = e; a->default_val.str_value = ep; break; } if (!ok) { fprintf (stderr, "ERROR: \"%s\" is an unknown value for the --%s option\n", (*argv)[1], a->name); exit (1); } (*argc)--; (*argv)++; break; case HID_Path: abort (); a->default_val.str_value = (*argv)[1]; (*argc)--; (*argv)++; break; case HID_Unit: unit = get_unit_struct ((*argv)[1]); if (unit == NULL) { fprintf (stderr, "ERROR: unit \"%s\" is unknown to pcb (option --%s)\n", (*argv)[1], a->name); exit (1); } a->default_val.int_value = unit->index; a->default_val.str_value = unit->suffix; (*argc)--; (*argv)++; break; } (*argc)--; (*argv)++; ha = 0; goto got_match; } if (bool_val == 1 && strncmp ((*argv)[0], "--no-", 5) == 0) { bool_val = 0; arg_ofs = 5; goto try_no_arg; } fprintf (stderr, "unrecognized option: %s\n", (*argv)[0]); exit (1); got_match:; } (*argc)++; (*argv)--; } static int attr_hash (HID_Attribute *a) { unsigned char *cp = (unsigned char *)a; int i, rv=0; for (i=0; i<(int)((char *)&(a->hash) - (char *)a); i++) rv = (rv * 13) ^ (rv >> 16) ^ cp[i]; return rv; } void hid_save_settings (int locally) { char *fname; struct stat st; FILE *f; HID_AttrNode *ha; int i; if (locally) { fname = Concat ("pcb.settings", NULL); } else { if (homedir == NULL) return; fname = Concat (homedir, PCB_DIR_SEPARATOR_S, ".pcb", NULL); if (stat (fname, &st)) if (MKDIR (fname, 0777)) { free (fname); return; } free (fname); fname = Concat (homedir, PCB_DIR_SEPARATOR_S, ".pcb", PCB_DIR_SEPARATOR_S, "settings", NULL); } f = fopen (fname, "w"); if (!f) { Message ("Can't open %s", fname); free (fname); return; } for (ha = hid_attr_nodes; ha; ha = ha->next) { for (i = 0; i < ha->n; i++) { const char *str; HID_Attribute *a = ha->attributes + i; if (a->hash == attr_hash (a)) fprintf (f, "# "); switch (a->type) { case HID_Label: break; case HID_Integer: fprintf (f, "%s = %d\n", a->name, a->value ? *(int *)a->value : a->default_val.int_value); break; case HID_Coord: pcb_fprintf (f, "%s = %$mS\n", a->name, a->value ? *(Coord *)a->value : a->default_val.coord_value); break; case HID_Boolean: fprintf (f, "%s = %d\n", a->name, a->value ? *(char *)a->value : a->default_val.int_value); break; case HID_Real: fprintf (f, "%s = %f\n", a->name, a->value ? *(double *)a->value : a->default_val.real_value); break; case HID_String: case HID_Path: str = a->value ? *(char **)a->value : a->default_val.str_value; fprintf (f, "%s = %s\n", a->name, str ? str : ""); break; case HID_Enum: fprintf (f, "%s = %s\n", a->name, a->enumerations[a->value ? *(int *)a->value : a->default_val.int_value]); break; case HID_Mixed: { HID_Attr_Val *value = a->value ? (HID_Attr_Val*) a->value : &(a->default_val); fprintf (f, "%s = %g%s\n", a->name, value->real_value, a->enumerations[value->int_value]); } break; case HID_Unit: fprintf (f, "%s = %s\n", a->name, get_unit_list()[a->value ? *(int *)a->value : a->default_val.int_value].suffix); break; } } fprintf (f, "\n"); } fclose (f); free (fname); } static void hid_set_attribute (char *name, char *value) { const Unit *unit; HID_AttrNode *ha; int i, e, ok; for (ha = hid_attr_nodes; ha; ha = ha->next) for (i = 0; i < ha->n; i++) if (strcmp (name, ha->attributes[i].name) == 0) { HID_Attribute *a = ha->attributes + i; switch (ha->attributes[i].type) { case HID_Label: break; case HID_Integer: a->default_val.int_value = strtol (value, 0, 0); break; case HID_Coord: a->default_val.coord_value = GetValue (value, NULL, NULL); break; case HID_Real: a->default_val.real_value = strtod (value, 0); break; case HID_String: a->default_val.str_value = strdup (value); break; case HID_Boolean: a->default_val.int_value = 1; break; case HID_Mixed: a->default_val.real_value = strtod (value, &value); /* fall through */ case HID_Enum: ok = 0; for (e = 0; a->enumerations[e]; e++) if (strcmp (a->enumerations[e], value) == 0) { ok = 1; a->default_val.int_value = e; a->default_val.str_value = value; break; } if (!ok) { fprintf (stderr, "ERROR: \"%s\" is an unknown value for the %s option\n", value, a->name); exit (1); } break; case HID_Path: a->default_val.str_value = value; break; case HID_Unit: unit = get_unit_struct (value); if (unit == NULL) { fprintf (stderr, "ERROR: unit \"%s\" is unknown to pcb (option --%s)\n", value, a->name); exit (1); } a->default_val.int_value = unit->index; a->default_val.str_value = unit->suffix; break; } } } static void hid_load_settings_1 (char *fname) { char line[1024], *namep, *valp, *cp; FILE *f; f = fopen (fname, "r"); if (!f) { free (fname); return; } free (fname); while (fgets (line, sizeof(line), f) != NULL) { for (namep=line; *namep && isspace ((int) *namep); namep++) ; if (*namep == '#') continue; for (valp=namep; *valp && !isspace((int) *valp); valp++) ; if (! *valp) continue; *valp++ = 0; while (*valp && (isspace ((int) *valp) || *valp == '=')) valp ++; if (! *valp) continue; cp = valp + strlen(valp) - 1; while (cp >= valp && isspace ((int) *cp)) *cp-- = 0; hid_set_attribute (namep, valp); } fclose (f); } void hid_load_settings () { HID_AttrNode *ha; int i; for (ha = hid_attr_nodes; ha; ha = ha->next) for (i = 0; i < ha->n; i++) ha->attributes[i].hash = attr_hash (ha->attributes+i); hid_load_settings_1 (Concat (pcblibdir, PCB_DIR_SEPARATOR_S, "settings", NULL)); if (homedir != NULL) hid_load_settings_1 (Concat (homedir, PCB_DIR_SEPARATOR_S, ".pcb", PCB_DIR_SEPARATOR_S, "settings", NULL)); hid_load_settings_1 (Concat ("pcb.settings", NULL)); } #define HASH_SIZE 31 typedef struct ecache { struct ecache *next; const char *name; hidval val; } ecache; typedef struct ccache { ecache *colors[HASH_SIZE]; ecache *lru; } ccache; static void copy_color (int set, hidval * cval, hidval * aval) { if (set) memcpy (cval, aval, sizeof (hidval)); else memcpy (aval, cval, sizeof (hidval)); } int hid_cache_color (int set, const char *name, hidval * val, void **vcache) { unsigned long hash; const char *cp; ccache *cache; ecache *e; cache = (ccache *) * vcache; if (cache == 0) { cache = (ccache *) calloc (sizeof (ccache), 1); *vcache = cache; } if (cache->lru && strcmp (cache->lru->name, name) == 0) { copy_color (set, &(cache->lru->val), val); return 1; } /* djb2: this algorithm (k=33) was first reported by dan bernstein many * years ago in comp.lang.c. another version of this algorithm (now favored * by bernstein) uses xor: hash(i) = hash(i - 1) * 33 ^ str[i]; the magic * of number 33 (why it works better than many other constants, prime or * not) has never been adequately explained. */ hash = 5381; for (cp = name, hash = 0; *cp; cp++) hash = ((hash << 5) + hash) + (*cp & 0xff); /* hash * 33 + c */ hash %= HASH_SIZE; for (e = cache->colors[hash]; e; e = e->next) if (strcmp (e->name, name) == 0) { copy_color (set, &(e->val), val); cache->lru = e; return 1; } if (!set) return 0; e = (ecache *) malloc (sizeof (ecache)); e->next = cache->colors[hash]; cache->colors[hash] = e; e->name = strdup (name); memcpy (&(e->val), val, sizeof (hidval)); cache->lru = e; return 1; } /* otherwise homeless function, refactored out of the five export HIDs */ void derive_default_filename(const char *pcbfile, HID_Attribute *filename_attrib, const char *suffix, char **memory) { char *buf; char *pf; if (pcbfile == NULL) pf = strdup ("unknown.pcb"); else pf = strdup (pcbfile); if (!pf || (memory && filename_attrib->default_val.str_value != *memory)) return; buf = (char *)malloc (strlen (pf) + strlen(suffix) + 1); if (memory) *memory = buf; if (buf) { size_t bl; strcpy (buf, pf); bl = strlen(buf); if (bl > 4 && strcmp (buf + bl - 4, ".pcb") == 0) buf[bl - 4] = 0; strcat(buf, suffix); if (filename_attrib->default_val.str_value) free ((void *) filename_attrib->default_val.str_value); filename_attrib->default_val.str_value = buf; } free (pf); } pcb-4.3.0/src/hid/common/hidinit.h0000664000175000017500000000020213773431044013631 00000000000000#ifndef PCB_HID_COMMON_HIDINIT_H #define PCB_HID_COMMON_HIDINIT_H void hid_parse_command_line (int *argc, char ***argv); #endif pcb-4.3.0/src/hid/common/hidnogui.h0000664000175000017500000000021713773431044014015 00000000000000#ifndef PCB_HID_COMMON_HIDNOGUI_H #define PCB_HID_COMMON_HIDNOGUI_H void common_nogui_init (HID *hid); HID *hid_nogui_get_hid (void); #endif pcb-4.3.0/src/hid/common/hid_resource.c0000664000175000017500000001105113773431044014653 00000000000000#include #include #include #include "global.h" #include "hid.h" #include "resource.h" #include "hid/common/hid_resource.h" /* #define DEBUG_HID_RESOURCE */ static int button_count; // number of buttons we have actions for static int *button_nums; // list of button numbers static int *mod_count; // how many mods they have static unsigned *mods; // mods, in order, one button after another static Resource** actions; // actions, in order, one button after another static Resource * res_wrap (char *value) { Resource *tmp; tmp = resource_create (0); resource_add_val (tmp, 0, value, 0); return tmp; } static unsigned parse_mods (char *value) { unsigned m = 0; long int mod_num; char *s; for (s=value; *s; s++) *s = tolower(*s); s = strstr(value, "mod"); if (s) { s += 3; // skip "mod" to get to number errno = 0; mod_num = strtol(s, (char**) NULL, 0); if (!errno) m |= M_Mod(mod_num); } if (strstr(value, "shift")) m |= M_Shift; if (strstr(value, "ctrl")) m |= M_Ctrl; if (strstr(value, "alt")) m |= M_Alt; if (strstr(value, "up")) m |= M_Release; return m; } static int button_name_to_num (const char *name) { /* All mouse-related resources must be named. The name is the mouse button number. */ if (!name) return -1; else if (strcasecmp (name, "left") == 0) return 1; else if (strcasecmp (name, "middle") == 0) return 2; else if (strcasecmp (name, "right") == 0) return 3; else if (strcasecmp (name, "up") == 0) return 4; else if (strcasecmp (name, "down") == 0) return 5; else if (strcasecmp (name, "scroll-left") == 0) return 6; else if (strcasecmp (name, "scroll-right") == 0) return 7; else return atoi (name); } void load_mouse_resource (const Resource *res) { int bi, mi, a; int action_count; #ifdef DEBUG_HID_RESOURCE fprintf(stderr, "note mouse resource:\n"); resource_dump (res); #endif button_count = res->c; button_nums = (int *)malloc(res->c * sizeof(int)); mod_count = (int *)malloc(res->c * sizeof(int)); action_count = 0; for (bi=0; bic; bi++) { if (res->v[bi].value) action_count++; if (res->v[bi].subres) action_count += res->v[bi].subres->c; } mods = (unsigned int *)malloc(action_count * sizeof(int)); actions = (Resource **)malloc(action_count * sizeof(Resource*)); a = 0; for (bi=0; bic; bi++) { int button_num = button_name_to_num(res->v[bi].name); if (button_num < 0) continue; button_nums[bi] = button_num; mod_count[bi] = 0; if (res->v[bi].value) { mods[a] = 0; actions[a++] = res_wrap (res->v[bi].value); mod_count[bi] = 1; } if (res->v[bi].subres) { Resource *m = res->v[bi].subres; mod_count[bi] += m->c; for (mi=0; mic; mi++, a++) { switch (resource_type (m->v[mi])) { case 1: /* subres only */ mods[a] = 0; actions[a] = m->v[mi].subres; break; case 10: /* value only */ mods[a] = 0; actions[a] = res_wrap (m->v[mi].value); break; case 101: /* name = subres */ mods[a] = parse_mods (m->v[mi].name); actions[a] = m->v[mi].subres; break; case 110: /* name = value */ mods[a] = parse_mods (m->v[mi].name); actions[a] = res_wrap (m->v[mi].value); break; } } } } } static Resource* find_best_action (int button, int start, unsigned mod_mask) { int i, j; int count = mod_count[button]; unsigned search_mask = mod_mask & ~M_Release; unsigned release_mask = mod_mask & M_Release; // look for exact mod match for (i=start; i=0; j--) if ((j & search_mask) == j) // this would work for (i=start; ic; i++) if (action->v[i].value) if (hid_parse_actions (action->v[i].value)) return; } pcb-4.3.0/src/hid/common/trackball.h0000664000175000017500000000626013773431044014152 00000000000000/* * (c) Copyright 1993, 1994, Silicon Graphics, Inc. * ALL RIGHTS RESERVED * Permission to use, copy, modify, and distribute this software for * any purpose and without fee is hereby granted, provided that the above * copyright notice appear in all copies and that both the copyright notice * and this permission notice appear in supporting documentation, and that * the name of Silicon Graphics, Inc. not be used in advertising * or publicity pertaining to distribution of the software without specific, * written prior permission. * * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN PAD_CONNECTION WITH THE * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE. * * US Government Users Restricted Rights * Use, duplication, or disclosure by the Government is subject to * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph * (c)(1)(ii) of the Rights in Technical Data and Computer Software * clause at DFARS 252.227-7013 and/or in similar or successor * clauses in the FAR or the DOD or NASA FAR Supplement. * Unpublished-- rights reserved under the copyright laws of the * United States. Contractor/manufacturer is Silicon Graphics, * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311. * * OpenGL(TM) is a trademark of Silicon Graphics, Inc. */ /* * trackball.h * A virtual trackball implementation * Written by Gavin Bell for Silicon Graphics, November 1988. */ /* * Pass the x and y coordinates of the last and current positions of * the mouse, scaled so they are from (-1.0 ... 1.0). * * The resulting rotation is returned as a quaternion rotation in the * first paramater. */ void trackball(float q[4], float p1x, float p1y, float p2x, float p2y); /* * Given two quaternions, add them together to get a third quaternion. * Adding quaternions to get a compound rotation is analagous to adding * translations to get a compound translation. When incrementally * adding rotations, the first argument here should be the new * rotation, the second and third the total rotation (which will be * over-written with the resulting new total rotation). */ void add_quats(float *q1, float *q2, float *dest); /* * A useful function, builds a rotation matrix in Matrix based on * given quaternion. */ void build_rotmatrix(float m[4][4], float q[4]); /* * This function computes a quaternion based on an axis (defined by * the given vector) and an angle about which to rotate. The angle is * expressed in radians. The result is put into the third argument. */ void axis_to_quat(float a[3], float phi, float q[4]); pcb-4.3.0/src/hid/common/extents.c0000664000175000017500000001053313773431044013676 00000000000000#ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "global.h" #include "data.h" #include "hid.h" #include "hid_draw.h" #include "../hidint.h" #include "hid/common/draw_helpers.h" #ifdef HAVE_LIBDMALLOC #include #endif static BoxType box; typedef struct hid_gc_struct { int width; } hid_gc_struct; static int extents_set_layer (const char *name, int group, int empty) { int idx = group; if (idx >= 0 && idx < max_group) { idx = PCB->LayerGroups.Entries[idx][0]; } if (idx >= 0 && idx < max_copper_layer + SILK_LAYER) return 1; if (idx < 0) { switch (SL_TYPE (idx)) { case SL_INVISIBLE: case SL_MASK: case SL_ASSY: return 0; case SL_SILK: case SL_PDRILL: case SL_UDRILL: return 1; } } return 0; } static hidGC extents_make_gc (void) { hidGC rv = (hidGC)malloc (sizeof (hid_gc_struct)); memset (rv, 0, sizeof (hid_gc_struct)); return rv; } static void extents_destroy_gc (hidGC gc) { free (gc); } static void extents_use_mask (enum mask_mode mode) { } static void extents_set_color (hidGC gc, const char *name) { } static void extents_set_line_cap (hidGC gc, EndCapStyle style) { } static void extents_set_line_width (hidGC gc, Coord width) { gc->width = width; } static void extents_set_draw_xor (hidGC gc, int xor_) { } #define PEX(x,w) if (box.X1 > (x)-(w)) box.X1 = (x)-(w); \ if (box.X2 < (x)+(w)) box.X2 = (x)+(w) #define PEY(y,w) if (box.Y1 > (y)-(w)) box.Y1 = (y)-(w); \ if (box.Y2 < (y)+(w)) box.Y2 = (y)+(w) static void extents_draw_line (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2) { PEX (x1, gc->width); PEY (y1, gc->width); PEX (x2, gc->width); PEY (y2, gc->width); } static void extents_draw_arc (hidGC gc, Coord cx, Coord cy, Coord width, Coord height, Angle start_angle, Angle end_angle) { /* Naive but good enough. */ PEX (cx, width + gc->width); PEY (cy, height + gc->width); } static void extents_draw_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2) { PEX (x1, gc->width); PEY (y1, gc->width); PEX (x2, gc->width); PEY (y2, gc->width); } static void extents_fill_circle (hidGC gc, Coord cx, Coord cy, Coord radius) { PEX (cx, radius); PEY (cy, radius); } static void extents_fill_polygon (hidGC gc, int n_coords, Coord *x, Coord *y) { int i; for (i = 0; i < n_coords; i++) { PEX (x[i], 0); PEY (y[i], 0); } } static void extents_fill_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2) { PEX (x1, 0); PEY (y1, 0); PEX (x2, 0); PEY (y2, 0); } static HID extents_hid; static HID_DRAW extents_graphics; void hid_extents_init (void) { static bool initialised = false; if (initialised) return; memset (&extents_hid, 0, sizeof (HID)); memset (&extents_graphics, 0, sizeof (HID_DRAW)); common_draw_helpers_init (&extents_graphics); extents_hid.struct_size = sizeof (HID); extents_hid.name = "extents-extents"; extents_hid.description = "used to calculate extents"; extents_hid.poly_before = 1; extents_hid.set_layer = extents_set_layer; extents_hid.graphics = &extents_graphics; extents_graphics.make_gc = extents_make_gc; extents_graphics.destroy_gc = extents_destroy_gc; extents_graphics.use_mask = extents_use_mask; extents_graphics.set_color = extents_set_color; extents_graphics.set_line_cap = extents_set_line_cap; extents_graphics.set_line_width = extents_set_line_width; extents_graphics.set_draw_xor = extents_set_draw_xor; extents_graphics.draw_line = extents_draw_line; extents_graphics.draw_arc = extents_draw_arc; extents_graphics.draw_rect = extents_draw_rect; extents_graphics.fill_circle = extents_fill_circle; extents_graphics.fill_polygon = extents_fill_polygon; extents_graphics.fill_rect = extents_fill_rect; initialised = true; } BoxType * hid_get_extents (void *item) { BoxType region; /* As this isn't a real "HID", we need to ensure we are initialised. */ hid_extents_init (); box.X1 = COORD_MAX; box.Y1 = COORD_MAX; box.X2 = -COORD_MAX - 1; box.Y2 = -COORD_MAX - 1; region.X1 = -COORD_MAX - 1; region.Y1 = -COORD_MAX - 1; region.X2 = COORD_MAX; region.Y2 = COORD_MAX; hid_expose_callback (&extents_hid, ®ion, item); return &box; } pcb-4.3.0/src/hid/batch/0000775000175000017500000000000014017001275011676 500000000000000pcb-4.3.0/src/hid/batch/batch.c0000664000175000017500000002145013773431044013056 00000000000000/*! * \file src/hid/batch/batch.c * * \brief This is a text-line "batch" HID, which exists for scripting * and non-GUI needs. * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 2006 DJ Delorie * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Contact addresses for paper mail and Email: * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * Thomas.Nau@rz.uni-ulm.de * *
*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "global.h" #include "crosshair.h" #include "hid.h" #include "data.h" #include "misc.h" #include "hid.h" #include "hid_draw.h" #include "../hidint.h" #include "pcb-printf.h" #include "hid/common/draw_helpers.h" #include "hid/common/hidnogui.h" #include "hid/common/actions.h" #include "hid/common/hidinit.h" #ifdef HAVE_LIBDMALLOC #include #endif typedef struct hid_gc_struct { int nothing_interesting_here; } hid_gc_struct; static HID_Attribute * batch_get_export_options (int *n_ret) { return 0; } /* ----------------------------------------------------------------------------- */ static char *prompt = "pcb"; static int nop (int argc, char **argv, Coord x, Coord y) { return 0; } static int PCBChanged (int argc, char **argv, Coord x, Coord y) { if (PCB && PCB->Filename) { prompt = strrchr(PCB->Filename, '/'); if (prompt) prompt ++; else prompt = PCB->Filename; } else prompt = "no-board"; crosshair_update_range(); return 0; } static int help (int argc, char **argv, Coord x, Coord y) { print_actions (); return 0; } static int info (int argc, char **argv, Coord x, Coord y) { int i, j; int top_group, bottom_group; if (!PCB || !PCB->Data || !PCB->Filename) { printf("No PCB loaded.\n"); return 0; } printf("Filename: %s\n", PCB->Filename); pcb_printf("Size: %ml x %ml mils, %mm x %mm mm\n", PCB->MaxWidth, PCB->MaxHeight, PCB->MaxWidth, PCB->MaxHeight); top_group = GetLayerGroupNumberBySide (TOP_SIDE); bottom_group = GetLayerGroupNumberBySide (BOTTOM_SIDE); for (i=0; iData->Layer[i].Name); } return 0; } HID_Action batch_action_list[] = { {"PCBChanged", 0, PCBChanged }, {"RouteStylesChanged", 0, nop }, {"NetlistChanged", 0, nop }, {"LayersChanged", 0, nop }, {"LibraryChanged", 0, nop }, {"Busy", 0, nop }, {"Help", 0, help }, {"Info", 0, info } }; REGISTER_ACTIONS (batch_action_list) /* ----------------------------------------------------------------------------- */ static void batch_do_export (HID_Attr_Val * options) { int interactive; char line[1000]; if (isatty (0)) interactive = 1; else interactive = 0; if (interactive) { printf("Entering %s version %s batch mode.\n", PACKAGE, VERSION); printf("See http://pcb.geda-project.org for project information\n"); } while (1) { if (interactive) { printf("%s> ", prompt); fflush(stdout); } if (fgets(line, sizeof(line)-1, stdin) == NULL) return; hid_parse_command (line); } } static void batch_parse_arguments (int *argc, char ***argv) { hid_parse_command_line (argc, argv); } static void batch_invalidate_lr (Coord l, Coord r, Coord t, Coord b) { } static void batch_invalidate_all (void) { } static int batch_set_layer (const char *name, int idx, int empty) { return 0; } static hidGC batch_make_gc (void) { return 0; } static void batch_destroy_gc (hidGC gc) { } static void batch_use_mask (enum mask_mode mode) { } static void batch_set_color (hidGC gc, const char *name) { } static void batch_set_line_cap (hidGC gc, EndCapStyle style) { } static void batch_set_line_width (hidGC gc, Coord width) { } static void batch_set_draw_xor (hidGC gc, int xor_set) { } static void batch_draw_line (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2) { } static void batch_draw_arc (hidGC gc, Coord cx, Coord cy, Coord width, Coord height, Angle start_angle, Angle end_angle) { } static void batch_draw_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2) { } static void batch_fill_circle (hidGC gc, Coord cx, Coord cy, Coord radius) { } static void batch_fill_polygon (hidGC gc, int n_coords, Coord *x, Coord *y) { } static void batch_fill_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2) { } static void batch_calibrate (double xval, double yval) { } static int batch_shift_is_pressed (void) { return 0; } static int batch_control_is_pressed (void) { return 0; } static int batch_mod1_is_pressed (void) { return 0; } static void batch_get_coords (const char *msg, Coord *x, Coord *y) { } static void batch_set_crosshair (int x, int y, int action) { } static hidval batch_add_timer (void (*func) (hidval user_data), unsigned long milliseconds, hidval user_data) { hidval rv; rv.lval = 0; return rv; } static void batch_stop_timer (hidval timer) { } hidval batch_watch_file (int fd, unsigned int condition, void (*func) (hidval watch, int fd, unsigned int condition, hidval user_data), hidval user_data) { hidval ret; ret.ptr = NULL; return ret; } void batch_unwatch_file (hidval data) { } static hidval batch_add_block_hook (void (*func) (hidval data), hidval user_data ) { hidval ret; ret.ptr = NULL; return ret; } static void batch_stop_block_hook (hidval mlpoll) { } static int batch_attribute_dialog (HID_Attribute * attrs_, int n_attrs_, HID_Attr_Val * results_, const char *title_, const char *descr_) { return 0; } static void batch_show_item (void *item) { } #include "dolists.h" static HID batch_hid; static HID_DRAW batch_graphics; void hid_batch_init () { memset (&batch_hid, 0, sizeof (HID)); memset (&batch_graphics, 0, sizeof (HID_DRAW)); common_nogui_init (&batch_hid); common_draw_helpers_init (&batch_graphics); batch_hid.struct_size = sizeof (HID); batch_hid.name = "batch"; batch_hid.description = "Batch-mode GUI for non-interactive use."; batch_hid.gui = 1; batch_hid.get_export_options = batch_get_export_options; batch_hid.do_export = batch_do_export; batch_hid.parse_arguments = batch_parse_arguments; batch_hid.invalidate_lr = batch_invalidate_lr; batch_hid.invalidate_all = batch_invalidate_all; batch_hid.set_layer = batch_set_layer; batch_hid.calibrate = batch_calibrate; batch_hid.shift_is_pressed = batch_shift_is_pressed; batch_hid.control_is_pressed = batch_control_is_pressed; batch_hid.mod1_is_pressed = batch_mod1_is_pressed; batch_hid.get_coords = batch_get_coords; batch_hid.set_crosshair = batch_set_crosshair; batch_hid.add_timer = batch_add_timer; batch_hid.stop_timer = batch_stop_timer; batch_hid.watch_file = batch_watch_file; batch_hid.unwatch_file = batch_unwatch_file; batch_hid.add_block_hook = batch_add_block_hook; batch_hid.stop_block_hook = batch_stop_block_hook; batch_hid.attribute_dialog = batch_attribute_dialog; batch_hid.show_item = batch_show_item; batch_hid.graphics = &batch_graphics; batch_graphics.make_gc = batch_make_gc; batch_graphics.destroy_gc = batch_destroy_gc; batch_graphics.use_mask = batch_use_mask; batch_graphics.set_color = batch_set_color; batch_graphics.set_line_cap = batch_set_line_cap; batch_graphics.set_line_width = batch_set_line_width; batch_graphics.set_draw_xor = batch_set_draw_xor; batch_graphics.draw_line = batch_draw_line; batch_graphics.draw_arc = batch_draw_arc; batch_graphics.draw_rect = batch_draw_rect; batch_graphics.fill_circle = batch_fill_circle; batch_graphics.fill_polygon = batch_fill_polygon; batch_graphics.fill_rect = batch_fill_rect; hid_register_hid (&batch_hid); #include "batch_lists.h" } pcb-4.3.0/src/hid/batch/hid.conf0000664000175000017500000000001113773431044013232 00000000000000type=gui pcb-4.3.0/src/hid/batch/batch_lists.h0000664000175000017500000000004514017001022014253 00000000000000REGISTER_ACTIONS (batch_action_list) pcb-4.3.0/src/hid/png/0000775000175000017500000000000014017001275011401 500000000000000pcb-4.3.0/src/hid/png/png_lists.h0000664000175000017500000000005114017001022013456 00000000000000REGISTER_ATTRIBUTES (png_attribute_list) pcb-4.3.0/src/hid/png/hid.conf0000664000175000017500000000001413773431044012740 00000000000000type=export pcb-4.3.0/src/hid/png/png.h0000664000175000017500000000200613773431044012265 00000000000000/*! * \file src/hid/png/png.h * * \brief Header file for the PNG HID exporter. * * Heavily based on the ps HID written by DJ Delorie. * *
* * PCB, interactive printed circuit board design. * * Copyright (C) 2006 Dan McMahill. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ extern void png_hid_export_to_file (FILE *, HID_Attr_Val *); pcb-4.3.0/src/hid/png/png.c0000664000175000017500000013303613773431044012270 00000000000000/*! * \file src/hid/png/png.c * * \brief PNG HID exporter. * * Heavily based on the ps HID written by DJ Delorie. * *
* * PCB, interactive printed circuit board design. * * Copyright (C) 2006 Dan McMahill. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include "global.h" #include "data.h" #include "error.h" #include "misc.h" #include "hid.h" #include "hid_draw.h" #include "../hidint.h" #include "hid/common/hidnogui.h" #include "hid/common/draw_helpers.h" #include "png.h" /* the gd library which makes this all so easy */ #include #include "hid/common/hidinit.h" #ifdef HAVE_LIBDMALLOC #include #endif #define CRASH fprintf(stderr, "HID error: pcb called unimplemented PNG function %s.\n", __FUNCTION__); abort() static HID png_hid; static HID_DRAW png_graphics; static void *color_cache = NULL; static void *brush_cache = NULL; static double bloat = 0; static double scale = 1; static Coord x_shift = 0; static Coord y_shift = 0; static int show_bottom_side; #define SCALE(w) ((int)round((w)/scale)) #define SCALE_X(x) ((int)round(((x) - x_shift)/scale)) #define SCALE_Y(y) ((int)round(((show_bottom_side ? (PCB->MaxHeight-(y)) : (y)) - y_shift)/scale)) #define SWAP_IF_SOLDER(a,b) do { Coord c; if (show_bottom_side) { c=a; a=b; b=c; }} while (0) /* Used to detect non-trivial outlines */ #define NOT_EDGE_X(x) ((x) != 0 && (x) != PCB->MaxWidth) #define NOT_EDGE_Y(y) ((y) != 0 && (y) != PCB->MaxHeight) #define NOT_EDGE(x,y) (NOT_EDGE_X(x) || NOT_EDGE_Y(y)) static void png_fill_circle (hidGC gc, Coord cx, Coord cy, Coord radius); /* The result of a failed gdImageColorAllocate() call */ #define BADC -1 typedef struct color_struct { /* the descriptor used by the gd library */ int c; /* so I can figure out what rgb value c refers to */ unsigned int r, g, b, a; } color_struct; typedef struct hid_gc_struct { HID *me_pointer; EndCapStyle cap; int width; unsigned char r, g, b; color_struct *color; gdImagePtr brush; int is_erase; } hid_gc_struct; static color_struct *black = NULL, *white = NULL; static gdImagePtr im = NULL, master_im, mask_im = NULL; static FILE *f = 0; static int linewidth = -1; static int lastgroup = -1; static gdImagePtr lastbrush = (gdImagePtr)((void *) -1); static int lastcap = -1; static int print_group[MAX_GROUP]; static int print_layer[MAX_ALL_LAYER]; /* For photo-mode we need the following layers as monochrome masks: top soldermask top silk copper layers drill */ #define PHOTO_FLIP_X 1 #define PHOTO_FLIP_Y 2 static int photo_mode, photo_flip; static gdImagePtr photo_copper[MAX_ALL_LAYER]; static gdImagePtr photo_silk, photo_mask, photo_drill, *photo_im; static gdImagePtr photo_outline; static int photo_groups[MAX_ALL_LAYER], photo_ngroups; static int photo_has_inners; static int doing_outline, have_outline; #define FMT_gif "GIF" #define FMT_jpg "JPEG" #define FMT_png "PNG" /* If this table has no elements in it, then we have no reason to register this HID and will refrain from doing so at the end of this file. */ #undef HAVE_SOME_FORMAT static const char *filetypes[] = { #ifdef HAVE_GDIMAGEPNG FMT_png, #define HAVE_SOME_FORMAT 1 #endif #ifdef HAVE_GDIMAGEGIF FMT_gif, #define HAVE_SOME_FORMAT 1 #endif #ifdef HAVE_GDIMAGEJPEG FMT_jpg, #define HAVE_SOME_FORMAT 1 #endif NULL }; static const char *mask_colour_names[] = { "green", "red", "blue", "purple", "black", "white", NULL }; // These values were arrived at through trial and error. // One potential improvement (especially for white) is // to use separate color_structs for the multiplication // and addition parts of the mask math. static const color_struct mask_colours[] = { #define MASK_COLOUR_GREEN 0 {.r = 60, .g = 160, .b = 60}, #define MASK_COLOUR_RED 1 {.r = 140, .g = 25, .b = 25}, #define MASK_COLOUR_BLUE 2 {.r = 50, .g = 50, .b = 160}, #define MASK_COLOUR_PURPLE 3 {.r = 60, .g = 20, .b = 70}, #define MASK_COLOUR_BLACK 4 {.r = 20, .g = 20, .b = 20}, #define MASK_COLOUR_WHITE 5 {.r = 167, .g = 230, .b = 162}, // <-- needs improvement over FR4 {} }; static const char *plating_type_names[] = { #define PLATING_TIN 0 "tinned", #define PLATING_GOLD 1 "gold", #define PLATING_SILVER 2 "silver", #define PLATING_COPPER 3 "copper", NULL }; static const char *silk_colour_names[] = { "white", "black", "yellow", NULL }; static const color_struct silk_colours[] = { #define SILK_COLOUR_WHITE 0 {.r = 224, .g = 224, .b = 224}, #define SILK_COLOUR_BLACK 1 {.r = 14, .g = 14, .b = 14}, #define SILK_COLOUR_YELLOW 2 {.r = 185, .g = 185, .b = 10}, {} }; static const color_struct silk_top_shadow = {.r = 21, .g = 21, .b = 21}; static const color_struct silk_bottom_shadow = {.r = 14, .g = 14, .b = 14}; HID_Attribute png_attribute_list[] = { /* other HIDs expect this to be first. */ /* %start-doc options "93 PNG Options" @ftable @code @item --outfile Name of the file to be exported to. Parameter @code{} can include a path. @end ftable %end-doc */ {"outfile", "Graphics output file", HID_String, 0, 0, {0, 0, 0}, 0, 0}, #define HA_pngfile 0 /* %start-doc options "93 PNG Options" @ftable @code @item --dpi Scale factor in pixels/inch. Set to 0 to scale to size specified in the layout. @end ftable %end-doc */ {"dpi", "Scale factor (pixels/inch). 0 to scale to specified size", HID_Integer, 0, 10000, {100, 0, 0}, 0, 0}, #define HA_dpi 1 /* %start-doc options "93 PNG Options" @ftable @code @item --x-max Width of the png image in pixels. No constraint, when set to 0. @end ftable %end-doc */ {"x-max", "Maximum width (pixels). 0 to not constrain", HID_Integer, 0, 10000, {0, 0, 0}, 0, 0}, #define HA_xmax 2 /* %start-doc options "93 PNG Options" @ftable @code @item --y-max Height of the png output in pixels. No constraint, when set to 0. @end ftable %end-doc */ {"y-max", "Maximum height (pixels). 0 to not constrain", HID_Integer, 0, 10000, {0, 0, 0}, 0, 0}, #define HA_ymax 3 /* %start-doc options "93 PNG Options" @ftable @code @item --xy-max Maximum width and height of the PNG output in pixels. No constraint, when set to 0. @end ftable %end-doc */ {"xy-max", "Maximum width and height (pixels). 0 to not constrain", HID_Integer, 0, 10000, {0, 0, 0}, 0, 0}, #define HA_xymax 4 /* %start-doc options "93 PNG Options" @ftable @code @item --screen-layer-order Export layers in the order shown on screen. @end ftable %end-doc */ {"screen-layer-order", "Export layers in the order shown on screen", HID_Boolean, 0, 0, {0, 0, 0}, 0, 0}, #define HA_as_shown 5 /* %start-doc options "93 PNG Options" @ftable @code @item --monochrome Convert output to monochrome. @end ftable %end-doc */ {"monochrome", "Convert to monochrome", HID_Boolean, 0, 0, {0, 0, 0}, 0, 0}, #define HA_mono 6 /* %start-doc options "93 PNG Options" @ftable @code @item --only-visible Limit the bounds of the exported PNG image to the visible items. @end ftable %end-doc */ {"only-visible", "Limit the bounds of the PNG image to the visible items", HID_Boolean, 0, 0, {0, 0, 0}, 0, 0}, #define HA_only_visible 7 /* %start-doc options "93 PNG Options" @ftable @code @item --use-alpha Make the background and any holes transparent. @end ftable %end-doc */ {"use-alpha", "Make the background and any holes transparent", HID_Boolean, 0, 0, {0, 0, 0}, 0, 0}, #define HA_use_alpha 8 /* %start-doc options "93 PNG Options" @ftable @code @item --fill-holes Drill holes in pins/pads are filled, not hollow. @end ftable %end-doc */ {"fill-holes", "Drill holes in pins/pads are filled, not hollow", HID_Boolean, 0, 0, {0, 0, 0}, 0, 0}, #define HA_fill_holes 9 /* %start-doc options "93 PNG Options" @ftable @code @item --format File format to be exported. Parameter @code{} can be @samp{PNG}, @samp{GIF}, or @samp{JPEG}. @end ftable %end-doc */ {"format", "Export file format", HID_Enum, 0, 0, {0, 0, 0}, filetypes, 0}, #define HA_filetype 10 /* %start-doc options "93 PNG Options" @ftable @code @item --png-bloat Amount of extra thickness to add to traces, pads, or pin edges. The parameter @samp{} is a number, appended by a dimension @samp{mm}, @samp{mil}, or @samp{pix}. If no dimension is given, the default dimension is 1/100 mil. @end ftable %end-doc */ {"png-bloat", "Amount (in/mm/mil/pix) to add to trace/pad/pin edges (1 = 1/100 mil)", HID_String, 0, 0, {0, 0, 0}, 0, 0}, #define HA_bloat 11 /* %start-doc options "93 PNG Options" @ftable @code @cindex photo-mode @item --photo-mode Export a photo realistic image of the layout. @end ftable %end-doc */ {"photo-mode", "Photo-realistic export mode", HID_Boolean, 0, 0, {0, 0, 0}, 0, 0}, #define HA_photo_mode 12 /* %start-doc options "93 PNG Options" @ftable @code @item --photo-flip-x In photo-realistic mode, export the reverse side of the layout. Left-right flip. @end ftable %end-doc */ {"photo-flip-x", "Show reverse side of the board, left-right flip", HID_Boolean, 0, 0, {0, 0, 0}, 0, 0}, #define HA_photo_flip_x 13 /* %start-doc options "93 PNG Options" @ftable @code @item --photo-flip-y In photo-realistic mode, export the reverse side of the layout. Up-down flip. @end ftable %end-doc */ {"photo-flip-y", "Show reverse side of the board, up-down flip", HID_Boolean, 0, 0, {0, 0, 0}, 0, 0}, #define HA_photo_flip_y 14 /* %start-doc options "93 PNG Options" @ftable @code @cindex photo-mask-colour @item --photo-mask-colour In photo-realistic mode, export the solder mask as this colour. Parameter @code{} can be @samp{green}, @samp{red}, @samp{blue}, @samp{purple}, @samp{black}, or @samp{white}. @end ftable %end-doc */ {"photo-mask-colour", "Colour for the exported colour mask", HID_Enum, 0, 0, {0, 0, 0}, mask_colour_names, 0}, #define HA_photo_mask_colour 15 /* %start-doc options "93 PNG Options" @ftable @code @cindex photo-plating @item --photo-plating In photo-realistic mode, export the exposed copper as though it has this type of plating. Parameter @code{} can be @samp{tinned}, @samp{gold}, @samp{silver}, or @samp{copper}. @end ftable %end-doc */ {"photo-plating", "Type of plating applied to exposed copper in photo-mode", HID_Enum, 0, 0, {0, 0, 0}, plating_type_names, 0}, #define HA_photo_plating 16 /* %start-doc options "93 PNG Options" @ftable @code @cindex photo-silk-colour @item --photo-silk-colour In photo-realistic mode, export the silk screen as this colour. Parameter @code{} can be @samp{white}, @samp{black}, or @samp{yellow}. @end ftable %end-doc */ {"photo-silk-colour", "Colour for the exported colour mask", HID_Enum, 0, 0, {0, 0, 0}, silk_colour_names, 0}, #define HA_photo_silk_colour 17 {"ben-mode", ATTR_UNDOCUMENTED, HID_Boolean, 0, 0, {0, 0, 0}, 0, 0}, #define HA_ben_mode 12 {"ben-flip-x", ATTR_UNDOCUMENTED, HID_Boolean, 0, 0, {0, 0, 0}, 0, 0}, #define HA_ben_flip_x 13 {"ben-flip-y", ATTR_UNDOCUMENTED, HID_Boolean, 0, 0, {0, 0, 0}, 0, 0}, #define HA_ben_flip_y 14 }; #define NUM_OPTIONS (sizeof(png_attribute_list)/sizeof(png_attribute_list[0])) REGISTER_ATTRIBUTES (png_attribute_list) static HID_Attr_Val png_values[NUM_OPTIONS]; static const char *get_file_suffix(void) { const char *result = NULL; const char *fmt; fmt = filetypes[png_attribute_list[HA_filetype].default_val.int_value]; if (fmt == NULL) ; /* Do nothing */ else if (strcmp (fmt, FMT_gif) == 0) result=".gif"; else if (strcmp (fmt, FMT_jpg) == 0) result=".jpg"; else if (strcmp (fmt, FMT_png) == 0) result=".png"; if (result == NULL) { fprintf (stderr, "Error: Invalid graphic file format\n"); result=".???"; } return result; } static HID_Attribute * png_get_export_options (int *n) { static char *last_made_filename = 0; const char *suffix = get_file_suffix(); if (PCB) derive_default_filename (PCB->Filename, &png_attribute_list[HA_pngfile], suffix, &last_made_filename); if (n) *n = NUM_OPTIONS; return png_attribute_list; } static int top_group, bottom_group; static int layer_stack_sort (const void *va, const void *vb) { int a_layer = *(int *) va; int b_layer = *(int *) vb; int a_group = GetLayerGroupNumberByNumber (a_layer); int b_group = GetLayerGroupNumberByNumber (b_layer); int aside = (a_group == bottom_group ? 0 : a_group == top_group ? 2 : 1); int bside = (b_group == bottom_group ? 0 : b_group == top_group ? 2 : 1); if (bside != aside) return bside - aside; if (b_group != a_group) return b_group - a_group; return b_layer - a_layer; } static const char *filename; static BoxType *bounds; static int in_mono, as_shown, fill_holes; static void parse_bloat (const char *str) { UnitList extra_units = { { "pix", scale, 0 }, { "px", scale, 0 }, { "", 0, 0 } }; if (str == NULL) return; bloat = GetValueEx (str, NULL, NULL, extra_units, ""); } void png_hid_export_to_file (FILE * the_file, HID_Attr_Val * options) { int i; static int saved_layer_stack[MAX_LAYER]; int saved_show_bottom_side; BoxType region; FlagType save_flags; f = the_file; region.X1 = 0; region.Y1 = 0; region.X2 = PCB->MaxWidth; region.Y2 = PCB->MaxHeight; if (options[HA_only_visible].int_value) bounds = GetDataBoundingBox (PCB->Data); else bounds = ®ion; memset (print_group, 0, sizeof (print_group)); memset (print_layer, 0, sizeof (print_layer)); for (i = 0; i < max_copper_layer; i++) { LayerType *layer = PCB->Data->Layer + i; if (layer->LineN || layer->TextN || layer->ArcN || layer->PolygonN) print_group[GetLayerGroupNumberByNumber (i)] = 1; } print_group[GetLayerGroupNumberBySide (BOTTOM_SIDE)] = 1; print_group[GetLayerGroupNumberBySide (TOP_SIDE)] = 1; for (i = 0; i < max_copper_layer; i++) if (print_group[GetLayerGroupNumberByNumber (i)]) print_layer[i] = 1; memcpy (saved_layer_stack, LayerStack, sizeof (LayerStack)); save_flags = PCB->Flags; saved_show_bottom_side = Settings.ShowBottomSide; as_shown = options[HA_as_shown].int_value; fill_holes = options[HA_fill_holes].int_value; if (!options[HA_as_shown].int_value) { CLEAR_FLAG (SHOWMASKFLAG, PCB); Settings.ShowBottomSide = 0; top_group = GetLayerGroupNumberBySide (TOP_SIDE); bottom_group = GetLayerGroupNumberBySide (BOTTOM_SIDE); qsort (LayerStack, max_copper_layer, sizeof (LayerStack[0]), layer_stack_sort); CLEAR_FLAG(THINDRAWFLAG, PCB); CLEAR_FLAG(THINDRAWPOLYFLAG, PCB); if (photo_mode) { int i, n=0; SET_FLAG (SHOWMASKFLAG, PCB); photo_has_inners = 0; if (top_group < bottom_group) for (i = top_group; i <= bottom_group; i++) { photo_groups[n++] = i; if (i != top_group && i != bottom_group && ! IsLayerGroupEmpty (i)) photo_has_inners = 1; } else for (i = top_group; i >= bottom_group; i--) { photo_groups[n++] = i; if (i != top_group && i != bottom_group && ! IsLayerGroupEmpty (i)) photo_has_inners = 1; } if (!photo_has_inners) { photo_groups[1] = photo_groups[n - 1]; n = 2; } photo_ngroups = n; if (photo_flip) { for (i=0, n=photo_ngroups-1; iFlags = save_flags; Settings.ShowBottomSide = saved_show_bottom_side; } /*! * \brief Clip RGB values. * * Red, Green and Blue values are clipped to a maximum value of 255. */ static void clip (color_struct *dest, color_struct *source) { #define CLIP(var) \ dest->var = source->var; \ if (dest->var > 255) dest->var = 255; \ if (dest->var < 0) dest->var = 0; CLIP (r); CLIP (g); CLIP (b); #undef CLIP } /*! * \brief Blend two colors. * * \param a color. * \param b color. * \param a_amount weighing value for color \c a. * * The weighing value for color \c b is the complement of \c a_amount * ( 1 - a_amount). */ static void blend (color_struct *dest, double a_amount, color_struct *a, color_struct *b) { dest->r = a->r * a_amount + b->r * (1 - a_amount); dest->g = a->g * a_amount + b->g * (1 - a_amount); dest->b = a->b * a_amount + b->b * (1 - a_amount); } /*! * \brief Multiply two colors. */ static void multiply (color_struct *dest, color_struct *a, color_struct *b) { dest->r = (a->r * b->r) / 255; dest->g = (a->g * b->g) / 255; dest->b = (a->b * b->b) / 255; } /*! * \brief Add two colors. * * \param a color. * \param b color. * \param a_amount weighing value for color \c a. * \param b_amount weighing value for color \c b. * * The result is clipped. */ static void add (color_struct *dest, double a_amount, const color_struct *a, double b_amount, const color_struct *b) { dest->r = a->r * a_amount + b->r * b_amount; dest->g = a->g * a_amount + b->g * b_amount; dest->b = a->b * a_amount + b->b * b_amount; clip (dest, dest); } /*! * \brief Subtract two colors. * * \param a color. * \param b color. * \param a_amount weighing value for color \c a. * \param b_amount weighing value for color \c b. * * The result is clipped. */ static void subtract (color_struct *dest, double a_amount, const color_struct *a, double b_amount, const color_struct *b) { dest->r = a->r * a_amount - b->r * b_amount; dest->g = a->g * a_amount - b->g * b_amount; dest->b = a->b * a_amount - b->b * b_amount; clip (dest, dest); } /*! * \brief Store RGB values in a color struct. * * \param dest pointer to a color struct. * \param r Red value. * \param g Green value. * \param b Blue value. */ static void rgb (color_struct *dest, int r, int g, int b) { dest->r = r; dest->g = g; dest->b = b; } static int smshadows[3][3] = { { 1, 20, 1 }, { 10, 0, -10 }, { -1, -20, -1 }, }; static int shadows[5][5] = { { 1, 1, 1, 1, -1 }, { 1, 1, 1, -1, -1 }, { 1, 1, 0, -1, -1 }, { 1, -1, -1, -1, -1 }, { -1, -1, -1, -1, -1 }, }; /* black and white are 0 and 1 */ #define TOP_SHADOW 2 #define BOTTOM_SHADOW 3 static void ts_bs (gdImagePtr im) { int x, y, sx, sy, si; for (x=0; x 1) gdImageSetPixel (im, x, y, TOP_SHADOW); else if (si < -1) gdImageSetPixel (im, x, y, BOTTOM_SHADOW); } } } static void ts_bs_sm (gdImagePtr im) { int x, y, sx, sy, si; for (x=0; x 1) gdImageSetPixel (im, x, y, TOP_SHADOW); else if (si < -1) gdImageSetPixel (im, x, y, BOTTOM_SHADOW); } } } static void png_do_export (HID_Attr_Val * options) { int save_ons[MAX_ALL_LAYER]; int i; BoxType *bbox; Coord w, h; Coord xmax, ymax; int dpi; const char *fmt; bool format_error = false; if (color_cache) { free (color_cache); color_cache = NULL; } if (brush_cache) { free (brush_cache); brush_cache = NULL; } if (!options) { png_get_export_options (0); for (i = 0; i < NUM_OPTIONS; i++) png_values[i] = png_attribute_list[i].default_val; options = png_values; } if (options[HA_photo_mode].int_value || options[HA_ben_mode].int_value) { photo_mode = 1; options[HA_mono].int_value = 1; options[HA_as_shown].int_value = 0; memset (photo_copper, 0, sizeof(photo_copper)); photo_silk = photo_mask = photo_drill = 0; photo_outline = 0; if (options[HA_photo_flip_x].int_value || options[HA_ben_flip_x].int_value) photo_flip = PHOTO_FLIP_X; else if (options[HA_photo_flip_y].int_value || options[HA_ben_flip_y].int_value) photo_flip = PHOTO_FLIP_Y; else photo_flip = 0; } else photo_mode = 0; filename = options[HA_pngfile].str_value; if (!filename) filename = "pcb-out.png"; /* figure out width and height of the board */ if (options[HA_only_visible].int_value) { bbox = GetDataBoundingBox (PCB->Data); if (bbox == NULL) { fprintf (stderr, _("ERROR: Unable to determine bounding box limits\n")); fprintf (stderr, _("ERROR: Does the file contain any data?\n")); return; } x_shift = bbox->X1; y_shift = bbox->Y1; h = bbox->Y2 - bbox->Y1; w = bbox->X2 - bbox->X1; } else { x_shift = 0; y_shift = 0; h = PCB->MaxHeight; w = PCB->MaxWidth; } /* * figure out the scale factor we need to make the image * fit in our specified PNG file size */ xmax = ymax = dpi = 0; if (options[HA_dpi].int_value != 0) { dpi = options[HA_dpi].int_value; if (dpi < 0) { fprintf (stderr, "ERROR: dpi may not be < 0\n"); return; } } if (options[HA_xmax].int_value > 0) { xmax = options[HA_xmax].int_value; dpi = 0; } if (options[HA_ymax].int_value > 0) { ymax = options[HA_ymax].int_value; dpi = 0; } if (options[HA_xymax].int_value > 0) { dpi = 0; if (options[HA_xymax].int_value < xmax || xmax == 0) xmax = options[HA_xymax].int_value; if (options[HA_xymax].int_value < ymax || ymax == 0) ymax = options[HA_xymax].int_value; } if (xmax < 0 || ymax < 0) { fprintf (stderr, "ERROR: xmax and ymax may not be < 0\n"); return; } if (dpi > 0) { /* * a scale of 1 means 1 pixel is 1 inch * a scale of 10 means 1 pixel is 10 inches */ scale = round(INCH_TO_COORD(1) / (double) dpi); w = w / scale; h = h / scale; } else if( xmax == 0 && ymax == 0) { fprintf(stderr, "ERROR: You may not set both xmax, ymax," "and xy-max to zero\n"); return; } else { if (ymax == 0 || ( (xmax > 0) && ((w / xmax) > (h / ymax)) ) ) { scale = w / xmax; h = h / scale; w = xmax; } else { scale = h / ymax; w = w / scale; h = ymax; } } im = gdImageCreate (w, h); if (im == NULL) { Message ("%s(): gdImageCreate(%d, %d) returned NULL. Aborting export.\n", __FUNCTION__, w, h); return; } master_im = im; parse_bloat (options[HA_bloat].str_value); /* * Allocate white and black -- the first color allocated * becomes the background color */ white = (color_struct *) malloc (sizeof (color_struct)); white->r = white->g = white->b = 255; if (options[HA_use_alpha].int_value) white->a = 127; else white->a = 0; white->c = gdImageColorAllocateAlpha (im, white->r, white->g, white->b, white->a); if (white->c == BADC) { Message ("%s(): gdImageColorAllocateAlpha() returned NULL. Aborting export.\n", __FUNCTION__); return; } gdImageFilledRectangle (im, 0, 0, gdImageSX (im), gdImageSY (im), white->c); black = (color_struct *) malloc (sizeof (color_struct)); black->r = black->g = black->b = black->a = 0; black->c = gdImageColorAllocate (im, black->r, black->g, black->b); if (black->c == BADC) { Message ("%s(): gdImageColorAllocateAlpha() returned NULL. Aborting export.\n", __FUNCTION__); return; } f = fopen (filename, "wb"); if (!f) { perror (filename); return; } if (!options[HA_as_shown].int_value) hid_save_and_show_layer_ons (save_ons); png_hid_export_to_file (f, options); if (!options[HA_as_shown].int_value) hid_restore_layer_ons (save_ons); if (photo_mode) { int x, y; color_struct white, black, fr4; rgb (&white, 255, 255, 255); rgb (&black, 0, 0, 0); rgb (&fr4, 70, 70, 70); im = master_im; if (photo_copper[photo_groups[0]]) ts_bs (photo_copper[photo_groups[0]]); if (photo_silk) ts_bs (photo_silk); if (photo_mask) ts_bs_sm (photo_mask); if (photo_outline && have_outline) { int black=gdImageColorResolve(photo_outline, 0x00, 0x00, 0x00); // go all the way around the image, trying to fill the outline for (x=0; x= 0 && group < max_group) ? PCB->LayerGroups.Entries[group][0] : group; if (name == 0) name = PCB->Data->Layer[idx].Name; doing_outline = 0; if (idx >= 0 && idx < max_copper_layer && !print_layer[idx]) return 0; if (SL_TYPE (idx) == SL_ASSY || SL_TYPE (idx) == SL_FAB) return 0; if (strcmp (name, "invisible") == 0) return 0; is_drill = (SL_TYPE (idx) == SL_PDRILL || SL_TYPE (idx) == SL_UDRILL); is_mask = (SL_TYPE (idx) == SL_MASK); is_copper = (SL_TYPE (idx) == 0); if (is_drill && fill_holes) return 0; if (SL_TYPE (idx) == SL_PASTE) return 0; if (photo_mode) { switch (idx) { case SL (SILK, TOP): if (photo_flip) return 0; photo_im = &photo_silk; break; case SL (SILK, BOTTOM): if (!photo_flip) return 0; photo_im = &photo_silk; break; case SL (MASK, TOP): if (photo_flip) return 0; photo_im = &photo_mask; break; case SL (MASK, BOTTOM): if (!photo_flip) return 0; photo_im = &photo_mask; break; case SL (PDRILL, 0): case SL (UDRILL, 0): photo_im = &photo_drill; break; default: if (idx < 0) return 0; if (strcmp (name, "outline") == 0) { doing_outline = 1; have_outline = 0; photo_im = &photo_outline; } else photo_im = photo_copper + group; break; } if (! *photo_im) { static color_struct *black = NULL, *white = NULL; *photo_im = gdImageCreate (gdImageSX (im), gdImageSY (im)); if (photo_im == NULL) { Message ("%s(): gdImageCreate(%d, %d) returned NULL. Aborting export.\n", __FUNCTION__, gdImageSX (im), gdImageSY (im)); return 0; } white = (color_struct *) malloc (sizeof (color_struct)); white->r = white->g = white->b = 255; white->a = 0; white->c = gdImageColorAllocate (*photo_im, white->r, white->g, white->b); if (white->c == BADC) { Message ("%s(): gdImageColorAllocate() returned NULL. Aborting export.\n", __FUNCTION__); return 0; } black = (color_struct *) malloc (sizeof (color_struct)); black->r = black->g = black->b = black->a = 0; black->c = gdImageColorAllocate (*photo_im, black->r, black->g, black->b); if (black->c == BADC) { Message ("%s(): gdImageColorAllocate() returned NULL. Aborting export.\n", __FUNCTION__); return 0; } if (idx == SL (PDRILL, 0) || idx == SL (UDRILL, 0)) gdImageFilledRectangle (*photo_im, 0, 0, gdImageSX (im), gdImageSY (im), black->c); } im = *photo_im; return 1; } if (as_shown) { switch (idx) { case SL (SILK, TOP): case SL (SILK, BOTTOM): if (SL_MYSIDE (idx)) return PCB->ElementOn; return 0; case SL (MASK, TOP): case SL (MASK, BOTTOM): return TEST_FLAG (SHOWMASKFLAG, PCB) && SL_MYSIDE (idx); } } else { if (is_mask) return 0; switch (idx) { case SL (SILK, TOP): return 1; case SL (SILK, BOTTOM): return 0; } } return 1; } static hidGC png_make_gc (void) { hidGC rv = (hidGC) malloc (sizeof (hid_gc_struct)); rv->me_pointer = &png_hid; rv->cap = Trace_Cap; rv->width = 1; rv->color = (color_struct *) malloc (sizeof (color_struct)); rv->color->r = rv->color->g = rv->color->b = rv->color->a = 0; rv->color->c = 0; rv->is_erase = 0; return rv; } static void png_destroy_gc (hidGC gc) { free (gc); } static void png_use_mask (enum mask_mode mode) { if (photo_mode) return; if (mode == HID_MASK_CLEAR) { return; } if (mode != HID_MASK_OFF) { if (mask_im == NULL) { mask_im = gdImageCreate (gdImageSX (im), gdImageSY (im)); if (!mask_im) { Message ("%s(): gdImageCreate(%d, %d) returned NULL. Corrupt export!\n", __FUNCTION__, gdImageSY (im), gdImageSY (im)); return; } gdImagePaletteCopy (mask_im, im); } im = mask_im; gdImageFilledRectangle (mask_im, 0, 0, gdImageSX (mask_im), gdImageSY (mask_im), white->c); } else { int x, y, c; im = master_im; for (x=0; xcolor = white; gc->is_erase = 1; return; } gc->is_erase = 0; if (in_mono || (strcmp (name, "#000000") == 0)) { gc->color = black; return; } if (hid_cache_color (0, name, &cval, &color_cache)) { gc->color = (color_struct *)cval.ptr; } else if (name[0] == '#') { gc->color = (color_struct *) malloc (sizeof (color_struct)); sscanf (name + 1, "%2x%2x%2x", &(gc->color->r), &(gc->color->g), &(gc->color->b)); gc->color->c = gdImageColorAllocate (master_im, gc->color->r, gc->color->g, gc->color->b); if (gc->color->c == BADC) { Message ("%s(): gdImageColorAllocate() returned NULL. Aborting export.\n", __FUNCTION__); return; } cval.ptr = gc->color; hid_cache_color (1, name, &cval, &color_cache); } else { printf ("WE SHOULD NOT BE HERE!!!\n"); gc->color = black; } } static void png_set_line_cap (hidGC gc, EndCapStyle style) { gc->cap = style; } static void png_set_line_width (hidGC gc, Coord width) { gc->width = width; } static void png_set_draw_xor (hidGC gc, int xor_) { ; } static void use_gc (hidGC gc) { int need_brush = 0; if (gc->me_pointer != &png_hid) { fprintf (stderr, "Fatal: GC from another HID passed to png HID\n"); abort (); } if (linewidth != gc->width) { /* Make sure the scaling doesn't erase lines completely */ if (SCALE (gc->width) == 0 && gc->width > 0) gdImageSetThickness (im, 1); else gdImageSetThickness (im, SCALE (gc->width + 2*bloat)); linewidth = gc->width; need_brush = 1; } if (lastbrush != gc->brush || need_brush) { hidval bval; char name[256]; char type; int r; switch (gc->cap) { case Round_Cap: case Trace_Cap: type = 'C'; break; default: case Square_Cap: type = 'S'; break; } if (gc->width) r = SCALE (gc->width + 2*bloat); else r = 1; /* do not allow a brush size that is zero width. In this case limit to a single pixel. */ if (r == 0) { r = 1; } sprintf (name, "#%.2x%.2x%.2x_%c_%d", gc->color->r, gc->color->g, gc->color->b, type, r); if (hid_cache_color (0, name, &bval, &brush_cache)) { gc->brush = (gdImagePtr)bval.ptr; } else { int bg, fg; gc->brush = gdImageCreate (r, r); if (gc->brush == NULL) { Message ("%s(): gdImageCreate(%d, %d) returned NULL. Aborting export.\n", __FUNCTION__, r, r); return; } bg = gdImageColorAllocate (gc->brush, 255, 255, 255); if (bg == BADC) { Message ("%s(): gdImageColorAllocate() returned NULL. Aborting export.\n", __FUNCTION__); return; } fg = gdImageColorAllocateAlpha (gc->brush, gc->color->r, gc->color->g, gc->color->b, 0); if (fg == BADC) { Message ("%s(): gdImageColorAllocate() returned NULL. Aborting export.\n", __FUNCTION__); return; } gdImageColorTransparent (gc->brush, bg); /* * if we shrunk to a radius/box width of zero, then just use * a single pixel to draw with. */ if (r <= 1) gdImageFilledRectangle (gc->brush, 0, 0, 0, 0, fg); else { if (type == 'C') { gdImageFilledEllipse (gc->brush, r/2, r/2, r, r, fg); /* Make sure the ellipse is the right exact size. */ gdImageSetPixel (gc->brush, 0, r/2, fg); gdImageSetPixel (gc->brush, r-1, r/2, fg); gdImageSetPixel (gc->brush, r/2, 0, fg); gdImageSetPixel (gc->brush, r/2, r-1, fg); } else gdImageFilledRectangle (gc->brush, 0, 0, r-1, r-1, fg); } bval.ptr = gc->brush; hid_cache_color (1, name, &bval, &brush_cache); } gdImageSetBrush (im, gc->brush); lastbrush = gc->brush; } } static void png_draw_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2) { use_gc (gc); gdImageRectangle (im, SCALE_X (x1), SCALE_Y (y1), SCALE_X (x2), SCALE_Y (y2), gc->color->c); } static void png_fill_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2) { use_gc (gc); gdImageSetThickness (im, 0); linewidth = 0; y1 -= bloat; y2 += bloat; SWAP_IF_SOLDER (y1, y2); gdImageFilledRectangle (im, SCALE_X (x1-bloat), SCALE_Y (y1), SCALE_X (x2+bloat)-1, SCALE_Y (y2)-1, gc->color->c); have_outline |= doing_outline; } static void png_draw_line (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2) { if (x1 == x2 && y1 == y2) { Coord w = gc->width / 2; if (gc->cap != Square_Cap) png_fill_circle (gc, x1, y1, w); else png_fill_rect (gc, x1 - w, y1 - w, x1 + w, y1 + w); return; } use_gc (gc); if (NOT_EDGE (x1, y1) || NOT_EDGE (x2, y2)) have_outline |= doing_outline; if (doing_outline) { /* Special case - lines drawn along the bottom or right edges are brought in by a pixel to make sure we have contiguous outlines. */ if (x1 == PCB->MaxWidth && x2 == PCB->MaxWidth) { x1 -= scale/2; x2 -= scale/2; } if (y1 == PCB->MaxHeight && y2 == PCB->MaxHeight) { y1 -= scale/2; y2 -= scale/2; } } gdImageSetThickness (im, 0); linewidth = 0; if(gc->cap != Square_Cap || x1 == x2 || y1 == y2 ) { gdImageLine (im, SCALE_X (x1), SCALE_Y (y1), SCALE_X (x2), SCALE_Y (y2), gdBrushed); } else { /* * if we are drawing a line with a square end cap and it is * not purely horizontal or vertical, then we need to draw * it as a filled polygon. */ int fg = gdImageColorResolve (im, gc->color->r, gc->color->g, gc->color->b); Coord w = gc->width; Coord dwx, dwy; gdPoint p[4]; double l = Distance(x1, y1, x2, y2) * 2; w += 2 * bloat; dwx = -w / l * (y2 - y1); dwy = w / l * (x2 - x1); p[0].x = SCALE_X (x1 + dwx - dwy); p[0].y = SCALE_Y(y1 + dwy + dwx); p[1].x = SCALE_X (x1 - dwx - dwy); p[1].y = SCALE_Y(y1 - dwy + dwx); p[2].x = SCALE_X (x2 - dwx + dwy); p[2].y = SCALE_Y(y2 - dwy - dwx); p[3].x = SCALE_X (x2 + dwx + dwy); p[3].y = SCALE_Y(y2 + dwy - dwx); gdImageFilledPolygon (im, p, 4, fg); } } static void png_draw_arc (hidGC gc, Coord cx, Coord cy, Coord width, Coord height, Angle start_angle, Angle delta_angle) { Angle sa, ea; /* * zero angle arcs need special handling as gd will output either * nothing at all or a full circle when passed delta angle of 0 or 360. */ if (delta_angle == 0) { Coord x = (width * cos (start_angle * M_PI / 180)); Coord y = (width * sin (start_angle * M_PI / 180)); x = cx - x; y = cy + y; png_fill_circle (gc, x, y, gc->width / 2); return; } /* * in gdImageArc, 0 degrees is to the right and +90 degrees is down * in pcb, 0 degrees is to the left and +90 degrees is down */ start_angle = 180 - start_angle; delta_angle = -delta_angle; if (show_bottom_side) { start_angle = - start_angle; delta_angle = -delta_angle; } if (delta_angle > 0) { sa = start_angle; ea = start_angle + delta_angle; } else { sa = start_angle + delta_angle; ea = start_angle; } /* * make sure we start between 0 and 360 otherwise gd does * strange things */ sa = NormalizeAngle (sa); ea = NormalizeAngle (ea); have_outline |= doing_outline; #if 0 printf ("draw_arc %d,%d %dx%d %d..%d %d..%d\n", cx, cy, width, height, start_angle, delta_angle, sa, ea); printf ("gdImageArc (%p, %d, %d, %d, %d, %d, %d, %d)\n", im, SCALE_X (cx), SCALE_Y (cy), SCALE (width), SCALE (height), sa, ea, gc->color->c); #endif use_gc (gc); gdImageSetThickness (im, 0); linewidth = 0; gdImageArc (im, SCALE_X (cx), SCALE_Y (cy), SCALE (2 * width), SCALE (2 * height), sa, ea, gdBrushed); } static void png_fill_circle (hidGC gc, Coord cx, Coord cy, Coord radius) { Coord my_bloat; use_gc (gc); if (fill_holes && gc->is_erase && is_copper) return; if (gc->is_erase) my_bloat = -2 * bloat; else my_bloat = 2 * bloat; have_outline |= doing_outline; gdImageSetThickness (im, 0); linewidth = 0; gdImageFilledEllipse (im, SCALE_X (cx), SCALE_Y (cy), SCALE (2 * radius + my_bloat), SCALE (2 * radius + my_bloat), gc->color->c); } static void png_fill_polygon (hidGC gc, int n_coords, Coord *x, Coord *y) { int i; gdPoint *points; points = (gdPoint *) malloc (n_coords * sizeof (gdPoint)); if (points == NULL) { fprintf (stderr, "ERROR: png_fill_polygon(): malloc failed\n"); exit (1); } use_gc (gc); for (i = 0; i < n_coords; i++) { if (NOT_EDGE (x[i], y[i])) have_outline |= doing_outline; points[i].x = SCALE_X (x[i]); points[i].y = SCALE_Y (y[i]); } gdImageSetThickness (im, 0); linewidth = 0; gdImageFilledPolygon (im, points, n_coords, gc->color->c); free (points); } static void png_calibrate (double xval, double yval) { CRASH; } static void png_set_crosshair (int x, int y, int a) { } #include "dolists.h" void hid_png_init () { memset (&png_hid, 0, sizeof (HID)); memset (&png_graphics, 0, sizeof (HID_DRAW)); common_nogui_init (&png_hid); common_draw_helpers_init (&png_graphics); png_hid.struct_size = sizeof (HID); png_hid.name = "png"; png_hid.description = "GIF/JPEG/PNG export"; png_hid.exporter = 1; png_hid.poly_before = 1; png_hid.get_export_options = png_get_export_options; png_hid.do_export = png_do_export; png_hid.parse_arguments = png_parse_arguments; png_hid.set_layer = png_set_layer; png_hid.calibrate = png_calibrate; png_hid.set_crosshair = png_set_crosshair; png_hid.graphics = &png_graphics; png_graphics.make_gc = png_make_gc; png_graphics.destroy_gc = png_destroy_gc; png_graphics.use_mask = png_use_mask; png_graphics.set_color = png_set_color; png_graphics.set_line_cap = png_set_line_cap; png_graphics.set_line_width = png_set_line_width; png_graphics.set_draw_xor = png_set_draw_xor; png_graphics.draw_line = png_draw_line; png_graphics.draw_arc = png_draw_arc; png_graphics.draw_rect = png_draw_rect; png_graphics.fill_circle = png_fill_circle; png_graphics.fill_polygon = png_fill_polygon; png_graphics.fill_rect = png_fill_rect; #ifdef HAVE_SOME_FORMAT hid_register_hid (&png_hid); #include "png_lists.h" #endif } pcb-4.3.0/src/hid/lesstif/0000775000175000017500000000000014017001275012266 500000000000000pcb-4.3.0/src/hid/lesstif/netlist.c0000664000175000017500000002776413773431044014065 00000000000000#ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "xincludes.h" #include "compat.h" #include "global.h" #include "data.h" #include "find.h" #include "flags.h" #include "rats.h" #include "select.h" #include "undo.h" #include "remove.h" #include "crosshair.h" #include "draw.h" #include "hid.h" #include "../hidint.h" #include "lesstif.h" #ifdef HAVE_LIBDMALLOC #include #endif static Arg args[30]; static int n; #define stdarg(t,v) XtSetArg(args[n], t, v); n++ static Widget netlist_dialog = 0; static Widget netlist_list, netnode_list; static XmString *netlist_strings = 0; static XmString *netnode_strings = 0; static int n_netnode_strings; static int last_pick = -1; static int LesstifNetlistChanged (int argc, char **argv, Coord x, Coord y); static void pick_net (int pick) { LibraryMenuType *menu = PCB->NetlistLib.Menu + pick; int i; if (pick == last_pick) return; last_pick = pick; if (netnode_strings) free (netnode_strings); /* XXX leaked all XmStrings??? */ n_netnode_strings = menu->EntryN; netnode_strings = (XmString *) malloc (menu->EntryN * sizeof (XmString)); for (i = 0; i < menu->EntryN; i++) netnode_strings[i] = XmStringCreatePCB (menu->Entry[i].ListEntry); n = 0; stdarg (XmNitems, netnode_strings); stdarg (XmNitemCount, menu->EntryN); XtSetValues (netnode_list, args, n); } static void netlist_select (Widget w, void *v, XmListCallbackStruct * cbs) { XmString str; int pos = cbs->item_position; LibraryMenuType *net = & (PCB->NetlistLib.Menu[pos - 1]); char *name = net->Name; if (name[0] == ' ') { name[0] = '*'; net->flag = 0; } else { name[0] = ' '; net->flag = 1; } str = XmStringCreatePCB (name); XmListReplaceItemsPos (netlist_list, &str, 1, pos); XmStringFree (str); XmListSelectPos (netlist_list, pos, False); } static void netlist_extend (Widget w, void *v, XmListCallbackStruct * cbs) { if (cbs->selected_item_count == 1) pick_net (cbs->item_position - 1); } typedef void (*Std_Nbcb_Func)(LibraryMenuType *, int); static void nbcb_rat_on (LibraryMenuType *net, int pos) { XmString str; char *name = net->Name; name[0] = ' '; net->flag = 1; str = XmStringCreatePCB (name); XmListReplaceItemsPos (netlist_list, &str, 1, pos); XmStringFree (str); } static void nbcb_rat_off (LibraryMenuType *net, int pos) { XmString str; char *name = net->Name; name[0] = '*'; net->flag = 0; str = XmStringCreatePCB (name); XmListReplaceItemsPos (netlist_list, &str, 1, pos); XmStringFree (str); } /* Select on the layout the current net treeview selection */ static void nbcb_select_common (LibraryMenuType *net, int pos, int select_flag) { LibraryEntryType *entry; ConnectionType conn; int i; InitConnectionLookup (); ClearFlagOnAllObjects (FOUNDFLAG, true); for (i = net->EntryN, entry = net->Entry; i; i--, entry++) if (SeekPad (entry, &conn, false)) RatFindHook (conn.type, conn.ptr1, conn.ptr2, conn.ptr2, true, FOUNDFLAG, true); SelectByFlag (FOUNDFLAG, select_flag); ClearFlagOnAllObjects (FOUNDFLAG, false); FreeConnectionLookupMemory (); IncrementUndoSerialNumber (); Draw (); } static void nbcb_select (LibraryMenuType *net, int pos) { nbcb_select_common (net, pos, 1); } static void nbcb_deselect (LibraryMenuType *net, int pos) { nbcb_select_common (net, pos, 0); } static void nbcb_find (LibraryMenuType *net, int pos) { char *name = net->Name + 2; hid_actionl ("netlist", "find", name, NULL); } static void nbcb_std_callback (Widget w, Std_Nbcb_Func v, XmPushButtonCallbackStruct * cbs) { int *posl, posc, i; XmString **items, **selected; if (XmListGetSelectedPos (netlist_list, &posl, &posc) == False) return; if (v == nbcb_find) hid_actionl ("connection", "reset", NULL); for (i=0; iNetlistLib.Menu[posl[i] - 1]); v(net, posl[i]); } n = 0; stdarg (XmNitems, &items); XtGetValues (netlist_list, args, n); selected = (XmString **) malloc (posc * sizeof (XmString *)); for (i=0; iData); { if (TEST_FLAG (FOUNDFLAG, line) && !TEST_FLAG (LOCKFLAG, line)) RemoveObject (LINE_TYPE, layer, line, line); } ENDALL_LOOP; VISIBLEARC_LOOP (PCB->Data); { if (TEST_FLAG (FOUNDFLAG, arc) && !TEST_FLAG (LOCKFLAG, arc)) RemoveObject (ARC_TYPE, layer, arc, arc); } ENDALL_LOOP; if (PCB->ViaOn) VIA_LOOP (PCB->Data); { if (TEST_FLAG (FOUNDFLAG, via) && !TEST_FLAG (LOCKFLAG, via)) RemoveObject (VIA_TYPE, via, via, via); } END_LOOP; } static void netnode_browse (Widget w, XtPointer v, XmListCallbackStruct * cbs) { LibraryMenuType *menu = PCB->NetlistLib.Menu + last_pick; char *name = menu->Entry[cbs->item_position - 1].ListEntry; char *ename, *pname; ename = strdup (name); pname = strchr (ename, '-'); if (! pname) { free (ename); return; } *pname++ = 0; ELEMENT_LOOP (PCB->Data); { char *es = element->Name[NAMEONPCB_INDEX].TextString; if (es && strcmp (es, ename) == 0) { PIN_LOOP (element); { if (strcmp (pin->Number, pname) == 0) { MoveCrosshairAbsolute (pin->X, pin->Y); free (ename); return; } } END_LOOP; PAD_LOOP (element); { if (strcmp (pad->Number, pname) == 0) { int x = (pad->Point1.X + pad->Point2.X) / 2; int y = (pad->Point1.Y + pad->Point2.Y) / 2; gui->set_crosshair (x, y, HID_SC_PAN_VIEWPORT); free (ename); return; } } END_LOOP; } } END_LOOP; free (ename); } #define NLB_FORM ((Widget)(~0)) static Widget netlist_button (Widget parent, char *name, char *string, Widget top, Widget bottom, Widget left, Widget right, XtCallbackProc callback, void *user_data) { Widget rv; XmString str; #define NLB_W(w) if (w == NLB_FORM) { stdarg(XmN ## w ## Attachment, XmATTACH_FORM); } \ else if (w) { stdarg(XmN ## w ## Attachment, XmATTACH_WIDGET); \ stdarg (XmN ## w ## Widget, w); } NLB_W (top); NLB_W (bottom); NLB_W (left); NLB_W (right); str = XmStringCreatePCB (string); stdarg(XmNlabelString, str); rv = XmCreatePushButton (parent, name, args, n); XtManageChild (rv); if (callback) XtAddCallback (rv, XmNactivateCallback, callback, (XtPointer)user_data); XmStringFree(str); return rv; } static int build_netlist_dialog () { Widget b_sel, b_unsel, b_find, b_rat_on, l_ops; XmString ops_str; if (!mainwind) return 1; if (netlist_dialog) return 0; n = 0; stdarg (XmNresizePolicy, XmRESIZE_GROW); stdarg (XmNtitle, "Netlists"); stdarg (XmNautoUnmanage, False); netlist_dialog = XmCreateFormDialog (mainwind, "netlist", args, n); n = 0; b_rat_on = netlist_button (netlist_dialog, "rat_on", "Enable for rats", 0, NLB_FORM, NLB_FORM, 0, (XtCallbackProc)nbcb_std_callback, (void *)nbcb_rat_on); n = 0; netlist_button (netlist_dialog, "rat_off", "Disable for rats", 0, NLB_FORM, b_rat_on, 0, (XtCallbackProc)nbcb_std_callback, (void *)nbcb_rat_off); n = 0; b_sel = netlist_button (netlist_dialog, "select", "Select", 0, b_rat_on, NLB_FORM, 0, (XtCallbackProc)nbcb_std_callback, (void *)nbcb_select); n = 0; b_unsel = netlist_button (netlist_dialog, "deselect", "Deselect", 0, b_rat_on, b_sel, 0, (XtCallbackProc)nbcb_std_callback, (void *)nbcb_deselect); n = 0; b_find = netlist_button (netlist_dialog, "find", "Find", 0, b_rat_on, b_unsel, 0, (XtCallbackProc)nbcb_std_callback, (void *)nbcb_find); n = 0; netlist_button (netlist_dialog, "ripup", "Rip Up", 0, b_rat_on, b_find, 0, (XtCallbackProc)nbcb_ripup, 0); n = 0; stdarg (XmNbottomAttachment, XmATTACH_WIDGET); stdarg (XmNbottomWidget, b_sel); stdarg (XmNleftAttachment, XmATTACH_FORM); ops_str = XmStringCreatePCB ("Operations on selected net names:"); stdarg (XmNlabelString, ops_str); l_ops = XmCreateLabel (netlist_dialog, "ops", args, n); XtManageChild (l_ops); n = 0; stdarg (XmNtopAttachment, XmATTACH_FORM); stdarg (XmNbottomAttachment, XmATTACH_WIDGET); stdarg (XmNbottomWidget, l_ops); stdarg (XmNleftAttachment, XmATTACH_FORM); stdarg (XmNrightAttachment, XmATTACH_POSITION); stdarg (XmNrightPosition, 50); stdarg (XmNvisibleItemCount, 10); stdarg (XmNselectionPolicy, XmEXTENDED_SELECT); netlist_list = XmCreateScrolledList (netlist_dialog, "nets", args, n); XtManageChild (netlist_list); XtAddCallback (netlist_list, XmNdefaultActionCallback, (XtCallbackProc)netlist_select, 0); XtAddCallback (netlist_list, XmNextendedSelectionCallback, (XtCallbackProc)netlist_extend, 0); n = 0; stdarg (XmNtopAttachment, XmATTACH_FORM); stdarg (XmNbottomAttachment, XmATTACH_WIDGET); stdarg (XmNbottomWidget, l_ops); stdarg (XmNrightAttachment, XmATTACH_FORM); stdarg (XmNleftAttachment, XmATTACH_POSITION); stdarg (XmNleftPosition, 50); netnode_list = XmCreateScrolledList (netlist_dialog, "nodes", args, n); XtManageChild (netnode_list); XtAddCallback (netnode_list, XmNbrowseSelectionCallback, (XtCallbackProc)netnode_browse, 0); return 0; } static int LesstifNetlistChanged (int argc, char **argv, Coord x, Coord y) { int i; if (!PCB->NetlistLib.MenuN) return 0; if (build_netlist_dialog ()) return 0; last_pick = -1; if (netlist_strings) free (netlist_strings); netlist_strings = (XmString *) malloc (PCB->NetlistLib.MenuN * sizeof (XmString)); for (i = 0; i < PCB->NetlistLib.MenuN; i++) netlist_strings[i] = XmStringCreatePCB (PCB->NetlistLib.Menu[i].Name); n = 0; stdarg (XmNitems, netlist_strings); stdarg (XmNitemCount, PCB->NetlistLib.MenuN); XtSetValues (netlist_list, args, n); pick_net (0); return 0; } static const char netlistshow_syntax[] = "NetlistShow(pinname|netname)"; static const char netlistshow_help[] = "Selects the given pinname or netname in the netlist window."; /* %start-doc actions NetlistShow %end-doc */ static int LesstifNetlistShow (int argc, char **argv, Coord x, Coord y) { if (build_netlist_dialog ()) return 0; if (argc == 1) { LibraryMenuType *net; net = netnode_to_netname(argv[0]); if (net) { XmString item; int vis = 0; /* Select net first, 'True' causes pick_net() to be invoked */ item = XmStringCreatePCB (net->Name); XmListSelectItem (netlist_list, item, True); XmListSetItem (netlist_list, item); XmStringFree (item); /* Now the netnode_list has the right contents */ item = XmStringCreatePCB (argv[0]); XmListSelectItem (netnode_list, item, False); /* * Only force the item to the top if there are enough to scroll. * A bug (?) in lesstif will cause the window to get ever wider * if an XmList that doesn't require a scrollbar is forced to * have one (when the top item is not the first item). */ n = 0; stdarg (XmNvisibleItemCount, &vis); XtGetValues (netnode_list, args, n); if (n_netnode_strings > vis) { XmListSetItem (netnode_list, item); } XmStringFree (item); } else { /* Try the argument as a netname */ net = netname_to_netname(argv[0]); if (net) { XmString item; item = XmStringCreatePCB (net->Name); XmListSetItem (netlist_list, item); XmListSelectItem (netlist_list, item, True); XmStringFree (item); } } } return 0; } void lesstif_show_netlist () { build_netlist_dialog (); XtManageChild (netlist_dialog); } HID_Action lesstif_netlist_action_list[] = { {"NetlistChanged", 0, LesstifNetlistChanged, netlistchanged_help, netlistchanged_syntax}, {"NetlistShow", 0, LesstifNetlistShow, netlistshow_help, netlistshow_syntax} }; REGISTER_ACTIONS (lesstif_netlist_action_list) pcb-4.3.0/src/hid/lesstif/lesstif_lists.h0000664000175000017500000000054714017001022015242 00000000000000REGISTER_ACTIONS (lesstif_dialog_action_list) REGISTER_ACTIONS (lesstif_library_action_list) REGISTER_FLAGS (lesstif_main_flag_list) REGISTER_ATTRIBUTES (lesstif_attribute_list) REGISTER_ACTIONS (lesstif_main_action_list) REGISTER_ACTIONS (lesstif_menu_action_list) REGISTER_ACTIONS (lesstif_netlist_action_list) REGISTER_ACTIONS (lesstif_styles_action_list) pcb-4.3.0/src/hid/lesstif/menu.c0000664000175000017500000010654013773431044013335 00000000000000#ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "xincludes.h" #include "global.h" #include "data.h" #include "error.h" #include "misc.h" #include "pcb-printf.h" #include "hid.h" #include "../hidint.h" #include "hid/common/hid_resource.h" #include "resource.h" #include "lesstif.h" #include "mymem.h" #include "layerflags.h" #include "pcb-menu.h" #ifdef HAVE_LIBDMALLOC #include #endif #ifndef R_OK /* Common value for systems that don't define it. */ #define R_OK 4 #endif static Colormap cmap; static Arg args[30]; static int n; #define stdarg(t,v) XtSetArg(args[n], t, v), n++ static void note_accelerator (char *acc, Resource * node); static void note_widget_flag (Widget w, char *type, char *name); static const char getxy_syntax[] = "GetXY()"; static const char getxy_help[] = "Get a coordinate."; /*! * \brief Get a coordinate. * * Each action is registered with a flag for the core ("need_coord_msg") * that says whether it requires an X,Y location from the user, and if * so, provides a prompt for that X,Y location. * * The GUIs display that prompt while waiting for the user to click. * * GetXY() is a "filler" action which exists *only* to request an X,Y * click from the user, for actions that don't (or optionally) need * coords, or don't have a message appropriate for the case being issued * (i.e. if there are multiple actions to be executed, the GetXY() might * be appropriate for the *group* results, not the first action that * happens to need a coordinate). * * The catch is that the core asks for the X,Y click *before* the action * is called, so there's no way for any argument to GetXY() to have any * effect. * * The string "printed" is the empty one in the struct where GetXY() is * registered. */ /* %start-doc actions GetXY Prompts the user for a coordinate, if one is not already selected. %end-doc */ static int GetXY (int argc, char **argv, Coord x, Coord y) { return 0; } static const char debug_syntax[] = "Debug(...)"; static const char debug_help[] = "Debug action."; /* %start-doc actions Debug This action exists to help debug scripts; it simply prints all its arguments to stdout. %end-doc */ static const char debugxy_syntax[] = "DebugXY(...)"; static const char debugxy_help[] = "Debug action, with coordinates"; /* %start-doc actions DebugXY Like @code{Debug}, but requires a coordinate. If the user hasn't yet indicated a location on the board, the user will be prompted to click on one. %end-doc */ static int Debug (int argc, char **argv, Coord x, Coord y) { int i; printf ("Debug:"); for (i = 0; i < argc; i++) printf (" [%d] `%s'", i, argv[i]); pcb_printf (" x,y %$mD\n", x, y); for (i = 0; i < max_copper_layer + SILK_LAYER; i++) { printf("0x%08x %s (%s)\n", PCB->Data->Layer[i].Type, PCB->Data->Layer[i].Name, layertype_to_string (PCB->Data->Layer[i].Type)); } return 0; } static const char return_syntax[] = "Return(0|1)"; static const char return_help[] = "Simulate a passing or failing action."; /* %start-doc actions Return This is for testing. If passed a 0, does nothing and succeeds. If passed a 1, does nothing but pretends to fail. %end-doc */ static int Return (int argc, char **argv, Coord x, Coord y) { if (argc < 1) return 0; else if (argc == 1) return atoi (argv[0]); return 1; } static const char dumpkeys_syntax[] = "DumpKeys()"; static const char dumpkeys_help[] = "Dump Lesstif key bindings."; /* %start-doc actions DumpKeys Causes the list of key bindings (from @code{pcb-menu.res}) to be dumped to stdout. This is most useful when invoked from the command line like this: @example pcb --action-string DumpKeys @end example %end-doc */ static int do_dump_keys = 0; static int DumpKeys (int argc, char **argv, Coord x, Coord y) { do_dump_keys = 1; return 0; } /*-----------------------------------------------------------------------------*/ #define LB_SILK (MAX_LAYER + BOTTOM_SILK_LAYER) #define LB_RATS (MAX_LAYER + 1) #define LB_NUMPICK (LB_RATS+1) /* more */ #define LB_PINS (MAX_ALL_LAYER) #define LB_VIAS (MAX_ALL_LAYER + 1) #define LB_BACK (MAX_ALL_LAYER + 2) #define LB_MASK (MAX_ALL_LAYER + 3) #define LB_NUM (MAX_ALL_LAYER + 4) typedef struct { Widget w[LB_NUM]; int is_pick; } LayerButtons; static LayerButtons *layer_button_list = 0; static int num_layer_buttons = 0; static int fg_colors[LB_NUM]; static int bg_color; extern Widget lesstif_m_layer; static int LayersChanged (int argc, char **argv, Coord x, Coord y) { int l, i, set; char *name; int current_layer; if (!layer_button_list) return 0; if (PCB && PCB->Data) { DataType *d = PCB->Data; for (i = 0; i < MAX_LAYER; i++) fg_colors[i] = lesstif_parse_color (d->Layer[i].Color); fg_colors[LB_SILK] = lesstif_parse_color (PCB->ElementColor); fg_colors[LB_RATS] = lesstif_parse_color (PCB->RatColor); fg_colors[LB_PINS] = lesstif_parse_color (PCB->PinColor); fg_colors[LB_VIAS] = lesstif_parse_color (PCB->ViaColor); fg_colors[LB_BACK] = lesstif_parse_color (PCB->InvisibleObjectsColor); fg_colors[LB_MASK] = lesstif_parse_color (PCB->MaskColor); bg_color = lesstif_parse_color (Settings.BackgroundColor); } else { for (i = 0; i < MAX_LAYER; i++) fg_colors[i] = lesstif_parse_color (Settings.LayerColor[i]); fg_colors[LB_SILK] = lesstif_parse_color (Settings.ElementColor); fg_colors[LB_RATS] = lesstif_parse_color (Settings.RatColor); fg_colors[LB_PINS] = lesstif_parse_color (Settings.PinColor); fg_colors[LB_VIAS] = lesstif_parse_color (Settings.ViaColor); fg_colors[LB_BACK] = lesstif_parse_color (Settings.InvisibleObjectsColor); fg_colors[LB_MASK] = lesstif_parse_color (Settings.MaskColor); bg_color = lesstif_parse_color (Settings.BackgroundColor); } if (PCB->RatDraw) current_layer = LB_RATS; else if (PCB->SilkActive) current_layer = LB_SILK; else current_layer = LayerStack[0]; for (l = 0; l < num_layer_buttons; l++) { LayerButtons *lb = layer_button_list + l; for (i = 0; i < (lb->is_pick ? LB_NUMPICK : LB_NUM); i++) { switch (i) { case LB_SILK: set = PCB->ElementOn; break; case LB_RATS: set = PCB->RatOn; break; case LB_PINS: set = PCB->PinOn; break; case LB_VIAS: set = PCB->ViaOn; break; case LB_BACK: set = PCB->InvisibleObjectsOn; break; case LB_MASK: set = TEST_FLAG (SHOWMASKFLAG, PCB); break; default: /* layers */ set = PCB->Data->Layer[i].On; break; } n = 0; if (i < MAX_LAYER && PCB->Data->Layer[i].Name) { XmString s = XmStringCreatePCB (PCB->Data->Layer[i].Name); stdarg (XmNlabelString, s); } if (!lb->is_pick) { if (set) { stdarg (XmNforeground, bg_color); stdarg (XmNbackground, fg_colors[i]); } else { stdarg (XmNforeground, fg_colors[i]); stdarg (XmNbackground, bg_color); } stdarg (XmNset, set); } else { stdarg (XmNforeground, bg_color); stdarg (XmNbackground, fg_colors[i]); stdarg (XmNset, current_layer == i ? True : False); } XtSetValues (lb->w[i], args, n); if (i >= max_copper_layer && i < MAX_LAYER) XtUnmanageChild(lb->w[i]); else XtManageChild(lb->w[i]); } } if (lesstif_m_layer) { switch (current_layer) { case LB_RATS: name = "Rats"; break; case LB_SILK: name = "Silk"; break; default: name = PCB->Data->Layer[current_layer].Name; break; } n = 0; stdarg (XmNbackground, fg_colors[current_layer]); stdarg (XmNforeground, bg_color); stdarg (XmNlabelString, XmStringCreatePCB (name)); XtSetValues (lesstif_m_layer, args, n); } lesstif_update_layer_groups (); return 0; } static void show_one_layer_button (int layer, int set) { int l; n = 0; if (set) { stdarg (XmNforeground, bg_color); stdarg (XmNbackground, fg_colors[layer]); } else { stdarg (XmNforeground, fg_colors[layer]); stdarg (XmNbackground, bg_color); } stdarg (XmNset, set); for (l = 0; l < num_layer_buttons; l++) { LayerButtons *lb = layer_button_list + l; if (!lb->is_pick) XtSetValues (lb->w[layer], args, n); } } static void layer_button_callback (Widget w, int layer, XmPushButtonCallbackStruct * pbcs) { int l, set; switch (layer) { case LB_SILK: set = PCB->ElementOn = !PCB->ElementOn; PCB->Data->SILKLAYER.On = set; PCB->Data->BACKSILKLAYER.On = set; break; case LB_RATS: set = PCB->RatOn = !PCB->RatOn; break; case LB_PINS: set = PCB->PinOn = !PCB->PinOn; break; case LB_VIAS: set = PCB->ViaOn = !PCB->ViaOn; break; case LB_BACK: set = PCB->InvisibleObjectsOn = !PCB->InvisibleObjectsOn; break; case LB_MASK: TOGGLE_FLAG (SHOWMASKFLAG, PCB); set = TEST_FLAG (SHOWMASKFLAG, PCB); break; default: /* layers */ set = PCB->Data->Layer[layer].On = !PCB->Data->Layer[layer].On; break; } show_one_layer_button (layer, set); if (layer < max_copper_layer) { int i; int group = GetLayerGroupNumberByNumber (layer); for (i = 0; i < PCB->LayerGroups.Number[group]; i++) { l = PCB->LayerGroups.Entries[group][i]; if (l != layer && l < max_copper_layer) { show_one_layer_button (l, set); PCB->Data->Layer[l].On = set; } } } lesstif_invalidate_all (); } static void layerpick_button_callback (Widget w, int layer, XmPushButtonCallbackStruct * pbcs) { int l, i; char *name; PCB->RatDraw = (layer == LB_RATS); PCB->SilkActive = (layer == LB_SILK); if (layer < max_copper_layer) ChangeGroupVisibility (layer, 1, 1); for (l = 0; l < num_layer_buttons; l++) { LayerButtons *lb = layer_button_list + l; if (!lb->is_pick) continue; for (i = 0; i < LB_NUMPICK; i++) XmToggleButtonSetState (lb->w[i], layer == i, False); } switch (layer) { case LB_RATS: name = "Rats"; break; case LB_SILK: name = "Silk"; break; default: name = PCB->Data->Layer[layer].Name; break; } n = 0; stdarg (XmNbackground, fg_colors[layer]); stdarg (XmNforeground, bg_color); stdarg (XmNlabelString, XmStringCreatePCB (name)); XtSetValues (lesstif_m_layer, args, n); lesstif_invalidate_all (); } static const char selectlayer_syntax[] = "SelectLayer(1..MAXLAYER|Silk|Rats)"; static const char selectlayer_help[] = "Select which layer is the current layer."; /* %start-doc actions SelectLayer The specified layer becomes the currently active layer. It is made visible if it is not already visible %end-doc */ static int SelectLayer (int argc, char **argv, Coord x, Coord y) { int i; int newl = -1; if (argc == 0) return 1; for (i = 0; i < max_copper_layer; ++i) if (strcasecmp (argv[0], PCB->Data->Layer[i].Name) == 0) newl = i; if (strcasecmp (argv[0], "silk") == 0) newl = LB_SILK; else if (strcasecmp (argv[0], "rats") == 0) newl = LB_RATS; else if (newl == -1) newl = atoi (argv[0]) - 1; layerpick_button_callback (0, newl, 0); return 0; } static const char toggleview_syntax[] = "ToggleView(1..MAXLAYER)\n" "ToggleView(layername)\n" "ToggleView(Silk|Rats|Pins|Vias|Mask|BackSide)"; static const char toggleview_help[] = "Toggle the visibility of the specified layer or layer group."; /* %start-doc actions ToggleView If you pass an integer, that layer is specified by index (the first layer is @code{1}, etc). If you pass a layer name, that layer is specified by name. When a layer is specified, the visibility of the layer group containing that layer is toggled. If you pass a special layer name, the visibility of those components (silk, rats, etc) is toggled. Note that if you have a layer named the same as a special layer, the layer is chosen over the special layer. %end-doc */ static int ToggleView (int argc, char **argv, Coord x, Coord y) { int i, l; if (argc == 0) return 1; if (isdigit ((int) argv[0][0])) { l = atoi (argv[0]) - 1; layer_button_callback (0, l, 0); } else if (strcmp (argv[0], "Silk") == 0) layer_button_callback (0, LB_SILK, 0); else if (strcmp (argv[0], "Rats") == 0) layer_button_callback (0, LB_RATS, 0); else if (strcmp (argv[0], "Pins") == 0) layer_button_callback (0, LB_PINS, 0); else if (strcmp (argv[0], "Vias") == 0) layer_button_callback (0, LB_VIAS, 0); else if (strcmp (argv[0], "Mask") == 0) layer_button_callback (0, LB_MASK, 0); else if (strcmp (argv[0], "BackSide") == 0) layer_button_callback (0, LB_BACK, 0); else { l = -1; for (i = 0; i < max_copper_layer + SILK_LAYER; i++) if (strcmp (argv[0], PCB->Data->Layer[i].Name) == 0) { l = i; break; } if (l == -1) return 1; layer_button_callback (0, l, 0); } return 0; } static void insert_layerview_buttons (Widget menu) { int i, s; LayerButtons *lb; num_layer_buttons++; s = num_layer_buttons * sizeof (LayerButtons); if (layer_button_list) layer_button_list = (LayerButtons *) realloc (layer_button_list, s); else layer_button_list = (LayerButtons *) malloc (s); lb = layer_button_list + num_layer_buttons - 1; for (i = 0; i < LB_NUM; i++) { static char namestr[] = "Label "; char *name = namestr; int accel_idx = i; Widget btn; name[5] = 'A' + i; switch (i) { case LB_SILK: name = "Silk"; accel_idx = max_copper_layer; break; case LB_RATS: name = "Rat Lines"; accel_idx = max_copper_layer + 1; break; case LB_PINS: name = "Pins/Pads"; break; case LB_VIAS: name = "Vias"; break; case LB_BACK: name = "Far Side"; break; case LB_MASK: name = "Solder Mask"; break; } n = 0; if (accel_idx < 9) { char buf[20], av[30]; Resource *ar; XmString as; sprintf (buf, "Ctrl-%d", accel_idx + 1); as = XmStringCreatePCB (buf); stdarg (XmNacceleratorText, as); ar = resource_create (0); sprintf (av, "ToggleView(%d)", i + 1); resource_add_val (ar, 0, strdup (av), 0); resource_add_val (ar, 0, strdup (av), 0); ar->flags |= FLAG_V; sprintf (av, "Ctrl%d", accel_idx + 1); note_accelerator (av, ar); stdarg (XmNmnemonic, accel_idx + '1'); } btn = XmCreateToggleButton (menu, name, args, n); XtManageChild (btn); XtAddCallback (btn, XmNvalueChangedCallback, (XtCallbackProc) layer_button_callback, (XtPointer) (size_t) i); lb->w[i] = btn; if (i == LB_MASK) note_widget_flag (btn, XmNset, "showmask"); } lb->is_pick = 0; LayersChanged (0, 0, 0, 0); } static void insert_layerpick_buttons (Widget menu) { int i, s; LayerButtons *lb; num_layer_buttons++; s = num_layer_buttons * sizeof (LayerButtons); if (layer_button_list) layer_button_list = (LayerButtons *) realloc (layer_button_list, s); else layer_button_list = (LayerButtons *) malloc (s); lb = layer_button_list + num_layer_buttons - 1; for (i = 0; i < LB_NUMPICK; i++) { static char namestr[] = "Label "; char *name = namestr; int accel_idx = i; char buf[20], av[30]; Widget btn; name[5] = 'A' + i; switch (i) { case LB_SILK: name = "Silk"; accel_idx = max_copper_layer; strcpy (av, "SelectLayer(Silk)"); break; case LB_RATS: name = "Rat Lines"; accel_idx = max_copper_layer + 1; strcpy (av, "SelectLayer(Rats)"); break; default: sprintf (av, "SelectLayer(%d)", i + 1); break; } n = 0; if (accel_idx < 9) { Resource *ar; XmString as; ar = resource_create (0); resource_add_val (ar, 0, strdup (av), 0); resource_add_val (ar, 0, strdup (av), 0); ar->flags |= FLAG_V; sprintf (buf, "%d", i + 1); as = XmStringCreatePCB (buf); stdarg (XmNacceleratorText, as); sprintf (av, "%d", accel_idx + 1); note_accelerator (av, ar); stdarg (XmNmnemonic, accel_idx + '1'); } stdarg (XmNindicatorType, XmONE_OF_MANY); btn = XmCreateToggleButton (menu, name, args, n); XtManageChild (btn); XtAddCallback (btn, XmNvalueChangedCallback, (XtCallbackProc) layerpick_button_callback, (XtPointer) (size_t) i); lb->w[i] = btn; } lb->is_pick = 1; LayersChanged (0, 0, 0, 0); } /*-----------------------------------------------------------------------------*/ typedef struct { Widget w; const char *flagname; int oldval; char *xres; } WidgetFlagType; static WidgetFlagType *wflags = 0; static int n_wflags = 0; static int max_wflags = 0; static void note_widget_flag (Widget w, char *type, char *name) { if (n_wflags >= max_wflags) { max_wflags += 20; wflags = (WidgetFlagType *) realloc (wflags, max_wflags * sizeof (WidgetFlagType)); } wflags[n_wflags].w = w; wflags[n_wflags].flagname = name; wflags[n_wflags].oldval = -1; wflags[n_wflags].xres = type; n_wflags++; } void lesstif_update_widget_flags () { int i; for (i = 0; i < n_wflags; i++) { int v = hid_get_flag (wflags[i].flagname); Arg args[1]; XtSetArg (args[0], wflags[i].xres, v ? 1 : 0); XtSetValues (wflags[i].w, args, 1); wflags[i].oldval = v; } } /*-----------------------------------------------------------------------------*/ HID_Action lesstif_menu_action_list[] = { {"DumpKeys", 0, DumpKeys, dumpkeys_help, dumpkeys_syntax}, {"Debug", 0, Debug, debug_help, debug_syntax}, {"DebugXY", "Click X,Y for Debug", Debug, debugxy_help, debugxy_syntax}, {"GetXY", "", GetXY, getxy_help, getxy_syntax}, {"Return", 0, Return, return_help, return_syntax}, {"LayersChanged", 0, LayersChanged, layerschanged_help, layerschanged_syntax}, {"ToggleView", 0, ToggleView, toggleview_help, toggleview_syntax}, {"SelectLayer", 0, SelectLayer, selectlayer_help, selectlayer_syntax} }; REGISTER_ACTIONS (lesstif_menu_action_list) #if 0 static void do_color (char *value, char *which) { XColor color; if (XParseColor (display, cmap, value, &color)) if (XAllocColor (display, cmap, &color)) { stdarg (which, color.pixel); } } #endif typedef struct ToggleItem { struct ToggleItem *next; Widget w; char *group, *item; XtCallbackProc callback; Resource *node; } ToggleItem; static ToggleItem *toggle_items = 0; static int need_xy = 0, have_xy = 0, action_x, action_y; static void radio_callback (Widget toggle, ToggleItem * me, XmToggleButtonCallbackStruct * cbs) { if (!cbs->set) /* uh uh, can't turn it off */ XmToggleButtonSetState (toggle, 1, 0); else { ToggleItem *ti; for (ti = toggle_items; ti; ti = ti->next) if (strcmp (me->group, ti->group) == 0) { if (me->item == ti->item || strcmp (me->item, ti->item) == 0) XmToggleButtonSetState (ti->w, 1, 0); else XmToggleButtonSetState (ti->w, 0, 0); } me->callback (toggle, me->node, cbs); } } int lesstif_button_event (Widget w, XEvent * e) { have_xy = 1; action_x = e->xbutton.x; action_y = e->xbutton.y; if (!need_xy) return 0; if (w != work_area) return 1; return 0; } void lesstif_get_xy (const char *message) { XmString ls = XmStringCreatePCB ((char *)message); XtManageChild (m_click); n = 0; stdarg (XmNlabelString, ls); XtSetValues (m_click, args, n); //printf("need xy: msg `%s'\n", msg); need_xy = 1; XBell (display, 100); while (!have_xy) { XEvent e; XtAppNextEvent (app_context, &e); XtDispatchEvent (&e); } need_xy = 0; have_xy = 1; XtUnmanageChild (m_click); } void lesstif_get_coords (const char *msg, Coord *px, Coord *py) { if (!have_xy && msg) lesstif_get_xy (msg); if (have_xy) lesstif_coords_to_pcb (action_x, action_y, px, py); } static void callback (Widget w, Resource * node, XmPushButtonCallbackStruct * pbcs) { int vi; have_xy = 0; lesstif_show_crosshair (0); if (pbcs->event && pbcs->event->type == KeyPress) { Dimension wx, wy; Widget aw = XtWindowToWidget (display, pbcs->event->xkey.window); action_x = pbcs->event->xkey.x; action_y = pbcs->event->xkey.y; if (aw) { Widget p = work_area; while (p && p != aw) { n = 0; stdarg (XmNx, &wx); stdarg (XmNy, &wy); XtGetValues (p, args, n); action_x -= wx; action_y -= wy; p = XtParent (p); } if (p == aw) have_xy = 1; } //pcb_printf("have xy from %s: %$mD\n", XtName(aw), action_x, action_y); } lesstif_need_idle_proc (); for (vi = 1; vi < node->c; vi++) if (resource_type (node->v[vi]) == 10) if (hid_parse_actions (node->v[vi].value)) return; } typedef struct acc_table_t { char mods; char key_char; union { /* If M_Multi is set in mods, these are used to chain to the next attribute table for multi-key accelerators. */ struct { int n_chain; struct acc_table_t *chain; } c; /* If M_Multi isn't set, these are used to map a single key to an event. */ struct { KeySym key; Resource *node; } a; } u; } acc_table_t; static acc_table_t *acc_table; static int acc_num = 0; static int acc_sort (const void *va, const void *vb) { acc_table_t *a = (acc_table_t *) va; acc_table_t *b = (acc_table_t *) vb; if (a->key_char != b->key_char) return a->key_char - b->key_char; if (!(a->mods & M_Multi)) if (a->u.a.key != b->u.a.key) return a->u.a.key - b->u.a.key; return a->mods - b->mods; } static int DumpKeys2 () { int i; char ch[2]; printf ("in dumpkeys! %d\n", acc_num); qsort (acc_table, acc_num, sizeof (acc_table_t), acc_sort); ch[1] = 0; for (i = 0; i < acc_num; i++) { char mod[16]; int vi; char *tabs = ""; sprintf (mod, "%s%s%s", acc_table[i].mods & M_Alt ? "Alt-" : "", acc_table[i].mods & M_Ctrl ? "Ctrl-" : "", acc_table[i].mods & M_Shift ? "Shift-" : ""); ch[0] = toupper ((int) acc_table[i].key_char); printf ("%16s%s\t", mod, acc_table[i].key_char ? ch : XKeysymToString (acc_table[i]. u.a.key)); for (vi = 1; vi < acc_table[i].u.a.node->c; vi++) if (resource_type (acc_table[i].u.a.node->v[vi]) == 10) { printf ("%s%s", tabs, acc_table[i].u.a.node->v[vi].value); tabs = "\n\t\t\t "; } printf ("\n"); } exit (0); } static acc_table_t * find_or_create_acc (char mods, char key, KeySym sym, acc_table_t **table, int *n_ents) { int i, max; acc_table_t *a; if (*table) for (i=(*n_ents)-1; i>=0; i--) { a = & (*table)[i]; if (a->mods == mods && a->key_char == key && (mods & M_Multi || a->u.a.key == sym)) return a; } (*n_ents) ++; max = (*n_ents + 16) & ~15; if (*table) *table = (acc_table_t *) realloc (*table, max * sizeof (acc_table_t)); else *table = (acc_table_t *) malloc (max * sizeof (acc_table_t)); a = & ((*table)[(*n_ents)-1]); memset (a, 0, sizeof(acc_table_t)); a->mods = mods; a->key_char = key; if (!(mods & M_Multi)) a->u.a.key = sym; return a; } static void note_accelerator (char *acc, Resource * node) { char *orig_acc = acc; int mods = 0; acc_table_t *a; char key_char = 0; KeySym key = 0; int multi_key = 0; while (isalpha ((int) acc[0])) { if (strncmp (acc, "Shift", 5) == 0) { mods |= M_Shift; acc += 5; } else if (strncmp (acc, "Ctrl", 4) == 0) { mods |= M_Ctrl; acc += 4; } else if (strncmp (acc, "Alt", 3) == 0) { mods |= M_Alt; acc += 3; } else { printf ("Must be Shift/Ctrl/Alt: %s\n", acc); return; } while (*acc == ' ') acc++; } if (strncmp (acc, "", 6) == 0) { multi_key = 1; acc ++; } else if (strncmp (acc, "", 5)) { fprintf (stderr, "accelerator \"%s\" not or \n", orig_acc); return; } /* We have a hard time specifying the Enter key the "usual" way. */ if (strcmp (acc, "Enter") == 0) acc = "\r"; acc += 5; if (acc[0] && acc[1] == 0) { key_char = acc[0]; a = find_or_create_acc (mods, key_char, 0, &acc_table, &acc_num); } else if (multi_key) { acc_table_t **ap = &acc_table; int *np = &acc_num; mods |= M_Multi; while (acc[0] && acc[1]) { a = find_or_create_acc (mods, acc[0], 0, ap, np); ap = & (a->u.c.chain); np = & (a->u.c.n_chain); acc ++; } a = find_or_create_acc (mods & ~M_Multi, acc[0], 0, ap, np); } else { key = XStringToKeysym (acc); if (key == NoSymbol && !key_char) { printf ("no symbol for %s\n", acc); return; } a = find_or_create_acc (mods, 0, key, &acc_table, &acc_num); } a->u.a.node = node; } #if 0 static void dump_multi (int ix, int ind, acc_table_t *a, int n) { int i = ix; while (n--) { if (a->mods & M_Multi) { printf("%*cacc[%d] mods %x char %c multi %p/%d\n", ind, ' ', i, a->mods, a->key_char, a->u.c.chain, a->u.c.n_chain); dump_multi(0, ind+4, a->u.c.chain, a->u.c.n_chain); } else { printf("%*cacc[%d] mods %x char %c key %d node `%s'\n", ind, ' ', i, a->mods, a->key_char, a->u.a.key, a->u.a.node->v[0].value); } a++; i++; } } #else #define dump_multi(x,a,b,c) #endif static acc_table_t *cur_table = 0; static int cur_ntable = 0; /*! * \brief . * * We sort these such that the ones with explicit modifiers come before * the ones with implicit modifiers. * That way, a ShiftCode gets chosen before a Code. */ static int acc_sort_rev (const void *va, const void *vb) { acc_table_t *a = (acc_table_t *) va; acc_table_t *b = (acc_table_t *) vb; if (a->key_char != b->key_char) return a->key_char - b->key_char; if (!(a->mods & M_Multi)) if (a->u.a.key != b->u.a.key) return a->u.a.key - b->u.a.key; return b->mods - a->mods; } int lesstif_key_event (XKeyEvent * e) { char buf[10], buf2[10]; KeySym sym, sym2; int slen, slen2; int mods = 0; int i, vi; static int sorted = 0; acc_table_t *my_table = 0; if (!sorted) { sorted = 1; qsort (acc_table, acc_num, sizeof (acc_table_t), acc_sort_rev); } if (e->state & ShiftMask) mods |= M_Shift; if (e->state & ControlMask) mods |= M_Ctrl; if (e->state & Mod1Mask) mods |= M_Alt; e->state &= ~(ControlMask | Mod1Mask); slen = XLookupString (e, buf, sizeof (buf), &sym, NULL); if (e->state & ShiftMask) { e->state &= ~ShiftMask; slen2 = XLookupString (e, buf2, sizeof (buf2), &sym2, NULL); } else slen2 = slen; /* Ignore these. */ switch (sym) { case XK_Shift_L: case XK_Shift_R: case XK_Control_L: case XK_Control_R: case XK_Caps_Lock: case XK_Shift_Lock: case XK_Meta_L: case XK_Meta_R: case XK_Alt_L: case XK_Alt_R: case XK_Super_L: case XK_Super_R: case XK_Hyper_L: case XK_Hyper_R: case XK_ISO_Level3_Shift: return 1; } if (cur_table == 0) { cur_table = acc_table; cur_ntable = acc_num; } //printf("\nmods %x key %d str `%s' in %p/%d\n", mods, (int)sym, buf, cur_table, cur_ntable); #define KM(m) ((m) & ~M_Multi) for (i = 0; i < cur_ntable; i++) { dump_multi (i, 0, cur_table+i, 1); if (KM(cur_table[i].mods) == mods) { if (sym == acc_table[i].u.a.key) break; } if (KM(cur_table[i].mods) == (mods & ~M_Shift)) { if (slen == 1 && buf[0] == cur_table[i].key_char) break; if (sym == cur_table[i].u.a.key) break; } if (mods & M_Shift && KM(cur_table[i].mods) == mods) { if (slen2 == 1 && buf2[0] == cur_table[i].key_char) break; if (sym2 == acc_table[i].u.a.key) break; } } if (i == cur_ntable) { if (cur_table == acc_table) lesstif_log ("Key \"%s\" not tied to an action\n", buf); else lesstif_log ("Key \"%s\" not tied to a multi-key action\n", buf); cur_table = 0; return 0; } if (cur_table[i].mods & M_Multi) { cur_ntable = cur_table[i].u.c.n_chain; cur_table = cur_table[i].u.c.chain; dump_multi (0, 0, cur_table, cur_ntable); return 1; } if (e->window == XtWindow (work_area)) { have_xy = 1; action_x = e->x; action_y = e->y; } else have_xy = 0; /* Parsing actions may not return until more user interaction happens, so remember which table we're scanning. */ my_table = cur_table; for (vi = 1; vi < my_table[i].u.a.node->c; vi++) if (resource_type (my_table[i].u.a.node->v[vi]) == 10) if (hid_parse_actions (my_table[i].u.a.node->v[vi].value)) break; cur_table = 0; return 1; } static void add_resource_to_menu (Widget menu, Resource * node, XtCallbackProc callback) { int i, j; char *v; Widget sub, btn; Resource *r; for (i = 0; i < node->c; i++) switch (resource_type (node->v[i])) { case 101: /* named subnode */ n = 0; stdarg (XmNtearOffModel, XmTEAR_OFF_ENABLED); sub = XmCreatePulldownMenu (menu, node->v[i].name, args, n); XtSetValues (sub, args, n); n = 0; stdarg (XmNsubMenuId, sub); btn = XmCreateCascadeButton (menu, node->v[i].name, args, n); XtManageChild (btn); add_resource_to_menu (sub, node->v[i].subres, callback); break; case 1: /* unnamed subres */ n = 0; #if 0 if ((v = resource_value (node->v[i].subres, "fg"))) { do_color (v, XmNforeground); } if ((v = resource_value (node->v[i].subres, "bg"))) { do_color (v, XmNbackground); } if ((v = resource_value (node->v[i].subres, "font"))) { XFontStruct *fs = XLoadQueryFont (display, v); if (fs) { XmFontList fl = XmFontListCreate (fs, XmSTRING_DEFAULT_CHARSET); stdarg (XmNfontList, fl); } } #endif if ((v = resource_value (node->v[i].subres, "m"))) { stdarg (XmNmnemonic, v); } if ((r = resource_subres (node->v[i].subres, "a"))) { XmString as = XmStringCreatePCB (r->v[0].value); stdarg (XmNacceleratorText, as); //stdarg(XmNaccelerator, r->v[1].value); note_accelerator (r->v[1].value, node->v[i].subres); } v = "button"; for (j = 0; j < node->v[i].subres->c; j++) if (resource_type (node->v[i].subres->v[j]) == 10) { v = node->v[i].subres->v[j].value; break; } stdarg (XmNlabelString, XmStringCreatePCB (v)); if (node->v[i].subres->flags & FLAG_S) { int nn = n; stdarg (XmNtearOffModel, XmTEAR_OFF_ENABLED); sub = XmCreatePulldownMenu (menu, v, args + nn, n - nn); n = nn; stdarg (XmNsubMenuId, sub); btn = XmCreateCascadeButton (menu, "menubutton", args, n); XtManageChild (btn); add_resource_to_menu (sub, node->v[i].subres, callback); } else { Resource *radio = resource_subres (node->v[i].subres, "radio"); char *checked = resource_value (node->v[i].subres, "checked"); char *label = resource_value (node->v[i].subres, "sensitive"); if (radio) { ToggleItem *ti = (ToggleItem *) malloc (sizeof (ToggleItem)); ti->next = toggle_items; ti->group = radio->v[0].value; ti->item = radio->v[1].value; ti->callback = callback; ti->node = node->v[i].subres; toggle_items = ti; if (resource_value (node->v[i].subres, "set")) { stdarg (XmNset, True); } stdarg (XmNindicatorType, XmONE_OF_MANY); btn = XmCreateToggleButton (menu, "menubutton", args, n); ti->w = btn; XtAddCallback (btn, XmNvalueChangedCallback, (XtCallbackProc) radio_callback, (XtPointer) ti); } else if (checked) { if (strchr (checked, ',')) stdarg (XmNindicatorType, XmONE_OF_MANY); else stdarg (XmNindicatorType, XmN_OF_MANY); btn = XmCreateToggleButton (menu, "menubutton", args, n); XtAddCallback (btn, XmNvalueChangedCallback, callback, (XtPointer) node->v[i].subres); } else if (label && strcmp (label, "false") == 0) { stdarg (XmNalignment, XmALIGNMENT_BEGINNING); btn = XmCreateLabel (menu, "menulabel", args, n); } else { btn = XmCreatePushButton (menu, "menubutton", args, n); XtAddCallback (btn, XmNactivateCallback, callback, (XtPointer) node->v[i].subres); } for (j = 0; j < node->v[i].subres->c; j++) switch (resource_type (node->v[i].subres->v[j])) { case 110: /* named value = X resource */ { char *n = node->v[i].subres->v[j].name; if (strcmp (n, "fg") == 0) n = "foreground"; if (strcmp (n, "bg") == 0) n = "background"; if (strcmp (n, "m") == 0 || strcmp (n, "a") == 0 || strcmp (n, "sensitive") == 0) break; if (strcmp (n, "checked") == 0) { note_widget_flag (btn, XmNset, node->v[i].subres->v[j].value); break; } if (strcmp (n, "active") == 0) { note_widget_flag (btn, XmNsensitive, node->v[i].subres->v[j].value); break; } XtVaSetValues (btn, XtVaTypedArg, n, XtRString, node->v[i].subres->v[j].value, strlen (node->v[i].subres->v[j].value) + 1, NULL); } break; } XtManageChild (btn); } break; case 10: /* unnamed value */ n = 0; if (node->v[i].value[0] == '@') { if (strcmp (node->v[i].value, "@layerview") == 0) insert_layerview_buttons (menu); if (strcmp (node->v[i].value, "@layerpick") == 0) insert_layerpick_buttons (menu); if (strcmp (node->v[i].value, "@routestyles") == 0) lesstif_insert_style_buttons (menu); } else if (strcmp (node->v[i].value, "-") == 0) { btn = XmCreateSeparator (menu, "sep", args, n); XtManageChild (btn); } else if (i > 0) { btn = XmCreatePushButton (menu, node->v[i].value, args, n); XtManageChild (btn); } break; } } extern char *lesstif_pcbmenu_path; Widget lesstif_menu (Widget parent, char *name, Arg * margs, int mn) { Widget mb = XmCreateMenuBar (parent, name, margs, mn); char *filename; Resource *r = 0, *bir; char *home_pcbmenu, *home; int screen; Resource *mr; display = XtDisplay (mb); screen = DefaultScreen (display); cmap = DefaultColormap (display, screen); /* homedir is set by the core */ home = homedir; home_pcbmenu = NULL; if (home == NULL) { Message ("Warning: could not determine home directory (from HOME)\n"); } else { home_pcbmenu = Concat (home, PCB_DIR_SEPARATOR_S, ".pcb", PCB_DIR_SEPARATOR_S, "pcb-menu.res", NULL); } if (access ("pcb-menu.res", R_OK) == 0) filename = "pcb-menu.res"; else if (home_pcbmenu != NULL && (access (home_pcbmenu, R_OK) == 0)) filename = home_pcbmenu; else if (access (lesstif_pcbmenu_path, R_OK) == 0) filename = lesstif_pcbmenu_path; else filename = 0; bir = resource_parse (0, pcb_menu_default); if (!bir) { fprintf (stderr, "Error: internal menu resource didn't parse\n"); exit(1); } if (filename) r = resource_parse (filename, 0); if (!r) r = bir; if (home_pcbmenu != NULL) { free (home_pcbmenu); } mr = resource_subres (r, "MainMenu"); if (!mr) mr = resource_subres (bir, "MainMenu"); if (mr) add_resource_to_menu (mb, mr, (XtCallbackProc) callback); mr = resource_subres (r, "Mouse"); if (!mr) mr = resource_subres (bir, "Mouse"); if (mr) load_mouse_resource (mr); if (do_dump_keys) DumpKeys2 (); return mb; } void lesstif_uninit_menu (void) { /*! \todo XtDestroyWidget (...); */ } pcb-4.3.0/src/hid/lesstif/lesstif.h0000664000175000017500000000470013773431044014042 00000000000000#define app_context lesstif_app_context #define appwidget lesstif_appwidget #define display lesstif_display #define screen_s lesstif_screen_s #define screen lesstif_screen #define mainwind lesstif_mainwind #define work_area lesstif_work_area #define messages lesstif_messages #define command lesstif_command #define hscroll lesstif_hscroll #define vscroll lesstif_vscroll #define m_click lesstif_message_click extern XtAppContext app_context; extern Widget appwidget; extern Display *display; extern Screen *screen_s; extern int screen; extern Widget mainwind, work_area, command, hscroll, vscroll; extern Widget m_click; extern Widget lesstif_menu (Widget, char *, Arg *, int); extern int lesstif_key_event (XKeyEvent *); extern int lesstif_button_event (Widget w, XEvent * e); /* Returns TRUE if the point mapped to the PCB region, FALSE (=0) if we're off-board. Note that *pcbxy is always written to, even if out of range. */ extern int lesstif_winxy_to_pcbxy (int winx, int winy, int *pcbx, int *pcby); /* Returns TRUE if the point is in the window, FALSE (=0) otherwise. */ extern int lesstif_pcbxy_to_winxy (int pcbx, int pcby, int *winx, int *winy); extern void lesstif_need_idle_proc (void); extern void lesstif_show_crosshair (int); extern void lesstif_invalidate_all (void); extern void lesstif_coords_to_pcb (int, int, Coord *, Coord *); extern void lesstif_get_xy (const char *msg); extern void lesstif_update_widget_flags (void); extern int lesstif_call_action (const char *, int, char **); extern void lesstif_sizes_reset (void); extern void lesstif_pan_fixup (void); extern void lesstif_show_library (void); extern void lesstif_show_netlist (void); extern Pixel lesstif_parse_color (char *value); extern void lesstif_insert_style_buttons (Widget menu); extern void lesstif_styles_update_values (); extern void lesstif_update_layer_groups (); extern void lesstif_update_status_line (); extern char *lesstif_prompt_for (const char *, const char *); extern char *lesstif_fileselect (const char *, const char *, char *, char *, const char *, int); extern void lesstif_log (const char *fmt, ...); extern void lesstif_attributes_dialog (char *, AttributeListType *); #ifndef XtRPCBCoord #define XtRPCBCoord "PCBCoord" #endif #define need_idle_proc lesstif_need_idle_proc #define show_crosshair lesstif_show_crosshair static XmString XmStringCreatePCB (char *x) { if (x && x[0]) x = gettext (x); return XmStringCreateLtoR (x, XmFONTLIST_DEFAULT_TAG); } pcb-4.3.0/src/hid/lesstif/styles.c0000664000175000017500000003071313773431044013712 00000000000000#ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "xincludes.h" #include "compat.h" #include "global.h" #include "data.h" #include "set.h" #include "misc.h" #include "mymem.h" #include "pcb-printf.h" #include "hid.h" #include "../hidint.h" #include "lesstif.h" #ifdef HAVE_LIBDMALLOC #include #endif /* There are three places where styles are kept: First, the "active" style is in Settings.LineThickness et al. Second, there are NUM_STYLES styles in PCB->RouteStyle[]. Third, there are NUM_STYLES styles in Settings.RouteStyle[] Selecting a style copies its values to the active style. We also need a way to modify the active style, copy the active style to PCB->RouteStyle[], and copy PCB->RouteStyle[] to Settings.RouteStyle[]. Since Lesstif reads the default style from .Xdefaults, we can ignore Settings.RouteStyle[] in general, as it's only used to initialize new PCB files. So, we need to do PCB->RouteStyle <-> active style. */ static Arg args[30]; static int n; #define stdarg(t,v) XtSetArg(args[n], t, v); n++ typedef enum { SSthick, SSdiam, SShole, SSkeep, SSviamask, SSNUM } StyleValues; static Widget style_dialog = 0; static Widget style_values[SSNUM]; static Widget style_pb[NUM_STYLES]; static Widget units_pb[SSNUM]; static int name_hashes[NUM_STYLES]; static Widget value_form, value_labels, value_texts, units_form; static int local_update = 0; XmString xms_mm, xms_mil; static const Unit *unit = 0; static XmString ustr; static int hash (char *cp) { int h = 0; while (*cp) { h = h * 13 + *(unsigned char *) cp; h ^= (h >> 16); cp++; } return h; } typedef struct { Widget w[NUM_STYLES]; } StyleButtons; static StyleButtons *style_button_list = 0; static int num_style_buttons = 0; static char *value_names[] = { "Thickness", "Diameter", "Hole", "Keepaway", "ViaMask" }; static int RouteStylesChanged (int argc, char **argv, Coord x, Coord y); static void update_one_value (int i, Coord v) { char buf[100]; pcb_snprintf (buf, sizeof (buf), "%m+%.2mS", unit->allow, v); XmTextSetString (style_values[i], buf); n = 0; stdarg (XmNlabelString, ustr); XtSetValues (units_pb[i], args, n); } static void update_values () { local_update = 1; update_one_value (SSthick, Settings.LineThickness); update_one_value (SSdiam, Settings.ViaThickness); update_one_value (SShole, Settings.ViaDrillingHole); update_one_value (SSkeep, Settings.Keepaway); update_one_value (SSviamask, Settings.ViaMaskAperture); local_update = 0; lesstif_update_status_line (); } void lesstif_styles_update_values () { if (!style_dialog) { lesstif_update_status_line (); return; } unit = Settings.grid_unit; ustr = XmStringCreateLocalized ((char *)Settings.grid_unit->suffix); update_values (); } static void update_style_buttons () { int i = hid_get_flag ("style"); int j, n; for (n = 0; n < num_style_buttons; n++) { for (j = 0; j < NUM_STYLES; j++) if (j != i - 1) XmToggleButtonSetState (style_button_list[n].w[j], 0, 0); else XmToggleButtonSetState (style_button_list[n].w[j], 1, 0); } if (style_dialog) { for (j = 0; j < NUM_STYLES; j++) if (j != i - 1) XmToggleButtonSetState (style_pb[j], 0, 0); else XmToggleButtonSetState (style_pb[j], 1, 0); } } static void style_value_cb (Widget w, int i, void *cbs) { Coord n; char *s; if (local_update) return; s = XmTextGetString (w); n = GetValueEx (s, NULL, NULL, NULL, unit->suffix); switch (i) { case SSthick: Settings.LineThickness = n; break; case SSdiam: Settings.ViaThickness = n; break; case SShole: Settings.ViaDrillingHole = n; break; case SSkeep: Settings.Keepaway = n; break; case SSviamask: Settings.ViaMaskAperture = n; break; } update_style_buttons (); } static void units_cb () { if (unit == get_unit_struct ("mm")) unit = get_unit_struct ("mil"); else unit = get_unit_struct ("mm"); ustr = XmStringCreateLocalized ((char *)unit->suffix); update_values (); } static Widget style_value (int i) { Widget w, l; n = 0; stdarg (XmNtopAttachment, XmATTACH_POSITION); stdarg (XmNtopPosition, i); stdarg (XmNbottomAttachment, XmATTACH_POSITION); stdarg (XmNbottomPosition, i + 1); stdarg (XmNleftAttachment, XmATTACH_FORM); stdarg (XmNrightAttachment, XmATTACH_FORM); stdarg (XmNalignment, XmALIGNMENT_END); l = XmCreateLabel (value_labels, value_names[i], args, n); XtManageChild (l); n = 0; stdarg (XmNtopAttachment, XmATTACH_POSITION); stdarg (XmNtopPosition, i); stdarg (XmNbottomAttachment, XmATTACH_POSITION); stdarg (XmNbottomPosition, i + 1); stdarg (XmNleftAttachment, XmATTACH_FORM); stdarg (XmNrightAttachment, XmATTACH_FORM); stdarg (XmNcolumns, 8); w = XmCreateTextField (value_texts, value_names[i], args, n); XtAddCallback (w, XmNvalueChangedCallback, (XtCallbackProc) style_value_cb, (XtPointer) (size_t) i); XtManageChild (w); n = 0; stdarg (XmNtopAttachment, XmATTACH_POSITION); stdarg (XmNtopPosition, i); stdarg (XmNbottomAttachment, XmATTACH_POSITION); stdarg (XmNbottomPosition, i + 1); stdarg (XmNleftAttachment, XmATTACH_FORM); stdarg (XmNrightAttachment, XmATTACH_FORM); stdarg (XmNlabelString, ustr); units_pb[i] = XmCreatePushButton (units_form, value_names[i], args, n); XtAddCallback (units_pb[i], XmNactivateCallback, (XtCallbackProc) units_cb, (XtPointer) (size_t) i); XtManageChild (units_pb[i]); return w; } static void style_name_cb (Widget w, int i, XmToggleButtonCallbackStruct * cbs) { char *newname = lesstif_prompt_for ("New name", PCB->RouteStyle[i].Name); free (PCB->RouteStyle[i].Name); PCB->RouteStyle[i].Name = newname; RouteStylesChanged (0, 0, 0, 0); } static void style_set_cb (Widget w, int i, XmToggleButtonCallbackStruct * cbs) { PCB->RouteStyle[i].Thick = Settings.LineThickness; PCB->RouteStyle[i].Diameter = Settings.ViaThickness; PCB->RouteStyle[i].Hole = Settings.ViaDrillingHole; PCB->RouteStyle[i].Keepaway = Settings.Keepaway; PCB->RouteStyle[i].ViaMask = Settings.ViaMaskAperture; update_style_buttons (); } static void style_selected (Widget w, int i, XmToggleButtonCallbackStruct * cbs) { RouteStyleType *style; int j, n; if (cbs && cbs->set == 0) { XmToggleButtonSetState (w, 1, 0); return; } style = PCB->RouteStyle + i; SetLineSize (style->Thick); SetViaSize (style->Diameter, true); SetViaDrillingHole (style->Hole, true); SetKeepawayWidth (style->Keepaway); SetViaMaskAperture(style->ViaMask); if (style_dialog) { for (j = 0; j < NUM_STYLES; j++) if (j != i) XmToggleButtonSetState (style_pb[j], 0, 0); else XmToggleButtonSetState (style_pb[j], 1, 0); update_values (); } else lesstif_update_status_line (); for (n = 0; n < num_style_buttons; n++) { for (j = 0; j < NUM_STYLES; j++) if (j != i) XmToggleButtonSetState (style_button_list[n].w[j], 0, 0); else XmToggleButtonSetState (style_button_list[n].w[j], 1, 0); } } static Widget style_button (int i) { Widget pb, set; n = 0; stdarg (XmNtopAttachment, XmATTACH_WIDGET); stdarg (XmNtopWidget, i ? style_pb[i - 1] : value_form); stdarg (XmNleftAttachment, XmATTACH_FORM); stdarg (XmNlabelString, XmStringCreatePCB ("Name")); set = XmCreatePushButton (style_dialog, "style", args, n); XtManageChild (set); XtAddCallback (set, XmNactivateCallback, (XtCallbackProc) style_name_cb, (XtPointer) (size_t) i); n = 0; stdarg (XmNtopAttachment, XmATTACH_WIDGET); stdarg (XmNtopWidget, i ? style_pb[i - 1] : value_form); stdarg (XmNleftAttachment, XmATTACH_WIDGET); stdarg (XmNleftWidget, set); stdarg (XmNlabelString, XmStringCreatePCB ("Set")); set = XmCreatePushButton (style_dialog, "style", args, n); XtManageChild (set); XtAddCallback (set, XmNactivateCallback, (XtCallbackProc) style_set_cb, (XtPointer) (size_t) i); n = 0; stdarg (XmNtopAttachment, XmATTACH_WIDGET); stdarg (XmNtopWidget, i ? style_pb[i - 1] : value_form); stdarg (XmNrightAttachment, XmATTACH_FORM); stdarg (XmNleftAttachment, XmATTACH_WIDGET); stdarg (XmNleftWidget, set); stdarg (XmNlabelString, XmStringCreatePCB (PCB->RouteStyle[i].Name)); stdarg (XmNindicatorType, XmONE_OF_MANY); stdarg (XmNalignment, XmALIGNMENT_BEGINNING); pb = XmCreateToggleButton (style_dialog, "style", args, n); XtManageChild (pb); XtAddCallback (pb, XmNvalueChangedCallback, (XtCallbackProc) style_selected, (XtPointer) (size_t) i); return pb; } static const char adjuststyle_syntax[] = "AdjustStyle()"; static const char adjuststyle_help[] = "Displays the route style adjustment window."; /* %start-doc actions AdjustStyle %end-doc */ static int AdjustStyle (int argc, char **argv, Coord x, Coord y) { if (!mainwind) return 1; if (style_dialog == 0) { int i; unit = Settings.grid_unit; ustr = XmStringCreateLocalized ((char *)unit->suffix); n = 0; stdarg (XmNautoUnmanage, False); stdarg (XmNtitle, "Route Styles"); style_dialog = XmCreateFormDialog (mainwind, "style", args, n); n = 0; stdarg (XmNtopAttachment, XmATTACH_FORM); stdarg (XmNleftAttachment, XmATTACH_FORM); stdarg (XmNrightAttachment, XmATTACH_FORM); value_form = XmCreateForm (style_dialog, "values", args, n); XtManageChild (value_form); n = 0; stdarg (XmNtopAttachment, XmATTACH_FORM); stdarg (XmNrightAttachment, XmATTACH_FORM); stdarg (XmNbottomAttachment, XmATTACH_FORM); stdarg (XmNfractionBase, SSNUM); stdarg (XmNresizePolicy, XmRESIZE_GROW); units_form = XmCreateForm (value_form, "units", args, n); XtManageChild (units_form); n = 0; stdarg (XmNtopAttachment, XmATTACH_FORM); stdarg (XmNbottomAttachment, XmATTACH_FORM); stdarg (XmNleftAttachment, XmATTACH_FORM); stdarg (XmNfractionBase, SSNUM); value_labels = XmCreateForm (value_form, "values", args, n); XtManageChild (value_labels); n = 0; stdarg (XmNtopAttachment, XmATTACH_FORM); stdarg (XmNbottomAttachment, XmATTACH_FORM); stdarg (XmNrightAttachment, XmATTACH_WIDGET); stdarg (XmNrightWidget, units_form); stdarg (XmNleftAttachment, XmATTACH_WIDGET); stdarg (XmNleftWidget, value_labels); stdarg (XmNfractionBase, SSNUM); value_texts = XmCreateForm (value_form, "values", args, n); XtManageChild (value_texts); for (i = 0; i < SSNUM; i++) { style_values[i] = style_value (i); } for (i = 0; i < NUM_STYLES; i++) { name_hashes[i] = hash (PCB->RouteStyle[i].Name); style_pb[i] = style_button (i); } update_values (); update_style_buttons (); } XtManageChild (style_dialog); return 0; } static int RouteStylesChanged (int argc, char **argv, Coord x, Coord y) { int i, j, h; if (!PCB || !PCB->RouteStyle[0].Name) return 0; update_style_buttons (); if (!style_dialog) return 0; for (j = 0; j < NUM_STYLES; j++) { h = hash (PCB->RouteStyle[j].Name); if (name_hashes[j] == h) continue; name_hashes[j] = h; n = 0; stdarg (XmNlabelString, XmStringCreatePCB (PCB->RouteStyle[j].Name)); if (style_dialog) XtSetValues (style_pb[j], args, n); for (i = 0; i < num_style_buttons; i++) XtSetValues (style_button_list[i].w[j], args, n); } update_values (); return 0; } void lesstif_insert_style_buttons (Widget menu) { StyleButtons *sb; int s, i; num_style_buttons++; s = num_style_buttons * sizeof (StyleButtons); style_button_list = (StyleButtons *) realloc (style_button_list, s); sb = style_button_list + num_style_buttons - 1; for (i = 0; i < NUM_STYLES; i++) { Widget btn; n = 0; stdarg (XmNindicatorType, XmONE_OF_MANY); stdarg (XmNlabelString, XmStringCreatePCB (PCB->RouteStyle[i].Name)); btn = XmCreateToggleButton (menu, "style", args, n); XtManageChild (btn); XtAddCallback (btn, XmNvalueChangedCallback, (XtCallbackProc) style_selected, (XtPointer) (size_t) i); sb->w[i] = btn; } update_style_buttons (); } HID_Action lesstif_styles_action_list[] = { {"AdjustStyle", 0, AdjustStyle, adjuststyle_help, adjuststyle_syntax}, {"RouteStylesChanged", 0, RouteStylesChanged, routestyleschanged_help, routestyleschanged_syntax} }; REGISTER_ACTIONS (lesstif_styles_action_list) pcb-4.3.0/src/hid/lesstif/xincludes.h0000664000175000017500000000212713773431044014370 00000000000000/* * Some of the X headers are not very friendly in terms of namespace. * For example, X.h typedef's Mask but we use Mask in the core of pcb * and this causes problem. To avoid this, pull in the X headers in * this file where we can add workarounds as needed. */ #define Mask X_Mask #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_XRENDER #include #endif /* HAVE_XRENDER */ #ifdef HAVE_XINERAMA #include #endif /* HAVE_XINERAMA */ #undef Mask pcb-4.3.0/src/hid/lesstif/main.c0000664000175000017500000031513513773431044013317 00000000000000/*! * \file src/hid/lesstif/main.c * * \brief The lesstif HID implementation * *
* *

Copyright.

\n * * PCB, interactive printed circuit board design * * Copyright (C) 1994,1995,1996,1997,1998,2005,2006 Thomas Nau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contact addresses for paper mail and Email: * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany * Thomas.Nau@rz.uni-ulm.de * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include "xincludes.h" #include "global.h" #include "data.h" #include "action.h" #include "crosshair.h" #include "mymem.h" #include "misc.h" #include "pcb-printf.h" #include "resource.h" #include "clip.h" #include "error.h" #include "hid.h" #include "hid_draw.h" #include "../hidint.h" #include "hid/common/hidnogui.h" #include "hid/common/draw_helpers.h" #include "hid/common/hid_resource.h" #include "lesstif.h" #ifdef HAVE_LIBDMALLOC #include #endif #include #ifndef XtRDouble #define XtRDouble "Double" #endif /* How big the viewport can be relative to the pcb size. */ #define MAX_ZOOM_SCALE 10 #define UUNIT Settings.grid_unit->allow typedef struct hid_gc_struct { HID *me_pointer; Pixel color; const char *colorname; int width; EndCapStyle cap; char xor_set; char erase; } hid_gc_struct; static HID lesstif_hid; static HID_DRAW lesstif_graphics; #define CRASH fprintf(stderr, "HID error: pcb called unimplemented GUI function %s\n", __FUNCTION__), abort() XtAppContext app_context; Widget appwidget; Display *display; static Window window = 0; static Cursor my_cursor = 0; static int old_cursor_mode = -1; static int over_point = 0; /* The first is the "current" pixmap. The main_ is the real one we usually use, the mask_ are the ones for doing polygon masks. The pixmap is the saved pixels, the bitmap is for the "erase" color. We set pixmap to point to main_pixmap or mask_pixmap as needed. */ static Pixmap pixmap = 0; static Pixmap main_pixmap = 0; static Pixmap mask_pixmap = 0; static Pixmap mask_bitmap = 0; static enum mask_mode use_mask = HID_MASK_OFF; static int use_xrender = 0; #ifdef HAVE_XRENDER static Picture main_picture; static Picture mask_picture; static Pixmap pale_pixmap; static Picture pale_picture; #endif /* HAVE_XRENDER */ static int pixmap_w = 0, pixmap_h = 0; Screen *screen_s; int screen; static Colormap colormap; static GC my_gc = 0, bg_gc, clip_gc = 0, bset_gc = 0, bclear_gc = 0, mask_gc = 0; static Pixel bgcolor, offlimit_color, grid_color; static int bgred, bggreen, bgblue; static GC arc1_gc, arc2_gc; static hidGC crosshair_gc; /* These are for the pinout windows. */ typedef struct PinoutData { struct PinoutData *prev, *next; Widget form; Window window; Coord left, right, top, bottom; /* PCB extents of item */ Coord x, y; /* PCB coordinates of upper right corner of window */ double zoom; /* PCB units per screen pixel */ int v_width, v_height; /* pixels */ void *item; } PinoutData; /* Linked list of all pinout windows. */ static PinoutData *pinouts = 0; /* If set, we are currently updating this pinout window. */ static PinoutData *pinout = 0; static int crosshair_x = 0, crosshair_y = 0; static int in_move_event = 0, crosshair_in_window = 1; Widget mainwind; Widget work_area, messages, command, hscroll, vscroll; static Widget m_mark, m_crosshair, m_grid, m_zoom, m_mode, m_status; static Widget m_rats; Widget lesstif_m_layer; Widget m_click; /* This is the size, in pixels, of the viewport. */ static int view_width, view_height; /* This is the PCB location represented by the upper left corner of the viewport. Note that PCB coordinates put 0,0 in the upper left, much like X does. */ static int view_left_x = 0, view_top_y = 0; /* Denotes PCB units per screen pixel. Larger numbers mean zooming out - the largest value means you are looking at the whole board. */ static double view_zoom = MIL_TO_COORD (10), prev_view_zoom = MIL_TO_COORD (10); static bool flip_x = 0, flip_y = 0; static bool autofade = 0; static bool crosshair_on = true; /* --------------------------------------------------------------------------- * some local prototypes */ static hidGC lesstif_make_gc (void); static void ShowCrosshair (bool show) { if (crosshair_on == show) return; notify_crosshair_change (false); if (Marked.status) notify_mark_change (false); crosshair_on = show; notify_crosshair_change (true); if (Marked.status) notify_mark_change (true); } static int flag_flipx (void *data) { return flip_x; } static int flag_flipy (void *data) { return flip_y; } HID_Flag lesstif_main_flag_list[] = { {"flip_x", flag_flipx, NULL}, {"flip_y", flag_flipy, NULL} }; REGISTER_FLAGS (lesstif_main_flag_list) /* This is the size of the current PCB work area. */ /* Use PCB->MaxWidth, PCB->MaxHeight. */ /* static int pcb_width, pcb_height; */ static Arg args[30]; static int n; #define stdarg(t,v) XtSetArg(args[n], t, v), n++ static int use_private_colormap = 0; static int stdin_listen = 0; static char *background_image_file = 0; char *lesstif_pcbmenu_path = "pcb-menu.res"; HID_Attribute lesstif_attribute_list[] = { {"install", "Install private colormap", HID_Boolean, 0, 0, {0, 0, 0}, 0, &use_private_colormap}, #define HA_colormap 0 /* %start-doc options "22 lesstif GUI Options" @ftable @code @item --listen Listen for actions on stdin. @end ftable %end-doc */ {"listen", "Listen on standard input for actions", HID_Boolean, 0, 0, {0, 0, 0}, 0, &stdin_listen}, #define HA_listen 1 /* %start-doc options "22 lesstif GUI Options" @ftable @code @item --bg-image File name of an image to put into the background of the GUI canvas. The image must be a color PPM image, in binary (not ASCII) format. It can be any size, and will be automatically scaled to fit the canvas. @end ftable %end-doc */ {"bg-image", "Background Image", HID_String, 0, 0, {0, 0, 0}, 0, &background_image_file}, #define HA_bg_image 2 /* %start-doc options "22 lesstif GUI Options" @ftable @code @item --pcb-menu Location of the @file{pcb-menu.res} file which defines the menu for the lesstif GUI. @end ftable %end-doc */ {"pcb-menu", "Location of pcb-menu.res file", HID_String, 0, 0, {0, PCBLIBDIR "/pcb-menu.res", 0}, 0, &lesstif_pcbmenu_path} #define HA_pcbmenu 3 }; REGISTER_ATTRIBUTES (lesstif_attribute_list) static void lesstif_use_mask (enum mask_mode mode); static void zoom_max (); static void zoom_to (double factor, int x, int y); static void zoom_by (double factor, int x, int y); static void zoom_toggle (int x, int y); static void pinout_callback (Widget, PinoutData *, XmDrawingAreaCallbackStruct *); static void pinout_unmap (Widget, PinoutData *, void *); static void Pan (int mode, int x, int y); /* Px converts view->pcb, Vx converts pcb->view */ static inline int Vx (Coord x) { int rv = (x - view_left_x) / view_zoom + 0.5; if (flip_x) rv = view_width - rv; return rv; } static inline int Vy (Coord y) { int rv = (y - view_top_y) / view_zoom + 0.5; if (flip_y) rv = view_height - rv; return rv; } static inline int Vz (Coord z) { return z / view_zoom + 0.5; } static inline Coord Px (int x) { if (flip_x) x = view_width - x; return x * view_zoom + view_left_x; } static inline Coord Py (int y) { if (flip_y) y = view_height - y; return y * view_zoom + view_top_y; } static inline Coord Pz (int z) { return z * view_zoom; } void lesstif_coords_to_pcb (int vx, int vy, Coord *px, Coord *py) { *px = Px (vx); *py = Py (vy); } Pixel lesstif_parse_color (char *value) { XColor color; if (XParseColor (display, colormap, value, &color)) if (XAllocColor (display, colormap, &color)) return color.pixel; return 0; } static void do_color (char *value, char *which) { XColor color; if (XParseColor (display, colormap, value, &color)) if (XAllocColor (display, colormap, &color)) { stdarg (which, color.pixel); } } /* ------------------------------------------------------------ */ static char * cur_clip () { if (TEST_FLAG (ORTHOMOVEFLAG, PCB)) return "+"; if (TEST_FLAG (ALLDIRECTIONFLAG, PCB)) return "*"; if (PCB->Clipping == 0) return "X"; if (PCB->Clipping == 1) return "_/"; return "\\_"; } /* Called from the core when it's busy doing something and we need to indicate that to the user. */ static int Busy(int argc, char **argv, Coord x, Coord y) { static Cursor busy_cursor = 0; if (busy_cursor == 0) busy_cursor = XCreateFontCursor (display, XC_watch); XDefineCursor (display, window, busy_cursor); XFlush(display); old_cursor_mode = -1; return 0; } /* ---------------------------------------------------------------------- */ /* Local actions. */ static int PointCursor (int argc, char **argv, Coord x, Coord y) { if (argc > 0) over_point = 1; else over_point = 0; old_cursor_mode = -1; return 0; } static int PCBChanged (int argc, char **argv, Coord x, Coord y) { if (work_area == 0) return 0; /*pcb_printf("PCB Changed! %$mD\n", PCB->MaxWidth, PCB->MaxHeight); */ n = 0; stdarg (XmNminimum, 0); stdarg (XmNvalue, 0); stdarg (XmNsliderSize, PCB->MaxWidth ? PCB->MaxWidth : 1); stdarg (XmNmaximum, PCB->MaxWidth ? PCB->MaxWidth : 1); XtSetValues (hscroll, args, n); n = 0; stdarg (XmNminimum, 0); stdarg (XmNvalue, 0); stdarg (XmNsliderSize, PCB->MaxHeight ? PCB->MaxHeight : 1); stdarg (XmNmaximum, PCB->MaxHeight ? PCB->MaxHeight : 1); XtSetValues (vscroll, args, n); zoom_max (); hid_action ("NetlistChanged"); hid_action ("LayersChanged"); hid_action ("RouteStylesChanged"); lesstif_sizes_reset (); lesstif_update_layer_groups (); while (pinouts) pinout_unmap (0, pinouts, 0); if (PCB->Filename) { char *cp = strrchr (PCB->Filename, '/'); n = 0; stdarg (XmNtitle, cp ? cp + 1 : PCB->Filename); XtSetValues (appwidget, args, n); } crosshair_update_range(); return 0; } static const char setunits_syntax[] = "SetUnits(mm|mil)"; static const char setunits_help[] = "Set the default measurement units."; /* %start-doc actions SetUnits @table @code @item mil Sets the display units to mils (1/1000 inch). @item mm Sets the display units to millimeters. @end table %end-doc */ static int SetUnits (int argc, char **argv, Coord x, Coord y) { const Unit *new_unit; if (argc == 0) return 0; new_unit = get_unit_struct (argv[0]); if (new_unit != NULL && new_unit->allow != NO_PRINT) { Settings.grid_unit = new_unit; Settings.increments = get_increments_struct (Settings.grid_unit->family); AttributePut (PCB, "PCB::grid::unit", argv[0]); } lesstif_sizes_reset (); lesstif_styles_update_values (); return 0; } static const char zoom_syntax[] = "Zoom()\n" "Zoom(factor)"; static const char zoom_help[] = "Various zoom factor changes."; /* %start-doc actions Zoom Changes the zoom (magnification) of the view of the board. If no arguments are passed, the view is scaled such that the board just fits inside the visible window (i.e. ``view all''). Otherwise, @var{factor} specifies a change in zoom factor. It may be prefixed by @code{+}, @code{-}, or @code{=} to change how the zoom factor is modified. The @var{factor} is a floating point number, such as @code{1.5} or @code{0.75}. @table @code @item +@var{factor} Values greater than 1.0 cause the board to be drawn smaller; more of the board will be visible. Values between 0.0 and 1.0 cause the board to be drawn bigger; less of the board will be visible. @item -@var{factor} Values greater than 1.0 cause the board to be drawn bigger; less of the board will be visible. Values between 0.0 and 1.0 cause the board to be drawn smaller; more of the board will be visible. @item =@var{factor} The @var{factor} is an absolute zoom factor; the unit for this value is "PCB units per screen pixel". Since PCB default units are 0.01 mil, a @var{factor} of 1000 means 10 mils (0.01 in) per pixel, or 100 DPI, about the actual resolution of most screens - resulting in an "actual size" board. Similarly, a @var{factor} of 100 gives you a 10x actual size. @end table Note that zoom factors of zero are silently ignored. %end-doc */ static int ZoomAction (int argc, char **argv, Coord x, Coord y) { const char *vp; double v; if (x == 0 && y == 0) { x = view_width / 2; y = view_height / 2; } else { x = Vx (x); y = Vy (y); } if (argc < 1) { zoom_max (); return 0; } vp = argv[0]; if (strcasecmp (vp, "toggle") == 0) { zoom_toggle (x, y); return 0; } if (*vp == '+' || *vp == '-' || *vp == '=') vp++; v = g_ascii_strtod (vp, 0); if (v <= 0) return 1; switch (argv[0][0]) { case '-': zoom_by (1 / v, x, y); break; default: case '+': zoom_by (v, x, y); break; case '=': zoom_to (v, x, y); break; } return 0; } static int pan_thumb_mode; static int PanAction (int argc, char **argv, Coord x, Coord y) { int mode; if (argc < 1) return 1; if (argc == 2) { pan_thumb_mode = (strcasecmp (argv[0], "thumb") == 0) ? 1 : 0; mode = atoi (argv[1]); } else { pan_thumb_mode = 0; mode = atoi (argv[0]); } Pan (mode, Vx(x), Vy(y)); return 0; } static const char swapsides_syntax[] = "SwapSides(|v|h|r)"; static const char swapsides_help[] = "Swaps the side of the board you're looking at."; /* %start-doc actions SwapSides This action changes the way you view the board. @table @code @item v Flips the board over vertically (up/down). @item h Flips the board over horizontally (left/right), like flipping pages in a book. @item r Rotates the board 180 degrees without changing sides. @end table If no argument is given, the board isn't moved but the opposite side is shown. Normally, this action changes which pads and silk layer are drawn as true silk, and which are drawn as the "invisible" layer. It also determines which solder mask you see. As a special case, if the layer group for the side you're looking at is visible and currently active, and the layer group for the opposite is not visible (i.e. disabled), then this action will also swap which layer group is visible and active, effectively swapping the ``working side'' of the board. %end-doc */ static int group_showing (int g, int *c) { int i, l; *c = PCB->LayerGroups.Entries[g][0]; for (i=0; iLayerGroups.Number[g]; i++) { l = PCB->LayerGroups.Entries[g][i]; if (l >= 0 && l < max_copper_layer) { *c = l; if (PCB->Data->Layer[l].On) return 1; } } return 0; } static int SwapSides (int argc, char **argv, Coord x, Coord y) { int old_shown_side = Settings.ShowBottomSide; int top_group = GetLayerGroupNumberBySide (TOP_SIDE); int bottom_group = GetLayerGroupNumberBySide (BOTTOM_SIDE); int active_group = GetLayerGroupNumberByNumber (LayerStack[0]); int top_layer; int bottom_layer; int top_showing = group_showing (top_group, &top_layer); int bottom_showing = group_showing (bottom_group, &bottom_layer); if (argc > 0) { switch (argv[0][0]) { case 'h': case 'H': flip_x = ! flip_x; break; case 'v': case 'V': flip_y = ! flip_y; break; case 'r': case 'R': flip_x = ! flip_x; flip_y = ! flip_y; break; default: return 1; } /* SwapSides will swap this */ Settings.ShowBottomSide = (flip_x == flip_y); } n = 0; if (flip_x) stdarg (XmNprocessingDirection, XmMAX_ON_LEFT); else stdarg (XmNprocessingDirection, XmMAX_ON_RIGHT); XtSetValues (hscroll, args, n); n = 0; if (flip_y) stdarg (XmNprocessingDirection, XmMAX_ON_TOP); else stdarg (XmNprocessingDirection, XmMAX_ON_BOTTOM); XtSetValues (vscroll, args, n); Settings.ShowBottomSide = !Settings.ShowBottomSide; /* The idea is that if we're looking at the front side and the front layer is active (or visa versa), switching sides should switch layers too. We used to only do this if the other layer wasn't shown, but we now do it always. Change it back if users get confused. */ if (Settings.ShowBottomSide != old_shown_side) { if (Settings.ShowBottomSide) { if (active_group == top_group) { if (top_showing && !bottom_showing) ChangeGroupVisibility (top_layer, 0, 0); ChangeGroupVisibility (bottom_layer, 1, 1); } } else { if (active_group == bottom_group) { if (bottom_showing && !top_showing) ChangeGroupVisibility (bottom_layer, 0, 0); ChangeGroupVisibility (top_layer, 1, 1); } } } lesstif_invalidate_all (); return 0; } static Widget m_cmd = 0, m_cmd_label; static void command_callback (Widget w, XtPointer uptr, XmTextVerifyCallbackStruct * cbs) { char *s; switch (cbs->reason) { case XmCR_ACTIVATE: s = XmTextGetString (w); lesstif_show_crosshair (0); hid_parse_command (s); XtFree (s); XmTextSetString (w, ""); case XmCR_LOSING_FOCUS: XtUnmanageChild (m_cmd); XtUnmanageChild (m_cmd_label); break; } } static void command_event_handler (Widget w, XtPointer p, XEvent * e, Boolean * cont) { char buf[10]; KeySym sym; switch (e->type) { case KeyPress: XLookupString ((XKeyEvent *)e, buf, sizeof (buf), &sym, NULL); switch (sym) { case XK_Escape: XtUnmanageChild (m_cmd); XtUnmanageChild (m_cmd_label); XmTextSetString (w, ""); *cont = False; break; } break; } } static const char command_syntax[] = "Command()"; static const char command_help[] = "Displays the command line input window."; /* %start-doc actions Command The command window allows the user to manually enter actions to be executed. Action syntax can be done one of two ways: @itemize @bullet @item Follow the action name by an open parenthesis, arguments separated by commas, end with a close parenthesis. Example: @example @code{Abc(1,2,3)} @end example @item Separate the action name and arguments by spaces. Example: @example @code{Abc 1 2 3} @end example @end itemize The first option allows you to have arguments with spaces in them, but the second is more ``natural'' to type for most people. Note that action names are not case sensitive, but arguments normally are. However, most actions will check for ``keywords'' in a case insensitive way. There are three ways to finish with the command window. If you press the @code{Enter} key, the command is invoked, the window goes away, and the next time you bring up the command window it's empty. If you press the @code{Esc} key, the window goes away without invoking anything, and the next time you bring up the command window it's empty. If you change focus away from the command window (i.e. click on some other window), the command window goes away but the next time you bring it up it resumes entering the command you were entering before. %end-doc */ static int Command (int argc, char **argv, Coord x, Coord y) { XtManageChild (m_cmd_label); XtManageChild (m_cmd); XmProcessTraversal (m_cmd, XmTRAVERSE_CURRENT); return 0; } static const char benchmark_syntax[] = "Benchmark()"; static const char benchmark_help[] = "Benchmark the GUI speed."; /* %start-doc actions Benchmark This action is used to speed-test the Lesstif graphics subsystem. It redraws the current screen as many times as possible in ten seconds. It reports the amount of time needed to draw the screen once. %end-doc */ static int Benchmark (int argc, char **argv, Coord x, Coord y) { int i = 0; time_t start, end; BoxType region; Drawable save_main; save_main = main_pixmap; main_pixmap = window; region.X1 = 0; region.Y1 = 0; region.X2 = PCB->MaxWidth; region.Y2 = PCB->MaxHeight; pixmap = window; XSync (display, 0); time (&start); do { XFillRectangle (display, pixmap, bg_gc, 0, 0, view_width, view_height); hid_expose_callback (&lesstif_hid, ®ion, 0); XSync (display, 0); time (&end); i++; } while (end - start < 10); printf ("%g redraws per second\n", i / 10.0); main_pixmap = save_main; return 0; } static int Center(int argc, char **argv, Coord x, Coord y) { x = GridFit (x, PCB->Grid, PCB->GridOffsetX); y = GridFit (y, PCB->Grid, PCB->GridOffsetY); view_left_x = x - (view_width * view_zoom) / 2; view_top_y = y - (view_height * view_zoom) / 2; lesstif_pan_fixup (); /* Move the pointer to the center of the window, but only if it's currently within the window already. Watch out for edges, though. */ XWarpPointer (display, window, window, 0, 0, view_width, view_height, Vx(x), Vy(y)); return 0; } static const char cursor_syntax[] = "Cursor(Type,DeltaUp,DeltaRight,Units)"; static const char cursor_help[] = "Move the cursor."; /* %start-doc actions Cursor This action moves the mouse cursor. Unlike other actions which take coordinates, this action's coordinates are always relative to the user's view of the board. Thus, a positive @var{DeltaUp} may move the cursor towards the board origin if the board is inverted. Type is one of @samp{Pan} or @samp{Warp}. @samp{Pan} causes the viewport to move such that the crosshair is under the mouse cursor. @samp{Warp} causes the mouse cursor to move to be above the crosshair. @var{Units} can be one of the following: @table @samp @item mil @itemx mm The cursor is moved by that amount, in board units. @item grid The cursor is moved by that many grid points. @item view The values are percentages of the viewport's view. Thus, a pan of @samp{100} would scroll the viewport by exactly the width of the current view. @item board The values are percentages of the board size. Thus, a move of @samp{50,50} moves you halfway across the board. @end table %end-doc */ static int CursorAction(int argc, char **argv, Coord x, Coord y) { UnitList extra_units_x = { { "grid", PCB->Grid, 0 }, { "view", Pz(view_width), UNIT_PERCENT }, { "board", PCB->MaxWidth, UNIT_PERCENT }, { "", 0, 0 } }; UnitList extra_units_y = { { "grid", PCB->Grid, 0 }, { "view", Pz(view_height), UNIT_PERCENT }, { "board", PCB->MaxHeight, UNIT_PERCENT }, { "", 0, 0 } }; int pan_warp = HID_SC_DO_NOTHING; double dx, dy; if (argc != 4) AFAIL(cursor); if (strcasecmp (argv[0], "pan") == 0) pan_warp = HID_SC_PAN_VIEWPORT; else if (strcasecmp (argv[0], "warp") == 0) pan_warp = HID_SC_WARP_POINTER; else AFAIL(cursor); dx = GetValueEx (argv[1], argv[3], NULL, extra_units_x, "mil"); if (flip_x) dx = -dx; dy = GetValueEx (argv[2], argv[3], NULL, extra_units_y, "mil"); if (!flip_y) dy = -dy; EventMoveCrosshair (Crosshair.X + dx, Crosshair.Y + dy); gui->set_crosshair (Crosshair.X, Crosshair.Y, pan_warp); return 0; } HID_Action lesstif_main_action_list[] = { {"PCBChanged", 0, PCBChanged, pcbchanged_help, pcbchanged_syntax}, {"SetUnits", 0, SetUnits, setunits_help, setunits_syntax}, {"Zoom", "Click on a place to zoom in", ZoomAction, zoom_help, zoom_syntax}, {"Pan", "Click on a place to pan", PanAction, zoom_help, zoom_syntax}, {"SwapSides", 0, SwapSides, swapsides_help, swapsides_syntax}, {"Command", 0, Command, command_help, command_syntax}, {"Benchmark", 0, Benchmark, benchmark_help, benchmark_syntax}, {"PointCursor", 0, PointCursor}, {"Center", "Click on a location to center", Center}, {"Busy", 0, Busy}, {"Cursor", 0, CursorAction, cursor_help, cursor_syntax}, }; REGISTER_ACTIONS (lesstif_main_action_list) /* ---------------------------------------------------------------------- * redraws the background image */ static int bg_w, bg_h, bgi_w, bgi_h; static Pixel **bg = 0; static XImage *bgi = 0; static enum { PT_unknown, PT_RGB565, PT_RGB888 } pixel_type = PT_unknown; static void LoadBackgroundFile (FILE *f, char *filename) { XVisualInfo vinfot, *vinfo; Visual *vis; int c, r, b; int i, nret; int p[3], rows, cols, maxval; if (fgetc(f) != 'P') { printf("bgimage: %s signature not P6\n", filename); return; } if (fgetc(f) != '6') { printf("bgimage: %s signature not P6\n", filename); return; } for (i=0; i<3; i++) { do { b = fgetc(f); if (feof(f)) return; if (b == '#') while (!feof(f) && b != '\n') b = fgetc(f); } while (!isdigit(b)); p[i] = b - '0'; while (isdigit(b = fgetc(f))) p[i] = p[i]*10 + b - '0'; } bg_w = cols = p[0]; bg_h = rows = p[1]; maxval = p[2]; setbuf(stdout, 0); bg = (Pixel **) malloc (rows * sizeof (Pixel *)); if (!bg) { printf("Out of memory loading %s\n", filename); return; } for (i=0; i= 0) free (bg[i]); free (bg); bg = 0; return; } } vis = DefaultVisual (display, DefaultScreen(display)); vinfot.visualid = XVisualIDFromVisual(vis); vinfo = XGetVisualInfo (display, VisualIDMask, &vinfot, &nret); #if 0 /* If you want to support more visuals below, you'll probably need this. */ printf("vinfo: rm %04x gm %04x bm %04x depth %d class %d\n", vinfo->red_mask, vinfo->green_mask, vinfo->blue_mask, vinfo->depth, vinfo->class); #endif #if !defined(__cplusplus) #define c_class class #endif if (vinfo->c_class == TrueColor && vinfo->depth == 16 && vinfo->red_mask == 0xf800 && vinfo->green_mask == 0x07e0 && vinfo->blue_mask == 0x001f) pixel_type = PT_RGB565; if (vinfo->c_class == TrueColor && vinfo->depth == 24 && vinfo->red_mask == 0xff0000 && vinfo->green_mask == 0x00ff00 && vinfo->blue_mask == 0x0000ff) pixel_type = PT_RGB888; for (r=0; r>3)<<11 | (pg>>2)<<5 | (pb>>3); break; case PT_RGB888: bg[r][c] = (pr << 16) | (pg << 8) | (pb); break; } } } } void LoadBackgroundImage (char *filename) { FILE *f = fopen(filename, "rb"); if (!f) { if (NSTRCMP (filename, "pcb-background.ppm")) perror(filename); return; } LoadBackgroundFile (f, filename); fclose(f); } static void DrawBackgroundImage () { int x, y, w, h; double xscale, yscale; int pcbwidth = PCB->MaxWidth / view_zoom; int pcbheight = PCB->MaxHeight / view_zoom; if (!window || !bg) return; if (!bgi || view_width != bgi_w || view_height != bgi_h) { if (bgi) XDestroyImage (bgi); /* Cheat - get the image, which sets up the format too. */ bgi = XGetImage (XtDisplay(work_area), window, 0, 0, view_width, view_height, -1, ZPixmap); bgi_w = view_width; bgi_h = view_height; } w = MIN (view_width, pcbwidth); h = MIN (view_height, pcbheight); xscale = (double)bg_w / PCB->MaxWidth; yscale = (double)bg_h / PCB->MaxHeight; for (y=0; y pcb) sz = pcb; if ((pos < 0) || (pos > (pcb - sz))) pos = 0; n = 0; stdarg (XmNvalue, pos); stdarg (XmNsliderSize, sz); stdarg (XmNincrement, view_zoom); stdarg (XmNpageIncrement, sz); stdarg (XmNmaximum, pcb); XtSetValues (s, args, n); } void lesstif_pan_fixup () { #if 0 if (view_left_x > PCB->MaxWidth - (view_width * view_zoom)) view_left_x = PCB->MaxWidth - (view_width * view_zoom); if (view_top_y > PCB->MaxHeight - (view_height * view_zoom)) view_top_y = PCB->MaxHeight - (view_height * view_zoom); if (view_left_x < 0) view_left_x = 0; if (view_top_y < 0) view_top_y = 0; if (view_width * view_zoom > PCB->MaxWidth && view_height * view_zoom > PCB->MaxHeight) { zoom_by (1, 0, 0); return; } #endif set_scroll (hscroll, view_left_x, view_width, PCB->MaxWidth); set_scroll (vscroll, view_top_y, view_height, PCB->MaxHeight); lesstif_invalidate_all (); } static void zoom_max () { double new_zoom = PCB->MaxWidth / view_width; if (new_zoom < PCB->MaxHeight / view_height) new_zoom = PCB->MaxHeight / view_height; view_left_x = -(view_width * new_zoom - PCB->MaxWidth) / 2; view_top_y = -(view_height * new_zoom - PCB->MaxHeight) / 2; view_zoom = new_zoom; pixel_slop = view_zoom; lesstif_pan_fixup (); } static void zoom_to (double new_zoom, int x, int y) { double max_zoom, xfrac, yfrac; int cx, cy; xfrac = (double) x / (double) view_width; yfrac = (double) y / (double) view_height; if (flip_x) xfrac = 1-xfrac; if (flip_y) yfrac = 1-yfrac; max_zoom = PCB->MaxWidth / view_width; if (max_zoom < PCB->MaxHeight / view_height) max_zoom = PCB->MaxHeight / view_height; max_zoom *= MAX_ZOOM_SCALE; if (new_zoom < 1) new_zoom = 1; if (new_zoom > max_zoom) new_zoom = max_zoom; cx = view_left_x + view_width * xfrac * view_zoom; cy = view_top_y + view_height * yfrac * view_zoom; if (view_zoom != new_zoom) { view_zoom = new_zoom; pixel_slop = view_zoom; view_left_x = cx - view_width * xfrac * view_zoom; view_top_y = cy - view_height * yfrac * view_zoom; } lesstif_pan_fixup (); } static void zoom_toggle(int x, int y) { double tmp; tmp = prev_view_zoom; prev_view_zoom = view_zoom; zoom_to(tmp, x, y); } void zoom_by (double factor, int x, int y) { zoom_to (view_zoom * factor, x, y); } static int panning = 0; static int shift_pressed; static int ctrl_pressed; static int alt_pressed; /* X and Y are in screen coordinates. */ static void Pan (int mode, int x, int y) { static int ox, oy; static int opx, opy; panning = mode; /* This is for ctrl-pan, where the viewport's position is directly proportional to the cursor position in the window (like the Xaw thumb panner) */ if (pan_thumb_mode) { opx = x * PCB->MaxWidth / view_width; opy = y * PCB->MaxHeight / view_height; if (flip_x) opx = PCB->MaxWidth - opx; if (flip_y) opy = PCB->MaxHeight - opy; view_left_x = opx - view_width / 2 * view_zoom; view_top_y = opy - view_height / 2 * view_zoom; lesstif_pan_fixup (); } /* This is the start of a regular pan. On the first click, we remember the coordinates where we "grabbed" the screen. */ else if (mode == 1) { ox = x; oy = y; opx = view_left_x; opy = view_top_y; } /* continued drag, we calculate how far we've moved the cursor and set the position accordingly. */ else { if (flip_x) view_left_x = opx + (x - ox) * view_zoom; else view_left_x = opx - (x - ox) * view_zoom; if (flip_y) view_top_y = opy + (y - oy) * view_zoom; else view_top_y = opy - (y - oy) * view_zoom; lesstif_pan_fixup (); } } static void mod_changed (XKeyEvent * e, int set) { switch (XkbKeycodeToKeysym (display, e->keycode, 0, e->state & ShiftMask ? 1:0)) { case XK_Shift_L: case XK_Shift_R: shift_pressed = set; break; case XK_Control_L: case XK_Control_R: ctrl_pressed = set; break; #ifdef __APPLE__ case XK_Mode_switch: #else case XK_Alt_L: case XK_Alt_R: #endif alt_pressed = set; break; default: // to include the Apple keyboard left and right command keys use XK_Meta_L and XK_Meta_R respectivly. return; } in_move_event = 1; notify_crosshair_change (false); if (panning) Pan (2, e->x, e->y); EventMoveCrosshair (Px (e->x), Py (e->y)); AdjustAttachedObjects (); notify_crosshair_change (true); in_move_event = 0; } static void work_area_input (Widget w, XtPointer v, XEvent * e, Boolean * ctd) { static int pressed_button = 0; show_crosshair (0); switch (e->type) { case KeyPress: mod_changed (&(e->xkey), 1); if (lesstif_key_event (&(e->xkey))) return; break; case KeyRelease: mod_changed (&(e->xkey), 0); break; case ButtonPress: { int mods; if (pressed_button) return; /*printf("click %d\n", e->xbutton.button); */ if (lesstif_button_event (w, e)) return; notify_crosshair_change (false); pressed_button = e->xbutton.button; mods = ((e->xbutton.state & ShiftMask) ? M_Shift : 0) + ((e->xbutton.state & ControlMask) ? M_Ctrl : 0) #ifdef __APPLE__ + ((e->xbutton.state & (1<<13)) ? M_Alt : 0); #else + ((e->xbutton.state & Mod1Mask) ? M_Alt : 0); #endif do_mouse_action(e->xbutton.button, mods); notify_crosshair_change (true); break; } case ButtonRelease: { int mods; if (e->xbutton.button != pressed_button) return; lesstif_button_event (w, e); notify_crosshair_change (false); pressed_button = 0; mods = ((e->xbutton.state & ShiftMask) ? M_Shift : 0) + ((e->xbutton.state & ControlMask) ? M_Ctrl : 0) #ifdef __APPLE__ + ((e->xbutton.state & (1<<13)) ? M_Alt : 0) #else + ((e->xbutton.state & Mod1Mask) ? M_Alt : 0) #endif + M_Release; do_mouse_action (e->xbutton.button, mods); notify_crosshair_change (true); break; } case MotionNotify: { Window root, child; unsigned int keys_buttons; int root_x, root_y, pos_x, pos_y; while (XCheckMaskEvent (display, PointerMotionMask, e)); XQueryPointer (display, e->xmotion.window, &root, &child, &root_x, &root_y, &pos_x, &pos_y, &keys_buttons); shift_pressed = (keys_buttons & ShiftMask); ctrl_pressed = (keys_buttons & ControlMask); #ifdef __APPLE__ alt_pressed = (keys_buttons & (1<<13)); #else alt_pressed = (keys_buttons & Mod1Mask); #endif /*pcb_printf("m %#mS %#mS\n", Px(e->xmotion.x), Py(e->xmotion.y)); */ crosshair_in_window = 1; in_move_event = 1; if (panning) Pan (2, pos_x, pos_y); EventMoveCrosshair (Px (pos_x), Py (pos_y)); in_move_event = 0; } break; case LeaveNotify: crosshair_in_window = 0; ShowCrosshair (false); need_idle_proc (); break; case EnterNotify: crosshair_in_window = 1; in_move_event = 1; EventMoveCrosshair (Px (e->xcrossing.x), Py (e->xcrossing.y)); ShowCrosshair (true); in_move_event = 0; need_idle_proc (); break; default: printf ("work_area: unknown event %d\n", e->type); break; } } static void draw_right_cross (GC xor_gc, int x, int y, int view_width, int view_height) { XDrawLine (display, window, xor_gc, 0, y, view_width, y); XDrawLine (display, window, xor_gc, x, 0, x, view_height); } static void draw_slanted_cross (GC xor_gc, int x, int y, int view_width, int view_height) { int x0, y0, x1, y1; x0 = x + (view_height - y); x0 = MAX(0, MIN (x0, view_width)); x1 = x - y; x1 = MAX(0, MIN (x1, view_width)); y0 = y + (view_width - x); y0 = MAX(0, MIN (y0, view_height)); y1 = y - x; y1 = MAX(0, MIN (y1, view_height)); XDrawLine (display, window, xor_gc, x0, y0, x1, y1); x0 = x - (view_height - y); x0 = MAX(0, MIN (x0, view_width)); x1 = x + y; x1 = MAX(0, MIN (x1, view_width)); y0 = y + x; y0 = MAX(0, MIN (y0, view_height)); y1 = y - (view_width - x); y1 = MAX(0, MIN (y1, view_height)); XDrawLine (display, window, xor_gc, x0, y0, x1, y1); } static void draw_dozen_cross (GC xor_gc, int x, int y, int view_width, int view_height) { int x0, y0, x1, y1; double tan60 = sqrt (3); x0 = x + (view_height - y) / tan60; x0 = MAX(0, MIN (x0, view_width)); x1 = x - y / tan60; x1 = MAX(0, MIN (x1, view_width)); y0 = y + (view_width - x) * tan60; y0 = MAX(0, MIN (y0, view_height)); y1 = y - x * tan60; y1 = MAX(0, MIN (y1, view_height)); XDrawLine (display, window, xor_gc, x0, y0, x1, y1); x0 = x + (view_height - y) * tan60; x0 = MAX(0, MIN (x0, view_width)); x1 = x - y * tan60; x1 = MAX(0, MIN (x1, view_width)); y0 = y + (view_width - x) / tan60; y0 = MAX(0, MIN (y0, view_height)); y1 = y - x / tan60; y1 = MAX(0, MIN (y1, view_height)); XDrawLine (display, window, xor_gc, x0, y0, x1, y1); x0 = x - (view_height - y) / tan60; x0 = MAX(0, MIN (x0, view_width)); x1 = x + y / tan60; x1 = MAX(0, MIN (x1, view_width)); y0 = y + x * tan60; y0 = MAX(0, MIN (y0, view_height)); y1 = y - (view_width - x) * tan60; y1 = MAX(0, MIN (y1, view_height)); XDrawLine (display, window, xor_gc, x0, y0, x1, y1); x0 = x - (view_height - y) * tan60; x0 = MAX(0, MIN (x0, view_width)); x1 = x + y * tan60; x1 = MAX(0, MIN (x1, view_width)); y0 = y + x / tan60; y0 = MAX(0, MIN (y0, view_height)); y1 = y - (view_width - x) / tan60; y1 = MAX(0, MIN (y1, view_height)); XDrawLine (display, window, xor_gc, x0, y0, x1, y1); } static void draw_crosshair (GC xor_gc, int x, int y, int view_width, int view_height) { draw_right_cross (xor_gc, x, y, view_width, view_height); if (Crosshair.shape == Union_Jack_Crosshair_Shape) draw_slanted_cross (xor_gc, x, y, view_width, view_height); if (Crosshair.shape == Dozen_Crosshair_Shape) draw_dozen_cross (xor_gc, x, y, view_width, view_height); } void lesstif_show_crosshair (int show) { static int showing = 0; static int sx, sy; static GC xor_gc = 0; Pixel crosshair_color; if (!crosshair_in_window || !window) return; if (xor_gc == 0) { crosshair_color = lesstif_parse_color (Settings.CrosshairColor) ^ bgcolor; xor_gc = XCreateGC (display, window, 0, 0); XSetFunction (display, xor_gc, GXxor); XSetForeground (display, xor_gc, crosshair_color); } if (show == showing) return; if (show) { sx = Vx (crosshair_x); sy = Vy (crosshair_y); } else need_idle_proc (); draw_crosshair (xor_gc, sx, sy, view_width, view_height); showing = show; } static void work_area_expose (Widget work_area, void *me, XmDrawingAreaCallbackStruct * cbs) { XExposeEvent *e; show_crosshair (0); e = &(cbs->event->xexpose); XSetFunction (display, my_gc, GXcopy); XCopyArea (display, main_pixmap, window, my_gc, e->x, e->y, e->width, e->height, e->x, e->y); show_crosshair (1); } static void scroll_callback (Widget scroll, int *view_dim, XmScrollBarCallbackStruct * cbs) { *view_dim = cbs->value; lesstif_invalidate_all (); } static void work_area_make_pixmaps (Dimension width, Dimension height) { if (main_pixmap) XFreePixmap (display, main_pixmap); main_pixmap = XCreatePixmap (display, window, width, height, XDefaultDepth (display, screen)); if (mask_pixmap) XFreePixmap (display, mask_pixmap); mask_pixmap = XCreatePixmap (display, window, width, height, XDefaultDepth (display, screen)); #ifdef HAVE_XRENDER if (main_picture) { XRenderFreePicture (display, main_picture); main_picture = 0; } if (mask_picture) { XRenderFreePicture (display, mask_picture); mask_picture = 0; } if (use_xrender) { main_picture = XRenderCreatePicture (display, main_pixmap, XRenderFindVisualFormat(display, DefaultVisual(display, screen)), 0, 0); mask_picture = XRenderCreatePicture (display, mask_pixmap, XRenderFindVisualFormat(display, DefaultVisual(display, screen)), 0, 0); if (!main_picture || !mask_picture) use_xrender = 0; } #endif /* HAVE_XRENDER */ if (mask_bitmap) XFreePixmap (display, mask_bitmap); mask_bitmap = XCreatePixmap (display, window, width, height, 1); pixmap = use_mask ? main_pixmap : mask_pixmap; pixmap_w = width; pixmap_h = height; } static void work_area_resize (Widget work_area, void *me, XmDrawingAreaCallbackStruct * cbs) { XColor color; Dimension width, height; show_crosshair (0); n = 0; stdarg (XtNwidth, &width); stdarg (XtNheight, &height); stdarg (XmNbackground, &bgcolor); XtGetValues (work_area, args, n); view_width = width; view_height = height; color.pixel = bgcolor; XQueryColor (display, colormap, &color); bgred = color.red; bggreen = color.green; bgblue = color.blue; if (!window) return; work_area_make_pixmaps (view_width, view_height); zoom_by (1, 0, 0); } static void work_area_first_expose (Widget work_area, void *me, XmDrawingAreaCallbackStruct * cbs) { int c; Dimension width, height; static char dashes[] = { 4, 4 }; window = XtWindow (work_area); my_gc = XCreateGC (display, window, 0, 0); arc1_gc = XCreateGC (display, window, 0, 0); c = lesstif_parse_color ("#804000"); XSetForeground (display, arc1_gc, c); arc2_gc = XCreateGC (display, window, 0, 0); c = lesstif_parse_color ("#004080"); XSetForeground (display, arc2_gc, c); XSetLineAttributes (display, arc1_gc, 1, LineOnOffDash, 0, 0); XSetLineAttributes (display, arc2_gc, 1, LineOnOffDash, 0, 0); XSetDashes (display, arc1_gc, 0, dashes, 2); XSetDashes (display, arc2_gc, 0, dashes, 2); n = 0; stdarg (XtNwidth, &width); stdarg (XtNheight, &height); stdarg (XmNbackground, &bgcolor); XtGetValues (work_area, args, n); view_width = width; view_height = height; offlimit_color = lesstif_parse_color (Settings.OffLimitColor); grid_color = lesstif_parse_color (Settings.GridColor); bg_gc = XCreateGC (display, window, 0, 0); XSetForeground (display, bg_gc, bgcolor); work_area_make_pixmaps (width, height); #ifdef HAVE_XRENDER if (use_xrender) { XRenderPictureAttributes pa; XRenderColor a = {0, 0, 0, 0x8000}; pale_pixmap = XCreatePixmap (display, window, 1, 1, 8); pa.repeat = True; pale_picture = XRenderCreatePicture (display, pale_pixmap, XRenderFindStandardFormat(display, PictStandardA8), CPRepeat, &pa); if (pale_picture) XRenderFillRectangle(display, PictOpSrc, pale_picture, &a, 0, 0, 1, 1); else use_xrender = 0; } #endif /* HAVE_XRENDER */ clip_gc = XCreateGC (display, window, 0, 0); bset_gc = XCreateGC (display, mask_bitmap, 0, 0); XSetForeground (display, bset_gc, 1); bclear_gc = XCreateGC (display, mask_bitmap, 0, 0); XSetForeground (display, bclear_gc, 0); XtRemoveCallback (work_area, XmNexposeCallback, (XtCallbackProc) work_area_first_expose, 0); XtAddCallback (work_area, XmNexposeCallback, (XtCallbackProc) work_area_expose, 0); lesstif_invalidate_all (); } static Widget make_message (char *name, Widget left, int resizeable) { Widget w, f; n = 0; if (left) { stdarg (XmNleftAttachment, XmATTACH_WIDGET); stdarg (XmNleftWidget, XtParent(left)); } else { stdarg (XmNleftAttachment, XmATTACH_FORM); } stdarg (XmNtopAttachment, XmATTACH_FORM); stdarg (XmNbottomAttachment, XmATTACH_FORM); stdarg (XmNshadowType, XmSHADOW_IN); stdarg (XmNshadowThickness, 1); stdarg (XmNalignment, XmALIGNMENT_CENTER); stdarg (XmNmarginWidth, 4); stdarg (XmNmarginHeight, 1); if (!resizeable) stdarg (XmNresizePolicy, XmRESIZE_GROW); f = XmCreateForm (messages, name, args, n); XtManageChild (f); n = 0; stdarg (XmNtopAttachment, XmATTACH_FORM); stdarg (XmNbottomAttachment, XmATTACH_FORM); stdarg (XmNleftAttachment, XmATTACH_FORM); stdarg (XmNrightAttachment, XmATTACH_FORM); w = XmCreateLabel (f, name, args, n); XtManageChild (w); return w; } static void lesstif_do_export (HID_Attr_Val * options) { Dimension width, height; Widget menu; Widget work_area_frame; crosshair_gc = lesstif_make_gc (); n = 0; stdarg (XtNwidth, &width); stdarg (XtNheight, &height); XtGetValues (appwidget, args, n); if (width < 1) width = 640; if (width > XDisplayWidth (display, screen)) width = XDisplayWidth (display, screen); if (height < 1) height = 480; if (height > XDisplayHeight (display, screen)) height = XDisplayHeight (display, screen); n = 0; stdarg (XmNwidth, width); stdarg (XmNheight, height); XtSetValues (appwidget, args, n); stdarg (XmNspacing, 0); mainwind = XmCreateMainWindow (appwidget, "mainWind", args, n); XtManageChild (mainwind); n = 0; stdarg (XmNmarginWidth, 0); stdarg (XmNmarginHeight, 0); menu = lesstif_menu (mainwind, "menubar", args, n); XtManageChild (menu); n = 0; stdarg (XmNshadowType, XmSHADOW_IN); work_area_frame = XmCreateFrame (mainwind, "work_area_frame", args, n); XtManageChild (work_area_frame); n = 0; do_color (Settings.BackgroundColor, XmNbackground); work_area = XmCreateDrawingArea (work_area_frame, "work_area", args, n); XtManageChild (work_area); XtAddCallback (work_area, XmNexposeCallback, (XtCallbackProc) work_area_first_expose, 0); XtAddCallback (work_area, XmNresizeCallback, (XtCallbackProc) work_area_resize, 0); /* A regular callback won't work here, because lesstif swallows any Ctrl