malaga-7.12/0000755000175000017500000000000010764165477012226 5ustar bjoernbjoernmalaga-7.12/configure0000755000175000017500000235712610761577756014161 0ustar bjoernbjoern#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61. # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006 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=: # Zsh 3.x and 4.x performs 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 # PATH needs CR # 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 # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false 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.) as_nl=' ' IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. 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 echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. 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 # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH if test "x$CONFIG_SHELL" = x; then if (eval ":") 2>/dev/null; then as_have_required=yes else as_have_required=no fi if test $as_have_required = yes && (eval ": (as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=\$LINENO as_lineno_2=\$LINENO test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } ") 2> /dev/null; then : else as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. case $as_dir in /*) for as_base in sh bash ksh sh5; do as_candidate_shells="$as_candidate_shells $as_dir/$as_base" done;; esac done IFS=$as_save_IFS for as_shell in $as_candidate_shells $SHELL; do # Try only shells that exist, to save several forks. if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { ("$as_shell") 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs 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 : _ASEOF }; then CONFIG_SHELL=$as_shell as_have_required=yes if { "$as_shell" 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs 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_func_return () { (exit $1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = "$1" ); then : else exitcode=1 echo positional parameters were not saved. fi test $exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } _ASEOF }; then break fi fi done if test "x$CONFIG_SHELL" != x; then for as_var in BASH_ENV ENV do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test $as_have_required = no; then echo This script requires a shell more modern than all the echo shells that I found on your system. Please install a echo modern shell, or manually run the script under such a echo shell if you do have one. { (exit 1); exit 1; } fi fi fi (eval "as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0") || { echo No shell found that supports shell functions. echo Please tell autoconf@gnu.org about your system, echo including any error possibly output before this echo message } as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. 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" || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # 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 } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi 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 fi echo >conf$$.file 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 -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' 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=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # 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'" # Check that we are running under the correct shell. SHELL=${CONFIG_SHELL-/bin/sh} case X$ECHO in X*--fallback-echo) # Remove one level of quotation (which was required for Make). ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','` ;; esac echo=${ECHO-echo} if test "X$1" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test "X$1" = X--fallback-echo; then # Avoid inline document here, it may be left over : elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then # Yippee, $echo works! : else # Restart under the correct shell. exec $SHELL "$0" --no-reexec ${1+"$@"} fi if test "X$1" = X--fallback-echo; then # used as fallback echo shift cat </dev/null 2>&1 && unset CDPATH if test -z "$ECHO"; then if test "X${echo_test_string+set}" != Xset; then # find a string as large as possible, as long as the shell can cope with it for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... if (echo_test_string=`eval $cmd`) 2>/dev/null && echo_test_string=`eval $cmd` && (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null then break fi done fi if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then : else # The Solaris, AIX, and Digital Unix default echo programs unquote # backslashes. This makes it impossible to quote backslashes using # echo "$something" | sed 's/\\/\\\\/g' # # So, first we look for a working echo in the user's PATH. lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for dir in $PATH /usr/ucb; do IFS="$lt_save_ifs" if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then echo="$dir/echo" break fi done IFS="$lt_save_ifs" if test "X$echo" = Xecho; then # We didn't find a better echo, so look for alternatives. if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # This shell has a builtin print -r that does the trick. echo='print -r' elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && test "X$CONFIG_SHELL" != X/bin/ksh; then # If we have ksh, try running configure again with it. ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} export ORIGINAL_CONFIG_SHELL CONFIG_SHELL=/bin/ksh export CONFIG_SHELL exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} else # Try using printf. echo='printf %s\n' if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # Cool, printf works : elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL export CONFIG_SHELL SHELL="$CONFIG_SHELL" export SHELL echo="$CONFIG_SHELL $0 --fallback-echo" elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then echo="$CONFIG_SHELL $0 --fallback-echo" else # maybe with a smaller string... prev=: for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null then break fi prev="$cmd" done if test "$prev" != 'sed 50q "$0"'; then echo_test_string=`eval $prev` export echo_test_string exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} else # Oops. We lost completely, so just stick with echo. echo=echo fi fi fi fi fi fi # Copy echo and quote the copy suitably for passing to libtool from # the Makefile, instead of quoting the original, which is used later. ECHO=$echo if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" fi tagnames=${tagnames+${tagnames},}CXX tagnames=${tagnames+${tagnames},}F77 exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, 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= SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= ac_unique_file="malaga.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" ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datarootdir datadir sysconfdir sharedstatedir localstatedir includedir oldincludedir docdir infodir htmldir dvidir pdfdir psdir libdir localedir mandir DEFS ECHO_C ECHO_N ECHO_T LIBS build_alias host_alias target_alias CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA build build_cpu build_vendor build_os host host_cpu host_vendor host_os GREP EGREP LN_S ECHO AR RANLIB STRIP CPP CXX CXXFLAGS ac_ct_CXX CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL GCCFLAGS MALSHOW GTK_LIBS GTK_CFLAGS GLIB_LIBS GLIB_CFLAGS READLINE_LIBS READLINE_CFLAGS SYS_CFLAGS INSTALL LIBOBJS LTLIBOBJS' ac_subst_files='' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP CXX CXXFLAGS CCC CXXCPP F77 FFLAGS' # Initialize some variables set by options. ac_init_help= ac_init_version=false # 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' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' 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=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_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` eval enable_$ac_feature=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_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` eval enable_$ac_feature=\$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 ;; -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_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/[-.]/_/g'` eval with_$ac_package=\$ac_optarg ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/[-.]/_/g'` eval with_$ac_package=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 ;; -*) { echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && 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'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute directory names. 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 do eval ac_val=\$$ac_var case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; } 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 echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 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 .` || { echo "$as_me: error: Working directory cannot be determined" >&2 { (exit 1); exit 1; }; } test "X$ac_ls_di" = "X$ac_pwd_ls_di" || { echo "$as_me: error: pwd does not report name of working directory" >&2 { (exit 1); exit 1; }; } # 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 -- "$0" || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X"$0" | 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 .." { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 { (exit 1); exit 1; }; } 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 this package 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] --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/PACKAGE] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF 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 cat <<\_ACEOF Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --enable-malshow Create the GUI "malshow" [default=yes] 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-pic try to use only PIC/non-PIC objects [default=use both] --with-tags[=TAGS] include additional configurations [automatic] --with-readline Support fancy command line editing [default=yes] 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 C/C++/Objective 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 CXXCPP C++ preprocessor F77 Fortran 77 compiler command FFLAGS Fortran 77 compiler flags Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. _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" || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`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 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 configure generated by GNU Autoconf 2.61 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 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 cat >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 $as_me, which was generated by GNU Autoconf 2.61. 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=. 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=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$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 ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export 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 cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX 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_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( *) $as_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 cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------------- ## ## File substitutions. ## ## ------------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo cat confdefs.h echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" 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'; { (exit 1); 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 # 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 # Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. if test -n "$CONFIG_SITE"; then set x "$CONFIG_SITE" elif test "x$prefix" != xNONE; then set x "$prefix/share/config.site" "$prefix/etc/config.site" else set x "$ac_default_prefix/share/config.site" \ "$ac_default_prefix/etc/config.site" fi shift for ac_site_file do if test -r "$ac_site_file"; then { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" 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. if test -f "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { echo "$as_me:$LINENO: creating cache $cache_file" >&5 echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # 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,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 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 { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`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. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } 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 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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$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" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } # Provide some information about the compiler. echo "$as_me:$LINENO: checking for C compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out 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. { echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # # List of possible output files, starting from the most likely. # The algorithm is not robust to junk in `.', hence go to wildcards (a.*) # only as a last resort. b.out is created by i960 compilers. ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' # # The IRIX 6 linker writes into existing files which may not be # executable, retaining their permissions. Remove them first so a # subsequent execution test works. ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link_default") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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 | *.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 { echo "$as_me:$LINENO: result: $ac_file" >&5 echo "${ECHO_T}$ac_file" >&6; } if test -z "$ac_file"; then echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi ac_exeext=$ac_cv_exeext # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { echo "$as_me:$LINENO: checking whether the C compiler works" >&5 echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi fi { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } { echo "$as_me:$LINENO: result: $cross_compiling" >&5 echo "${ECHO_T}$cross_compiling" >&6; } { echo "$as_me:$LINENO: checking for suffix of executables" >&5 echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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 | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest$ac_cv_exeext { echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 echo "${ECHO_T}$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT { echo "$as_me:$LINENO: checking for suffix of object files" >&5 echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } if test "${ac_cv_objext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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 ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 echo "${ECHO_T}$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } if test "${ac_cv_c_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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 { echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } GCC=`test $ac_compiler_gnu = yes && echo yes` ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } if test "${ac_cv_prog_cc_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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 { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 echo "${ECHO_T}$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 { echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } if test "${ac_cv_prog_cc_c89+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* 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" 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_c89=$ac_arg else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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) { echo "$as_me:$LINENO: result: none needed" >&5 echo "${ECHO_T}none needed" >&6; } ;; xno) { echo "$as_me:$LINENO: result: unsupported" >&5 echo "${ECHO_T}unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; esac 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 case "$GCC" in yes) GCCFLAGS="-Wall -Wstrict-prototypes -Wmissing-prototypes" ;; *) GCCFLAGS="" esac 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 { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} { (exit 1); exit 1; }; } 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. { echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$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 ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done IFS=$as_save_IFS 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 { echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$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' # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac else enable_shared=yes fi # Check whether --enable-static was given. if test "${enable_static+set}" = set; then enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac else enable_static=yes fi # Check whether --enable-fast-install was given. if test "${enable_fast_install+set}" = set; then enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac else enable_fast_install=yes fi # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} { (exit 1); exit 1; }; } { echo "$as_me:$LINENO: checking build system type" >&5 echo $ECHO_N "checking build system type... $ECHO_C" >&6; } if test "${ac_cv_build+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 && { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 echo "$as_me: error: cannot guess build type; you must specify one" >&2;} { (exit 1); exit 1; }; } ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} { (exit 1); exit 1; }; } fi { echo "$as_me:$LINENO: result: $ac_cv_build" >&5 echo "${ECHO_T}$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 echo "$as_me: error: invalid value of canonical build" >&2;} { (exit 1); exit 1; }; };; 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 { echo "$as_me:$LINENO: checking host system type" >&5 echo $ECHO_N "checking host system type... $ECHO_C" >&6; } if test "${ac_cv_host+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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` || { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} { (exit 1); exit 1; }; } fi fi { echo "$as_me:$LINENO: result: $ac_cv_host" >&5 echo "${ECHO_T}$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 echo "$as_me: error: invalid value of canonical host" >&2;} { (exit 1); exit 1; }; };; 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 { echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5 echo $ECHO_N "checking for a sed that does not truncate output... $ECHO_C" >&6; } if test "${lt_cv_path_SED+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f $lt_ac_sed && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test $lt_ac_count -gt 10 && break lt_ac_count=`expr $lt_ac_count + 1` if test $lt_ac_count -gt $lt_ac_max; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done fi SED=$lt_cv_path_SED { echo "$as_me:$LINENO: result: $SED" >&5 echo "${ECHO_T}$SED" >&6; } { echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } if test "${ac_cv_path_GREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Extract the first word of "grep ggrep" to use in msg output if test -z "$GREP"; then set dummy grep ggrep; ac_prog_name=$2 if test "${ac_cv_path_GREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else 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" { test -f "$ac_path_GREP" && $as_test_x "$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 echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" 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 ac_count=`expr $ac_count + 1` 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 fi GREP="$ac_cv_path_GREP" if test -z "$GREP"; then { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_GREP=$GREP fi fi { echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 echo "${ECHO_T}$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { echo "$as_me:$LINENO: checking for egrep" >&5 echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } if test "${ac_cv_path_EGREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else # Extract the first word of "egrep" to use in msg output if test -z "$EGREP"; then set dummy egrep; ac_prog_name=$2 if test "${ac_cv_path_EGREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else 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" { test -f "$ac_path_EGREP" && $as_test_x "$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 echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" 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 ac_count=`expr $ac_count + 1` 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 fi EGREP="$ac_cv_path_EGREP" if test -z "$EGREP"; then { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_EGREP=$EGREP fi fi fi { echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" # 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 ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { echo "$as_me:$LINENO: checking for ld used by $CC" >&5 echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&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 { echo "$as_me:$LINENO: checking for GNU ld" >&5 echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6; } else { echo "$as_me:$LINENO: checking for non-GNU ld" >&5 echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6; } fi if test "${lt_cv_path_LD+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_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 `"$lt_cv_path_LD" -v 2>&1 &5 echo "${ECHO_T}$LD" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} { (exit 1); exit 1; }; } { echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6; } if test "${lt_cv_prog_gnu_ld+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5 echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6; } if test "${lt_cv_ld_reload_flag+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_cv_ld_reload_flag='-r' fi { echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5 echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in darwin*) if test "$GCC" = yes; then reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac { echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5 echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6; } if test "${lt_cv_path_NM+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm fi fi { echo "$as_me:$LINENO: result: $lt_cv_path_NM" >&5 echo "${ECHO_T}$lt_cv_path_NM" >&6; } NM="$lt_cv_path_NM" { echo "$as_me:$LINENO: checking whether ln -s works" >&5 echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else { echo "$as_me:$LINENO: result: no, using $LN_S" >&5 echo "${ECHO_T}no, using $LN_S" >&6; } fi { echo "$as_me:$LINENO: checking how to recognise dependent libraries" >&5 echo $ECHO_N "checking how to recognise dependent libraries... $ECHO_C" >&6; } if test "${lt_cv_deplibs_check_method+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # `unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # which responds to the $file_magic_cmd with a given extended regex. # If you have `file' or equivalent on your system and you're not sure # whether `pass_all' will *always* work, you probably want this one. case $host_os in aix4* | aix5*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump'. lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; gnu*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix3*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be Linux ELF. linux* | k*bsd*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; nto-qnx*) lt_cv_deplibs_check_method=unknown ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; esac fi { echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5 echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6; } file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then enableval=$enable_libtool_lock; fi test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '#line 3731 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" { echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5 echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6; } if test "${lt_cv_cc_needs_belf+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else 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 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then lt_cv_cc_needs_belf=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext 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 { echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5 echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6; } if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; sparc*-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) LD="${LD-ld} -m elf64_sparc" ;; *) LD="${LD-ld} -64" ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" 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 { echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f 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 { echo "$as_me:$LINENO: result: $CPP" >&5 echo "${ECHO_T}$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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } 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 { echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF 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=`echo "ac_cv_header_$ac_header" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in dlfcn.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done 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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $CXX" >&5 echo "${ECHO_T}$CXX" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CXX="$ac_prog" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 echo "${ECHO_T}$ac_ct_CXX" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. echo "$as_me:$LINENO: checking for C++ compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6; } if test "${ac_cv_cxx_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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 { echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6; } GXX=`test $ac_compiler_gnu = yes && echo yes` ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6; } if test "${ac_cv_prog_cxx_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cxx_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CXXFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cxx_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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 { echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 echo "${ECHO_T}$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=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 -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; 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 { echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5 echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6; } if test -z "$CXXCPP"; then if test "${ac_cv_prog_CXXCPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CXXCPP needs to be expanded for CXXCPP in "$CXX -E" "/lib/cpp" do ac_preproc_ok=false for ac_cxx_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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { echo "$as_me:$LINENO: result: $CXXCPP" >&5 echo "${ECHO_T}$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } 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 fi ac_ext=f ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_f77_compiler_gnu if test -n "$ac_tool_prefix"; then for ac_prog in g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77 xlf90 f90 pgf90 pghpf epcf90 gfortran g95 xlf95 f95 fort ifort ifc efc pgf95 lf95 ftn 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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_F77+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$F77"; then ac_cv_prog_F77="$F77" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_F77="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi F77=$ac_cv_prog_F77 if test -n "$F77"; then { echo "$as_me:$LINENO: result: $F77" >&5 echo "${ECHO_T}$F77" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$F77" && break done fi if test -z "$F77"; then ac_ct_F77=$F77 for ac_prog in g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77 xlf90 f90 pgf90 pghpf epcf90 gfortran g95 xlf95 f95 fort ifort ifc efc pgf95 lf95 ftn do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_F77+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_F77"; then ac_cv_prog_ac_ct_F77="$ac_ct_F77" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_F77="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_F77=$ac_cv_prog_ac_ct_F77 if test -n "$ac_ct_F77"; then { echo "$as_me:$LINENO: result: $ac_ct_F77" >&5 echo "${ECHO_T}$ac_ct_F77" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$ac_ct_F77" && break done if test "x$ac_ct_F77" = x; then F77="" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac F77=$ac_ct_F77 fi fi # Provide some information about the compiler. echo "$as_me:$LINENO: checking for Fortran 77 compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } rm -f a.out # If we don't use `.F' as extension, the preprocessor is not run on the # input file. (Note that this only needs to work for GNU compilers.) ac_save_ext=$ac_ext ac_ext=F { echo "$as_me:$LINENO: checking whether we are using the GNU Fortran 77 compiler" >&5 echo $ECHO_N "checking whether we are using the GNU Fortran 77 compiler... $ECHO_C" >&6; } if test "${ac_cv_f77_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF program main #ifndef __GNUC__ choke me #endif end _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_f77_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_f77_compiler_gnu=$ac_compiler_gnu fi { echo "$as_me:$LINENO: result: $ac_cv_f77_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_f77_compiler_gnu" >&6; } ac_ext=$ac_save_ext ac_test_FFLAGS=${FFLAGS+set} ac_save_FFLAGS=$FFLAGS FFLAGS= { echo "$as_me:$LINENO: checking whether $F77 accepts -g" >&5 echo $ECHO_N "checking whether $F77 accepts -g... $ECHO_C" >&6; } if test "${ac_cv_prog_f77_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else FFLAGS=-g cat >conftest.$ac_ext <<_ACEOF program main end _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_f77_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_f77_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_prog_f77_g=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_prog_f77_g" >&5 echo "${ECHO_T}$ac_cv_prog_f77_g" >&6; } if test "$ac_test_FFLAGS" = set; then FFLAGS=$ac_save_FFLAGS elif test $ac_cv_prog_f77_g = yes; then if test "x$ac_cv_f77_compiler_gnu" = xyes; then FFLAGS="-g -O2" else FFLAGS="-g" fi else if test "x$ac_cv_f77_compiler_gnu" = xyes; then FFLAGS="-O2" else FFLAGS= fi fi G77=`test $ac_compiler_gnu = yes && echo yes` 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 # Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! # find the maximum length of command line arguments { echo "$as_me:$LINENO: checking the maximum length of command line arguments" >&5 echo $ECHO_N "checking the maximum length of command line arguments... $ECHO_C" >&6; } if test "${lt_cv_sys_max_cmd_len+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} while (test "X"`$SHELL $0 --fallback-echo "X$teststring" 2>/dev/null` \ = "XX$teststring") >/dev/null 2>&1 && new_result=`expr "X$teststring" : ".*" 2>&1` && lt_cv_sys_max_cmd_len=$new_result && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done teststring= # Add a significant safety factor because C++ compilers can tack on massive # amounts of additional arguments before passing them to the linker. # It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` ;; esac fi if test -n $lt_cv_sys_max_cmd_len ; then { echo "$as_me:$LINENO: result: $lt_cv_sys_max_cmd_len" >&5 echo "${ECHO_T}$lt_cv_sys_max_cmd_len" >&6; } else { echo "$as_me:$LINENO: result: none" >&5 echo "${ECHO_T}none" >&6; } fi # Check for command to grab the raw symbol name followed by C symbol from nm. { echo "$as_me:$LINENO: checking command to parse $NM output from $compiler object" >&5 echo $ECHO_N "checking command to parse $NM output from $compiler object... $ECHO_C" >&6; } if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Transform an extracted symbol line into a proper C declaration lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32*) symcode='[ABCDGISTW]' ;; hpux*) # Its linker distinguishes data from code symbols if test "$host_cpu" = ia64; then symcode='[ABCDEGRST]' fi lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" ;; linux* | k*bsd*-gnu) if test "$host_cpu" = ia64; then symcode='[ABCDGIRSTW]' lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac # Try without a prefix undercore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Now try to grab the symbols. nlist=conftest.nm if { (eval echo "$as_me:$LINENO: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\"") >&5 (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if grep ' nm_test_var$' "$nlist" >/dev/null; then if grep ' nm_test_func$' "$nlist" >/dev/null; then cat < conftest.$ac_ext #ifdef __cplusplus extern "C" { #endif EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' cat <> conftest.$ac_ext #if defined (__STDC__) && __STDC__ # define lt_ptr_t void * #else # define lt_ptr_t char * # define const #endif /* The mapping between symbol names and symbols. */ const struct { const char *name; lt_ptr_t address; } lt_preloaded_symbols[] = { EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext cat <<\EOF >> conftest.$ac_ext {0, (lt_ptr_t) 0} }; #ifdef __cplusplus } #endif EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_save_LIBS="$LIBS" lt_save_CFLAGS="$CFLAGS" LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS="$lt_save_LIBS" CFLAGS="$lt_save_CFLAGS" else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -f conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { echo "$as_me:$LINENO: result: failed" >&5 echo "${ECHO_T}failed" >&6; } else { echo "$as_me:$LINENO: result: ok" >&5 echo "${ECHO_T}ok" >&6; } fi { echo "$as_me:$LINENO: checking for objdir" >&5 echo $ECHO_N "checking for objdir... $ECHO_C" >&6; } if test "${lt_cv_objdir+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { echo "$as_me:$LINENO: result: $lt_cv_objdir" >&5 echo "${ECHO_T}$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed='sed -e 1s/^X//' sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' # Constants: rm="rm -f" # Global variables: default_ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a ltmain="$ac_aux_dir/ltmain.sh" ofile="$default_ofile" with_gnu_ld="$lt_cv_prog_gnu_ld" if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. set dummy ${ac_tool_prefix}ar; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_AR+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AR="${ac_tool_prefix}ar" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { echo "$as_me:$LINENO: result: $AR" >&5 echo "${ECHO_T}$AR" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_AR"; then ac_ct_AR=$AR # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_AR+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_AR="ar" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { echo "$as_me:$LINENO: result: $ac_ct_AR" >&5 echo "${ECHO_T}$ac_ct_AR" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi else AR="$ac_cv_prog_AR" 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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $RANLIB" >&5 echo "${ECHO_T}$RANLIB" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RANLIB="ranlib" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 echo "${ECHO_T}$ac_ct_RANLIB" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi 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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $STRIP" >&5 echo "${ECHO_T}$STRIP" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}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 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" echo "$as_me:$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 { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 echo "${ECHO_T}$ac_ct_STRIP" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$AR" && AR=ar test -z "$AR_FLAGS" && AR_FLAGS=cru test -z "$AS" && AS=as test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$DLLTOOL" && DLLTOOL=dlltool test -z "$LD" && LD=ld test -z "$LN_S" && LN_S="ln -s" test -z "$MAGIC_CMD" && MAGIC_CMD=file test -z "$NM" && NM=nm test -z "$SED" && SED=sed test -z "$OBJDUMP" && OBJDUMP=objdump test -z "$RANLIB" && RANLIB=: test -z "$STRIP" && STRIP=: test -z "$ac_objext" && ac_objext=o # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" fi for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` # Only perform the check for file, if the check method requires it case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5 echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6; } if test "${lt_cv_path_MAGIC_CMD+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/${ac_tool_prefix}file; then lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 echo "${ECHO_T}$MAGIC_CMD" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { echo "$as_me:$LINENO: checking for file" >&5 echo $ECHO_N "checking for file... $ECHO_C" >&6; } if test "${lt_cv_path_MAGIC_CMD+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/file; then lt_cv_path_MAGIC_CMD="$ac_dir/file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 echo "${ECHO_T}$MAGIC_CMD" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac enable_dlopen=no enable_win32_dll=no # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then enableval=$enable_libtool_lock; fi test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Check whether --with-pic was given. if test "${with_pic+set}" = set; then withval=$with_pic; pic_mode="$withval" else pic_mode=default fi test -z "$pic_mode" && pic_mode=default # Use C for the default configuration in the libtool script tagname= lt_save_CC="$CC" 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 # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;\n" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}\n' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext printf "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $rm conftest* ac_outfile=conftest.$ac_objext printf "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $rm conftest* lt_prog_compiler_no_builtin_flag= if test "$GCC" = yes; then lt_prog_compiler_no_builtin_flag=' -fno-builtin' { echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6; } if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext printf "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:6349: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:6353: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $rm conftest* fi { echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= { echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } if test "$GCC" = yes; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi ;; amigaos*) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | pw32* | os2*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; interix3*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; hpux*) # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; *) lt_prog_compiler_pic='-fPIC' ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; darwin*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files case $cc_basename in xlc*) lt_prog_compiler_pic='-qnocommon' lt_prog_compiler_wl='-Wl,' ;; esac ;; mingw* | pw32* | os2*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; linux* | k*bsd*-gnu) case $cc_basename in icc* | ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; pgcc* | pgf77* | pgf90* | pgf95*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; esac ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi { echo "$as_me:$LINENO: result: $lt_prog_compiler_pic" >&5 echo "${ECHO_T}$lt_prog_compiler_pic" >&6; } # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic works... $ECHO_C" >&6; } if test "${lt_prog_compiler_pic_works+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext printf "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:6617: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:6621: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_prog_compiler_pic_works=yes fi fi $rm conftest* fi { echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works" >&5 echo "${ECHO_T}$lt_prog_compiler_pic_works" >&6; } if test x"$lt_prog_compiler_pic_works" = xyes; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; } if test "${lt_prog_compiler_static_works+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_prog_compiler_static_works=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" printf "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_prog_compiler_static_works=yes fi else lt_prog_compiler_static_works=yes fi fi $rm conftest* LDFLAGS="$save_LDFLAGS" fi { echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works" >&5 echo "${ECHO_T}$lt_prog_compiler_static_works" >&6; } if test x"$lt_prog_compiler_static_works" = xyes; then : else lt_prog_compiler_static= fi { echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; } if test "${lt_cv_prog_compiler_c_o+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_cv_prog_compiler_c_o=no $rm -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out printf "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:6721: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:6725: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $rm conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files $rm out/* && rmdir out cd .. rmdir conftest $rm conftest* fi { echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5 echo "${ECHO_T}$lt_cv_prog_compiler_c_o" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; } hard_links=yes $rm conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { echo "$as_me:$LINENO: result: $hard_links" >&5 echo "${ECHO_T}$hard_links" >&6; } if test "$hard_links" = no; then { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; } runpath_var= allow_undefined_flag= enable_shared_with_static_runtimes=no archive_cmds= archive_expsym_cmds= old_archive_From_new_cmds= old_archive_from_expsyms_cmds= export_dynamic_flag_spec= whole_archive_flag_spec= thread_safe_flag_spec= hardcode_libdir_flag_spec= hardcode_libdir_flag_spec_ld= hardcode_libdir_separator= hardcode_direct=no hardcode_minus_L=no hardcode_shlibpath_var=unsupported link_all_deplibs=unknown hardcode_automatic=no module_cmds= module_expsym_cmds= always_export_symbols=no export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. exclude_expsyms="_GLOBAL_OFFSET_TABLE_" # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. extract_expsyms_cmds= # Just being paranoid about ensuring that cc_basename is set. for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` case $host_os in cygwin* | mingw* | pw32*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; esac ld_shlibs=yes if test "$with_gnu_ld" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' export_dynamic_flag_spec='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v 2>/dev/null` in *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix3* | aix4* | aix5*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs=no cat <&2 *** Warning: the GNU linker, at least up to release 2.9.1, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to modify your PATH *** so that a non-GNU linker is found, and then restart. EOF fi ;; amigaos*) archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes # Samuel A. Falvo II reports # that the semantics of dynamic libraries on AmigaOS, at least up # to version 4, is to share data among multiple programs linked # with the same dynamic library. Since this doesn't match the # behavior of shared libraries on other platforms, we can't use # them. ld_shlibs=no ;; beos*) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32*) # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; interix3*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; linux* | k*bsd*-gnu) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then tmp_addflag= case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; esac archive_cmds='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test $supports_anon_versioning = yes; then archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ $echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi link_all_deplibs=no else ld_shlibs=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. EOF elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test "$ld_shlibs" = no; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix4* | aix5*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm if $NM -V 2>&1 | grep 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix5*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_libdir_separator=':' link_all_deplibs=yes if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && \ strings "$collect2name" | grep resolve_lib_name >/dev/null then # We have reworked collect2 hardcode_direct=yes else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an empty executable. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'`; fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an empty executable. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'`; fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' ${wl}-bernotok' allow_undefined_flag=' ${wl}-berok' # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' archive_cmds_need_lc=yes # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes # see comment about different semantics on the GNU ld section ld_shlibs=no ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_From_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs' fix_srcfile_path='`cygpath -w "$srcfile"`' enable_shared_with_static_runtimes=yes ;; darwin* | rhapsody*) case $host_os in rhapsody* | darwin1.[012]) allow_undefined_flag='${wl}-undefined ${wl}suppress' ;; *) # Darwin 1.3 on if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' else case ${MACOSX_DEPLOYMENT_TARGET} in 10.[012]) allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) allow_undefined_flag='${wl}-undefined ${wl}dynamic_lookup' ;; esac fi ;; esac archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported whole_archive_flag_spec='' link_all_deplibs=yes if test "$GCC" = yes ; then output_verbose_link_cmd='echo' archive_cmds='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' else case $cc_basename in xlc*) output_verbose_link_cmd='echo' archive_cmds='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ;; *) ld_shlibs=no ;; esac fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; freebsd1*) ld_shlibs=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test "$GCC" = yes; then archive_cmds='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='${wl}-E' ;; hpux10*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_libdir_flag_spec_ld='+b $libdir' hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec_ld='-rpath $libdir' fi hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: link_all_deplibs=yes ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; openbsd*) hardcode_direct=yes hardcode_shlibpath_var=no if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' else case $host_os in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-R$libdir' ;; *) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; esac fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' fi hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z text' if test "$GCC" = yes; then wlarc='${wl}' archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' else wlarc='' archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine linker options so we # cannot just pass the convience library names through # without $wl, iff we do not link with $LD. # Luckily, gcc supports the same syntax we need for Sun Studio. # Supported since Solaris 2.6 (maybe 2.5.1?) case $wlarc in '') whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; *) whole_archive_flag_spec='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; esac ;; esac link_all_deplibs=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*) no_undefined_flag='${wl}-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='${wl}-z,text' allow_undefined_flag='${wl}-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac fi { echo "$as_me:$LINENO: result: $ld_shlibs" >&5 echo "${ECHO_T}$ld_shlibs" >&6; } test "$ld_shlibs" = no && can_build_shared=no # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; } $rm conftest* printf "$lt_simple_compile_test_code" > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { (eval echo "$as_me:$LINENO: \"$archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 (eval $archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } then archive_cmds_need_lc=no else archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $rm conftest* { echo "$as_me:$LINENO: result: $archive_cmds_need_lc" >&5 echo "${ECHO_T}$archive_cmds_need_lc" >&6; } ;; esac fi ;; esac { echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; } library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" if test "$GCC" = yes; then sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix4* | aix5*) version_type=linux need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$host_os in yes,cygwin* | yes,mingw* | yes,pw32*) library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $rm \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ;; mingw*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH printed by # mingw gcc, but we are running on Cygwin. Gcc prints its search # path with ; separators, and with drive letters. We can handle the # drive letters (cygwin fileutils understands them), so leave them, # especially as we might pass files found there to a mingw objdump, # which wouldn't understand a cygwinified path. Ahh. sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac ;; *) library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' ;; esac dynamic_linker='Win32 ld.exe' # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. if test "$GCC" = yes; then sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` else sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' fi sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd1*) dynamic_linker=no ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[123]*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; freebsd*) # from 4.6 on shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555. postinstall_cmds='chmod 555 $lib' ;; interix3*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be Linux ELF. linux* | k*bsd*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; nto-qnx*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; solaris*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no export_dynamic_flag_spec='${wl}-Blargedynsym' runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' shlibpath_overrides_runpath=no else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' shlibpath_overrides_runpath=yes case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { echo "$as_me:$LINENO: result: $dynamic_linker" >&5 echo "${ECHO_T}$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi { echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || \ test -n "$runpath_var" || \ test "X$hardcode_automatic" = "Xyes" ; then # We can hardcode non-existant directories. if test "$hardcode_direct" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, )" != no && test "$hardcode_minus_L" != no; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { echo "$as_me:$LINENO: result: $hardcode_action" >&5 echo "${ECHO_T}$hardcode_action" >&6; } if test "$hardcode_action" = relink; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi striplib= old_striplib= { echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6; } if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi ;; *) { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } ;; esac fi if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; } if test "${ac_cv_lib_dl_dlopen+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_dl_dlopen=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; } if test $ac_cv_lib_dl_dlopen = yes; then lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; *) { echo "$as_me:$LINENO: checking for shl_load" >&5 echo $ECHO_N "checking for shl_load... $ECHO_C" >&6; } if test "${ac_cv_func_shl_load+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define shl_load to an innocuous variant, in case declares shl_load. For example, HP-UX 11i declares gettimeofday. */ #define shl_load innocuous_shl_load /* System header to define __stub macros and hopefully few prototypes, which can conflict with char shl_load (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef shl_load /* 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 shl_load (); /* 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_shl_load || defined __stub___shl_load choke me #endif int main () { return shl_load (); ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_func_shl_load=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_shl_load=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 echo "${ECHO_T}$ac_cv_func_shl_load" >&6; } if test $ac_cv_func_shl_load = yes; then lt_cv_dlopen="shl_load" else { echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6; } if test "${ac_cv_lib_dld_shl_load+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_dld_shl_load=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6; } if test $ac_cv_lib_dld_shl_load = yes; then lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld" else { echo "$as_me:$LINENO: checking for dlopen" >&5 echo $ECHO_N "checking for dlopen... $ECHO_C" >&6; } if test "${ac_cv_func_dlopen+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define dlopen to an innocuous variant, in case declares dlopen. For example, HP-UX 11i declares gettimeofday. */ #define dlopen innocuous_dlopen /* System header to define __stub macros and hopefully few prototypes, which can conflict with char dlopen (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef dlopen /* 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 (); /* 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_dlopen || defined __stub___dlopen choke me #endif int main () { return dlopen (); ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_func_dlopen=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 echo "${ECHO_T}$ac_cv_func_dlopen" >&6; } if test $ac_cv_func_dlopen = yes; then lt_cv_dlopen="dlopen" else { echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; } if test "${ac_cv_lib_dl_dlopen+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_dl_dlopen=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; } if test $ac_cv_lib_dl_dlopen = yes; then lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else { echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6; } if test "${ac_cv_lib_svld_dlopen+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_svld_dlopen=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6; } if test $ac_cv_lib_svld_dlopen = yes; then lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" else { echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6; } if test "${ac_cv_lib_dld_dld_link+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_dld_dld_link=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6; } if test $ac_cv_lib_dld_dld_link = yes; then lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld" fi fi fi fi fi fi ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" { echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5 echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6; } if test "${lt_cv_dlopen_self+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif #ifdef __cplusplus extern "C" void exit (int); #endif void fnord() { int i=42;} int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; /* dlclose (self); */ } else puts (dlerror ()); exit (status); } EOF if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5 echo "${ECHO_T}$lt_cv_dlopen_self" >&6; } if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5 echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6; } if test "${lt_cv_dlopen_self_static+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif #ifdef __cplusplus extern "C" void exit (int); #endif void fnord() { int i=42;} int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; /* dlclose (self); */ } else puts (dlerror ()); exit (status); } EOF if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5 echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi # Report which library types will actually be built { echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6; } { echo "$as_me:$LINENO: result: $can_build_shared" >&5 echo "${ECHO_T}$can_build_shared" >&6; } { echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6; } test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix4* | aix5*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac { echo "$as_me:$LINENO: result: $enable_shared" >&5 echo "${ECHO_T}$enable_shared" >&6; } { echo "$as_me:$LINENO: checking whether to build static libraries" >&5 echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6; } # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes { echo "$as_me:$LINENO: result: $enable_static" >&5 echo "${ECHO_T}$enable_static" >&6; } # The else clause should only fire when bootstrapping the # libtool distribution, otherwise you forgot to ship ltmain.sh # with your package, and you will get complaints that there are # no rules to generate ltmain.sh. if test -f "$ltmain"; then # See if we are running on zsh, and set the options which allow our commands through # without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi # Now quote all the things that may contain metacharacters while being # careful not to overquote the AC_SUBSTed values. We take copies of the # variables and quote the copies for generation of the libtool script. for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ SED SHELL STRIP \ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ deplibs_check_method reload_flag reload_cmds need_locks \ lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_c_name_address \ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ old_postinstall_cmds old_postuninstall_cmds \ compiler \ CC \ LD \ lt_prog_compiler_wl \ lt_prog_compiler_pic \ lt_prog_compiler_static \ lt_prog_compiler_no_builtin_flag \ export_dynamic_flag_spec \ thread_safe_flag_spec \ whole_archive_flag_spec \ enable_shared_with_static_runtimes \ old_archive_cmds \ old_archive_from_new_cmds \ predep_objects \ postdep_objects \ predeps \ postdeps \ compiler_lib_search_path \ archive_cmds \ archive_expsym_cmds \ postinstall_cmds \ postuninstall_cmds \ old_archive_from_expsyms_cmds \ allow_undefined_flag \ no_undefined_flag \ export_symbols_cmds \ hardcode_libdir_flag_spec \ hardcode_libdir_flag_spec_ld \ hardcode_libdir_separator \ hardcode_automatic \ module_cmds \ module_expsym_cmds \ lt_cv_prog_compiler_c_o \ exclude_expsyms \ include_expsyms; do case $var in old_archive_cmds | \ old_archive_from_new_cmds | \ archive_cmds | \ archive_expsym_cmds | \ module_cmds | \ module_expsym_cmds | \ old_archive_from_expsyms_cmds | \ export_symbols_cmds | \ extract_expsyms_cmds | reload_cmds | finish_cmds | \ postinstall_cmds | postuninstall_cmds | \ old_postinstall_cmds | old_postuninstall_cmds | \ sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) # Double-quote double-evaled strings. eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" ;; *) eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" ;; esac done case $lt_echo in *'\$0 --fallback-echo"') lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` ;; esac cfgfile="${ofile}T" trap "$rm \"$cfgfile\"; exit 1" 1 2 15 $rm -f "$cfgfile" { echo "$as_me:$LINENO: creating $ofile" >&5 echo "$as_me: creating $ofile" >&6;} cat <<__EOF__ >> "$cfgfile" #! $SHELL # `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) # NOTE: Changes made to this file will be lost: look at ltmain.sh. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 # Free Software Foundation, Inc. # # This file is part of GNU Libtool: # Originally by Gordon Matzigkeit , 1996 # # 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. # # 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. # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="$SED -e 1s/^X//" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # The names of the tagged configurations supported by this script. available_tags= # ### BEGIN LIBTOOL CONFIG # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # An echo program that does not interpret backslashes. echo=$lt_echo # The archiver. AR=$lt_AR AR_FLAGS=$lt_AR_FLAGS # A C compiler. LTCC=$lt_LTCC # LTCC compiler flags. LTCFLAGS=$lt_LTCFLAGS # A language-specific compiler. CC=$lt_compiler # Is the compiler the GNU C compiler? with_gcc=$GCC # An ERE matcher. EGREP=$lt_EGREP # The linker used to build libraries. LD=$lt_LD # Whether we need hard or soft links. LN_S=$lt_LN_S # A BSD-compatible nm program. NM=$lt_NM # A symbol stripping program STRIP=$lt_STRIP # Used to examine libraries when file_magic_cmd begins "file" MAGIC_CMD=$MAGIC_CMD # Used on cygwin: DLL creation program. DLLTOOL="$DLLTOOL" # Used on cygwin: object dumper. OBJDUMP="$OBJDUMP" # Used on cygwin: assembler. AS="$AS" # The name of the directory that contains temporary libtool files. objdir=$objdir # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Object file suffix (normally "o"). objext="$ac_objext" # Old archive suffix (normally "a"). libext="$libext" # Shared library suffix (normally ".so"). shrext_cmds='$shrext_cmds' # Executable file suffix (normally ""). exeext="$exeext" # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic pic_mode=$pic_mode # What is the maximum length of a command? max_cmd_len=$lt_cv_sys_max_cmd_len # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Must we lock files when doing compilation? need_locks=$lt_need_locks # Do we need the lib prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Compiler flag to generate thread-safe objects. thread_safe_flag_spec=$lt_thread_safe_flag_spec # Library versioning type. version_type=$version_type # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME. library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Commands used to build and install an old-style archive. RANLIB=$lt_RANLIB old_archive_cmds=$lt_old_archive_cmds old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build and install a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds postinstall_cmds=$lt_postinstall_cmds postuninstall_cmds=$lt_postuninstall_cmds # Commands used to build a loadable module (assumed same as above if empty) module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # Dependencies to place before the objects being linked to create a # shared library. predep_objects=$lt_predep_objects # Dependencies to place after the objects being linked to create a # shared library. postdep_objects=$lt_postdep_objects # Dependencies to place before the objects being linked to create a # shared library. predeps=$lt_predeps # Dependencies to place after the objects being linked to create a # shared library. postdeps=$lt_postdeps # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method == file_magic. file_magic_cmd=$lt_file_magic_cmd # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that forces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # Same as above, but a single script fragment to be evaled but not shown. finish_eval=$lt_finish_eval # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm in a C name address pair global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # This is the shared library runtime path variable. runpath_var=$runpath_var # This is the shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist. hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # If ld is used when linking, flag to hardcode \$libdir into # a binary during linking. This must work even if \$libdir does # not exist. hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld # Whether we need a single -rpath flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the # resulting binary. hardcode_direct=$hardcode_direct # Set to yes if using the -LDIR flag during linking hardcodes DIR into the # resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into # the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to yes if building a shared library automatically hardcodes DIR into the library # and all subsequent libraries and executables linked against it. hardcode_automatic=$hardcode_automatic # Variables whose values should be saved in libtool wrapper scripts and # restored at relink time. variables_saved_for_relink="$variables_saved_for_relink" # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Compile-time system search path for libraries sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Run-time system search path for libraries sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Fix the shell variable \$srcfile for the compiler. fix_srcfile_path="$fix_srcfile_path" # Set to yes if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # ### END LIBTOOL CONFIG __EOF__ case $host_os in aix3*) cat <<\EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi EOF ;; esac # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || \ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" else # If there is no Makefile yet, we rely on a make rule to execute # `config.status --recheck' to rerun these tests and create the # libtool script then. ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` if test -f "$ltmain_in"; then test -f Makefile && make "$ltmain" 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 CC="$lt_save_CC" # Check whether --with-tags was given. if test "${with_tags+set}" = set; then withval=$with_tags; tagnames="$withval" fi if test -f "$ltmain" && test -n "$tagnames"; then if test ! -f "${ofile}"; then { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not exist" >&5 echo "$as_me: WARNING: output file \`$ofile' does not exist" >&2;} fi if test -z "$LTCC"; then eval "`$SHELL ${ofile} --config | grep '^LTCC='`" if test -z "$LTCC"; then { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not look like a libtool script" >&5 echo "$as_me: WARNING: output file \`$ofile' does not look like a libtool script" >&2;} else { echo "$as_me:$LINENO: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&5 echo "$as_me: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&2;} fi fi if test -z "$LTCFLAGS"; then eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`" fi # Extract list of available tagged configurations in $ofile. # Note that this assumes the entire list is on one line. available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for tagname in $tagnames; do IFS="$lt_save_ifs" # Check whether tagname contains only valid characters case `$echo "X$tagname" | $Xsed -e 's:[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]::g'` in "") ;; *) { { echo "$as_me:$LINENO: error: invalid tag name: $tagname" >&5 echo "$as_me: error: invalid tag name: $tagname" >&2;} { (exit 1); exit 1; }; } ;; esac if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null then { { echo "$as_me:$LINENO: error: tag name \"$tagname\" already exists" >&5 echo "$as_me: error: tag name \"$tagname\" already exists" >&2;} { (exit 1); exit 1; }; } fi # Update the list of available tags. if test -n "$tagname"; then echo appending configuration tag \"$tagname\" to $ofile case $tagname in CXX) if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; 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 archive_cmds_need_lc_CXX=no allow_undefined_flag_CXX= always_export_symbols_CXX=no archive_expsym_cmds_CXX= export_dynamic_flag_spec_CXX= hardcode_direct_CXX=no hardcode_libdir_flag_spec_CXX= hardcode_libdir_flag_spec_ld_CXX= hardcode_libdir_separator_CXX= hardcode_minus_L_CXX=no hardcode_shlibpath_var_CXX=unsupported hardcode_automatic_CXX=no module_cmds_CXX= module_expsym_cmds_CXX= link_all_deplibs_CXX=unknown old_archive_cmds_CXX=$old_archive_cmds no_undefined_flag_CXX= whole_archive_flag_spec_CXX= enable_shared_with_static_runtimes_CXX=no # Dependencies to place before and after the object being linked: predep_objects_CXX= postdep_objects_CXX= predeps_CXX= postdeps_CXX= compiler_lib_search_path_CXX= # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o objext_CXX=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;\n" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[]) { return(0); }\n' # ltmain only uses $CC for tagged configurations so make sure $CC is set. # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext printf "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $rm conftest* ac_outfile=conftest.$ac_objext printf "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $rm conftest* # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} compiler=$CC compiler_CXX=$CC for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` # We don't want -fno-exception wen compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' else lt_prog_compiler_no_builtin_flag_CXX= fi if test "$GXX" = yes; then # Set up default GNU C++ configuration # 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 ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { echo "$as_me:$LINENO: checking for ld used by $CC" >&5 echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&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 { echo "$as_me:$LINENO: checking for GNU ld" >&5 echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6; } else { echo "$as_me:$LINENO: checking for non-GNU ld" >&5 echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6; } fi if test "${lt_cv_path_LD+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_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 `"$lt_cv_path_LD" -v 2>&1 &5 echo "${ECHO_T}$LD" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} { (exit 1); exit 1; }; } { echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6; } if test "${lt_cv_prog_gnu_ld+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='${wl}' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ grep 'no-whole-archive' > /dev/null; then whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec_CXX= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics { echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; } ld_shlibs_CXX=yes case $host_os in aix3*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aix4* | aix5*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix5*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds_CXX='' hardcode_direct_CXX=yes hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes if test "$GXX" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && \ strings "$collect2name" | grep resolve_lib_name >/dev/null then # We have reworked collect2 hardcode_direct_CXX=yes else # We have old collect2 hardcode_direct_CXX=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L_CXX=yes hardcode_libdir_flag_spec_CXX='-L$libdir' hardcode_libdir_separator_CXX= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols_CXX=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag_CXX='-berok' # Determine the default libpath from the value encoded in an empty executable. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'`; fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds_CXX="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag_CXX="-z nodefs" archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an empty executable. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'`; fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag_CXX=' ${wl}-bernotok' allow_undefined_flag_CXX=' ${wl}-berok' # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec_CXX='$convenience' archive_cmds_need_lc_CXX=yes # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then allow_undefined_flag_CXX=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs_CXX=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; cygwin* | mingw* | pw32*) # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec_CXX='-L$libdir' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=no enable_shared_with_static_runtimes_CXX=yes if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs_CXX=no fi ;; darwin* | rhapsody*) case $host_os in rhapsody* | darwin1.[012]) allow_undefined_flag_CXX='${wl}-undefined ${wl}suppress' ;; *) # Darwin 1.3 on if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' else case ${MACOSX_DEPLOYMENT_TARGET} in 10.[012]) allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) allow_undefined_flag_CXX='${wl}-undefined ${wl}dynamic_lookup' ;; esac fi ;; esac archive_cmds_need_lc_CXX=no hardcode_direct_CXX=no hardcode_automatic_CXX=yes hardcode_shlibpath_var_CXX=unsupported whole_archive_flag_spec_CXX='' link_all_deplibs_CXX=yes if test "$GXX" = yes ; then lt_int_apple_cc_single_mod=no output_verbose_link_cmd='echo' if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then lt_int_apple_cc_single_mod=yes fi if test "X$lt_int_apple_cc_single_mod" = Xyes ; then archive_cmds_CXX='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' else archive_cmds_CXX='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' fi module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds if test "X$lt_int_apple_cc_single_mod" = Xyes ; then archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' else archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' fi module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' else case $cc_basename in xlc*) output_verbose_link_cmd='echo' archive_cmds_CXX='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ;; *) ld_shlibs_CXX=no ;; esac fi ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; freebsd[12]*) # C++ shared libraries reported to be fairly broken before switch to ELF ld_shlibs_CXX=no ;; freebsd-elf*) archive_cmds_need_lc_CXX=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions ld_shlibs_CXX=yes ;; gnu*) ;; hpux9*) hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' hardcode_libdir_separator_CXX=: export_dynamic_flag_spec_CXX='${wl}-E' hardcode_direct_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) archive_cmds_CXX='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[-]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ;; *) if test "$GXX" = yes; then archive_cmds_CXX='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' hardcode_libdir_separator_CXX=: case $host_cpu in hppa*64*|ia64*) hardcode_libdir_flag_spec_ld_CXX='+b $libdir' ;; *) export_dynamic_flag_spec_CXX='${wl}-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no ;; *) hardcode_direct_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; interix3*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' export_dynamic_flag_spec_CXX='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' fi fi link_all_deplibs_CXX=yes ;; esac hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_CXX=: ;; linux* | k*bsd*-gnu) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' hardcode_libdir_flag_spec_CXX='${wl}--rpath,$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc*) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; esac archive_cmds_need_lc_CXX=no hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; pgCC*) # Portland Group C++ compiler archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec_CXX='-rpath $libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ;; esac ;; lynxos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; m88k*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; openbsd2*) # C++ shared libraries are fairly broken ld_shlibs_CXX=no ;; openbsd*) hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' export_dynamic_flag_spec_CXX='${wl}-E' whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' fi output_verbose_link_cmd='echo' ;; osf3*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' hardcode_libdir_separator_CXX=: # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; cxx*) allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' hardcode_libdir_separator_CXX=: # Archives containing C++ object files must be created using # the KAI C++ compiler. old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; cxx*) allow_undefined_flag_CXX=' -expect_unresolved \*' archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~ $rm $lib.exp' hardcode_libdir_flag_spec_CXX='-rpath $libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; solaris*) case $cc_basename in CC*) # Sun C++ 4.2, 5.x and Centerline C++ archive_cmds_need_lc_CXX=yes no_undefined_flag_CXX=' -zdefs' archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_shlibpath_var_CXX=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The C++ compiler is used as linker so we must use $wl # flag to pass the commands to the underlying system # linker. We must also pass each convience library through # to the system linker between allextract/defaultextract. # The C++ compiler will combine linker options so we # cannot just pass the convience library names through # without $wl. # Supported since Solaris 2.6 (maybe 2.5.1?) whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; esac link_all_deplibs_CXX=yes output_verbose_link_cmd='echo' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test "$GXX" = yes && test "$with_gnu_ld" = no; then no_undefined_flag_CXX=' ${wl}-z ${wl}defs' if $CC --version | grep -v '^2\.7' > /dev/null; then archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" fi hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag_CXX='${wl}-z,text' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. # So that behaviour is only enabled if SCOABSPATH is set to a # non-empty value in the environment. Most likely only useful for # creating official distributions of packages. # This is a hack until libtool officially supports absolute path # names for shared libraries. no_undefined_flag_CXX='${wl}-z,text' allow_undefined_flag_CXX='${wl}-z,nodefs' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes export_dynamic_flag_spec_CXX='${wl}-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac { echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5 echo "${ECHO_T}$ld_shlibs_CXX" >&6; } test "$ld_shlibs_CXX" = no && can_build_shared=no GCC_CXX="$GXX" LD_CXX="$LD" cat > conftest.$ac_ext <&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no # The `*' in the case matches for architectures that use `case' in # $output_verbose_cmd can trigger glob expansion during the loop # eval without this substitution. output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"` for p in `eval $output_verbose_link_cmd`; do case $p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" \ || test $p = "-R"; then prev=$p continue else prev= fi if test "$pre_test_object_deps_done" = no; then case $p in -L* | -R*) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$compiler_lib_search_path_CXX"; then compiler_lib_search_path_CXX="${prev}${p}" else compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$postdeps_CXX"; then postdeps_CXX="${prev}${p}" else postdeps_CXX="${postdeps_CXX} ${prev}${p}" fi fi ;; *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test "$pre_test_object_deps_done" = no; then if test -z "$predep_objects_CXX"; then predep_objects_CXX="$p" else predep_objects_CXX="$predep_objects_CXX $p" fi else if test -z "$postdep_objects_CXX"; then postdep_objects_CXX="$p" else postdep_objects_CXX="$postdep_objects_CXX $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling CXX test program" fi $rm -f confest.$objext # PORTME: override above test on systems where it is broken case $host_os in interix3*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. predep_objects_CXX= postdep_objects_CXX= postdeps_CXX= ;; solaris*) case $cc_basename in CC*) # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. postdeps_CXX='-lCstd -lCrun' ;; esac ;; esac case " $postdeps_CXX " in *" -lc "*) archive_cmds_need_lc_CXX=no ;; esac lt_prog_compiler_wl_CXX= lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX= { echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' fi ;; amigaos*) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' ;; beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | os2* | pw32*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic_CXX='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic_CXX='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all lt_prog_compiler_pic_CXX= ;; interix3*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic_CXX=-Kconform_pic fi ;; hpux*) # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac else case $host_os in aix4* | aix5*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' else lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_AC_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; darwin*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files case $cc_basename in xlc*) lt_prog_compiler_pic_CXX='-qnocommon' lt_prog_compiler_wl_CXX='-Wl,' ;; esac ;; dgux*) case $cc_basename in ec++*) lt_prog_compiler_pic_CXX='-KPIC' ;; ghcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then lt_prog_compiler_pic_CXX='+Z' fi ;; aCC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic_CXX='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu) case $cc_basename in KCC*) # KAI C++ Compiler lt_prog_compiler_wl_CXX='--backend -Wl,' lt_prog_compiler_pic_CXX='-fPIC' ;; icpc* | ecpc*) # Intel C++ lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-static' ;; pgCC*) # Portland Group C++ compiler. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fpic' lt_prog_compiler_static_CXX='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; *) ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) lt_prog_compiler_pic_CXX='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) lt_prog_compiler_wl_CXX='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 lt_prog_compiler_pic_CXX='-pic' ;; cxx*) # Digital/Compaq C++ lt_prog_compiler_wl_CXX='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC*) # Sun C++ 4.2, 5.x and Centerline C++ lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x lt_prog_compiler_pic_CXX='-pic' lt_prog_compiler_static_CXX='-Bstatic' ;; lcc*) # Lucid lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 lt_prog_compiler_pic_CXX='-KPIC' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' ;; esac ;; vxworks*) ;; *) lt_prog_compiler_can_build_shared_CXX=no ;; esac fi { echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_CXX" >&5 echo "${ECHO_T}$lt_prog_compiler_pic_CXX" >&6; } # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic_CXX"; then { echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... $ECHO_C" >&6; } if test "${lt_prog_compiler_pic_works_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_prog_compiler_pic_works_CXX=no ac_outfile=conftest.$ac_objext printf "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:11454: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:11458: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_prog_compiler_pic_works_CXX=yes fi fi $rm conftest* fi { echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_CXX" >&5 echo "${ECHO_T}$lt_prog_compiler_pic_works_CXX" >&6; } if test x"$lt_prog_compiler_pic_works_CXX" = xyes; then case $lt_prog_compiler_pic_CXX in "" | " "*) ;; *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; esac else lt_prog_compiler_pic_CXX= lt_prog_compiler_can_build_shared_CXX=no fi fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic_CXX= ;; *) lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" ;; esac # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" { echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; } if test "${lt_prog_compiler_static_works_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_prog_compiler_static_works_CXX=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" printf "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_prog_compiler_static_works_CXX=yes fi else lt_prog_compiler_static_works_CXX=yes fi fi $rm conftest* LDFLAGS="$save_LDFLAGS" fi { echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_CXX" >&5 echo "${ECHO_T}$lt_prog_compiler_static_works_CXX" >&6; } if test x"$lt_prog_compiler_static_works_CXX" = xyes; then : else lt_prog_compiler_static_CXX= fi { echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; } if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_cv_prog_compiler_c_o_CXX=no $rm -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out printf "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:11558: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:11562: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi chmod u+w . 2>&5 $rm conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files $rm out/* && rmdir out cd .. rmdir conftest $rm conftest* fi { echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_CXX" >&5 echo "${ECHO_T}$lt_cv_prog_compiler_c_o_CXX" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; } hard_links=yes $rm conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { echo "$as_me:$LINENO: result: $hard_links" >&5 echo "${ECHO_T}$hard_links" >&6; } if test "$hard_links" = no; then { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; } export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' case $host_os in aix4* | aix5*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm if $NM -V 2>&1 | grep 'GNU' > /dev/null; then export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) export_symbols_cmds_CXX="$ltdll_cmds" ;; cygwin* | mingw*) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([^ ]*\) [^ ]*/\1 DATA/;/^I /d;/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' ;; linux* | k*bsd*-gnu) link_all_deplibs_CXX=no ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac { echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5 echo "${ECHO_T}$ld_shlibs_CXX" >&6; } test "$ld_shlibs_CXX" = no && can_build_shared=no # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc_CXX" in x|xyes) # Assume -lc should be added archive_cmds_need_lc_CXX=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds_CXX in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; } $rm conftest* printf "$lt_simple_compile_test_code" > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl_CXX pic_flag=$lt_prog_compiler_pic_CXX compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag_CXX allow_undefined_flag_CXX= if { (eval echo "$as_me:$LINENO: \"$archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 (eval $archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } then archive_cmds_need_lc_CXX=no else archive_cmds_need_lc_CXX=yes fi allow_undefined_flag_CXX=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $rm conftest* { echo "$as_me:$LINENO: result: $archive_cmds_need_lc_CXX" >&5 echo "${ECHO_T}$archive_cmds_need_lc_CXX" >&6; } ;; esac fi ;; esac { echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; } library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" if test "$GCC" = yes; then sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix4* | aix5*) version_type=linux need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$host_os in yes,cygwin* | yes,mingw* | yes,pw32*) library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $rm \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ;; mingw*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH printed by # mingw gcc, but we are running on Cygwin. Gcc prints its search # path with ; separators, and with drive letters. We can handle the # drive letters (cygwin fileutils understands them), so leave them, # especially as we might pass files found there to a mingw objdump, # which wouldn't understand a cygwinified path. Ahh. sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac ;; *) library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' ;; esac dynamic_linker='Win32 ld.exe' # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. if test "$GCC" = yes; then sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` else sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' fi sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd1*) dynamic_linker=no ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[123]*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; freebsd*) # from 4.6 on shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555. postinstall_cmds='chmod 555 $lib' ;; interix3*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be Linux ELF. linux* | k*bsd*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; nto-qnx*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; solaris*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no export_dynamic_flag_spec='${wl}-Blargedynsym' runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' shlibpath_overrides_runpath=no else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' shlibpath_overrides_runpath=yes case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { echo "$as_me:$LINENO: result: $dynamic_linker" >&5 echo "${ECHO_T}$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi { echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; } hardcode_action_CXX= if test -n "$hardcode_libdir_flag_spec_CXX" || \ test -n "$runpath_var_CXX" || \ test "X$hardcode_automatic_CXX" = "Xyes" ; then # We can hardcode non-existant directories. if test "$hardcode_direct_CXX" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, CXX)" != no && test "$hardcode_minus_L_CXX" != no; then # Linking always hardcodes the temporary library directory. hardcode_action_CXX=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action_CXX=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action_CXX=unsupported fi { echo "$as_me:$LINENO: result: $hardcode_action_CXX" >&5 echo "${ECHO_T}$hardcode_action_CXX" >&6; } if test "$hardcode_action_CXX" = relink; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi # The else clause should only fire when bootstrapping the # libtool distribution, otherwise you forgot to ship ltmain.sh # with your package, and you will get complaints that there are # no rules to generate ltmain.sh. if test -f "$ltmain"; then # See if we are running on zsh, and set the options which allow our commands through # without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi # Now quote all the things that may contain metacharacters while being # careful not to overquote the AC_SUBSTed values. We take copies of the # variables and quote the copies for generation of the libtool script. for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ SED SHELL STRIP \ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ deplibs_check_method reload_flag reload_cmds need_locks \ lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_c_name_address \ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ old_postinstall_cmds old_postuninstall_cmds \ compiler_CXX \ CC_CXX \ LD_CXX \ lt_prog_compiler_wl_CXX \ lt_prog_compiler_pic_CXX \ lt_prog_compiler_static_CXX \ lt_prog_compiler_no_builtin_flag_CXX \ export_dynamic_flag_spec_CXX \ thread_safe_flag_spec_CXX \ whole_archive_flag_spec_CXX \ enable_shared_with_static_runtimes_CXX \ old_archive_cmds_CXX \ old_archive_from_new_cmds_CXX \ predep_objects_CXX \ postdep_objects_CXX \ predeps_CXX \ postdeps_CXX \ compiler_lib_search_path_CXX \ archive_cmds_CXX \ archive_expsym_cmds_CXX \ postinstall_cmds_CXX \ postuninstall_cmds_CXX \ old_archive_from_expsyms_cmds_CXX \ allow_undefined_flag_CXX \ no_undefined_flag_CXX \ export_symbols_cmds_CXX \ hardcode_libdir_flag_spec_CXX \ hardcode_libdir_flag_spec_ld_CXX \ hardcode_libdir_separator_CXX \ hardcode_automatic_CXX \ module_cmds_CXX \ module_expsym_cmds_CXX \ lt_cv_prog_compiler_c_o_CXX \ exclude_expsyms_CXX \ include_expsyms_CXX; do case $var in old_archive_cmds_CXX | \ old_archive_from_new_cmds_CXX | \ archive_cmds_CXX | \ archive_expsym_cmds_CXX | \ module_cmds_CXX | \ module_expsym_cmds_CXX | \ old_archive_from_expsyms_cmds_CXX | \ export_symbols_cmds_CXX | \ extract_expsyms_cmds | reload_cmds | finish_cmds | \ postinstall_cmds | postuninstall_cmds | \ old_postinstall_cmds | old_postuninstall_cmds | \ sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) # Double-quote double-evaled strings. eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" ;; *) eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" ;; esac done case $lt_echo in *'\$0 --fallback-echo"') lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` ;; esac cfgfile="$ofile" cat <<__EOF__ >> "$cfgfile" # ### BEGIN LIBTOOL TAG CONFIG: $tagname # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc_CXX # Whether or not to disallow shared libs when runtime libs are static allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # An echo program that does not interpret backslashes. echo=$lt_echo # The archiver. AR=$lt_AR AR_FLAGS=$lt_AR_FLAGS # A C compiler. LTCC=$lt_LTCC # LTCC compiler flags. LTCFLAGS=$lt_LTCFLAGS # A language-specific compiler. CC=$lt_compiler_CXX # Is the compiler the GNU C compiler? with_gcc=$GCC_CXX # An ERE matcher. EGREP=$lt_EGREP # The linker used to build libraries. LD=$lt_LD_CXX # Whether we need hard or soft links. LN_S=$lt_LN_S # A BSD-compatible nm program. NM=$lt_NM # A symbol stripping program STRIP=$lt_STRIP # Used to examine libraries when file_magic_cmd begins "file" MAGIC_CMD=$MAGIC_CMD # Used on cygwin: DLL creation program. DLLTOOL="$DLLTOOL" # Used on cygwin: object dumper. OBJDUMP="$OBJDUMP" # Used on cygwin: assembler. AS="$AS" # The name of the directory that contains temporary libtool files. objdir=$objdir # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl_CXX # Object file suffix (normally "o"). objext="$ac_objext" # Old archive suffix (normally "a"). libext="$libext" # Shared library suffix (normally ".so"). shrext_cmds='$shrext_cmds' # Executable file suffix (normally ""). exeext="$exeext" # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic_CXX pic_mode=$pic_mode # What is the maximum length of a command? max_cmd_len=$lt_cv_sys_max_cmd_len # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX # Must we lock files when doing compilation? need_locks=$lt_need_locks # Do we need the lib prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static_CXX # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX # Compiler flag to generate thread-safe objects. thread_safe_flag_spec=$lt_thread_safe_flag_spec_CXX # Library versioning type. version_type=$version_type # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME. library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Commands used to build and install an old-style archive. RANLIB=$lt_RANLIB old_archive_cmds=$lt_old_archive_cmds_CXX old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX # Commands used to build and install a shared archive. archive_cmds=$lt_archive_cmds_CXX archive_expsym_cmds=$lt_archive_expsym_cmds_CXX postinstall_cmds=$lt_postinstall_cmds postuninstall_cmds=$lt_postuninstall_cmds # Commands used to build a loadable module (assumed same as above if empty) module_cmds=$lt_module_cmds_CXX module_expsym_cmds=$lt_module_expsym_cmds_CXX # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # Dependencies to place before the objects being linked to create a # shared library. predep_objects=$lt_predep_objects_CXX # Dependencies to place after the objects being linked to create a # shared library. postdep_objects=$lt_postdep_objects_CXX # Dependencies to place before the objects being linked to create a # shared library. predeps=$lt_predeps_CXX # Dependencies to place after the objects being linked to create a # shared library. postdeps=$lt_postdeps_CXX # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path_CXX # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method == file_magic. file_magic_cmd=$lt_file_magic_cmd # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag_CXX # Flag that forces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag_CXX # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # Same as above, but a single script fragment to be evaled but not shown. finish_eval=$lt_finish_eval # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm in a C name address pair global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # This is the shared library runtime path variable. runpath_var=$runpath_var # This is the shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action_CXX # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist. hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX # If ld is used when linking, flag to hardcode \$libdir into # a binary during linking. This must work even if \$libdir does # not exist. hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX # Whether we need a single -rpath flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX # Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the # resulting binary. hardcode_direct=$hardcode_direct_CXX # Set to yes if using the -LDIR flag during linking hardcodes DIR into the # resulting binary. hardcode_minus_L=$hardcode_minus_L_CXX # Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into # the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX # Set to yes if building a shared library automatically hardcodes DIR into the library # and all subsequent libraries and executables linked against it. hardcode_automatic=$hardcode_automatic_CXX # Variables whose values should be saved in libtool wrapper scripts and # restored at relink time. variables_saved_for_relink="$variables_saved_for_relink" # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs_CXX # Compile-time system search path for libraries sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Run-time system search path for libraries sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Fix the shell variable \$srcfile for the compiler. fix_srcfile_path="$fix_srcfile_path_CXX" # Set to yes if exported symbols are required. always_export_symbols=$always_export_symbols_CXX # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds_CXX # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms_CXX # Symbols that must always be exported. include_expsyms=$lt_include_expsyms_CXX # ### END LIBTOOL TAG CONFIG: $tagname __EOF__ else # If there is no Makefile yet, we rely on a make rule to execute # `config.status --recheck' to rerun these tests and create the # libtool script then. ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` if test -f "$ltmain_in"; then test -f Makefile && make "$ltmain" 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 CC=$lt_save_CC LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ldcxx=$with_gnu_ld with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld else tagname="" fi ;; F77) if test -n "$F77" && test "X$F77" != "Xno"; then ac_ext=f ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_f77_compiler_gnu archive_cmds_need_lc_F77=no allow_undefined_flag_F77= always_export_symbols_F77=no archive_expsym_cmds_F77= export_dynamic_flag_spec_F77= hardcode_direct_F77=no hardcode_libdir_flag_spec_F77= hardcode_libdir_flag_spec_ld_F77= hardcode_libdir_separator_F77= hardcode_minus_L_F77=no hardcode_automatic_F77=no module_cmds_F77= module_expsym_cmds_F77= link_all_deplibs_F77=unknown old_archive_cmds_F77=$old_archive_cmds no_undefined_flag_F77= whole_archive_flag_spec_F77= enable_shared_with_static_runtimes_F77=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o objext_F77=$objext # Code to be used in simple compile tests lt_simple_compile_test_code=" subroutine t\n return\n end\n" # Code to be used in simple link tests lt_simple_link_test_code=" program t\n end\n" # ltmain only uses $CC for tagged configurations so make sure $CC is set. # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext printf "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $rm conftest* ac_outfile=conftest.$ac_objext printf "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $rm conftest* # Allow CC to be a program name with arguments. lt_save_CC="$CC" CC=${F77-"f77"} compiler=$CC compiler_F77=$CC for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` { echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6; } { echo "$as_me:$LINENO: result: $can_build_shared" >&5 echo "${ECHO_T}$can_build_shared" >&6; } { echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6; } test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix4* | aix5*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac { echo "$as_me:$LINENO: result: $enable_shared" >&5 echo "${ECHO_T}$enable_shared" >&6; } { echo "$as_me:$LINENO: checking whether to build static libraries" >&5 echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6; } # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes { echo "$as_me:$LINENO: result: $enable_static" >&5 echo "${ECHO_T}$enable_static" >&6; } GCC_F77="$G77" LD_F77="$LD" lt_prog_compiler_wl_F77= lt_prog_compiler_pic_F77= lt_prog_compiler_static_F77= { echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } if test "$GCC" = yes; then lt_prog_compiler_wl_F77='-Wl,' lt_prog_compiler_static_F77='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_F77='-Bstatic' fi ;; amigaos*) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. lt_prog_compiler_pic_F77='-m68020 -resident32 -malways-restore-a4' ;; beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | pw32* | os2*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic_F77='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic_F77='-fno-common' ;; interix3*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared_F77=no enable_shared=no ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic_F77=-Kconform_pic fi ;; hpux*) # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic_F77='-fPIC' ;; esac ;; *) lt_prog_compiler_pic_F77='-fPIC' ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl_F77='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_F77='-Bstatic' else lt_prog_compiler_static_F77='-bnso -bI:/lib/syscalls.exp' fi ;; darwin*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files case $cc_basename in xlc*) lt_prog_compiler_pic_F77='-qnocommon' lt_prog_compiler_wl_F77='-Wl,' ;; esac ;; mingw* | pw32* | os2*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic_F77='-DDLL_EXPORT' ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl_F77='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic_F77='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static_F77='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl_F77='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static_F77='-non_shared' ;; newsos6) lt_prog_compiler_pic_F77='-KPIC' lt_prog_compiler_static_F77='-Bstatic' ;; linux* | k*bsd*-gnu) case $cc_basename in icc* | ecc*) lt_prog_compiler_wl_F77='-Wl,' lt_prog_compiler_pic_F77='-KPIC' lt_prog_compiler_static_F77='-static' ;; pgcc* | pgf77* | pgf90* | pgf95*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl_F77='-Wl,' lt_prog_compiler_pic_F77='-fpic' lt_prog_compiler_static_F77='-Bstatic' ;; ccc*) lt_prog_compiler_wl_F77='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static_F77='-non_shared' ;; esac ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl_F77='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static_F77='-non_shared' ;; solaris*) lt_prog_compiler_pic_F77='-KPIC' lt_prog_compiler_static_F77='-Bstatic' case $cc_basename in f77* | f90* | f95*) lt_prog_compiler_wl_F77='-Qoption ld ';; *) lt_prog_compiler_wl_F77='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl_F77='-Qoption ld ' lt_prog_compiler_pic_F77='-PIC' lt_prog_compiler_static_F77='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl_F77='-Wl,' lt_prog_compiler_pic_F77='-KPIC' lt_prog_compiler_static_F77='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then lt_prog_compiler_pic_F77='-Kconform_pic' lt_prog_compiler_static_F77='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl_F77='-Wl,' lt_prog_compiler_pic_F77='-KPIC' lt_prog_compiler_static_F77='-Bstatic' ;; unicos*) lt_prog_compiler_wl_F77='-Wl,' lt_prog_compiler_can_build_shared_F77=no ;; uts4*) lt_prog_compiler_pic_F77='-pic' lt_prog_compiler_static_F77='-Bstatic' ;; *) lt_prog_compiler_can_build_shared_F77=no ;; esac fi { echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_F77" >&5 echo "${ECHO_T}$lt_prog_compiler_pic_F77" >&6; } # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic_F77"; then { echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works" >&5 echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works... $ECHO_C" >&6; } if test "${lt_prog_compiler_pic_works_F77+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_prog_compiler_pic_works_F77=no ac_outfile=conftest.$ac_objext printf "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic_F77" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:13119: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:13123: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_prog_compiler_pic_works_F77=yes fi fi $rm conftest* fi { echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_F77" >&5 echo "${ECHO_T}$lt_prog_compiler_pic_works_F77" >&6; } if test x"$lt_prog_compiler_pic_works_F77" = xyes; then case $lt_prog_compiler_pic_F77 in "" | " "*) ;; *) lt_prog_compiler_pic_F77=" $lt_prog_compiler_pic_F77" ;; esac else lt_prog_compiler_pic_F77= lt_prog_compiler_can_build_shared_F77=no fi fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic_F77= ;; *) lt_prog_compiler_pic_F77="$lt_prog_compiler_pic_F77" ;; esac # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl_F77 eval lt_tmp_static_flag=\"$lt_prog_compiler_static_F77\" { echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; } if test "${lt_prog_compiler_static_works_F77+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_prog_compiler_static_works_F77=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" printf "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_prog_compiler_static_works_F77=yes fi else lt_prog_compiler_static_works_F77=yes fi fi $rm conftest* LDFLAGS="$save_LDFLAGS" fi { echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_F77" >&5 echo "${ECHO_T}$lt_prog_compiler_static_works_F77" >&6; } if test x"$lt_prog_compiler_static_works_F77" = xyes; then : else lt_prog_compiler_static_F77= fi { echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; } if test "${lt_cv_prog_compiler_c_o_F77+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_cv_prog_compiler_c_o_F77=no $rm -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out printf "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:13223: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:13227: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_F77=yes fi fi chmod u+w . 2>&5 $rm conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files $rm out/* && rmdir out cd .. rmdir conftest $rm conftest* fi { echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_F77" >&5 echo "${ECHO_T}$lt_cv_prog_compiler_c_o_F77" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o_F77" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; } hard_links=yes $rm conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { echo "$as_me:$LINENO: result: $hard_links" >&5 echo "${ECHO_T}$hard_links" >&6; } if test "$hard_links" = no; then { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; } runpath_var= allow_undefined_flag_F77= enable_shared_with_static_runtimes_F77=no archive_cmds_F77= archive_expsym_cmds_F77= old_archive_From_new_cmds_F77= old_archive_from_expsyms_cmds_F77= export_dynamic_flag_spec_F77= whole_archive_flag_spec_F77= thread_safe_flag_spec_F77= hardcode_libdir_flag_spec_F77= hardcode_libdir_flag_spec_ld_F77= hardcode_libdir_separator_F77= hardcode_direct_F77=no hardcode_minus_L_F77=no hardcode_shlibpath_var_F77=unsupported link_all_deplibs_F77=unknown hardcode_automatic_F77=no module_cmds_F77= module_expsym_cmds_F77= always_export_symbols_F77=no export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms_F77= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. exclude_expsyms_F77="_GLOBAL_OFFSET_TABLE_" # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. extract_expsyms_cmds= # Just being paranoid about ensuring that cc_basename is set. for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` case $host_os in cygwin* | mingw* | pw32*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; esac ld_shlibs_F77=yes if test "$with_gnu_ld" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec_F77='${wl}--rpath ${wl}$libdir' export_dynamic_flag_spec_F77='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then whole_archive_flag_spec_F77="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec_F77= fi supports_anon_versioning=no case `$LD -v 2>/dev/null` in *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix3* | aix4* | aix5*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs_F77=no cat <&2 *** Warning: the GNU linker, at least up to release 2.9.1, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to modify your PATH *** so that a non-GNU linker is found, and then restart. EOF fi ;; amigaos*) archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec_F77='-L$libdir' hardcode_minus_L_F77=yes # Samuel A. Falvo II reports # that the semantics of dynamic libraries on AmigaOS, at least up # to version 4, is to share data among multiple programs linked # with the same dynamic library. Since this doesn't match the # behavior of shared libraries on other platforms, we can't use # them. ld_shlibs_F77=no ;; beos*) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then allow_undefined_flag_F77=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds_F77='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs_F77=no fi ;; cygwin* | mingw* | pw32*) # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, F77) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec_F77='-L$libdir' allow_undefined_flag_F77=unsupported always_export_symbols_F77=no enable_shared_with_static_runtimes_F77=yes export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds_F77='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs_F77=no fi ;; interix3*) hardcode_direct_F77=no hardcode_shlibpath_var_F77=no hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' export_dynamic_flag_spec_F77='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds_F77='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; linux* | k*bsd*-gnu) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then tmp_addflag= case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; esac archive_cmds_F77='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test $supports_anon_versioning = yes; then archive_expsym_cmds_F77='$echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ $echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi link_all_deplibs_F77=no else ld_shlibs_F77=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then archive_cmds_F77='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then ld_shlibs_F77=no cat <&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. EOF elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs_F77=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs_F77=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' else ld_shlibs_F77=no fi ;; esac ;; sunos4*) archive_cmds_F77='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct_F77=yes hardcode_shlibpath_var_F77=no ;; *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs_F77=no fi ;; esac if test "$ld_shlibs_F77" = no; then runpath_var= hardcode_libdir_flag_spec_F77= export_dynamic_flag_spec_F77= whole_archive_flag_spec_F77= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag_F77=unsupported always_export_symbols_F77=yes archive_expsym_cmds_F77='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L_F77=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct_F77=unsupported fi ;; aix4* | aix5*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm if $NM -V 2>&1 | grep 'GNU' > /dev/null; then export_symbols_cmds_F77='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds_F77='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix5*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds_F77='' hardcode_direct_F77=yes hardcode_libdir_separator_F77=':' link_all_deplibs_F77=yes if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && \ strings "$collect2name" | grep resolve_lib_name >/dev/null then # We have reworked collect2 hardcode_direct_F77=yes else # We have old collect2 hardcode_direct_F77=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L_F77=yes hardcode_libdir_flag_spec_F77='-L$libdir' hardcode_libdir_separator_F77= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols_F77=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag_F77='-berok' # Determine the default libpath from the value encoded in an empty executable. cat >conftest.$ac_ext <<_ACEOF program main end _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_f77_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'`; fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds_F77="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec_F77='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag_F77="-z nodefs" archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an empty executable. cat >conftest.$ac_ext <<_ACEOF program main end _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_f77_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'`; fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag_F77=' ${wl}-bernotok' allow_undefined_flag_F77=' ${wl}-berok' # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec_F77='$convenience' archive_cmds_need_lc_F77=yes # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec_F77='-L$libdir' hardcode_minus_L_F77=yes # see comment about different semantics on the GNU ld section ld_shlibs_F77=no ;; bsdi[45]*) export_dynamic_flag_spec_F77=-rdynamic ;; cygwin* | mingw* | pw32*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec_F77=' ' allow_undefined_flag_F77=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds_F77='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_From_new_cmds_F77='true' # FIXME: Should let the user specify the lib program. old_archive_cmds_F77='lib /OUT:$oldlib$oldobjs$old_deplibs' fix_srcfile_path_F77='`cygpath -w "$srcfile"`' enable_shared_with_static_runtimes_F77=yes ;; darwin* | rhapsody*) case $host_os in rhapsody* | darwin1.[012]) allow_undefined_flag_F77='${wl}-undefined ${wl}suppress' ;; *) # Darwin 1.3 on if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' else case ${MACOSX_DEPLOYMENT_TARGET} in 10.[012]) allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) allow_undefined_flag_F77='${wl}-undefined ${wl}dynamic_lookup' ;; esac fi ;; esac archive_cmds_need_lc_F77=no hardcode_direct_F77=no hardcode_automatic_F77=yes hardcode_shlibpath_var_F77=unsupported whole_archive_flag_spec_F77='' link_all_deplibs_F77=yes if test "$GCC" = yes ; then output_verbose_link_cmd='echo' archive_cmds_F77='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' else case $cc_basename in xlc*) output_verbose_link_cmd='echo' archive_cmds_F77='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ;; *) ld_shlibs_F77=no ;; esac fi ;; dgux*) archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec_F77='-L$libdir' hardcode_shlibpath_var_F77=no ;; freebsd1*) ld_shlibs_F77=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec_F77='-R$libdir' hardcode_direct_F77=yes hardcode_shlibpath_var_F77=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2*) archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct_F77=yes hardcode_minus_L_F77=yes hardcode_shlibpath_var_F77=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) archive_cmds_F77='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec_F77='-R$libdir' hardcode_direct_F77=yes hardcode_shlibpath_var_F77=no ;; hpux9*) if test "$GCC" = yes; then archive_cmds_F77='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else archive_cmds_F77='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' hardcode_libdir_separator_F77=: hardcode_direct_F77=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L_F77=yes export_dynamic_flag_spec_F77='${wl}-E' ;; hpux10*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds_F77='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' hardcode_libdir_separator_F77=: hardcode_direct_F77=yes export_dynamic_flag_spec_F77='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L_F77=yes fi ;; hpux11*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' hardcode_libdir_separator_F77=: case $host_cpu in hppa*64*|ia64*) hardcode_libdir_flag_spec_ld_F77='+b $libdir' hardcode_direct_F77=no hardcode_shlibpath_var_F77=no ;; *) hardcode_direct_F77=yes export_dynamic_flag_spec_F77='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L_F77=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else archive_cmds_F77='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec_ld_F77='-rpath $libdir' fi hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_F77=: link_all_deplibs_F77=yes ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds_F77='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec_F77='-R$libdir' hardcode_direct_F77=yes hardcode_shlibpath_var_F77=no ;; newsos6) archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct_F77=yes hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_F77=: hardcode_shlibpath_var_F77=no ;; openbsd*) hardcode_direct_F77=yes hardcode_shlibpath_var_F77=no if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' export_dynamic_flag_spec_F77='${wl}-E' else case $host_os in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec_F77='-R$libdir' ;; *) archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' ;; esac fi ;; os2*) hardcode_libdir_flag_spec_F77='-L$libdir' hardcode_minus_L_F77=yes allow_undefined_flag_F77=unsupported archive_cmds_F77='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' old_archive_From_new_cmds_F77='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*' archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else allow_undefined_flag_F77=' -expect_unresolved \*' archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' fi hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_F77=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*' archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' else allow_undefined_flag_F77=' -expect_unresolved \*' archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds_F77='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec_F77='-rpath $libdir' fi hardcode_libdir_separator_F77=: ;; solaris*) no_undefined_flag_F77=' -z text' if test "$GCC" = yes; then wlarc='${wl}' archive_cmds_F77='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' else wlarc='' archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' fi hardcode_libdir_flag_spec_F77='-R$libdir' hardcode_shlibpath_var_F77=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine linker options so we # cannot just pass the convience library names through # without $wl, iff we do not link with $LD. # Luckily, gcc supports the same syntax we need for Sun Studio. # Supported since Solaris 2.6 (maybe 2.5.1?) case $wlarc in '') whole_archive_flag_spec_F77='-z allextract$convenience -z defaultextract' ;; *) whole_archive_flag_spec_F77='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; esac ;; esac link_all_deplibs_F77=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds_F77='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds_F77='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec_F77='-L$libdir' hardcode_direct_F77=yes hardcode_minus_L_F77=yes hardcode_shlibpath_var_F77=no ;; sysv4) case $host_vendor in sni) archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct_F77=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds_F77='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds_F77='$CC -r -o $output$reload_objs' hardcode_direct_F77=no ;; motorola) archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct_F77=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var_F77=no ;; sysv4.3*) archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var_F77=no export_dynamic_flag_spec_F77='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var_F77=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs_F77=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*) no_undefined_flag_F77='${wl}-z,text' archive_cmds_need_lc_F77=no hardcode_shlibpath_var_F77=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds_F77='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds_F77='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag_F77='${wl}-z,text' allow_undefined_flag_F77='${wl}-z,nodefs' archive_cmds_need_lc_F77=no hardcode_shlibpath_var_F77=no hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' hardcode_libdir_separator_F77=':' link_all_deplibs_F77=yes export_dynamic_flag_spec_F77='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds_F77='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds_F77='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec_F77='-L$libdir' hardcode_shlibpath_var_F77=no ;; *) ld_shlibs_F77=no ;; esac fi { echo "$as_me:$LINENO: result: $ld_shlibs_F77" >&5 echo "${ECHO_T}$ld_shlibs_F77" >&6; } test "$ld_shlibs_F77" = no && can_build_shared=no # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc_F77" in x|xyes) # Assume -lc should be added archive_cmds_need_lc_F77=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds_F77 in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; } $rm conftest* printf "$lt_simple_compile_test_code" > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl_F77 pic_flag=$lt_prog_compiler_pic_F77 compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag_F77 allow_undefined_flag_F77= if { (eval echo "$as_me:$LINENO: \"$archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 (eval $archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } then archive_cmds_need_lc_F77=no else archive_cmds_need_lc_F77=yes fi allow_undefined_flag_F77=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $rm conftest* { echo "$as_me:$LINENO: result: $archive_cmds_need_lc_F77" >&5 echo "${ECHO_T}$archive_cmds_need_lc_F77" >&6; } ;; esac fi ;; esac { echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; } library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" if test "$GCC" = yes; then sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix4* | aix5*) version_type=linux need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$host_os in yes,cygwin* | yes,mingw* | yes,pw32*) library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $rm \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ;; mingw*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH printed by # mingw gcc, but we are running on Cygwin. Gcc prints its search # path with ; separators, and with drive letters. We can handle the # drive letters (cygwin fileutils understands them), so leave them, # especially as we might pass files found there to a mingw objdump, # which wouldn't understand a cygwinified path. Ahh. sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac ;; *) library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' ;; esac dynamic_linker='Win32 ld.exe' # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. if test "$GCC" = yes; then sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` else sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' fi sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd1*) dynamic_linker=no ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[123]*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; freebsd*) # from 4.6 on shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555. postinstall_cmds='chmod 555 $lib' ;; interix3*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be Linux ELF. linux* | k*bsd*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; nto-qnx*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; solaris*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no export_dynamic_flag_spec='${wl}-Blargedynsym' runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' shlibpath_overrides_runpath=no else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' shlibpath_overrides_runpath=yes case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { echo "$as_me:$LINENO: result: $dynamic_linker" >&5 echo "${ECHO_T}$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi { echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; } hardcode_action_F77= if test -n "$hardcode_libdir_flag_spec_F77" || \ test -n "$runpath_var_F77" || \ test "X$hardcode_automatic_F77" = "Xyes" ; then # We can hardcode non-existant directories. if test "$hardcode_direct_F77" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, F77)" != no && test "$hardcode_minus_L_F77" != no; then # Linking always hardcodes the temporary library directory. hardcode_action_F77=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action_F77=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action_F77=unsupported fi { echo "$as_me:$LINENO: result: $hardcode_action_F77" >&5 echo "${ECHO_T}$hardcode_action_F77" >&6; } if test "$hardcode_action_F77" = relink; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi # The else clause should only fire when bootstrapping the # libtool distribution, otherwise you forgot to ship ltmain.sh # with your package, and you will get complaints that there are # no rules to generate ltmain.sh. if test -f "$ltmain"; then # See if we are running on zsh, and set the options which allow our commands through # without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi # Now quote all the things that may contain metacharacters while being # careful not to overquote the AC_SUBSTed values. We take copies of the # variables and quote the copies for generation of the libtool script. for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ SED SHELL STRIP \ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ deplibs_check_method reload_flag reload_cmds need_locks \ lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_c_name_address \ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ old_postinstall_cmds old_postuninstall_cmds \ compiler_F77 \ CC_F77 \ LD_F77 \ lt_prog_compiler_wl_F77 \ lt_prog_compiler_pic_F77 \ lt_prog_compiler_static_F77 \ lt_prog_compiler_no_builtin_flag_F77 \ export_dynamic_flag_spec_F77 \ thread_safe_flag_spec_F77 \ whole_archive_flag_spec_F77 \ enable_shared_with_static_runtimes_F77 \ old_archive_cmds_F77 \ old_archive_from_new_cmds_F77 \ predep_objects_F77 \ postdep_objects_F77 \ predeps_F77 \ postdeps_F77 \ compiler_lib_search_path_F77 \ archive_cmds_F77 \ archive_expsym_cmds_F77 \ postinstall_cmds_F77 \ postuninstall_cmds_F77 \ old_archive_from_expsyms_cmds_F77 \ allow_undefined_flag_F77 \ no_undefined_flag_F77 \ export_symbols_cmds_F77 \ hardcode_libdir_flag_spec_F77 \ hardcode_libdir_flag_spec_ld_F77 \ hardcode_libdir_separator_F77 \ hardcode_automatic_F77 \ module_cmds_F77 \ module_expsym_cmds_F77 \ lt_cv_prog_compiler_c_o_F77 \ exclude_expsyms_F77 \ include_expsyms_F77; do case $var in old_archive_cmds_F77 | \ old_archive_from_new_cmds_F77 | \ archive_cmds_F77 | \ archive_expsym_cmds_F77 | \ module_cmds_F77 | \ module_expsym_cmds_F77 | \ old_archive_from_expsyms_cmds_F77 | \ export_symbols_cmds_F77 | \ extract_expsyms_cmds | reload_cmds | finish_cmds | \ postinstall_cmds | postuninstall_cmds | \ old_postinstall_cmds | old_postuninstall_cmds | \ sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) # Double-quote double-evaled strings. eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" ;; *) eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" ;; esac done case $lt_echo in *'\$0 --fallback-echo"') lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` ;; esac cfgfile="$ofile" cat <<__EOF__ >> "$cfgfile" # ### BEGIN LIBTOOL TAG CONFIG: $tagname # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc_F77 # Whether or not to disallow shared libs when runtime libs are static allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_F77 # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # An echo program that does not interpret backslashes. echo=$lt_echo # The archiver. AR=$lt_AR AR_FLAGS=$lt_AR_FLAGS # A C compiler. LTCC=$lt_LTCC # LTCC compiler flags. LTCFLAGS=$lt_LTCFLAGS # A language-specific compiler. CC=$lt_compiler_F77 # Is the compiler the GNU C compiler? with_gcc=$GCC_F77 # An ERE matcher. EGREP=$lt_EGREP # The linker used to build libraries. LD=$lt_LD_F77 # Whether we need hard or soft links. LN_S=$lt_LN_S # A BSD-compatible nm program. NM=$lt_NM # A symbol stripping program STRIP=$lt_STRIP # Used to examine libraries when file_magic_cmd begins "file" MAGIC_CMD=$MAGIC_CMD # Used on cygwin: DLL creation program. DLLTOOL="$DLLTOOL" # Used on cygwin: object dumper. OBJDUMP="$OBJDUMP" # Used on cygwin: assembler. AS="$AS" # The name of the directory that contains temporary libtool files. objdir=$objdir # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl_F77 # Object file suffix (normally "o"). objext="$ac_objext" # Old archive suffix (normally "a"). libext="$libext" # Shared library suffix (normally ".so"). shrext_cmds='$shrext_cmds' # Executable file suffix (normally ""). exeext="$exeext" # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic_F77 pic_mode=$pic_mode # What is the maximum length of a command? max_cmd_len=$lt_cv_sys_max_cmd_len # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o_F77 # Must we lock files when doing compilation? need_locks=$lt_need_locks # Do we need the lib prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static_F77 # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_F77 # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_F77 # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec_F77 # Compiler flag to generate thread-safe objects. thread_safe_flag_spec=$lt_thread_safe_flag_spec_F77 # Library versioning type. version_type=$version_type # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME. library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Commands used to build and install an old-style archive. RANLIB=$lt_RANLIB old_archive_cmds=$lt_old_archive_cmds_F77 old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_F77 # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_F77 # Commands used to build and install a shared archive. archive_cmds=$lt_archive_cmds_F77 archive_expsym_cmds=$lt_archive_expsym_cmds_F77 postinstall_cmds=$lt_postinstall_cmds postuninstall_cmds=$lt_postuninstall_cmds # Commands used to build a loadable module (assumed same as above if empty) module_cmds=$lt_module_cmds_F77 module_expsym_cmds=$lt_module_expsym_cmds_F77 # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # Dependencies to place before the objects being linked to create a # shared library. predep_objects=$lt_predep_objects_F77 # Dependencies to place after the objects being linked to create a # shared library. postdep_objects=$lt_postdep_objects_F77 # Dependencies to place before the objects being linked to create a # shared library. predeps=$lt_predeps_F77 # Dependencies to place after the objects being linked to create a # shared library. postdeps=$lt_postdeps_F77 # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path_F77 # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method == file_magic. file_magic_cmd=$lt_file_magic_cmd # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag_F77 # Flag that forces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag_F77 # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # Same as above, but a single script fragment to be evaled but not shown. finish_eval=$lt_finish_eval # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm in a C name address pair global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # This is the shared library runtime path variable. runpath_var=$runpath_var # This is the shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action_F77 # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist. hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_F77 # If ld is used when linking, flag to hardcode \$libdir into # a binary during linking. This must work even if \$libdir does # not exist. hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_F77 # Whether we need a single -rpath flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator_F77 # Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the # resulting binary. hardcode_direct=$hardcode_direct_F77 # Set to yes if using the -LDIR flag during linking hardcodes DIR into the # resulting binary. hardcode_minus_L=$hardcode_minus_L_F77 # Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into # the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var_F77 # Set to yes if building a shared library automatically hardcodes DIR into the library # and all subsequent libraries and executables linked against it. hardcode_automatic=$hardcode_automatic_F77 # Variables whose values should be saved in libtool wrapper scripts and # restored at relink time. variables_saved_for_relink="$variables_saved_for_relink" # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs_F77 # Compile-time system search path for libraries sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Run-time system search path for libraries sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Fix the shell variable \$srcfile for the compiler. fix_srcfile_path="$fix_srcfile_path_F77" # Set to yes if exported symbols are required. always_export_symbols=$always_export_symbols_F77 # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds_F77 # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms_F77 # Symbols that must always be exported. include_expsyms=$lt_include_expsyms_F77 # ### END LIBTOOL TAG CONFIG: $tagname __EOF__ else # If there is no Makefile yet, we rely on a make rule to execute # `config.status --recheck' to rerun these tests and create the # libtool script then. ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` if test -f "$ltmain_in"; then test -f Makefile && make "$ltmain" 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 CC="$lt_save_CC" else tagname="" fi ;; GCJ) if test -n "$GCJ" && test "X$GCJ" != "Xno"; then # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o objext_GCJ=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}\n" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[] argv) {}; }\n' # ltmain only uses $CC for tagged configurations so make sure $CC is set. # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext printf "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $rm conftest* ac_outfile=conftest.$ac_objext printf "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $rm conftest* # Allow CC to be a program name with arguments. lt_save_CC="$CC" CC=${GCJ-"gcj"} compiler=$CC compiler_GCJ=$CC for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` # GCJ did not exist at the time GCC didn't implicitly link libc in. archive_cmds_need_lc_GCJ=no old_archive_cmds_GCJ=$old_archive_cmds lt_prog_compiler_no_builtin_flag_GCJ= if test "$GCC" = yes; then lt_prog_compiler_no_builtin_flag_GCJ=' -fno-builtin' { echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6; } if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext printf "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:15410: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:15414: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $rm conftest* fi { echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then lt_prog_compiler_no_builtin_flag_GCJ="$lt_prog_compiler_no_builtin_flag_GCJ -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl_GCJ= lt_prog_compiler_pic_GCJ= lt_prog_compiler_static_GCJ= { echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } if test "$GCC" = yes; then lt_prog_compiler_wl_GCJ='-Wl,' lt_prog_compiler_static_GCJ='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_GCJ='-Bstatic' fi ;; amigaos*) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. lt_prog_compiler_pic_GCJ='-m68020 -resident32 -malways-restore-a4' ;; beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | pw32* | os2*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic_GCJ='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic_GCJ='-fno-common' ;; interix3*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared_GCJ=no enable_shared=no ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic_GCJ=-Kconform_pic fi ;; hpux*) # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic_GCJ='-fPIC' ;; esac ;; *) lt_prog_compiler_pic_GCJ='-fPIC' ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl_GCJ='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_GCJ='-Bstatic' else lt_prog_compiler_static_GCJ='-bnso -bI:/lib/syscalls.exp' fi ;; darwin*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files case $cc_basename in xlc*) lt_prog_compiler_pic_GCJ='-qnocommon' lt_prog_compiler_wl_GCJ='-Wl,' ;; esac ;; mingw* | pw32* | os2*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic_GCJ='-DDLL_EXPORT' ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl_GCJ='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic_GCJ='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static_GCJ='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl_GCJ='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static_GCJ='-non_shared' ;; newsos6) lt_prog_compiler_pic_GCJ='-KPIC' lt_prog_compiler_static_GCJ='-Bstatic' ;; linux* | k*bsd*-gnu) case $cc_basename in icc* | ecc*) lt_prog_compiler_wl_GCJ='-Wl,' lt_prog_compiler_pic_GCJ='-KPIC' lt_prog_compiler_static_GCJ='-static' ;; pgcc* | pgf77* | pgf90* | pgf95*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl_GCJ='-Wl,' lt_prog_compiler_pic_GCJ='-fpic' lt_prog_compiler_static_GCJ='-Bstatic' ;; ccc*) lt_prog_compiler_wl_GCJ='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static_GCJ='-non_shared' ;; esac ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl_GCJ='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static_GCJ='-non_shared' ;; solaris*) lt_prog_compiler_pic_GCJ='-KPIC' lt_prog_compiler_static_GCJ='-Bstatic' case $cc_basename in f77* | f90* | f95*) lt_prog_compiler_wl_GCJ='-Qoption ld ';; *) lt_prog_compiler_wl_GCJ='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl_GCJ='-Qoption ld ' lt_prog_compiler_pic_GCJ='-PIC' lt_prog_compiler_static_GCJ='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl_GCJ='-Wl,' lt_prog_compiler_pic_GCJ='-KPIC' lt_prog_compiler_static_GCJ='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then lt_prog_compiler_pic_GCJ='-Kconform_pic' lt_prog_compiler_static_GCJ='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl_GCJ='-Wl,' lt_prog_compiler_pic_GCJ='-KPIC' lt_prog_compiler_static_GCJ='-Bstatic' ;; unicos*) lt_prog_compiler_wl_GCJ='-Wl,' lt_prog_compiler_can_build_shared_GCJ=no ;; uts4*) lt_prog_compiler_pic_GCJ='-pic' lt_prog_compiler_static_GCJ='-Bstatic' ;; *) lt_prog_compiler_can_build_shared_GCJ=no ;; esac fi { echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_GCJ" >&5 echo "${ECHO_T}$lt_prog_compiler_pic_GCJ" >&6; } # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic_GCJ"; then { echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works" >&5 echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works... $ECHO_C" >&6; } if test "${lt_prog_compiler_pic_works_GCJ+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_prog_compiler_pic_works_GCJ=no ac_outfile=conftest.$ac_objext printf "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic_GCJ" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:15678: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:15682: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_prog_compiler_pic_works_GCJ=yes fi fi $rm conftest* fi { echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_GCJ" >&5 echo "${ECHO_T}$lt_prog_compiler_pic_works_GCJ" >&6; } if test x"$lt_prog_compiler_pic_works_GCJ" = xyes; then case $lt_prog_compiler_pic_GCJ in "" | " "*) ;; *) lt_prog_compiler_pic_GCJ=" $lt_prog_compiler_pic_GCJ" ;; esac else lt_prog_compiler_pic_GCJ= lt_prog_compiler_can_build_shared_GCJ=no fi fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic_GCJ= ;; *) lt_prog_compiler_pic_GCJ="$lt_prog_compiler_pic_GCJ" ;; esac # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl_GCJ eval lt_tmp_static_flag=\"$lt_prog_compiler_static_GCJ\" { echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; } if test "${lt_prog_compiler_static_works_GCJ+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_prog_compiler_static_works_GCJ=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" printf "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_prog_compiler_static_works_GCJ=yes fi else lt_prog_compiler_static_works_GCJ=yes fi fi $rm conftest* LDFLAGS="$save_LDFLAGS" fi { echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_GCJ" >&5 echo "${ECHO_T}$lt_prog_compiler_static_works_GCJ" >&6; } if test x"$lt_prog_compiler_static_works_GCJ" = xyes; then : else lt_prog_compiler_static_GCJ= fi { echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; } if test "${lt_cv_prog_compiler_c_o_GCJ+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_cv_prog_compiler_c_o_GCJ=no $rm -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out printf "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:15782: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:15786: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_GCJ=yes fi fi chmod u+w . 2>&5 $rm conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files $rm out/* && rmdir out cd .. rmdir conftest $rm conftest* fi { echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_GCJ" >&5 echo "${ECHO_T}$lt_cv_prog_compiler_c_o_GCJ" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o_GCJ" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; } hard_links=yes $rm conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { echo "$as_me:$LINENO: result: $hard_links" >&5 echo "${ECHO_T}$hard_links" >&6; } if test "$hard_links" = no; then { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; } runpath_var= allow_undefined_flag_GCJ= enable_shared_with_static_runtimes_GCJ=no archive_cmds_GCJ= archive_expsym_cmds_GCJ= old_archive_From_new_cmds_GCJ= old_archive_from_expsyms_cmds_GCJ= export_dynamic_flag_spec_GCJ= whole_archive_flag_spec_GCJ= thread_safe_flag_spec_GCJ= hardcode_libdir_flag_spec_GCJ= hardcode_libdir_flag_spec_ld_GCJ= hardcode_libdir_separator_GCJ= hardcode_direct_GCJ=no hardcode_minus_L_GCJ=no hardcode_shlibpath_var_GCJ=unsupported link_all_deplibs_GCJ=unknown hardcode_automatic_GCJ=no module_cmds_GCJ= module_expsym_cmds_GCJ= always_export_symbols_GCJ=no export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms_GCJ= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. exclude_expsyms_GCJ="_GLOBAL_OFFSET_TABLE_" # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. extract_expsyms_cmds= # Just being paranoid about ensuring that cc_basename is set. for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` case $host_os in cygwin* | mingw* | pw32*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; esac ld_shlibs_GCJ=yes if test "$with_gnu_ld" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec_GCJ='${wl}--rpath ${wl}$libdir' export_dynamic_flag_spec_GCJ='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then whole_archive_flag_spec_GCJ="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec_GCJ= fi supports_anon_versioning=no case `$LD -v 2>/dev/null` in *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix3* | aix4* | aix5*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs_GCJ=no cat <&2 *** Warning: the GNU linker, at least up to release 2.9.1, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to modify your PATH *** so that a non-GNU linker is found, and then restart. EOF fi ;; amigaos*) archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec_GCJ='-L$libdir' hardcode_minus_L_GCJ=yes # Samuel A. Falvo II reports # that the semantics of dynamic libraries on AmigaOS, at least up # to version 4, is to share data among multiple programs linked # with the same dynamic library. Since this doesn't match the # behavior of shared libraries on other platforms, we can't use # them. ld_shlibs_GCJ=no ;; beos*) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then allow_undefined_flag_GCJ=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds_GCJ='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs_GCJ=no fi ;; cygwin* | mingw* | pw32*) # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, GCJ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec_GCJ='-L$libdir' allow_undefined_flag_GCJ=unsupported always_export_symbols_GCJ=no enable_shared_with_static_runtimes_GCJ=yes export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds_GCJ='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs_GCJ=no fi ;; interix3*) hardcode_direct_GCJ=no hardcode_shlibpath_var_GCJ=no hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' export_dynamic_flag_spec_GCJ='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds_GCJ='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds_GCJ='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; linux* | k*bsd*-gnu) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then tmp_addflag= case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; esac archive_cmds_GCJ='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test $supports_anon_versioning = yes; then archive_expsym_cmds_GCJ='$echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ $echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi link_all_deplibs_GCJ=no else ld_shlibs_GCJ=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then archive_cmds_GCJ='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then ld_shlibs_GCJ=no cat <&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. EOF elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs_GCJ=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs_GCJ=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' else ld_shlibs_GCJ=no fi ;; esac ;; sunos4*) archive_cmds_GCJ='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct_GCJ=yes hardcode_shlibpath_var_GCJ=no ;; *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs_GCJ=no fi ;; esac if test "$ld_shlibs_GCJ" = no; then runpath_var= hardcode_libdir_flag_spec_GCJ= export_dynamic_flag_spec_GCJ= whole_archive_flag_spec_GCJ= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag_GCJ=unsupported always_export_symbols_GCJ=yes archive_expsym_cmds_GCJ='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L_GCJ=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct_GCJ=unsupported fi ;; aix4* | aix5*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm if $NM -V 2>&1 | grep 'GNU' > /dev/null; then export_symbols_cmds_GCJ='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds_GCJ='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix5*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds_GCJ='' hardcode_direct_GCJ=yes hardcode_libdir_separator_GCJ=':' link_all_deplibs_GCJ=yes if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && \ strings "$collect2name" | grep resolve_lib_name >/dev/null then # We have reworked collect2 hardcode_direct_GCJ=yes else # We have old collect2 hardcode_direct_GCJ=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L_GCJ=yes hardcode_libdir_flag_spec_GCJ='-L$libdir' hardcode_libdir_separator_GCJ= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols_GCJ=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag_GCJ='-berok' # Determine the default libpath from the value encoded in an empty executable. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'`; fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds_GCJ="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec_GCJ='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag_GCJ="-z nodefs" archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an empty executable. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'`; fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag_GCJ=' ${wl}-bernotok' allow_undefined_flag_GCJ=' ${wl}-berok' # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec_GCJ='$convenience' archive_cmds_need_lc_GCJ=yes # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec_GCJ='-L$libdir' hardcode_minus_L_GCJ=yes # see comment about different semantics on the GNU ld section ld_shlibs_GCJ=no ;; bsdi[45]*) export_dynamic_flag_spec_GCJ=-rdynamic ;; cygwin* | mingw* | pw32*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec_GCJ=' ' allow_undefined_flag_GCJ=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds_GCJ='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_From_new_cmds_GCJ='true' # FIXME: Should let the user specify the lib program. old_archive_cmds_GCJ='lib /OUT:$oldlib$oldobjs$old_deplibs' fix_srcfile_path_GCJ='`cygpath -w "$srcfile"`' enable_shared_with_static_runtimes_GCJ=yes ;; darwin* | rhapsody*) case $host_os in rhapsody* | darwin1.[012]) allow_undefined_flag_GCJ='${wl}-undefined ${wl}suppress' ;; *) # Darwin 1.3 on if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' else case ${MACOSX_DEPLOYMENT_TARGET} in 10.[012]) allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) allow_undefined_flag_GCJ='${wl}-undefined ${wl}dynamic_lookup' ;; esac fi ;; esac archive_cmds_need_lc_GCJ=no hardcode_direct_GCJ=no hardcode_automatic_GCJ=yes hardcode_shlibpath_var_GCJ=unsupported whole_archive_flag_spec_GCJ='' link_all_deplibs_GCJ=yes if test "$GCC" = yes ; then output_verbose_link_cmd='echo' archive_cmds_GCJ='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' else case $cc_basename in xlc*) output_verbose_link_cmd='echo' archive_cmds_GCJ='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ;; *) ld_shlibs_GCJ=no ;; esac fi ;; dgux*) archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec_GCJ='-L$libdir' hardcode_shlibpath_var_GCJ=no ;; freebsd1*) ld_shlibs_GCJ=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec_GCJ='-R$libdir' hardcode_direct_GCJ=yes hardcode_shlibpath_var_GCJ=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2*) archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct_GCJ=yes hardcode_minus_L_GCJ=yes hardcode_shlibpath_var_GCJ=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) archive_cmds_GCJ='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec_GCJ='-R$libdir' hardcode_direct_GCJ=yes hardcode_shlibpath_var_GCJ=no ;; hpux9*) if test "$GCC" = yes; then archive_cmds_GCJ='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else archive_cmds_GCJ='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' hardcode_libdir_separator_GCJ=: hardcode_direct_GCJ=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L_GCJ=yes export_dynamic_flag_spec_GCJ='${wl}-E' ;; hpux10*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds_GCJ='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' hardcode_libdir_separator_GCJ=: hardcode_direct_GCJ=yes export_dynamic_flag_spec_GCJ='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L_GCJ=yes fi ;; hpux11*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' hardcode_libdir_separator_GCJ=: case $host_cpu in hppa*64*|ia64*) hardcode_libdir_flag_spec_ld_GCJ='+b $libdir' hardcode_direct_GCJ=no hardcode_shlibpath_var_GCJ=no ;; *) hardcode_direct_GCJ=yes export_dynamic_flag_spec_GCJ='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L_GCJ=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else archive_cmds_GCJ='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec_ld_GCJ='-rpath $libdir' fi hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_GCJ=: link_all_deplibs_GCJ=yes ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds_GCJ='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec_GCJ='-R$libdir' hardcode_direct_GCJ=yes hardcode_shlibpath_var_GCJ=no ;; newsos6) archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct_GCJ=yes hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_GCJ=: hardcode_shlibpath_var_GCJ=no ;; openbsd*) hardcode_direct_GCJ=yes hardcode_shlibpath_var_GCJ=no if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' export_dynamic_flag_spec_GCJ='${wl}-E' else case $host_os in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec_GCJ='-R$libdir' ;; *) archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' ;; esac fi ;; os2*) hardcode_libdir_flag_spec_GCJ='-L$libdir' hardcode_minus_L_GCJ=yes allow_undefined_flag_GCJ=unsupported archive_cmds_GCJ='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' old_archive_From_new_cmds_GCJ='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*' archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else allow_undefined_flag_GCJ=' -expect_unresolved \*' archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' fi hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_GCJ=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*' archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' else allow_undefined_flag_GCJ=' -expect_unresolved \*' archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds_GCJ='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec_GCJ='-rpath $libdir' fi hardcode_libdir_separator_GCJ=: ;; solaris*) no_undefined_flag_GCJ=' -z text' if test "$GCC" = yes; then wlarc='${wl}' archive_cmds_GCJ='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' else wlarc='' archive_cmds_GCJ='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' fi hardcode_libdir_flag_spec_GCJ='-R$libdir' hardcode_shlibpath_var_GCJ=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine linker options so we # cannot just pass the convience library names through # without $wl, iff we do not link with $LD. # Luckily, gcc supports the same syntax we need for Sun Studio. # Supported since Solaris 2.6 (maybe 2.5.1?) case $wlarc in '') whole_archive_flag_spec_GCJ='-z allextract$convenience -z defaultextract' ;; *) whole_archive_flag_spec_GCJ='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; esac ;; esac link_all_deplibs_GCJ=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds_GCJ='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds_GCJ='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec_GCJ='-L$libdir' hardcode_direct_GCJ=yes hardcode_minus_L_GCJ=yes hardcode_shlibpath_var_GCJ=no ;; sysv4) case $host_vendor in sni) archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct_GCJ=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds_GCJ='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds_GCJ='$CC -r -o $output$reload_objs' hardcode_direct_GCJ=no ;; motorola) archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct_GCJ=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var_GCJ=no ;; sysv4.3*) archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var_GCJ=no export_dynamic_flag_spec_GCJ='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var_GCJ=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs_GCJ=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*) no_undefined_flag_GCJ='${wl}-z,text' archive_cmds_need_lc_GCJ=no hardcode_shlibpath_var_GCJ=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds_GCJ='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds_GCJ='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag_GCJ='${wl}-z,text' allow_undefined_flag_GCJ='${wl}-z,nodefs' archive_cmds_need_lc_GCJ=no hardcode_shlibpath_var_GCJ=no hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' hardcode_libdir_separator_GCJ=':' link_all_deplibs_GCJ=yes export_dynamic_flag_spec_GCJ='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds_GCJ='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds_GCJ='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec_GCJ='-L$libdir' hardcode_shlibpath_var_GCJ=no ;; *) ld_shlibs_GCJ=no ;; esac fi { echo "$as_me:$LINENO: result: $ld_shlibs_GCJ" >&5 echo "${ECHO_T}$ld_shlibs_GCJ" >&6; } test "$ld_shlibs_GCJ" = no && can_build_shared=no # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc_GCJ" in x|xyes) # Assume -lc should be added archive_cmds_need_lc_GCJ=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds_GCJ in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; } $rm conftest* printf "$lt_simple_compile_test_code" > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl_GCJ pic_flag=$lt_prog_compiler_pic_GCJ compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag_GCJ allow_undefined_flag_GCJ= if { (eval echo "$as_me:$LINENO: \"$archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 (eval $archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } then archive_cmds_need_lc_GCJ=no else archive_cmds_need_lc_GCJ=yes fi allow_undefined_flag_GCJ=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $rm conftest* { echo "$as_me:$LINENO: result: $archive_cmds_need_lc_GCJ" >&5 echo "${ECHO_T}$archive_cmds_need_lc_GCJ" >&6; } ;; esac fi ;; esac { echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; } library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" if test "$GCC" = yes; then sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix4* | aix5*) version_type=linux need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$host_os in yes,cygwin* | yes,mingw* | yes,pw32*) library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $rm \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ;; mingw*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH printed by # mingw gcc, but we are running on Cygwin. Gcc prints its search # path with ; separators, and with drive letters. We can handle the # drive letters (cygwin fileutils understands them), so leave them, # especially as we might pass files found there to a mingw objdump, # which wouldn't understand a cygwinified path. Ahh. sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac ;; *) library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' ;; esac dynamic_linker='Win32 ld.exe' # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. if test "$GCC" = yes; then sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` else sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' fi sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd1*) dynamic_linker=no ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[123]*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; freebsd*) # from 4.6 on shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555. postinstall_cmds='chmod 555 $lib' ;; interix3*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be Linux ELF. linux* | k*bsd*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; nto-qnx*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; solaris*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no export_dynamic_flag_spec='${wl}-Blargedynsym' runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' shlibpath_overrides_runpath=no else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' shlibpath_overrides_runpath=yes case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { echo "$as_me:$LINENO: result: $dynamic_linker" >&5 echo "${ECHO_T}$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi { echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; } hardcode_action_GCJ= if test -n "$hardcode_libdir_flag_spec_GCJ" || \ test -n "$runpath_var_GCJ" || \ test "X$hardcode_automatic_GCJ" = "Xyes" ; then # We can hardcode non-existant directories. if test "$hardcode_direct_GCJ" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, GCJ)" != no && test "$hardcode_minus_L_GCJ" != no; then # Linking always hardcodes the temporary library directory. hardcode_action_GCJ=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action_GCJ=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action_GCJ=unsupported fi { echo "$as_me:$LINENO: result: $hardcode_action_GCJ" >&5 echo "${ECHO_T}$hardcode_action_GCJ" >&6; } if test "$hardcode_action_GCJ" = relink; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi # The else clause should only fire when bootstrapping the # libtool distribution, otherwise you forgot to ship ltmain.sh # with your package, and you will get complaints that there are # no rules to generate ltmain.sh. if test -f "$ltmain"; then # See if we are running on zsh, and set the options which allow our commands through # without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi # Now quote all the things that may contain metacharacters while being # careful not to overquote the AC_SUBSTed values. We take copies of the # variables and quote the copies for generation of the libtool script. for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ SED SHELL STRIP \ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ deplibs_check_method reload_flag reload_cmds need_locks \ lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_c_name_address \ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ old_postinstall_cmds old_postuninstall_cmds \ compiler_GCJ \ CC_GCJ \ LD_GCJ \ lt_prog_compiler_wl_GCJ \ lt_prog_compiler_pic_GCJ \ lt_prog_compiler_static_GCJ \ lt_prog_compiler_no_builtin_flag_GCJ \ export_dynamic_flag_spec_GCJ \ thread_safe_flag_spec_GCJ \ whole_archive_flag_spec_GCJ \ enable_shared_with_static_runtimes_GCJ \ old_archive_cmds_GCJ \ old_archive_from_new_cmds_GCJ \ predep_objects_GCJ \ postdep_objects_GCJ \ predeps_GCJ \ postdeps_GCJ \ compiler_lib_search_path_GCJ \ archive_cmds_GCJ \ archive_expsym_cmds_GCJ \ postinstall_cmds_GCJ \ postuninstall_cmds_GCJ \ old_archive_from_expsyms_cmds_GCJ \ allow_undefined_flag_GCJ \ no_undefined_flag_GCJ \ export_symbols_cmds_GCJ \ hardcode_libdir_flag_spec_GCJ \ hardcode_libdir_flag_spec_ld_GCJ \ hardcode_libdir_separator_GCJ \ hardcode_automatic_GCJ \ module_cmds_GCJ \ module_expsym_cmds_GCJ \ lt_cv_prog_compiler_c_o_GCJ \ exclude_expsyms_GCJ \ include_expsyms_GCJ; do case $var in old_archive_cmds_GCJ | \ old_archive_from_new_cmds_GCJ | \ archive_cmds_GCJ | \ archive_expsym_cmds_GCJ | \ module_cmds_GCJ | \ module_expsym_cmds_GCJ | \ old_archive_from_expsyms_cmds_GCJ | \ export_symbols_cmds_GCJ | \ extract_expsyms_cmds | reload_cmds | finish_cmds | \ postinstall_cmds | postuninstall_cmds | \ old_postinstall_cmds | old_postuninstall_cmds | \ sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) # Double-quote double-evaled strings. eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" ;; *) eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" ;; esac done case $lt_echo in *'\$0 --fallback-echo"') lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` ;; esac cfgfile="$ofile" cat <<__EOF__ >> "$cfgfile" # ### BEGIN LIBTOOL TAG CONFIG: $tagname # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc_GCJ # Whether or not to disallow shared libs when runtime libs are static allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_GCJ # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # An echo program that does not interpret backslashes. echo=$lt_echo # The archiver. AR=$lt_AR AR_FLAGS=$lt_AR_FLAGS # A C compiler. LTCC=$lt_LTCC # LTCC compiler flags. LTCFLAGS=$lt_LTCFLAGS # A language-specific compiler. CC=$lt_compiler_GCJ # Is the compiler the GNU C compiler? with_gcc=$GCC_GCJ # An ERE matcher. EGREP=$lt_EGREP # The linker used to build libraries. LD=$lt_LD_GCJ # Whether we need hard or soft links. LN_S=$lt_LN_S # A BSD-compatible nm program. NM=$lt_NM # A symbol stripping program STRIP=$lt_STRIP # Used to examine libraries when file_magic_cmd begins "file" MAGIC_CMD=$MAGIC_CMD # Used on cygwin: DLL creation program. DLLTOOL="$DLLTOOL" # Used on cygwin: object dumper. OBJDUMP="$OBJDUMP" # Used on cygwin: assembler. AS="$AS" # The name of the directory that contains temporary libtool files. objdir=$objdir # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl_GCJ # Object file suffix (normally "o"). objext="$ac_objext" # Old archive suffix (normally "a"). libext="$libext" # Shared library suffix (normally ".so"). shrext_cmds='$shrext_cmds' # Executable file suffix (normally ""). exeext="$exeext" # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic_GCJ pic_mode=$pic_mode # What is the maximum length of a command? max_cmd_len=$lt_cv_sys_max_cmd_len # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o_GCJ # Must we lock files when doing compilation? need_locks=$lt_need_locks # Do we need the lib prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static_GCJ # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_GCJ # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_GCJ # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec_GCJ # Compiler flag to generate thread-safe objects. thread_safe_flag_spec=$lt_thread_safe_flag_spec_GCJ # Library versioning type. version_type=$version_type # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME. library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Commands used to build and install an old-style archive. RANLIB=$lt_RANLIB old_archive_cmds=$lt_old_archive_cmds_GCJ old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_GCJ # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_GCJ # Commands used to build and install a shared archive. archive_cmds=$lt_archive_cmds_GCJ archive_expsym_cmds=$lt_archive_expsym_cmds_GCJ postinstall_cmds=$lt_postinstall_cmds postuninstall_cmds=$lt_postuninstall_cmds # Commands used to build a loadable module (assumed same as above if empty) module_cmds=$lt_module_cmds_GCJ module_expsym_cmds=$lt_module_expsym_cmds_GCJ # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # Dependencies to place before the objects being linked to create a # shared library. predep_objects=$lt_predep_objects_GCJ # Dependencies to place after the objects being linked to create a # shared library. postdep_objects=$lt_postdep_objects_GCJ # Dependencies to place before the objects being linked to create a # shared library. predeps=$lt_predeps_GCJ # Dependencies to place after the objects being linked to create a # shared library. postdeps=$lt_postdeps_GCJ # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path_GCJ # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method == file_magic. file_magic_cmd=$lt_file_magic_cmd # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag_GCJ # Flag that forces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag_GCJ # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # Same as above, but a single script fragment to be evaled but not shown. finish_eval=$lt_finish_eval # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm in a C name address pair global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # This is the shared library runtime path variable. runpath_var=$runpath_var # This is the shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action_GCJ # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist. hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_GCJ # If ld is used when linking, flag to hardcode \$libdir into # a binary during linking. This must work even if \$libdir does # not exist. hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_GCJ # Whether we need a single -rpath flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator_GCJ # Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the # resulting binary. hardcode_direct=$hardcode_direct_GCJ # Set to yes if using the -LDIR flag during linking hardcodes DIR into the # resulting binary. hardcode_minus_L=$hardcode_minus_L_GCJ # Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into # the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var_GCJ # Set to yes if building a shared library automatically hardcodes DIR into the library # and all subsequent libraries and executables linked against it. hardcode_automatic=$hardcode_automatic_GCJ # Variables whose values should be saved in libtool wrapper scripts and # restored at relink time. variables_saved_for_relink="$variables_saved_for_relink" # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs_GCJ # Compile-time system search path for libraries sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Run-time system search path for libraries sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Fix the shell variable \$srcfile for the compiler. fix_srcfile_path="$fix_srcfile_path_GCJ" # Set to yes if exported symbols are required. always_export_symbols=$always_export_symbols_GCJ # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds_GCJ # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms_GCJ # Symbols that must always be exported. include_expsyms=$lt_include_expsyms_GCJ # ### END LIBTOOL TAG CONFIG: $tagname __EOF__ else # If there is no Makefile yet, we rely on a make rule to execute # `config.status --recheck' to rerun these tests and create the # libtool script then. ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` if test -f "$ltmain_in"; then test -f Makefile && make "$ltmain" 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 CC="$lt_save_CC" else tagname="" fi ;; RC) # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o objext_RC=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n' # Code to be used in simple link tests lt_simple_link_test_code="$lt_simple_compile_test_code" # ltmain only uses $CC for tagged configurations so make sure $CC is set. # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext printf "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $rm conftest* ac_outfile=conftest.$ac_objext printf "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $rm conftest* # Allow CC to be a program name with arguments. lt_save_CC="$CC" CC=${RC-"windres"} compiler=$CC compiler_RC=$CC for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` lt_cv_prog_compiler_c_o_RC=yes # The else clause should only fire when bootstrapping the # libtool distribution, otherwise you forgot to ship ltmain.sh # with your package, and you will get complaints that there are # no rules to generate ltmain.sh. if test -f "$ltmain"; then # See if we are running on zsh, and set the options which allow our commands through # without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi # Now quote all the things that may contain metacharacters while being # careful not to overquote the AC_SUBSTed values. We take copies of the # variables and quote the copies for generation of the libtool script. for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ SED SHELL STRIP \ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ deplibs_check_method reload_flag reload_cmds need_locks \ lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_c_name_address \ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ old_postinstall_cmds old_postuninstall_cmds \ compiler_RC \ CC_RC \ LD_RC \ lt_prog_compiler_wl_RC \ lt_prog_compiler_pic_RC \ lt_prog_compiler_static_RC \ lt_prog_compiler_no_builtin_flag_RC \ export_dynamic_flag_spec_RC \ thread_safe_flag_spec_RC \ whole_archive_flag_spec_RC \ enable_shared_with_static_runtimes_RC \ old_archive_cmds_RC \ old_archive_from_new_cmds_RC \ predep_objects_RC \ postdep_objects_RC \ predeps_RC \ postdeps_RC \ compiler_lib_search_path_RC \ archive_cmds_RC \ archive_expsym_cmds_RC \ postinstall_cmds_RC \ postuninstall_cmds_RC \ old_archive_from_expsyms_cmds_RC \ allow_undefined_flag_RC \ no_undefined_flag_RC \ export_symbols_cmds_RC \ hardcode_libdir_flag_spec_RC \ hardcode_libdir_flag_spec_ld_RC \ hardcode_libdir_separator_RC \ hardcode_automatic_RC \ module_cmds_RC \ module_expsym_cmds_RC \ lt_cv_prog_compiler_c_o_RC \ exclude_expsyms_RC \ include_expsyms_RC; do case $var in old_archive_cmds_RC | \ old_archive_from_new_cmds_RC | \ archive_cmds_RC | \ archive_expsym_cmds_RC | \ module_cmds_RC | \ module_expsym_cmds_RC | \ old_archive_from_expsyms_cmds_RC | \ export_symbols_cmds_RC | \ extract_expsyms_cmds | reload_cmds | finish_cmds | \ postinstall_cmds | postuninstall_cmds | \ old_postinstall_cmds | old_postuninstall_cmds | \ sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) # Double-quote double-evaled strings. eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" ;; *) eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" ;; esac done case $lt_echo in *'\$0 --fallback-echo"') lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` ;; esac cfgfile="$ofile" cat <<__EOF__ >> "$cfgfile" # ### BEGIN LIBTOOL TAG CONFIG: $tagname # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc_RC # Whether or not to disallow shared libs when runtime libs are static allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_RC # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # An echo program that does not interpret backslashes. echo=$lt_echo # The archiver. AR=$lt_AR AR_FLAGS=$lt_AR_FLAGS # A C compiler. LTCC=$lt_LTCC # LTCC compiler flags. LTCFLAGS=$lt_LTCFLAGS # A language-specific compiler. CC=$lt_compiler_RC # Is the compiler the GNU C compiler? with_gcc=$GCC_RC # An ERE matcher. EGREP=$lt_EGREP # The linker used to build libraries. LD=$lt_LD_RC # Whether we need hard or soft links. LN_S=$lt_LN_S # A BSD-compatible nm program. NM=$lt_NM # A symbol stripping program STRIP=$lt_STRIP # Used to examine libraries when file_magic_cmd begins "file" MAGIC_CMD=$MAGIC_CMD # Used on cygwin: DLL creation program. DLLTOOL="$DLLTOOL" # Used on cygwin: object dumper. OBJDUMP="$OBJDUMP" # Used on cygwin: assembler. AS="$AS" # The name of the directory that contains temporary libtool files. objdir=$objdir # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl_RC # Object file suffix (normally "o"). objext="$ac_objext" # Old archive suffix (normally "a"). libext="$libext" # Shared library suffix (normally ".so"). shrext_cmds='$shrext_cmds' # Executable file suffix (normally ""). exeext="$exeext" # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic_RC pic_mode=$pic_mode # What is the maximum length of a command? max_cmd_len=$lt_cv_sys_max_cmd_len # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o_RC # Must we lock files when doing compilation? need_locks=$lt_need_locks # Do we need the lib prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static_RC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_RC # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_RC # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec_RC # Compiler flag to generate thread-safe objects. thread_safe_flag_spec=$lt_thread_safe_flag_spec_RC # Library versioning type. version_type=$version_type # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME. library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Commands used to build and install an old-style archive. RANLIB=$lt_RANLIB old_archive_cmds=$lt_old_archive_cmds_RC old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_RC # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_RC # Commands used to build and install a shared archive. archive_cmds=$lt_archive_cmds_RC archive_expsym_cmds=$lt_archive_expsym_cmds_RC postinstall_cmds=$lt_postinstall_cmds postuninstall_cmds=$lt_postuninstall_cmds # Commands used to build a loadable module (assumed same as above if empty) module_cmds=$lt_module_cmds_RC module_expsym_cmds=$lt_module_expsym_cmds_RC # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # Dependencies to place before the objects being linked to create a # shared library. predep_objects=$lt_predep_objects_RC # Dependencies to place after the objects being linked to create a # shared library. postdep_objects=$lt_postdep_objects_RC # Dependencies to place before the objects being linked to create a # shared library. predeps=$lt_predeps_RC # Dependencies to place after the objects being linked to create a # shared library. postdeps=$lt_postdeps_RC # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path_RC # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method == file_magic. file_magic_cmd=$lt_file_magic_cmd # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag_RC # Flag that forces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag_RC # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # Same as above, but a single script fragment to be evaled but not shown. finish_eval=$lt_finish_eval # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm in a C name address pair global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # This is the shared library runtime path variable. runpath_var=$runpath_var # This is the shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action_RC # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist. hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_RC # If ld is used when linking, flag to hardcode \$libdir into # a binary during linking. This must work even if \$libdir does # not exist. hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_RC # Whether we need a single -rpath flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator_RC # Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the # resulting binary. hardcode_direct=$hardcode_direct_RC # Set to yes if using the -LDIR flag during linking hardcodes DIR into the # resulting binary. hardcode_minus_L=$hardcode_minus_L_RC # Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into # the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var_RC # Set to yes if building a shared library automatically hardcodes DIR into the library # and all subsequent libraries and executables linked against it. hardcode_automatic=$hardcode_automatic_RC # Variables whose values should be saved in libtool wrapper scripts and # restored at relink time. variables_saved_for_relink="$variables_saved_for_relink" # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs_RC # Compile-time system search path for libraries sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Run-time system search path for libraries sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Fix the shell variable \$srcfile for the compiler. fix_srcfile_path="$fix_srcfile_path_RC" # Set to yes if exported symbols are required. always_export_symbols=$always_export_symbols_RC # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds_RC # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms_RC # Symbols that must always be exported. include_expsyms=$lt_include_expsyms_RC # ### END LIBTOOL TAG CONFIG: $tagname __EOF__ else # If there is no Makefile yet, we rely on a make rule to execute # `config.status --recheck' to rerun these tests and create the # libtool script then. ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` if test -f "$ltmain_in"; then test -f Makefile && make "$ltmain" 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 CC="$lt_save_CC" ;; *) { { echo "$as_me:$LINENO: error: Unsupported tag name: $tagname" >&5 echo "$as_me: error: Unsupported tag name: $tagname" >&2;} { (exit 1); exit 1; }; } ;; esac # Append the new tag name to the list of available tags. if test -n "$tagname" ; then available_tags="$available_tags $tagname" fi fi done IFS="$lt_save_ifs" # Now substitute the updated list of available tags. if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then mv "${ofile}T" "$ofile" chmod +x "$ofile" else rm -f "${ofile}T" { { echo "$as_me:$LINENO: error: unable to update list of available tagged configurations." >&5 echo "$as_me: error: unable to update list of available tagged configurations." >&2;} { (exit 1); exit 1; }; } fi fi # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' # Prevent multiple expansion { echo "$as_me:$LINENO: checking for Win32" >&5 echo $ECHO_N "checking for Win32... $ECHO_C" >&6; } case "$host" in *-*-mingw*) SYS_CFLAGS="-DWIN32 -mms-bitfields" use_win32=yes ;; *) SYS_CFLAGS="-DPOSIX" use_win32=no esac { echo "$as_me:$LINENO: result: $use_win32" >&5 echo "${ECHO_T}$use_win32" >&6; } # Check whether --with-readline was given. if test "${with_readline+set}" = set; then withval=$with_readline; use_readline=$withval else use_readline=yes fi if test $use_readline = yes then { echo "$as_me:$LINENO: checking for readline in -lreadline" >&5 echo $ECHO_N "checking for readline in -lreadline... $ECHO_C" >&6; } if test "${ac_cv_lib_readline_readline+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lreadline -lcurses $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 readline (); int main () { return readline (); ; return 0; } _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_readline_readline=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_readline_readline=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_readline_readline" >&5 echo "${ECHO_T}$ac_cv_lib_readline_readline" >&6; } if test $ac_cv_lib_readline_readline = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBREADLINE 1 _ACEOF LIBS="-lreadline $LIBS" else use_readline=no fi if test "${ac_cv_header_readline_readline_h+set}" = set; then { echo "$as_me:$LINENO: checking for readline/readline.h" >&5 echo $ECHO_N "checking for readline/readline.h... $ECHO_C" >&6; } if test "${ac_cv_header_readline_readline_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_readline_readline_h" >&5 echo "${ECHO_T}$ac_cv_header_readline_readline_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking readline/readline.h usability" >&5 echo $ECHO_N "checking readline/readline.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking readline/readline.h presence" >&5 echo $ECHO_N "checking readline/readline.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: readline/readline.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: readline/readline.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: readline/readline.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: readline/readline.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: readline/readline.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: readline/readline.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: readline/readline.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: readline/readline.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: readline/readline.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: readline/readline.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: readline/readline.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: readline/readline.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: readline/readline.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: readline/readline.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: readline/readline.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: readline/readline.h: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for readline/readline.h" >&5 echo $ECHO_N "checking for readline/readline.h... $ECHO_C" >&6; } if test "${ac_cv_header_readline_readline_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_readline_readline_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_readline_readline_h" >&5 echo "${ECHO_T}$ac_cv_header_readline_readline_h" >&6; } fi if test $ac_cv_header_readline_readline_h = yes; then : else use_readline=no fi fi if test $use_readline = yes then READLINE_LIBS="-lreadline -lcurses" READLINE_CFLAGS="-DREADLINE" else READLINE_LIBS="" READLINE_CFLAGS="" fi # Check whether --enable-malshow was given. if test "${enable_malshow+set}" = set; then enableval=$enable_malshow; use_malshow=$enableval else use_malshow=yes fi if test $use_malshow = yes then { echo "$as_me:$LINENO: checking for GTK+ 2.8 or later" >&5 echo $ECHO_N "checking for GTK+ 2.8 or later... $ECHO_C" >&6; } if ! $SHELL -c 'pkg-config --atleast-version=2.8 gtk+-2.0' >/dev/null 2>/dev/null then use_malshow=no fi { echo "$as_me:$LINENO: result: $use_malshow" >&5 echo "${ECHO_T}$use_malshow" >&6; } if test $use_malshow = no then echo 1>&2 "*** No GTK+, version 2.8 or later, found. Disabling malshow." echo 1>&2 "*** You may get GTK+ from ." fi fi if test $use_malshow = yes then GTK_LIBS=`pkg-config gtk+-2.0 --libs` GTK_CFLAGS=`pkg-config gtk+-2.0 --cflags` MALSHOW="malshow" else GTK_LIBS="" GTK_CFLAGS="" MALSHOW="" fi { echo "$as_me:$LINENO: checking for GLib" >&5 echo $ECHO_N "checking for GLib... $ECHO_C" >&6; } if $SHELL -c 'pkg-config glib-2.0' >/dev/null 2>/dev/null then have_glib=yes else have_glib=no fi { echo "$as_me:$LINENO: result: $have_glib" >&5 echo "${ECHO_T}$have_glib" >&6; } if test $have_glib = yes then GLIB_LIBS=`pkg-config glib-2.0 --libs` GLIB_CFLAGS=`pkg-config glib-2.0 --cflags` else echo 1>&2 "*** No GLib, version 2.0 or later, found. Please install it." echo 1>&2 "*** You may get GLib from ." exit 1 fi ac_config_files="$ac_config_files 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_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( *) $as_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 test "x$cache_file" != "x/dev/null" && { echo "$as_me:$LINENO: updating cache $cache_file" >&5 echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 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}' # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. ac_script=' t clear :clear s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g t quote s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g t quote b any :quote s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g s/\[/\\&/g s/\]/\\&/g s/\$/$$/g H :any ${ g s/^\n// s/\n/ /g p } ' DEFS=`sed -n "$ac_script" confdefs.h` ac_libobjs= ac_ltlibobjs= 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=`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. ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $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} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ## --------------------- ## ## 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=: # Zsh 3.x and 4.x performs 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 # PATH needs CR # 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 # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false 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.) as_nl=' ' IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. 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 echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. 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 # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. 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" || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # 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 } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi 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 fi echo >conf$$.file 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 -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' 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=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # 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 # 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 $as_me, which was generated by GNU Autoconf 2.61. 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 cat >>$CONFIG_STATUS <<_ACEOF # Files that config.status was made for. config_files="$ac_config_files" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit -q, --quiet 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 Configuration files: $config_files Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.61, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2006 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' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. 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=$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 ) echo "$ac_cs_version"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift CONFIG_FILES="$CONFIG_FILES $ac_optarg" ac_need_defaults=false;; --he | --h | --help | --hel | -h ) 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. -*) { echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *) ac_config_targets="$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 if \$ac_cs_recheck; then echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 CONFIG_SHELL=$SHELL export CONFIG_SHELL exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; 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 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= trap 'exit_status=$? { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } # # Set up the sed scripts for CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h if test -n "$CONFIG_FILES"; then _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF SHELL!$SHELL$ac_delim PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim PACKAGE_NAME!$PACKAGE_NAME$ac_delim PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim PACKAGE_STRING!$PACKAGE_STRING$ac_delim PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim exec_prefix!$exec_prefix$ac_delim prefix!$prefix$ac_delim program_transform_name!$program_transform_name$ac_delim bindir!$bindir$ac_delim sbindir!$sbindir$ac_delim libexecdir!$libexecdir$ac_delim datarootdir!$datarootdir$ac_delim datadir!$datadir$ac_delim sysconfdir!$sysconfdir$ac_delim sharedstatedir!$sharedstatedir$ac_delim localstatedir!$localstatedir$ac_delim includedir!$includedir$ac_delim oldincludedir!$oldincludedir$ac_delim docdir!$docdir$ac_delim infodir!$infodir$ac_delim htmldir!$htmldir$ac_delim dvidir!$dvidir$ac_delim pdfdir!$pdfdir$ac_delim psdir!$psdir$ac_delim libdir!$libdir$ac_delim localedir!$localedir$ac_delim mandir!$mandir$ac_delim DEFS!$DEFS$ac_delim ECHO_C!$ECHO_C$ac_delim ECHO_N!$ECHO_N$ac_delim ECHO_T!$ECHO_T$ac_delim LIBS!$LIBS$ac_delim build_alias!$build_alias$ac_delim host_alias!$host_alias$ac_delim target_alias!$target_alias$ac_delim CC!$CC$ac_delim CFLAGS!$CFLAGS$ac_delim LDFLAGS!$LDFLAGS$ac_delim CPPFLAGS!$CPPFLAGS$ac_delim ac_ct_CC!$ac_ct_CC$ac_delim EXEEXT!$EXEEXT$ac_delim OBJEXT!$OBJEXT$ac_delim INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim INSTALL_DATA!$INSTALL_DATA$ac_delim build!$build$ac_delim build_cpu!$build_cpu$ac_delim build_vendor!$build_vendor$ac_delim build_os!$build_os$ac_delim host!$host$ac_delim host_cpu!$host_cpu$ac_delim host_vendor!$host_vendor$ac_delim host_os!$host_os$ac_delim GREP!$GREP$ac_delim EGREP!$EGREP$ac_delim LN_S!$LN_S$ac_delim ECHO!$ECHO$ac_delim AR!$AR$ac_delim RANLIB!$RANLIB$ac_delim STRIP!$STRIP$ac_delim CPP!$CPP$ac_delim CXX!$CXX$ac_delim CXXFLAGS!$CXXFLAGS$ac_delim ac_ct_CXX!$ac_ct_CXX$ac_delim CXXCPP!$CXXCPP$ac_delim F77!$F77$ac_delim FFLAGS!$FFLAGS$ac_delim ac_ct_F77!$ac_ct_F77$ac_delim LIBTOOL!$LIBTOOL$ac_delim GCCFLAGS!$GCCFLAGS$ac_delim MALSHOW!$MALSHOW$ac_delim GTK_LIBS!$GTK_LIBS$ac_delim GTK_CFLAGS!$GTK_CFLAGS$ac_delim GLIB_LIBS!$GLIB_LIBS$ac_delim GLIB_CFLAGS!$GLIB_CFLAGS$ac_delim READLINE_LIBS!$READLINE_LIBS$ac_delim READLINE_CFLAGS!$READLINE_CFLAGS$ac_delim SYS_CFLAGS!$SYS_CFLAGS$ac_delim INSTALL!$INSTALL$ac_delim LIBOBJS!$LIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 83; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` if test -n "$ac_eof"; then ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` ac_eof=`expr $ac_eof + 1` fi cat >>$CONFIG_STATUS <<_ACEOF cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof /@[a-zA-Z_][a-zA-Z_0-9]*@/!b end _ACEOF sed ' s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g s/^/s,@/; s/!/@,|#_!!_#|/ :n t n s/'"$ac_delim"'$/,g/; t s/$/\\/; p N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n ' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF :end s/|#_!!_#|//g CEOF$ac_eof _ACEOF # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ 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[ ]*=/{ s/:*\$(srcdir):*/:/ s/:*\${srcdir}:*/:/ s/:*@srcdir@:*/:/ s/^\([^=]*=[ ]*\):*/\1/ s/:*$// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF fi # test -n "$CONFIG_FILES" for ac_tag in :F $CONFIG_FILES do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 echo "$as_me: error: Invalid tag $ac_tag." >&2;} { (exit 1); exit 1; }; };; :[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="$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 || { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 echo "$as_me: error: cannot find input file: $ac_f" >&2;} { (exit 1); exit 1; }; };; esac ac_file_inputs="$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 "`IFS=: echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} fi case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin";; 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 || 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" case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`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 || 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" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`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 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # 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= case `sed -n '/datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p ' $ac_file_inputs` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF 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 sed "$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s&@configure_input@&$configure_input&;t t s&@top_builddir@&$ac_top_builddir_sub&;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 $ac_datarootdir_hack " $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&5 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 "$tmp/stdin" case $ac_file in -) cat "$tmp/out"; rm -f "$tmp/out";; *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; esac ;; esac done # for ac_tag { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save # 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 || { (exit 1); exit 1; } fi malaga-7.12/configure.in0000644000175000017500000000524010761575701014530 0ustar bjoernbjoerndnl Copyright (C) 1999 Bjoern Beutel dnl Process this file with autoconf to produce a configure script. AC_INIT AC_CONFIG_SRCDIR(malaga.c) dnl Set the compiler flags if we are using GCC. AC_PROG_CC case "$GCC" in yes) GCCFLAGS="-Wall -Wstrict-prototypes -Wmissing-prototypes" ;; *) GCCFLAGS="" esac AC_PROG_INSTALL AC_PROG_LIBTOOL dnl Check for Posix or Win32 system. AC_MSG_CHECKING(for Win32) case "$host" in *-*-mingw*) SYS_CFLAGS="-DWIN32 -mms-bitfields" use_win32=yes ;; *) SYS_CFLAGS="-DPOSIX" use_win32=no esac AC_MSG_RESULT($use_win32) dnl Check for "readline" library AC_ARG_WITH(readline, AS_HELP_STRING(--with-readline, [Support fancy command line editing @<:@default=yes@:>@]), use_readline=$withval, use_readline=yes) if test $use_readline = yes then AC_CHECK_LIB(readline,readline,,use_readline=no,-lcurses) AC_CHECK_HEADER(readline/readline.h,,use_readline=no) fi if test $use_readline = yes then READLINE_LIBS="-lreadline -lcurses" READLINE_CFLAGS="-DREADLINE" else READLINE_LIBS="" READLINE_CFLAGS="" fi dnl Check for GTK+, version 2.8 or later, when malshow is enabled. AC_ARG_ENABLE(malshow, AS_HELP_STRING(--enable-malshow, [Create the GUI "malshow" @<:@default=yes@:>@]), use_malshow=$enableval, use_malshow=yes) if test $use_malshow = yes then AC_MSG_CHECKING(for GTK+ 2.8 or later) if ! $SHELL -c 'pkg-config --atleast-version=2.8 gtk+-2.0' >/dev/null 2>/dev/null then use_malshow=no fi AC_MSG_RESULT($use_malshow) if test $use_malshow = no then echo 1>&2 "*** No GTK+, version 2.8 or later, found. Disabling malshow." echo 1>&2 "*** You may get GTK+ from ." fi fi if test $use_malshow = yes then GTK_LIBS=`pkg-config gtk+-2.0 --libs` GTK_CFLAGS=`pkg-config gtk+-2.0 --cflags` MALSHOW="malshow" else GTK_LIBS="" GTK_CFLAGS="" MALSHOW="" fi dnl Check for GLib, version 2 AC_MSG_CHECKING(for GLib) if $SHELL -c 'pkg-config glib-2.0' >/dev/null 2>/dev/null then have_glib=yes else have_glib=no fi AC_MSG_RESULT($have_glib) if test $have_glib = yes then GLIB_LIBS=`pkg-config glib-2.0 --libs` GLIB_CFLAGS=`pkg-config glib-2.0 --cflags` else echo 1>&2 "*** No GLib, version 2.0 or later, found. Please install it." echo 1>&2 "*** You may get GLib from ." exit 1 fi AC_SUBST(GCCFLAGS) AC_SUBST(MALSHOW) AC_SUBST(GTK_LIBS) AC_SUBST(GTK_CFLAGS) AC_SUBST(GLIB_LIBS) AC_SUBST(GLIB_CFLAGS) AC_SUBST(READLINE_LIBS) AC_SUBST(READLINE_CFLAGS) AC_SUBST(SYS_CFLAGS) AC_SUBST(INSTALL) AC_SUBST(INSTALL_PROGRAM) AC_SUBST(INSTALL_DATA) AC_CONFIG_FILES(Makefile) AC_OUTPUT dnl End of file. malaga-7.12/config.guess0000744000175000017500000012605110462570523014534 0ustar bjoernbjoern#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. timestamp='2006-02-23' # This file 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. # # 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. # Originally written by Per Bothner . # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit build system type. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep __ELF__ >/dev/null then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerppc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm:riscos:*:*|arm:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:SunOS:5.*:*) echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[45]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep __LP64__ >/dev/null then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) case ${UNAME_MACHINE} in pc98) echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; i*:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:MSYS_NT-*:*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; x86:Interix*:[345]*) echo i586-pc-interix${UNAME_RELEASE} exit ;; EM64T:Interix*:[345]*) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; arm*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) echo cris-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo crisv32-axis-linux-gnu exit ;; frv:Linux:*:*) echo frv-unknown-linux-gnu exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; mips:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips #undef mipsel #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mipsel #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips #else CPU= #endif #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^CPU/{ s: ::g p }'`" test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips64 #undef mips64el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mips64el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips64 #else CPU= #endif #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^CPU/{ s: ::g p }'`" test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) echo or32-unknown-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit ;; i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent # problems with other programs or directories called `ld' in the path. # Set LC_ALL=C to ensure ld outputs messages in English. ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ | sed -ne '/supported targets:/!d s/[ ][ ]*/ /g s/.*supported targets: *// s/ .*// p'` case "$ld_supported_targets" in elf32-i386) TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" ;; a.out-i386-linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" exit ;; coff-i386) echo "${UNAME_MACHINE}-pc-linux-gnucoff" exit ;; "") # Either a pre-BFD a.out linker (linux-gnuoldld) or # one that does not give us useful --help. echo "${UNAME_MACHINE}-pc-linux-gnuoldld" exit ;; esac # Determine whether the default compiler is a.out or elf eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 LIBC=gnu # else LIBC=gnulibc1 # endif # else LIBC=gnulibc1 # endif #else #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__sun) LIBC=gnu #else LIBC=gnuaout #endif #endif #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^LIBC/{ s: ::g p }'`" test x"${LIBC}" != x && { echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit } test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i386. echo i386-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp 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` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: malaga-7.12/config.sub0000744000175000017500000007713010462570523014202 0ustar bjoernbjoern#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. timestamp='2006-02-23' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file 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. # # 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. # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray) os= basic_machine=$1 ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | m32r | m32rle | m68000 | m68k | m88k | maxq | mb | microblaze | mcore \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64vr | mips64vrel \ | mips64orion | mips64orionel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | mt \ | msp430 \ | nios | nios2 \ | ns16k | ns32k \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b \ | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ | v850 | v850e \ | we32k \ | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ | z8k) basic_machine=$basic_machine-unknown ;; m32c) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64vr-* | mips64vrel-* \ | mips64orion-* | mips64orionel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ | xstormy16-* | xtensa-* \ | ymp-* \ | z8k-*) ;; m32c-*) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; c90) basic_machine=c90-cray os=-unicos ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16c) basic_machine=cr16c-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; mvs) basic_machine=i370-ibm os=-mvs ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff ;; tic55x | c55x*) basic_machine=tic55x-unknown os=-coff ;; tic6x | c6x*) basic_machine=tic6x-unknown os=-coff ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: malaga-7.12/ltmain.sh0000744000175000017500000060015710462570523014043 0ustar bjoernbjoern# ltmain.sh - Provide generalized library-building support services. # NOTE: Changing this file will not affect anything until you rerun configure. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005 # Free Software Foundation, Inc. # Originally by Gordon Matzigkeit , 1996 # # 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. # # 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. basename="s,^.*/,,g" # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath="$0" # The name of this program: progname=`echo "$progpath" | $SED $basename` modename="$progname" # Global variables: EXIT_SUCCESS=0 EXIT_FAILURE=1 PROGRAM=ltmain.sh PACKAGE=libtool VERSION="1.5.22 Debian 1.5.22-4" TIMESTAMP=" (1.1220.2.365 2005/12/18 22:14:06)" # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi # Check that we have a working $echo. if test "X$1" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test "X$1" = X--fallback-echo; then # Avoid inline document here, it may be left over : elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then # Yippee, $echo works! : else # Restart under the correct shell, and then maybe $echo will work. exec $SHELL "$progpath" --no-reexec ${1+"$@"} fi if test "X$1" = X--fallback-echo; then # used as fallback echo shift cat <&2 $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 exit $EXIT_FAILURE fi # Global variables. mode=$default_mode nonopt= prev= prevopt= run= show="$echo" show_help= execute_dlfiles= duplicate_deps=no preserve_args= lo2o="s/\\.lo\$/.${objext}/" o2lo="s/\\.${objext}\$/.lo/" ##################################### # Shell function definitions: # This seems to be the best place for them # func_mktempdir [string] # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, STRING is the basename for that directory. func_mktempdir () { my_template="${TMPDIR-/tmp}/${1-$progname}" if test "$run" = ":"; then # Return a directory name, but don't create it in dry-run mode my_tmpdir="${my_template}-$$" else # If mktemp works, use that first and foremost my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` if test ! -d "$my_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race my_tmpdir="${my_template}-${RANDOM-0}$$" save_mktempdir_umask=`umask` umask 0077 $mkdir "$my_tmpdir" umask $save_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$my_tmpdir" || { $echo "cannot create temporary directory \`$my_tmpdir'" 1>&2 exit $EXIT_FAILURE } fi $echo "X$my_tmpdir" | $Xsed } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. func_win32_libid () { win32_libid_type="unknown" win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \ $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then win32_nmres=`eval $NM -f posix -A $1 | \ $SED -n -e '1,100{/ I /{s,.*,import,;p;q;};}'` case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $echo $win32_libid_type } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do case $arg in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") arg="\"$arg\"" ;; esac CC_quoted="$CC_quoted $arg" done case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. case $arg in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") arg="\"$arg\"" ;; esac CC_quoted="$CC_quoted $arg" done case "$@ " in " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then $echo "$modename: unable to infer tagged configuration" $echo "$modename: specify a tag with \`--tag'" 1>&2 exit $EXIT_FAILURE # else # $echo "$modename: using $tagname tagged configuration" fi ;; esac fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { f_ex_an_ar_dir="$1"; shift f_ex_an_ar_oldlib="$1" $show "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_oldlib)" $run eval "(cd \$f_ex_an_ar_dir && $AR x \$f_ex_an_ar_oldlib)" || exit $? if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else $echo "$modename: ERROR: object name conflicts: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" 1>&2 exit $EXIT_FAILURE fi } # func_extract_archives gentop oldlib ... func_extract_archives () { my_gentop="$1"; shift my_oldlibs=${1+"$@"} my_oldobjs="" my_xlib="" my_xabs="" my_xdir="" my_status="" $show "${rm}r $my_gentop" $run ${rm}r "$my_gentop" $show "$mkdir $my_gentop" $run $mkdir "$my_gentop" my_status=$? if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then exit $my_status fi for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'` my_xdir="$my_gentop/$my_xlib" $show "${rm}r $my_xdir" $run ${rm}r "$my_xdir" $show "$mkdir $my_xdir" $run $mkdir "$my_xdir" exit_status=$? if test "$exit_status" -ne 0 && test ! -d "$my_xdir"; then exit $exit_status fi case $host in *-darwin*) $show "Extracting $my_xabs" # Do not bother doing anything if just a dry run if test -z "$run"; then darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` darwin_base_archive=`$echo "X$darwin_archive" | $Xsed -e 's%^.*/%%'` darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null` if test -n "$darwin_arches"; then darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= $show "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches ; do mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}" lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" func_extract_an_archive "`pwd`" "${darwin_base_archive}" cd "$darwin_curdir" $rm "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" done # $darwin_arches ## Okay now we have a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print| xargs basename | sort -u | $NL2SP` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` lipo -create -output "$darwin_file" $darwin_files done # $darwin_filelist ${rm}r unfat-$$ cd "$darwin_orig_dir" else cd "$darwin_orig_dir" func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches fi # $run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` done func_extract_archives_result="$my_oldobjs" } # End of Shell function definitions ##################################### # Darwin sucks eval std_shrext=\"$shrext_cmds\" disable_libs=no # Parse our command line options once, thoroughly. while test "$#" -gt 0 do arg="$1" shift case $arg in -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; *) optarg= ;; esac # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in execute_dlfiles) execute_dlfiles="$execute_dlfiles $arg" ;; tag) tagname="$arg" preserve_args="${preserve_args}=$arg" # Check whether tagname contains only valid characters case $tagname in *[!-_A-Za-z0-9,/]*) $echo "$progname: invalid tag name: $tagname" 1>&2 exit $EXIT_FAILURE ;; esac case $tagname in CC) # Don't test for the "default" C tag, as we know, it's there, but # not specially marked. ;; *) if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then taglist="$taglist $tagname" # Evaluate the configuration. eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`" else $echo "$progname: ignoring unknown tag $tagname" 1>&2 fi ;; esac ;; *) eval "$prev=\$arg" ;; esac prev= prevopt= continue fi # Have we seen a non-optional argument yet? case $arg in --help) show_help=yes ;; --version) $echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" $echo $echo "Copyright (C) 2005 Free Software Foundation, Inc." $echo "This is free software; see the source for copying conditions. There is NO" $echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." exit $? ;; --config) ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath # Now print the configurations for the tags. for tagname in $taglist; do ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath" done exit $? ;; --debug) $echo "$progname: enabling shell trace mode" set -x preserve_args="$preserve_args $arg" ;; --dry-run | -n) run=: ;; --features) $echo "host: $host" if test "$build_libtool_libs" = yes; then $echo "enable shared libraries" else $echo "disable shared libraries" fi if test "$build_old_libs" = yes; then $echo "enable static libraries" else $echo "disable static libraries" fi exit $? ;; --finish) mode="finish" ;; --mode) prevopt="--mode" prev=mode ;; --mode=*) mode="$optarg" ;; --preserve-dup-deps) duplicate_deps="yes" ;; --quiet | --silent) show=: preserve_args="$preserve_args $arg" ;; --tag) prevopt="--tag" prev=tag preserve_args="$preserve_args --tag" ;; --tag=*) set tag "$optarg" ${1+"$@"} shift prev=tag preserve_args="$preserve_args --tag" ;; -dlopen) prevopt="-dlopen" prev=execute_dlfiles ;; -*) $echo "$modename: unrecognized option \`$arg'" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE ;; *) nonopt="$arg" break ;; esac done if test -n "$prevopt"; then $echo "$modename: option \`$prevopt' requires an argument" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi case $disable_libs in no) ;; shared) build_libtool_libs=no build_old_libs=yes ;; static) build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` ;; esac # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= if test -z "$show_help"; then # Infer the operation mode. if test -z "$mode"; then $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2 $echo "*** Future versions of Libtool will require --mode=MODE be specified." 1>&2 case $nonopt in *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*) mode=link for arg do case $arg in -c) mode=compile break ;; esac done ;; *db | *dbx | *strace | *truss) mode=execute ;; *install*|cp|mv) mode=install ;; *rm) mode=uninstall ;; *) # If we have no mode, but dlfiles were specified, then do execute mode. test -n "$execute_dlfiles" && mode=execute # Just use the default operation mode. if test -z "$mode"; then if test -n "$nonopt"; then $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 else $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 fi fi ;; esac fi # Only execute mode is allowed to have -dlopen flags. if test -n "$execute_dlfiles" && test "$mode" != execute; then $echo "$modename: unrecognized option \`-dlopen'" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help="$help" help="Try \`$modename --help --mode=$mode' for more information." # These modes are in order of execution frequency so that they run quickly. case $mode in # libtool compile mode compile) modename="$modename: compile" # Get the compilation command and the source file. base_compile= srcfile="$nonopt" # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= for arg do case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile lastarg="$arg" arg_mode=normal ;; target ) libobj="$arg" arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) if test -n "$libobj" ; then $echo "$modename: you cannot specify \`-o' more than once" 1>&2 exit $EXIT_FAILURE fi arg_mode=target continue ;; -static | -prefer-pic | -prefer-non-pic) later="$later $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` lastarg= save_ifs="$IFS"; IFS=',' for arg in $args; do IFS="$save_ifs" # Double-quote args containing other shell metacharacters. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. case $arg in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") arg="\"$arg\"" ;; esac lastarg="$lastarg $arg" done IFS="$save_ifs" lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` # Add the arguments to base_compile. base_compile="$base_compile $lastarg" continue ;; * ) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg="$srcfile" srcfile="$arg" ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` case $lastarg in # Double-quote args containing other shell metacharacters. # Many Bourne shells cannot handle close brackets correctly # in scan sets, and some SunOS ksh mistreat backslash-escaping # in scan sets (worked around with variable expansion), # and furthermore cannot handle '|' '&' '(' ')' in scan sets # at all, so we specify them separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") lastarg="\"$lastarg\"" ;; esac base_compile="$base_compile $lastarg" done # for arg case $arg_mode in arg) $echo "$modename: you must specify an argument for -Xcompile" exit $EXIT_FAILURE ;; target) $echo "$modename: you must specify a target with \`-o'" 1>&2 exit $EXIT_FAILURE ;; *) # Get the name of the library object. [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo xform='[cCFSifmso]' case $libobj in *.ada) xform=ada ;; *.adb) xform=adb ;; *.ads) xform=ads ;; *.asm) xform=asm ;; *.c++) xform=c++ ;; *.cc) xform=cc ;; *.ii) xform=ii ;; *.class) xform=class ;; *.cpp) xform=cpp ;; *.cxx) xform=cxx ;; *.f90) xform=f90 ;; *.for) xform=for ;; *.java) xform=java ;; esac libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` case $libobj in *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; *) $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 exit $EXIT_FAILURE ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -static) build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"` case $qlibobj in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") qlibobj="\"$qlibobj\"" ;; esac test "X$libobj" != "X$qlibobj" \ && $echo "X$libobj" | grep '[]~#^*{};<>?"'"'"' &()|`$[]' \ && $echo "$modename: libobj name \`$libobj' may not contain shell special characters." objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` if test "X$xdir" = "X$obj"; then xdir= else xdir=$xdir/ fi lobj=${xdir}$objdir/$objname if test -z "$base_compile"; then $echo "$modename: you must specify a compilation command" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi # Delete any leftover library objects. if test "$build_old_libs" = yes; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi $run $rm $removelist trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2*) pic_mode=default ;; esac if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test "$compiler_c_o" = no; then output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} lockfile="$output_obj.lock" removelist="$removelist $output_obj $lockfile" trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test "$need_locks" = yes; then until $run ln "$progpath" "$lockfile" 2>/dev/null; do $show "Waiting for $lockfile to be removed" sleep 2 done elif test "$need_locks" = warn; then if test -f "$lockfile"; then $echo "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $run $rm $removelist exit $EXIT_FAILURE fi $echo "$srcfile" > "$lockfile" fi if test -n "$fix_srcfile_path"; then eval srcfile=\"$fix_srcfile_path\" fi qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"` case $qsrcfile in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") qsrcfile="\"$qsrcfile\"" ;; esac $run $rm "$libobj" "${libobj}T" # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. test -z "$run" && cat > ${libobj}T </dev/null`" != "X$srcfile"; then $echo "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $run $rm $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then $show "$mv $output_obj $lobj" if $run $mv $output_obj $lobj; then : else error=$? $run $rm $removelist exit $error fi fi # Append the name of the PIC object to the libtool object file. test -z "$run" && cat >> ${libobj}T <> ${libobj}T </dev/null`" != "X$srcfile"; then $echo "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $run $rm $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then $show "$mv $output_obj $obj" if $run $mv $output_obj $obj; then : else error=$? $run $rm $removelist exit $error fi fi # Append the name of the non-PIC object the libtool object file. # Only append if the libtool object file exists. test -z "$run" && cat >> ${libobj}T <> ${libobj}T <&2 fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes else if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built fi build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg="$1" shift case $arg in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test ;; *) qarg=$arg ;; esac libtool_args="$libtool_args $qarg" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) compile_command="$compile_command @OUTPUT@" finalize_command="$finalize_command @OUTPUT@" ;; esac case $prev in dlfiles|dlprefiles) if test "$preload" = no; then # Add the symbol object into the linking commands. compile_command="$compile_command @SYMFILE@" finalize_command="$finalize_command @SYMFILE@" preload=yes fi case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test "$dlself" = no; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test "$prev" = dlprefiles; then dlself=yes elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test "$prev" = dlfiles; then dlfiles="$dlfiles $arg" else dlprefiles="$dlprefiles $arg" fi prev= continue ;; esac ;; expsyms) export_symbols="$arg" if test ! -f "$arg"; then $echo "$modename: symbol file \`$arg' does not exist" exit $EXIT_FAILURE fi prev= continue ;; expsyms_regex) export_symbols_regex="$arg" prev= continue ;; inst_prefix) inst_prefix_dir="$arg" prev= continue ;; precious_regex) precious_files_regex="$arg" prev= continue ;; release) release="-$arg" prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat $save_arg` do # moreargs="$moreargs $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then pic_object= non_pic_object= # Read the .lo file # If there is no directory component, then add one. case $arg in */* | *\\*) . $arg ;; *) . ./$arg ;; esac if test -z "$pic_object" || \ test -z "$non_pic_object" || test "$pic_object" = none && \ test "$non_pic_object" = none; then $echo "$modename: cannot find name of object for \`$arg'" 1>&2 exit $EXIT_FAILURE fi # Extract subdirectory from the argument. xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` if test "X$xdir" = "X$arg"; then xdir= else xdir="$xdir/" fi if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then dlfiles="$dlfiles $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. dlprefiles="$dlprefiles $pic_object" prev= fi # A PIC object. libobjs="$libobjs $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object non_pic_objects="$non_pic_objects $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" non_pic_objects="$non_pic_objects $non_pic_object" fi else # Only an error if not doing a dry-run. if test -z "$run"; then $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 exit $EXIT_FAILURE else # Dry-run case. # Extract subdirectory from the argument. xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` if test "X$xdir" = "X$arg"; then xdir= else xdir="$xdir/" fi pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` libobjs="$libobjs $pic_object" non_pic_objects="$non_pic_objects $non_pic_object" fi fi done else $echo "$modename: link input file \`$save_arg' does not exist" exit $EXIT_FAILURE fi arg=$save_arg prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) $echo "$modename: only absolute run-paths are allowed" 1>&2 exit $EXIT_FAILURE ;; esac if test "$prev" = rpath; then case "$rpath " in *" $arg "*) ;; *) rpath="$rpath $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) xrpath="$xrpath $arg" ;; esac fi prev= continue ;; xcompiler) compiler_flags="$compiler_flags $qarg" prev= compile_command="$compile_command $qarg" finalize_command="$finalize_command $qarg" continue ;; xlinker) linker_flags="$linker_flags $qarg" compiler_flags="$compiler_flags $wl$qarg" prev= compile_command="$compile_command $wl$qarg" finalize_command="$finalize_command $wl$qarg" continue ;; xcclinker) linker_flags="$linker_flags $qarg" compiler_flags="$compiler_flags $qarg" prev= compile_command="$compile_command $qarg" finalize_command="$finalize_command $qarg" continue ;; shrext) shrext_cmds="$arg" prev= continue ;; darwin_framework|darwin_framework_skip) test "$prev" = "darwin_framework" && compiler_flags="$compiler_flags $arg" compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" prev= continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg="$arg" case $arg in -all-static) if test -n "$link_static_flag"; then compile_command="$compile_command $link_static_flag" finalize_command="$finalize_command $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 continue ;; -avoid-version) avoid_version=yes continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then $echo "$modename: more than one -exported-symbols argument is not allowed" exit $EXIT_FAILURE fi if test "X$arg" = "X-export-symbols"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework|-arch|-isysroot) case " $CC " in *" ${arg} ${1} "* | *" ${arg} ${1} "*) prev=darwin_framework_skip ;; *) compiler_flags="$compiler_flags $arg" prev=darwin_framework ;; esac compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" ;; esac continue ;; -L*) dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 absdir="$dir" notinst_path="$notinst_path $dir" fi dir="$absdir" ;; esac case "$deplibs " in *" -L$dir "*) ;; *) deplibs="$deplibs -L$dir" lib_search_path="$lib_search_path $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) testbindir=`$echo "X$dir" | $Xsed -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; *) dllsearchpath="$dllsearchpath:$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; *) dllsearchpath="$dllsearchpath:$testbindir";; esac ;; esac continue ;; -l*) if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test "X$arg" = "X-lc" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. test "X$arg" = "X-lc" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework deplibs="$deplibs -framework System" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test "X$arg" = "X-lc" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test "X$arg" = "X-lc" && continue ;; esac elif test "X$arg" = "X-lc_r"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi deplibs="$deplibs $arg" continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. -model) compile_command="$compile_command $arg" compiler_flags="$compiler_flags $arg" finalize_command="$finalize_command $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) compiler_flags="$compiler_flags $arg" compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" continue ;; -module) module=yes continue ;; # -64, -mips[0-9] enable 64-bit mode on the SGI compiler # -r[0-9][0-9]* specifies the processor on the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler # +DA*, +DD* enable 64-bit mode on the HP compiler # -q* pass through compiler args for the IBM compiler # -m* pass through architecture-specific compiler args for GCC # -m*, -t[45]*, -txscale* pass through architecture-specific # compiler args for GCC # -pg pass through profiling flag for GCC # @file GCC response files -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*|-pg| \ -t[45]*|-txscale*|@*) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` case $arg in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") arg="\"$arg\"" ;; esac compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" compiler_flags="$compiler_flags $arg" continue ;; -shrext) prev=shrext continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) # The PATH hackery in wrapper scripts is required on Windows # in order for the loader to find any dlls it needs. $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) $echo "$modename: only absolute run-paths are allowed" 1>&2 exit $EXIT_FAILURE ;; esac case "$xrpath " in *" $dir "*) ;; *) xrpath="$xrpath $dir" ;; esac continue ;; -static) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -Wc,*) args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" case $flag in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") flag="\"$flag\"" ;; esac arg="$arg $wl$flag" compiler_flags="$compiler_flags $flag" done IFS="$save_ifs" arg=`$echo "X$arg" | $Xsed -e "s/^ //"` ;; -Wl,*) args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" case $flag in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") flag="\"$flag\"" ;; esac arg="$arg $wl$flag" compiler_flags="$compiler_flags $wl$flag" linker_flags="$linker_flags $flag" done IFS="$save_ifs" arg=`$echo "X$arg" | $Xsed -e "s/^ //"` ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # Some other compiler flag. -* | +*) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` case $arg in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") arg="\"$arg\"" ;; esac ;; *.$objext) # A standard object. objs="$objs $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then pic_object= non_pic_object= # Read the .lo file # If there is no directory component, then add one. case $arg in */* | *\\*) . $arg ;; *) . ./$arg ;; esac if test -z "$pic_object" || \ test -z "$non_pic_object" || test "$pic_object" = none && \ test "$non_pic_object" = none; then $echo "$modename: cannot find name of object for \`$arg'" 1>&2 exit $EXIT_FAILURE fi # Extract subdirectory from the argument. xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` if test "X$xdir" = "X$arg"; then xdir= else xdir="$xdir/" fi if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then dlfiles="$dlfiles $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. dlprefiles="$dlprefiles $pic_object" prev= fi # A PIC object. libobjs="$libobjs $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object non_pic_objects="$non_pic_objects $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" non_pic_objects="$non_pic_objects $non_pic_object" fi else # Only an error if not doing a dry-run. if test -z "$run"; then $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 exit $EXIT_FAILURE else # Dry-run case. # Extract subdirectory from the argument. xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` if test "X$xdir" = "X$arg"; then xdir= else xdir="$xdir/" fi pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` libobjs="$libobjs $pic_object" non_pic_objects="$non_pic_objects $non_pic_object" fi fi ;; *.$libext) # An archive. deplibs="$deplibs $arg" old_deplibs="$old_deplibs $arg" continue ;; *.la) # A libtool-controlled library. if test "$prev" = dlfiles; then # This library was specified with -dlopen. dlfiles="$dlfiles $arg" prev= elif test "$prev" = dlprefiles; then # The library was specified with -dlpreopen. dlprefiles="$dlprefiles $arg" prev= else deplibs="$deplibs $arg" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` case $arg in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") arg="\"$arg\"" ;; esac ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" fi done # argument parsing loop if test -n "$prev"; then $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" fi oldlibs= # calculate the name of the file, without its directory outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` libobjs_save="$libobjs" if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` if test "X$output_objdir" = "X$output"; then output_objdir="$objdir" else output_objdir="$output_objdir/$objdir" fi # Create the object directory. if test ! -d "$output_objdir"; then $show "$mkdir $output_objdir" $run $mkdir $output_objdir exit_status=$? if test "$exit_status" -ne 0 && test ! -d "$output_objdir"; then exit $exit_status fi fi # Determine the type of output case $output in "") $echo "$modename: you must specify an output file" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac case $host in *cygwin* | *mingw* | *pw32*) # don't eliminate duplications in $postdeps and $predeps duplicate_compiler_generated_deps=yes ;; *) duplicate_compiler_generated_deps=$duplicate_deps ;; esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if test "X$duplicate_deps" = "Xyes" ; then case "$libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi libs="$libs $deplib" done if test "$linkmode" = lib; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; esac pre_post_deps="$pre_post_deps $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries case $linkmode in lib) passes="conv link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 exit $EXIT_FAILURE ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=no newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan"; then libs="$deplibs" deplibs= fi if test "$linkmode" = prog; then case $pass in dlopen) libs="$dlfiles" ;; dlpreopen) libs="$dlprefiles" ;; link) libs="$deplibs %DEPLIBS%" test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" ;; esac fi if test "$pass" = dlopen; then # Collect dlpreopened libraries save_deplibs="$deplibs" deplibs= fi for deplib in $libs; do lib= found=no case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else compiler_flags="$compiler_flags $deplib" fi continue ;; -l*) if test "$linkmode" != lib && test "$linkmode" != prog; then $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2 continue fi name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib="$searchdir/lib${name}${search_ext}" if test -f "$lib"; then if test "$search_ext" = ".la"; then found=yes else found=no fi break 2 fi done done if test "$found" != yes; then # deplib doesn't seem to be a libtool library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue else # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $deplib "*) if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then library_names= old_library= case $lib in */* | *\\*) . $lib ;; *) . ./$lib ;; esac for l in $old_library $library_names; do ll="$l" done if test "X$ll" = "X$old_library" ; then # only static version available found=no ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` test "X$ladir" = "X$lib" && ladir="." lib=$ladir/$old_library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi fi ;; # -l -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test "$pass" = conv && continue newdependency_libs="$deplib $newdependency_libs" newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` ;; prog) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi if test "$pass" = scan; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` ;; *) $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2 ;; esac # linkmode continue ;; # -L -R*) if test "$pass" = link; then dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) xrpath="$xrpath $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) lib="$deplib" ;; *.$libext) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) valid_a_lib=no case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` if eval $echo \"$deplib\" 2>/dev/null \ | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=yes fi ;; pass_all) valid_a_lib=yes ;; esac if test "$valid_a_lib" != yes; then $echo $echo "*** Warning: Trying to link with static lib archive $deplib." $echo "*** I have the capability to make that library automatically link in when" $echo "*** you link to this library. But I can only do this if you have a" $echo "*** shared version of the library, which you do not appear to have" $echo "*** because the file extensions .$libext of this argument makes me believe" $echo "*** that it is just a static archive that I should not used here." else $echo $echo "*** Warning: Linking the shared library $output against the" $echo "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" fi continue ;; prog) if test "$pass" != link; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test "$pass" = conv; then deplibs="$deplib $deplibs" elif test "$linkmode" = prog; then if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlopen support or we're linking statically, # we need to preload. newdlprefiles="$newdlprefiles $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else newdlfiles="$newdlfiles $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=yes continue ;; esac # case $deplib if test "$found" = yes || test -f "$lib"; then : else $echo "$modename: cannot find the library \`$lib' or unhandled argument \`$deplib'" 1>&2 exit $EXIT_FAILURE fi # Check to see that this really is a libtool archive. if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : else $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 exit $EXIT_FAILURE fi ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` test "X$ladir" = "X$lib" && ladir="." dlname= dlopen= dlpreopen= libdir= library_names= old_library= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file case $lib in */* | *\\*) . $lib ;; *) . ./$lib ;; esac if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan" || { test "$linkmode" != prog && test "$linkmode" != lib; }; then test -n "$dlopen" && dlfiles="$dlfiles $dlopen" test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" fi if test "$pass" = conv; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 exit $EXIT_FAILURE fi # It is a libtool convenience library, so add in its objects. convenience="$convenience $ladir/$objdir/$old_library" old_convenience="$old_convenience $ladir/$objdir/$old_library" tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if test "X$duplicate_deps" = "Xyes" ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done elif test "$linkmode" != prog && test "$linkmode" != lib; then $echo "$modename: \`$lib' is not a convenience library" 1>&2 exit $EXIT_FAILURE fi continue fi # $pass = conv # Get the name of the library we link against. linklib= for l in $old_library $library_names; do linklib="$l" done if test -z "$linklib"; then $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 exit $EXIT_FAILURE fi # This library was specified with -dlopen. if test "$pass" = dlopen; then if test -z "$libdir"; then $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 exit $EXIT_FAILURE fi if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. dlprefiles="$dlprefiles $lib $dependency_libs" else newdlfiles="$newdlfiles $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 abs_ladir="$ladir" fi ;; esac laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` # Find the relevant object directory and library name. if test "X$installed" = Xyes; then if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then $echo "$modename: warning: library \`$lib' was moved." 1>&2 dir="$ladir" absdir="$abs_ladir" libdir="$abs_ladir" else dir="$libdir" absdir="$libdir" fi test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir="$ladir" absdir="$abs_ladir" # Remove this search path later notinst_path="$notinst_path $abs_ladir" else dir="$ladir/$objdir" absdir="$abs_ladir/$objdir" # Remove this search path later notinst_path="$notinst_path $abs_ladir" fi fi # $installed = yes name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` # This library was specified with -dlpreopen. if test "$pass" = dlpreopen; then if test -z "$libdir"; then $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 exit $EXIT_FAILURE fi # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then newdlprefiles="$newdlprefiles $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then newdlprefiles="$newdlprefiles $dir/$dlname" else newdlprefiles="$newdlprefiles $dir/$linklib" fi fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test "$linkmode" = lib; then deplibs="$dir/$old_library $deplibs" elif test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test "$linkmode" = prog && test "$pass" != link; then newlib_search_path="$newlib_search_path $ladir" deplibs="$lib $deplibs" linkalldeplibs=no if test "$link_all_deplibs" != no || test -z "$library_names" || test "$build_libtool_libs" = no; then linkalldeplibs=yes fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test esac # Need to link against all dependency_libs? if test "$linkalldeplibs" = yes; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if test "X$duplicate_deps" = "Xyes" ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done # for deplib continue fi # $linkmode = prog... if test "$linkmode,$pass" = "prog,link"; then if test -n "$library_names" && { test "$prefer_static_libs" = no || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then # Make sure the rpath contains only unique directories. case "$temp_rpath " in *" $dir "*) ;; *" $absdir "*) ;; *) temp_rpath="$temp_rpath $absdir" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) compile_rpath="$compile_rpath $absdir" esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" esac ;; esac fi # $linkmode,$pass = prog,link... if test "$alldeplibs" = yes && { test "$deplibs_check_method" = pass_all || { test "$build_libtool_libs" = yes && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test "$use_static_libs" = built && test "$installed" = yes ; then use_static_libs=no fi if test -n "$library_names" && { test "$use_static_libs" = no || test -z "$old_library"; }; then if test "$installed" = no; then notinst_deplibs="$notinst_deplibs $lib" need_relink=yes fi # This is a shared library # Warn about portability, can't link against -module's on # some systems (darwin) if test "$shouldnotlink" = yes && test "$pass" = link ; then $echo if test "$linkmode" = prog; then $echo "*** Warning: Linking the executable $output against the loadable module" else $echo "*** Warning: Linking the shared library $output against the loadable module" fi $echo "*** $linklib is not portable!" fi if test "$linkmode" = lib && test "$hardcode_into_libs" = yes; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) compile_rpath="$compile_rpath $absdir" esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names realname="$2" shift; shift libname=`eval \\$echo \"$libname_spec\"` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname="$dlname" elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw*) major=`expr $current - $age` versuffix="-$major" ;; esac eval soname=\"$soname_spec\" else soname="$realname" fi # Make a new name for the extract_expsyms_cmds to use soroot="$soname" soname=`$echo $soroot | ${SED} -e 's/^.*\///'` newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a" # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else $show "extracting exported symbol list from \`$soname'" save_ifs="$IFS"; IFS='~' cmds=$extract_expsyms_cmds for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else $show "generating import library for \`$soname'" save_ifs="$IFS"; IFS='~' cmds=$old_archive_from_expsyms_cmds for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test "$linkmode" = prog || test "$mode" != relink; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test "$hardcode_direct" = no; then add="$dir/$linklib" case $host in *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; *-*-sysv4*uw2*) add_dir="-L$dir" ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir="-L$dir" ;; *-*-darwin* ) # if the lib is a module then we can not link against # it, someone is ignoring the new warnings I added if /usr/bin/file -L $add 2> /dev/null | $EGREP ": [^:]* bundle" >/dev/null ; then $echo "** Warning, lib $linklib is a module, not a shared library" if test -z "$old_library" ; then $echo $echo "** And there doesn't seem to be a static archive available" $echo "** The link will probably fail, sorry" else add="$dir/$old_library" fi fi esac elif test "$hardcode_minus_L" = no; then case $host in *-*-sunos*) add_shlibpath="$dir" ;; esac add_dir="-L$dir" add="-l$name" elif test "$hardcode_shlibpath_var" = no; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; relink) if test "$hardcode_direct" = yes; then add="$dir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$dir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) add_dir="$add_dir -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; *) lib_linked=no ;; esac if test "$lib_linked" != yes; then $echo "$modename: configuration error: unsupported hardcode properties" exit $EXIT_FAILURE fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; esac fi if test "$linkmode" = prog; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test "$hardcode_direct" != yes && \ test "$hardcode_minus_L" != yes && \ test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; esac fi fi fi if test "$linkmode" = prog || test "$mode" = relink; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test "$hardcode_direct" = yes; then add="$libdir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$libdir" add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; esac add="-l$name" elif test "$hardcode_automatic" = yes; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib" ; then add="$inst_prefix_dir$libdir/$linklib" else add="$libdir/$linklib" fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir="-L$libdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) add_dir="$add_dir -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" fi if test "$linkmode" = prog; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test "$linkmode" = prog; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test "$hardcode_direct" != unsupported; then test -n "$old_library" && linklib="$old_library" compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test "$build_libtool_libs" = yes; then # Not a shared library if test "$deplibs_check_method" != pass_all; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. $echo $echo "*** Warning: This system can not link to static lib archive $lib." $echo "*** I have the capability to make that library automatically link in when" $echo "*** you link to this library. But I can only do this if you have a" $echo "*** shared version of the library, which you do not appear to have." if test "$module" = yes; then $echo "*** But as you try to build a module library, libtool will still create " $echo "*** a static module, that should work as long as the dlopening application" $echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then $echo $echo "*** However, this would only work if libtool was able to extract symbol" $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" $echo "*** not find such a program. So, this module is probably useless." $echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test "$linkmode" = lib; then if test -n "$dependency_libs" && { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes || test "$link_static" = yes; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` case " $xrpath " in *" $temp_xrpath "*) ;; *) xrpath="$xrpath $temp_xrpath";; esac;; *) temp_deplibs="$temp_deplibs $libdir";; esac done dependency_libs="$temp_deplibs" fi newlib_search_path="$newlib_search_path $absdir" # Link against this library test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" if test "X$duplicate_deps" = "Xyes" ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done if test "$link_all_deplibs" != no; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do case $deplib in -L*) path="$deplib" ;; *.la) dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` test "X$dir" = "X$deplib" && dir="." # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 absdir="$dir" fi ;; esac if grep "^installed=no" $deplib > /dev/null; then path="$absdir/$objdir" else eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` if test -z "$libdir"; then $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 exit $EXIT_FAILURE fi if test "$absdir" != "$libdir"; then $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 fi path="$absdir" fi depdepl= case $host in *-*-darwin*) # we do not want to link against static libs, # but need to link against shared eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names" ; then for tmp in $deplibrary_names ; do depdepl=$tmp done if test -f "$path/$depdepl" ; then depdepl="$path/$depdepl" fi # do not add paths which are already there case " $newlib_search_path " in *" $path "*) ;; *) newlib_search_path="$newlib_search_path $path";; esac fi path="" ;; *) path="-L$path" ;; esac ;; -l*) case $host in *-*-darwin*) # Again, we only want to link against shared libraries eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"` for tmp in $newlib_search_path ; do if test -f "$tmp/lib$tmp_libs.dylib" ; then eval depdepl="$tmp/lib$tmp_libs.dylib" break fi done path="" ;; *) continue ;; esac ;; *) continue ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac case " $deplibs " in *" $depdepl "*) ;; *) deplibs="$depdepl $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs dependency_libs="$newdependency_libs" if test "$pass" = dlpreopen; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test "$pass" != dlopen; then if test "$pass" != conv; then # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) lib_search_path="$lib_search_path $dir" ;; esac done newlib_search_path= fi if test "$linkmode,$pass" != "prog,link"; then vars="deplibs" else vars="compile_deplibs finalize_deplibs" fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) tmp_libs="$tmp_libs $deplib" ;; esac ;; *) tmp_libs="$tmp_libs $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs ; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i="" ;; esac if test -n "$i" ; then tmp_libs="$tmp_libs $i" fi done dependency_libs=$tmp_libs done # for pass if test "$linkmode" = prog; then dlfiles="$newdlfiles" dlprefiles="$newdlprefiles" fi case $linkmode in oldlib) if test -n "$deplibs"; then $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 fi if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 fi if test -n "$rpath"; then $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 fi if test -n "$xrpath"; then $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 fi if test -n "$vinfo"; then $echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2 fi if test -n "$release"; then $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 fi if test -n "$export_symbols" || test -n "$export_symbols_regex"; then $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 fi # Now set the variables for building old libraries. build_libtool_libs=no oldlibs="$output" objs="$objs$old_deplibs" ;; lib) # Make sure we only generate libraries of the form `libNAME.la'. case $outputname in lib*) name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) if test "$module" = no; then $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi if test "$need_lib_prefix" != no; then # Add the "lib" prefix for modules if required name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` fi ;; esac if test -n "$objs"; then if test "$deplibs_check_method" != pass_all; then $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 exit $EXIT_FAILURE else $echo $echo "*** Warning: Linking the shared library $output against the non-libtool" $echo "*** objects $objs is not portable!" libobjs="$libobjs $objs" fi fi if test "$dlself" != no; then $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 fi set dummy $rpath if test "$#" -gt 2; then $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 fi install_libdir="$2" oldlibs= if test -z "$rpath"; then if test "$build_libtool_libs" = yes; then # Building a libtool convenience library. # Some compilers have problems with a `.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi if test -n "$vinfo"; then $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2 fi if test -n "$release"; then $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 fi else # Parse the version information argument. save_ifs="$IFS"; IFS=':' set dummy $vinfo 0 0 0 IFS="$save_ifs" if test -n "$8"; then $echo "$modename: too many parameters to \`-version-info'" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major="$2" number_minor="$3" number_revision="$4" # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # which has an extra 1 added just for fun # case $version_type in darwin|linux|osf|windows) current=`expr $number_major + $number_minor` age="$number_minor" revision="$number_revision" ;; freebsd-aout|freebsd-elf|sunos) current="$number_major" revision="$number_minor" age="0" ;; irix|nonstopux) current=`expr $number_major + $number_minor - 1` age="$number_minor" revision="$number_minor" ;; *) $echo "$modename: unknown library version type \`$version_type'" 1>&2 $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 exit $EXIT_FAILURE ;; esac ;; no) current="$2" revision="$3" age="$4" ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) $echo "$modename: CURRENT \`$current' must be a nonnegative integer" 1>&2 $echo "$modename: \`$vinfo' is not valid version information" 1>&2 exit $EXIT_FAILURE ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) $echo "$modename: REVISION \`$revision' must be a nonnegative integer" 1>&2 $echo "$modename: \`$vinfo' is not valid version information" 1>&2 exit $EXIT_FAILURE ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) $echo "$modename: AGE \`$age' must be a nonnegative integer" 1>&2 $echo "$modename: \`$vinfo' is not valid version information" 1>&2 exit $EXIT_FAILURE ;; esac if test "$age" -gt "$current"; then $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 $echo "$modename: \`$vinfo' is not valid version information" 1>&2 exit $EXIT_FAILURE fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header major=.`expr $current - $age` versuffix="$major.$age.$revision" # Darwin ld doesn't like 0 for these options... minor_current=`expr $current + 1` verstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" ;; freebsd-aout) major=".$current" versuffix=".$current.$revision"; ;; freebsd-elf) major=".$current" versuffix=".$current"; ;; irix | nonstopux) major=`expr $current - $age + 1` case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring="$verstring_prefix$major.$revision" # Add in all the interfaces that we are compatible with. loop=$revision while test "$loop" -ne 0; do iface=`expr $revision - $loop` loop=`expr $loop - 1` verstring="$verstring_prefix$major.$iface:$verstring" done # Before this point, $major must not contain `.'. major=.$major versuffix="$major.$revision" ;; linux) major=.`expr $current - $age` versuffix="$major.$age.$revision" ;; osf) major=.`expr $current - $age` versuffix=".$current.$age.$revision" verstring="$current.$age.$revision" # Add in all the interfaces that we are compatible with. loop=$age while test "$loop" -ne 0; do iface=`expr $current - $loop` loop=`expr $loop - 1` verstring="$verstring:${iface}.0" done # Make executables depend on our current version. verstring="$verstring:${current}.0" ;; sunos) major=".$current" versuffix=".$current.$revision" ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 filesystems. major=`expr $current - $age` versuffix="-$major" ;; *) $echo "$modename: unknown library version type \`$version_type'" 1>&2 $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 exit $EXIT_FAILURE ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring="0.0" ;; esac if test "$need_version" = no; then versuffix= else versuffix=".0.0" fi fi # Remove version info from name if versioning should be avoided if test "$avoid_version" = yes && test "$need_version" = no; then major= versuffix= verstring="" fi # Check to see if the archive will have undefined symbols. if test "$allow_undefined" = yes; then if test "$allow_undefined_flag" = unsupported; then $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 build_libtool_libs=no build_old_libs=yes fi else # Don't allow undefined symbols. allow_undefined_flag="$no_undefined_flag" fi fi if test "$mode" != relink; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$echo "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) if test "X$precious_files_regex" != "X"; then if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi removelist="$removelist $p" ;; *) ;; esac done if test -n "$removelist"; then $show "${rm}r $removelist" $run ${rm}r $removelist fi fi # Now set the variables for building old libraries. if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then oldlibs="$oldlibs $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` fi # Eliminate all temporary directories. for path in $notinst_path; do lib_search_path=`$echo "$lib_search_path " | ${SED} -e "s% $path % %g"` deplibs=`$echo "$deplibs " | ${SED} -e "s% -L$path % %g"` dependency_libs=`$echo "$dependency_libs " | ${SED} -e "s% -L$path % %g"` done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do temp_xrpath="$temp_xrpath -R$libdir" case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" ;; esac done if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles="$dlfiles" dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) dlfiles="$dlfiles $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles="$dlprefiles" dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) dlprefiles="$dlprefiles $lib" ;; esac done if test "$build_libtool_libs" = yes; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework deplibs="$deplibs -framework System" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test "$build_libtool_need_lc" = "yes"; then deplibs="$deplibs -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release="" versuffix="" major="" newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $rm conftest.c cat > conftest.c </dev/null` for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null \ | grep " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib="$potent_lib" while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ | ${SED} 10q \ | $EGREP "$file_magic_regex" > /dev/null; then newdeplibs="$newdeplibs $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes $echo $echo "*** Warning: linker path does not have real file for library $a_deplib." $echo "*** I have the capability to make that library automatically link in when" $echo "*** you link to this library. But I can only do this if you have a" $echo "*** shared version of the library, which you do not appear to have" $echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $echo "*** with $libname but no candidates were found. (...for file magic test)" else $echo "*** with $libname and none of the candidates passed a file format test" $echo "*** using a file magic. Last file checked: $potlib" fi fi else # Add a -L argument. newdeplibs="$newdeplibs $a_deplib" fi done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` for a_deplib in $deplibs; do name=`expr $a_deplib : '-l\(.*\)'` # If $name is empty we are operating on a -L argument. if test -n "$name" && test "$name" != "0"; then if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $a_deplib "*) newdeplibs="$newdeplibs $a_deplib" a_deplib="" ;; esac fi if test -n "$a_deplib" ; then libname=`eval \\$echo \"$libname_spec\"` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib="$potent_lib" # see symlink-check above in file_magic test if eval $echo \"$potent_lib\" 2>/dev/null \ | ${SED} 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then newdeplibs="$newdeplibs $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes $echo $echo "*** Warning: linker path does not have real file for library $a_deplib." $echo "*** I have the capability to make that library automatically link in when" $echo "*** you link to this library. But I can only do this if you have a" $echo "*** shared version of the library, which you do not appear to have" $echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $echo "*** with $libname but no candidates were found. (...for regex pattern test)" else $echo "*** with $libname and none of the candidates passed a file format test" $echo "*** using a regex pattern. Last file checked: $potlib" fi fi else # Add a -L argument. newdeplibs="$newdeplibs $a_deplib" fi done # Gone through all deplibs. ;; none | unknown | *) newdeplibs="" tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ -e 's/ -[LR][^ ]*//g'` if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then for i in $predeps $postdeps ; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"` done fi if $echo "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' \ | grep . >/dev/null; then $echo if test "X$deplibs_check_method" = "Xnone"; then $echo "*** Warning: inter-library dependencies are not supported in this platform." else $echo "*** Warning: inter-library dependencies are not known to be supported." fi $echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes fi ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` ;; esac if test "$droppeddeps" = yes; then if test "$module" = yes; then $echo $echo "*** Warning: libtool could not satisfy all declared inter-library" $echo "*** dependencies of module $libname. Therefore, libtool will create" $echo "*** a static module, that should work as long as the dlopening" $echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then $echo $echo "*** However, this would only work if libtool was able to extract symbol" $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" $echo "*** not find such a program. So, this module is probably useless." $echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else $echo "*** The inter-library dependencies that have been dropped here will be" $echo "*** automatically added whenever a program is linked with this library" $echo "*** or is declared to -dlopen it." if test "$allow_undefined" = no; then $echo $echo "*** Since this library must not contain undefined symbols," $echo "*** because either the platform does not support them or" $echo "*** it was explicitly requested with -no-undefined," $echo "*** libtool will only create a static version of it." if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) new_libs="$new_libs -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$new_libs $deplib" ;; esac ;; *) new_libs="$new_libs $deplib" ;; esac done deplibs="$new_libs" # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test "$build_libtool_libs" = yes; then if test "$hardcode_into_libs" = yes; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath="$finalize_rpath" test "$mode" != relink && rpath="$compile_rpath$rpath" for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" dep_rpath="$dep_rpath $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) perm_rpath="$perm_rpath $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" if test -n "$hardcode_libdir_flag_spec_ld"; then eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" else eval dep_rpath=\"$hardcode_libdir_flag_spec\" fi fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do rpath="$rpath$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath="$finalize_shlibpath" test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names realname="$2" shift; shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname="$realname" fi if test -z "$dlname"; then dlname=$soname fi lib="$output_objdir/$realname" linknames= for link do linknames="$linknames $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` # Prepare the list of exported symbols if test -z "$export_symbols"; then if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then $show "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $run $rm $export_symbols cmds=$export_symbols_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" if len=`expr "X$cmd" : ".*"` && test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then $show "$cmd" $run eval "$cmd" || exit $? skipped_export=false else # The command line is too long to execute in one step. $show "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS="$save_ifs" if test -n "$export_symbols_regex"; then $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' $show "$mv \"${export_symbols}T\" \"$export_symbols\"" $run eval '$mv "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) tmp_deplibs="$tmp_deplibs $test_deplib" ;; esac done deplibs="$tmp_deplibs" if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" else gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_extract_archives $gentop $convenience libobjs="$libobjs $func_extract_archives_result" fi fi if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" linker_flags="$linker_flags $flag" fi # Make a backup of the uninstalled library when relinking if test "$mode" = relink; then $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test "X$skipped_export" != "X:" && len=`expr "X$test_cmds" : ".*" 2>/dev/null` && test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise. $echo "creating reloadable object files..." # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output output_la=`$echo "X$output" | $Xsed -e "$basename"` # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= delfiles= last_robj= k=1 output=$output_objdir/$output_la-${k}.$objext # Loop over the list of objects to be linked. for obj in $save_libobjs do eval test_cmds=\"$reload_cmds $objlist $last_robj\" if test "X$objlist" = X || { len=`expr "X$test_cmds" : ".*" 2>/dev/null` && test "$len" -le "$max_cmd_len"; }; then objlist="$objlist $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test "$k" -eq 1 ; then # The first file doesn't have a previous command to add. eval concat_cmds=\"$reload_cmds $objlist $last_robj\" else # All subsequent reloadable object files will link in # the last one created. eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\" fi last_robj=$output_objdir/$output_la-${k}.$objext k=`expr $k + 1` output=$output_objdir/$output_la-${k}.$objext objlist=$obj len=1 fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" if ${skipped_export-false}; then $show "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $run $rm $export_symbols libobjs=$output # Append the command to create the export file. eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\" fi # Set up a command to remove the reloadable object files # after they are used. i=0 while test "$i" -lt "$k" do i=`expr $i + 1` delfiles="$delfiles $output_objdir/$output_la-${i}.$objext" done $echo "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs="$IFS"; IFS='~' for cmd in $concat_cmds; do IFS="$save_ifs" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi # Append the command to remove the reloadable object files # to the just-reset $cmds. eval cmds=\"\$cmds~\$rm $delfiles\" fi save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$mode" = relink; then $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)' fi exit $lt_exit } done IFS="$save_ifs" # Restore the uninstalled library and exit if test "$mode" = relink; then $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then $show "${rm}r $gentop" $run ${rm}r "$gentop" fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? fi done # If -module or -export-dynamic was specified, set the dlname. if test "$module" = yes || test "$export_dynamic" = yes; then # On all known operating systems, these are identical. dlname="$soname" fi fi ;; obj) if test -n "$deplibs"; then $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 fi if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 fi if test -n "$rpath"; then $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 fi if test -n "$xrpath"; then $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 fi if test -n "$vinfo"; then $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 fi if test -n "$release"; then $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 fi case $output in *.lo) if test -n "$objs$old_deplibs"; then $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 exit $EXIT_FAILURE fi libobj="$output" obj=`$echo "X$output" | $Xsed -e "$lo2o"` ;; *) libobj= obj="$output" ;; esac # Delete the old objects. $run $rm $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # reload_cmds runs $LD directly, so let us get rid of # -Wl from whole_archive_flag_spec wl= if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\" else gentop="$output_objdir/${obj}x" generated="$generated $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # Create the old-style object. reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test output="$obj" cmds=$reload_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then $show "${rm}r $gentop" $run ${rm}r $gentop fi exit $EXIT_SUCCESS fi if test "$build_libtool_libs" != yes; then if test -n "$gentop"; then $show "${rm}r $gentop" $run ${rm}r $gentop fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $run eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS fi if test -n "$pic_flag" || test "$pic_mode" != default; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output="$libobj" cmds=$reload_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" fi if test -n "$gentop"; then $show "${rm}r $gentop" $run ${rm}r $gentop fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; esac if test -n "$vinfo"; then $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 fi if test -n "$release"; then $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 fi if test "$preload" = yes; then if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && test "$dlopen_self_static" = unknown; then $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." fi fi case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` ;; esac case $host in *darwin*) # Don't allow lazy linking, it breaks C++ global constructors if test "$tagname" = CXX ; then compile_command="$compile_command ${wl}-bind_at_load" finalize_command="$finalize_command ${wl}-bind_at_load" fi ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) new_libs="$new_libs -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$new_libs $deplib" ;; esac ;; *) new_libs="$new_libs $deplib" ;; esac done compile_deplibs="$new_libs" compile_command="$compile_command $compile_deplibs" finalize_command="$finalize_command $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" rpath="$rpath $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) perm_rpath="$perm_rpath $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) testbindir=`$echo "X$libdir" | $Xsed -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; *) dllsearchpath="$dllsearchpath:$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; *) dllsearchpath="$dllsearchpath:$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath="$rpath" rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" rpath="$rpath $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath="$rpath" if test -n "$libobjs" && test "$build_old_libs" = yes; then # Transform all the library objects into standard objects. compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` fi dlsyms= if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then if test -n "$NM" && test -n "$global_symbol_pipe"; then dlsyms="${outputname}S.c" else $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 fi fi if test -n "$dlsyms"; then case $dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist="$output_objdir/${outputname}.nm" $show "$rm $nlist ${nlist}S ${nlist}T" $run $rm "$nlist" "${nlist}S" "${nlist}T" # Parse the name list into a source file. $show "creating $output_objdir/$dlsyms" test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ /* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ /* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ #ifdef __cplusplus extern \"C\" { #endif /* Prevent the only kind of declaration conflicts we can make. */ #define lt_preloaded_symbols some_other_symbol /* External symbol declarations for the compiler. */\ " if test "$dlself" = yes; then $show "generating symbol list for \`$output'" test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` for arg in $progfiles; do $show "extracting global C symbols from \`$arg'" $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' $run eval '$mv "$nlist"T "$nlist"' fi if test -n "$export_symbols_regex"; then $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' $run eval '$mv "$nlist"T "$nlist"' fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols="$output_objdir/$outputname.exp" $run $rm $export_symbols $run eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* ) $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' $run eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac else $run eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' $run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' $run eval 'mv "$nlist"T "$nlist"' case $host in *cygwin* | *mingw* ) $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' $run eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac fi fi for arg in $dlprefiles; do $show "extracting global C symbols from \`$arg'" name=`$echo "$arg" | ${SED} -e 's%^.*/%%'` $run eval '$echo ": $name " >> "$nlist"' $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" done if test -z "$run"; then # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $mv "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if grep -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else grep -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' else $echo '/* NONE */' >> "$output_objdir/$dlsyms" fi $echo >> "$output_objdir/$dlsyms" "\ #undef lt_preloaded_symbols #if defined (__STDC__) && __STDC__ # define lt_ptr void * #else # define lt_ptr char * # define const #endif /* The mapping between symbol names and symbols. */ " case $host in *cygwin* | *mingw* ) $echo >> "$output_objdir/$dlsyms" "\ /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs */ struct { " ;; * ) $echo >> "$output_objdir/$dlsyms" "\ const struct { " ;; esac $echo >> "$output_objdir/$dlsyms" "\ const char *name; lt_ptr address; } lt_preloaded_symbols[] = {\ " eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" $echo >> "$output_objdir/$dlsyms" "\ {0, (lt_ptr) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " fi pic_flag_for_symtable= case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) case "$compile_command " in *" -static "*) ;; *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";; esac;; *-*-hpux*) case "$compile_command " in *" -static "*) ;; *) pic_flag_for_symtable=" $pic_flag";; esac esac # Now compile the dynamic symbol file. $show "(cd $output_objdir && $LTCC $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" $run eval '(cd $output_objdir && $LTCC $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? # Clean up the generated files. $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" # Transform the symbol file into the correct name. case $host in *cygwin* | *mingw* ) if test -f "$output_objdir/${outputname}.def" ; then compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%"` finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%"` else compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` fi ;; * ) compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` ;; esac ;; *) $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 exit $EXIT_FAILURE ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` fi if test "$need_relink" = no || test "$build_libtool_libs" != yes; then # Replace the output file specification. compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` link_command="$compile_command$compile_rpath" # We have no uninstalled library dependencies, so finalize right now. $show "$link_command" $run eval "$link_command" exit_status=$? # Delete the generated files. if test -n "$dlsyms"; then $show "$rm $output_objdir/${outputname}S.${objext}" $run $rm "$output_objdir/${outputname}S.${objext}" fi exit $exit_status fi if test -n "$shlibpath_var"; then # We should set the shlibpath_var rpath= for dir in $temp_rpath; do case $dir in [\\/]* | [A-Za-z]:[\\/]*) # Absolute path. rpath="$rpath$dir:" ;; *) # Relative path: add a thisdir entry. rpath="$rpath\$thisdir/$dir:" ;; esac done temp_rpath="$rpath" fi if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do rpath="$rpath$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do rpath="$rpath$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test "$no_install" = yes; then # We don't need to create a wrapper script. link_command="$compile_var$compile_command$compile_rpath" # Replace the output file specification. link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $run $rm $output # Link the executable and exit $show "$link_command" $run eval "$link_command" || exit $? exit $EXIT_SUCCESS fi if test "$hardcode_action" = relink; then # Fast installation is not supported link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 $echo "$modename: \`$output' will be relinked during installation" 1>&2 else if test "$fast_install" != no; then link_command="$finalize_var$compile_command$finalize_rpath" if test "$fast_install" = yes; then relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` else # fast_install is set to needless relink_command= fi else link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" fi fi # Replace the output file specification. link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname $show "$link_command" $run eval "$link_command" || exit $? # Now create the wrapper script. $show "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` relink_command="$var=\"$var_value\"; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` fi # Quote $echo for shipping. if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then case $progpath in [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; esac qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` else qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` fi # Only actually do things if our run command is non-null. if test -z "$run"; then # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) output_name=`basename $output` output_path=`dirname $output` cwrappersource="$output_path/$objdir/lt-$output_name.c" cwrapper="$output_path/$output_name.exe" $rm $cwrappersource $cwrapper trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 cat > $cwrappersource <> $cwrappersource<<"EOF" #include #include #include #include #include #include #include #include #include #if defined(PATH_MAX) # define LT_PATHMAX PATH_MAX #elif defined(MAXPATHLEN) # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ defined (__OS2__) # define HAVE_DOS_BASED_FILE_SYSTEM # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free ((void *) stale); stale = 0; } \ } while (0) /* -DDEBUG is fairly common in CFLAGS. */ #undef DEBUG #if defined DEBUGWRAPPER # define DEBUG(format, ...) fprintf(stderr, format, __VA_ARGS__) #else # define DEBUG(format, ...) #endif const char *program_name = NULL; void * xmalloc (size_t num); char * xstrdup (const char *string); const char * base_name (const char *name); char * find_executable(const char *wrapper); int check_executable(const char *path); char * strendzap(char *str, const char *pat); void lt_fatal (const char *message, ...); int main (int argc, char *argv[]) { char **newargz; int i; program_name = (char *) xstrdup (base_name (argv[0])); DEBUG("(main) argv[0] : %s\n",argv[0]); DEBUG("(main) program_name : %s\n",program_name); newargz = XMALLOC(char *, argc+2); EOF cat >> $cwrappersource <> $cwrappersource <<"EOF" newargz[1] = find_executable(argv[0]); if (newargz[1] == NULL) lt_fatal("Couldn't find %s", argv[0]); DEBUG("(main) found exe at : %s\n",newargz[1]); /* we know the script has the same name, without the .exe */ /* so make sure newargz[1] doesn't end in .exe */ strendzap(newargz[1],".exe"); for (i = 1; i < argc; i++) newargz[i+1] = xstrdup(argv[i]); newargz[argc+1] = NULL; for (i=0; i> $cwrappersource <> $cwrappersource <> $cwrappersource <<"EOF" return 127; } void * xmalloc (size_t num) { void * p = (void *) malloc (num); if (!p) lt_fatal ("Memory exhausted"); return p; } char * xstrdup (const char *string) { return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL ; } const char * base_name (const char *name) { const char *base; #if defined (HAVE_DOS_BASED_FILE_SYSTEM) /* Skip over the disk name in MSDOS pathnames. */ if (isalpha ((unsigned char)name[0]) && name[1] == ':') name += 2; #endif for (base = name; *name; name++) if (IS_DIR_SEPARATOR (*name)) base = name + 1; return base; } int check_executable(const char * path) { struct stat st; DEBUG("(check_executable) : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!"); if ((!path) || (!*path)) return 0; if ((stat (path, &st) >= 0) && ( /* MinGW & native WIN32 do not support S_IXOTH or S_IXGRP */ #if defined (S_IXOTH) ((st.st_mode & S_IXOTH) == S_IXOTH) || #endif #if defined (S_IXGRP) ((st.st_mode & S_IXGRP) == S_IXGRP) || #endif ((st.st_mode & S_IXUSR) == S_IXUSR)) ) return 1; else return 0; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise */ char * find_executable (const char* wrapper) { int has_slash = 0; const char* p; const char* p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; int tmp_len; char* concat_name; DEBUG("(find_executable) : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!"); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined (HAVE_DOS_BASED_FILE_SYSTEM) if (isalpha ((unsigned char)wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable(concat_name)) return concat_name; XFREE(concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable(concat_name)) return concat_name; XFREE(concat_name); } #if defined (HAVE_DOS_BASED_FILE_SYSTEM) } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char* path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char* q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR(*q)) break; p_len = q - p; p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal ("getcwd failed"); tmp_len = strlen(tmp); concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC(char, p_len + 1 + strlen(wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable(concat_name)) return concat_name; XFREE(concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal ("getcwd failed"); tmp_len = strlen(tmp); concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable(concat_name)) return concat_name; XFREE(concat_name); return NULL; } char * strendzap(char *str, const char *pat) { size_t len, patlen; assert(str != NULL); assert(pat != NULL); len = strlen(str); patlen = strlen(pat); if (patlen <= len) { str += len - patlen; if (strcmp(str, pat) == 0) *str = '\0'; } return str; } static void lt_error_core (int exit_status, const char * mode, const char * message, va_list ap) { fprintf (stderr, "%s: %s: ", program_name, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, "FATAL", message, ap); va_end (ap); } EOF # we should really use a build-platform specific compiler # here, but OTOH, the wrappers (shell script and this C one) # are only useful if you want to execute the "real" binary. # Since the "real" binary is built for $host, then this # wrapper might as well be built for $host, too. $run $LTCC $LTCFLAGS -s -o $cwrapper $cwrappersource ;; esac $rm $output trap "$rm $output; exit $EXIT_FAILURE" 1 2 15 $echo > $output "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed='${SED} -e 1s/^X//' sed_quote_subst='$sed_quote_subst' # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variable: notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$echo are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then echo=\"$qecho\" file=\"\$0\" # Make sure echo works. if test \"X\$1\" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then # Yippee, \$echo works! : else # Restart under the correct shell, and then maybe \$echo will work. exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} fi fi\ " $echo >> $output "\ # Find the directory that this script lives in. thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` done # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test "$fast_install" = yes; then $echo >> $output "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || \\ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $mkdir \"\$progdir\" else $rm \"\$progdir/\$file\" fi" $echo >> $output "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else $echo \"\$relink_command_output\" >&2 $rm \"\$progdir/\$file\" exit $EXIT_FAILURE fi fi $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $rm \"\$progdir/\$program\"; $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } $rm \"\$progdir/\$file\" fi" else $echo >> $output "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $echo >> $output "\ if test -f \"\$progdir/\$program\"; then" # Export our shlibpath_var if we have one. if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $echo >> $output "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` export $shlibpath_var " fi # fixup the dll searchpath if we need to. if test -n "$dllsearchpath"; then $echo >> $output "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi $echo >> $output "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2*) $echo >> $output "\ exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $echo >> $output "\ exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $echo >> $output "\ \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" exit $EXIT_FAILURE fi else # The program doesn't exist. \$echo \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 \$echo \"This script is just a wrapper for \$program.\" 1>&2 $echo \"See the $PACKAGE documentation for more information.\" 1>&2 exit $EXIT_FAILURE fi fi\ " chmod +x $output fi exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do if test "$build_libtool_libs" = convenience; then oldobjs="$libobjs_save" addlibs="$convenience" build_libtool_libs=no else if test "$build_libtool_libs" = module; then oldobjs="$libobjs_save" build_libtool_libs=no else oldobjs="$old_deplibs $non_pic_objects" fi addlibs="$old_convenience" fi if test -n "$addlibs"; then gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_extract_archives $gentop $addlibs oldobjs="$oldobjs $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then cmds=$old_archive_from_new_cmds else # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do $echo "X$obj" | $Xsed -e 's%^.*/%%' done | sort | sort -uc >/dev/null 2>&1); then : else $echo "copying selected object files to avoid basename conflicts..." if test -z "$gentop"; then gentop="$output_objdir/${outputname}x" generated="$generated $gentop" $show "${rm}r $gentop" $run ${rm}r "$gentop" $show "$mkdir $gentop" $run $mkdir "$gentop" exit_status=$? if test "$exit_status" -ne 0 && test ! -d "$gentop"; then exit $exit_status fi fi save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do objbase=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase counter=`expr $counter + 1` case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done $show "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" $run ln "$obj" "$gentop/$newobj" || $run cp "$obj" "$gentop/$newobj" oldobjs="$oldobjs $gentop/$newobj" ;; *) oldobjs="$oldobjs $obj" ;; esac done fi eval cmds=\"$old_archive_cmds\" if len=`expr "X$cmds" : ".*"` && test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts $echo "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done for obj in $save_oldobjs do oldobjs="$objlist $obj" objlist="$objlist $obj" eval test_cmds=\"$old_archive_cmds\" if len=`expr "X$test_cmds" : ".*" 2>/dev/null` && test "$len" -le "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj" ; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" objlist= fi done RANLIB=$save_RANLIB oldobjs=$objlist if test "X$oldobjs" = "X" ; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi save_ifs="$IFS"; IFS='~' for cmd in $cmds; do eval cmd=\"$cmd\" IFS="$save_ifs" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" done if test -n "$generated"; then $show "${rm}r$generated" $run ${rm}r$generated fi # Now create the libtool archive. case $output in *.la) old_library= test "$build_old_libs" = yes && old_library="$libname.$libext" $show "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` relink_command="$var=\"$var_value\"; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` if test "$hardcode_automatic" = yes ; then relink_command= fi # Only create the output if not a dry run. if test -z "$run"; then for installed in no yes; do if test "$installed" = yes; then if test -z "$install_libdir"; then break fi output="$output_objdir/$outputname"i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` if test -z "$libdir"; then $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 exit $EXIT_FAILURE fi newdependency_libs="$newdependency_libs $libdir/$name" ;; *) newdependency_libs="$newdependency_libs $deplib" ;; esac done dependency_libs="$newdependency_libs" newdlfiles= for lib in $dlfiles; do name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` if test -z "$libdir"; then $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 exit $EXIT_FAILURE fi newdlfiles="$newdlfiles $libdir/$name" done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` if test -z "$libdir"; then $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 exit $EXIT_FAILURE fi newdlprefiles="$newdlprefiles $libdir/$name" done dlprefiles="$newdlprefiles" else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac newdlfiles="$newdlfiles $abs" done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac newdlprefiles="$newdlprefiles $abs" done dlprefiles="$newdlprefiles" fi $rm $output # place dlname in correct position for cygwin tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; esac $echo > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test "$installed" = no && test "$need_relink" = yes; then $echo >> $output "\ relink_command=\"$relink_command\"" fi done fi # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? ;; esac exit $EXIT_SUCCESS ;; # libtool install mode install) modename="$modename: install" # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || # Allow the use of GNU shtool's install command. $echo "X$nonopt" | grep shtool > /dev/null; then # Aesthetically quote it. arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` case $arg in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") arg="\"$arg\"" ;; esac install_prog="$arg " arg="$1" shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` case $arg in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") arg="\"$arg\"" ;; esac install_prog="$install_prog$arg" # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=no stripme= for arg do if test -n "$dest"; then files="$files $dest" dest=$arg continue fi case $arg in -d) isdir=yes ;; -f) case " $install_prog " in *[\\\ /]cp\ *) ;; *) prev=$arg ;; esac ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` case $arg in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") arg="\"$arg\"" ;; esac install_prog="$install_prog $arg" done if test -z "$install_prog"; then $echo "$modename: you must specify an install program" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi if test -n "$prev"; then $echo "$modename: the \`$prev' option requires an argument" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi if test -z "$files"; then if test -z "$dest"; then $echo "$modename: no file or destination specified" 1>&2 else $echo "$modename: you must specify a destination" 1>&2 fi $echo "$help" 1>&2 exit $EXIT_FAILURE fi # Strip any trailing slash from the destination. dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` # Check to see that the destination is a directory. test -d "$dest" && isdir=yes if test "$isdir" = yes; then destdir="$dest" destname= else destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` test "X$destdir" = "X$dest" && destdir=. destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` # Not a directory, so check to see that there is only one file specified. set dummy $files if test "$#" -gt 2; then $echo "$modename: \`$dest' is not a directory" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. staticlibs="$staticlibs $file" ;; *.la) # Check to see that this really is a libtool archive. if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : else $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi library_names= old_library= relink_command= # If there is no directory component, then add one. case $file in */* | *\\*) . $file ;; *) . ./$file ;; esac # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) current_libdirs="$current_libdirs $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) future_libdirs="$future_libdirs $libdir" ;; esac fi dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ test "X$dir" = "X$file/" && dir= dir="$dir$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. if test "$inst_prefix_dir" = "$destdir"; then $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2 exit $EXIT_FAILURE fi if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi $echo "$modename: warning: relinking \`$file'" 1>&2 $show "$relink_command" if $run eval "$relink_command"; then : else $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 exit $EXIT_FAILURE fi fi # See the names of the shared library. set dummy $library_names if test -n "$2"; then realname="$2" shift shift srcname="$realname" test -n "$relink_command" && srcname="$realname"T # Install the shared library and build the symlinks. $show "$install_prog $dir/$srcname $destdir/$realname" $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? if test -n "$stripme" && test -n "$striplib"; then $show "$striplib $destdir/$realname" $run eval "$striplib $destdir/$realname" || exit $? fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try `ln -sf' first, because the `ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do if test "$linkname" != "$realname"; then $show "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })" $run eval "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })" fi done fi # Do each command in the postinstall commands. lib="$destdir/$realname" cmds=$postinstall_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$mode" = relink; then $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)' fi exit $lt_exit } done IFS="$save_ifs" fi # Install the pseudo-library for information purposes. name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` instname="$dir/$name"i $show "$install_prog $instname $destdir/$name" $run eval "$install_prog $instname $destdir/$name" || exit $? # Maybe install the static library, too. test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` destfile="$destdir/$destfile" fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` ;; *.$objext) staticdest="$destfile" destfile= ;; *) $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE ;; esac # Install the libtool object if requested. if test -n "$destfile"; then $show "$install_prog $file $destfile" $run eval "$install_prog $file $destfile" || exit $? fi # Install the old object if enabled. if test "$build_old_libs" = yes; then # Deduce the name of the old-style object file. staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` $show "$install_prog $staticobj $staticdest" $run eval "$install_prog \$staticobj \$staticdest" || exit $? fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` destfile="$destdir/$destfile" fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext="" case $file in *.exe) if test ! -f "$file"; then file=`$echo $file|${SED} 's,.exe$,,'` stripped_ext=".exe" fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin*|*mingw*) wrapper=`$echo $file | ${SED} -e 's,.exe$,,'` ;; *) wrapper=$file ;; esac if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then notinst_deplibs= relink_command= # Note that it is not necessary on cygwin/mingw to append a dot to # foo even if both foo and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # `FILE.' does not work on cygwin managed mounts. # # If there is no directory component, then add one. case $wrapper in */* | *\\*) . ${wrapper} ;; *) . ./${wrapper} ;; esac # Check the variables that should have been set. if test -z "$notinst_deplibs"; then $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 exit $EXIT_FAILURE fi finalize=yes for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then # If there is no directory component, then add one. case $lib in */* | *\\*) . $lib ;; *) . ./$lib ;; esac fi libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test if test -n "$libdir" && test ! -f "$libfile"; then $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 finalize=no fi done relink_command= # Note that it is not necessary on cygwin/mingw to append a dot to # foo even if both foo and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # `FILE.' does not work on cygwin managed mounts. # # If there is no directory component, then add one. case $wrapper in */* | *\\*) . ${wrapper} ;; *) . ./${wrapper} ;; esac outputname= if test "$fast_install" = no && test -n "$relink_command"; then if test "$finalize" = yes && test -z "$run"; then tmpdir=`func_mktempdir` file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'` outputname="$tmpdir/$file" # Replace the output file specification. relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` $show "$relink_command" if $run eval "$relink_command"; then : else $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 ${rm}r "$tmpdir" continue fi file="$outputname" else $echo "$modename: warning: cannot relink \`$file'" 1>&2 fi else # Install the binary that we compiled earlier. file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'` ;; esac ;; esac $show "$install_prog$stripme $file $destfile" $run eval "$install_prog\$stripme \$file \$destfile" || exit $? test -n "$outputname" && ${rm}r "$tmpdir" ;; esac done for file in $staticlibs; do name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` # Set up the ranlib parameters. oldlib="$destdir/$name" $show "$install_prog $file $oldlib" $run eval "$install_prog \$file \$oldlib" || exit $? if test -n "$stripme" && test -n "$old_striplib"; then $show "$old_striplib $oldlib" $run eval "$old_striplib $oldlib" || exit $? fi # Do each command in the postinstall commands. cmds=$old_postinstall_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" done if test -n "$future_libdirs"; then $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 fi if test -n "$current_libdirs"; then # Maybe just do a dry run. test -n "$run" && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi ;; # libtool finish mode finish) modename="$modename: finish" libdirs="$nonopt" admincmds= if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for dir do libdirs="$libdirs $dir" done for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. cmds=$finish_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || admincmds="$admincmds $cmd" done IFS="$save_ifs" fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $run eval "$cmds" || admincmds="$admincmds $cmds" fi done fi # Exit here if they wanted silent mode. test "$show" = : && exit $EXIT_SUCCESS $echo "X----------------------------------------------------------------------" | $Xsed $echo "Libraries have been installed in:" for libdir in $libdirs; do $echo " $libdir" done $echo $echo "If you ever happen to want to link against installed libraries" $echo "in a given directory, LIBDIR, you must either use libtool, and" $echo "specify the full pathname of the library, or use the \`-LLIBDIR'" $echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then $echo " - add LIBDIR to the \`$shlibpath_var' environment variable" $echo " during execution" fi if test -n "$runpath_var"; then $echo " - add LIBDIR to the \`$runpath_var' environment variable" $echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $echo " - use the \`$flag' linker flag" fi if test -n "$admincmds"; then $echo " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then $echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" fi $echo $echo "See any operating system documentation about shared libraries for" $echo "more information, such as the ld(1) and ld.so(8) manual pages." $echo "X----------------------------------------------------------------------" | $Xsed exit $EXIT_SUCCESS ;; # libtool execute mode execute) modename="$modename: execute" # The first argument is the command name. cmd="$nonopt" if test -z "$cmd"; then $echo "$modename: you must specify a COMMAND" 1>&2 $echo "$help" exit $EXIT_FAILURE fi # Handle -dlopen flags immediately. for file in $execute_dlfiles; do if test ! -f "$file"; then $echo "$modename: \`$file' is not a file" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi dir= case $file in *.la) # Check to see that this really is a libtool archive. if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : else $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi # Read the libtool library. dlname= library_names= # If there is no directory component, then add one. case $file in */* | *\\*) . $file ;; *) . ./$file ;; esac # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" continue fi dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` test "X$dir" = "X$file" && dir=. if test -f "$dir/$objdir/$dlname"; then dir="$dir/$objdir" else $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 exit $EXIT_FAILURE fi ;; *.lo) # Just add the directory containing the .lo file. dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` test "X$dir" = "X$file" && dir=. ;; *) $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir="$absdir" # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic="$magic" # Check if any of the arguments is a wrapper script. args= for file do case $file in -*) ;; *) # Do a test to see if this is really a libtool program. if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then # If there is no directory component, then add one. case $file in */* | *\\*) . $file ;; *) . ./$file ;; esac # Transform arg to wrapped name. file="$progdir/$program" fi ;; esac # Quote arguments (to preserve shell metacharacters). file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` args="$args \"$file\"" done if test -z "$run"; then if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables if test "${save_LC_ALL+set}" = set; then LC_ALL="$save_LC_ALL"; export LC_ALL fi if test "${save_LANG+set}" = set; then LANG="$save_LANG"; export LANG fi # Now prepare to actually exec the command. exec_cmd="\$cmd$args" else # Display what would be done. if test -n "$shlibpath_var"; then eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" $echo "export $shlibpath_var" fi $echo "$cmd$args" exit $EXIT_SUCCESS fi ;; # libtool clean and uninstall mode clean | uninstall) modename="$modename: $mode" rm="$nonopt" files= rmforce= exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" for arg do case $arg in -f) rm="$rm $arg"; rmforce=yes ;; -*) rm="$rm $arg" ;; *) files="$files $arg" ;; esac done if test -z "$rm"; then $echo "$modename: you must specify an RM program" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi rmdirs= origobjdir="$objdir" for file in $files; do dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` if test "X$dir" = "X$file"; then dir=. objdir="$origobjdir" else objdir="$dir/$origobjdir" fi name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` test "$mode" = uninstall && objdir="$dir" # Remember objdir for removal later, being careful to avoid duplicates if test "$mode" = clean; then case " $rmdirs " in *" $objdir "*) ;; *) rmdirs="$rmdirs $objdir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if (test -L "$file") >/dev/null 2>&1 \ || (test -h "$file") >/dev/null 2>&1 \ || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif test "$rmforce" = yes; then continue fi rmfiles="$file" case $name in *.la) # Possibly a libtool archive, so verify it. if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then . $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do rmfiles="$rmfiles $objdir/$n" done test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" case "$mode" in clean) case " $library_names " in # " " in the beginning catches empty $dlname *" $dlname "*) ;; *) rmfiles="$rmfiles $objdir/$dlname" ;; esac test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. cmds=$postuninstall_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" if test "$?" -ne 0 && test "$rmforce" != yes; then exit_status=1 fi done IFS="$save_ifs" fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. cmds=$old_postuninstall_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" if test "$?" -ne 0 && test "$rmforce" != yes; then exit_status=1 fi done IFS="$save_ifs" fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then # Read the .lo file . $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" \ && test "$pic_object" != none; then rmfiles="$rmfiles $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" \ && test "$non_pic_object" != none; then rmfiles="$rmfiles $dir/$non_pic_object" fi fi ;; *) if test "$mode" = clean ; then noexename=$name case $file in *.exe) file=`$echo $file|${SED} 's,.exe$,,'` noexename=`$echo $name|${SED} 's,.exe$,,'` # $file with .exe has already been added to rmfiles, # add $file without .exe rmfiles="$rmfiles $file" ;; esac # Do a test to see if this is a libtool program. if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then relink_command= . $dir/$noexename # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" if test "$fast_install" = yes && test -n "$relink_command"; then rmfiles="$rmfiles $objdir/lt-$name" fi if test "X$noexename" != "X$name" ; then rmfiles="$rmfiles $objdir/lt-${noexename}.c" fi fi fi ;; esac $show "$rm $rmfiles" $run $rm $rmfiles || exit_status=1 done objdir="$origobjdir" # Try to remove the ${objdir}s in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then $show "rmdir $dir" $run rmdir $dir >/dev/null 2>&1 fi done exit $exit_status ;; "") $echo "$modename: you must specify a MODE" 1>&2 $echo "$generic_help" 1>&2 exit $EXIT_FAILURE ;; esac if test -z "$exec_cmd"; then $echo "$modename: invalid operation mode \`$mode'" 1>&2 $echo "$generic_help" 1>&2 exit $EXIT_FAILURE fi fi # test -z "$show_help" if test -n "$exec_cmd"; then eval exec $exec_cmd exit $EXIT_FAILURE fi # We need to display help for each of the modes. case $mode in "") $echo \ "Usage: $modename [OPTION]... [MODE-ARG]... Provide generalized library-building support services. --config show all configuration variables --debug enable verbose shell tracing -n, --dry-run display commands without modifying any files --features display basic configuration information and exit --finish same as \`--mode=finish' --help display this help message and exit --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] --quiet same as \`--silent' --silent don't print informational messages --tag=TAG use configuration variables from tag TAG --version print version information MODE must be one of the following: clean remove files from the build directory compile compile a source file into a libtool object execute automatically set library path, then run a program finish complete the installation of libtool libraries install install libraries or executables link create a library or an executable uninstall remove libraries from an installed directory MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for a more detailed description of MODE. Report bugs to ." exit $EXIT_SUCCESS ;; clean) $echo \ "Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $echo \ "Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -prefer-pic try to building PIC objects only -prefer-non-pic try to building non-PIC objects only -static always build a \`.o' file suitable for static linking COMPILE-COMMAND is a command to be used in creating a \`standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix \`.c' with the library object suffix, \`.lo'." ;; execute) $echo \ "Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to \`-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $echo \ "Usage: $modename [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the \`--dry-run' option if you just want to see what would be executed." ;; install) $echo \ "Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the \`install' or \`cp' program. The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $echo \ "Usage: $modename [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE Use a list of object files found in FILE to specify objects -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -static do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] All other options (arguments beginning with \`-') are ignored. Every other argument is treated as a filename. Files ending in \`.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only library objects (\`.lo' files) may be specified, and \`-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created using \`ar' and \`ranlib', or on Windows using \`lib'. If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $echo \ "Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) $echo "$modename: invalid operation mode \`$mode'" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE ;; esac $echo $echo "Try \`$modename --help' for more information about other modes." exit $? # The TAGs below are defined such that we never get into a situation # in which we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared disable_libs=shared # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static disable_libs=static # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: malaga-7.12/install-sh0000755000175000017500000001435010235644266014224 0ustar bjoernbjoern#!/bin/sh # # install - install a program, script, or datafile # # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else : fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: chmodcmd="" else instcmd=$mkdirprog fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f "$src" ] || [ -d "$src" ] then : else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else : fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else : fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else : fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else : fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 malaga-7.12/Makefile.in0000644000175000017500000003067110761577635014302 0ustar bjoernbjoern# Copyright (C) 1995 Bjoern Beutel. # Compilation rules for Malaga. =============================================== # Always use POSIX shell. SHELL = /bin/sh # Support object files for different architectures in different directories. VPATH = @srcdir@ srcdir = @srcdir@ # The directories where files will be installed. prefix = @prefix@ exec_prefix = @exec_prefix@ datarootdir = @datarootdir@ bindir = ${DESTDIR}@bindir@ libdir = ${DESTDIR}@libdir@ includedir = ${DESTDIR}@includedir@ infodir = ${DESTDIR}@infodir@ datadir = ${DESTDIR}@datadir@ mandir = ${DESTDIR}@mandir@ man1dir = $(mandir)/man1 # How to install a program or data. INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_DIR = ${INSTALL} -d # How to update the "dir" entry in an info directory. INSTALL_INFO = install-info # How to compile a C source file. COMPILE = @CC@ -c @CFLAGS@ @GCCFLAGS@ @SYS_CFLAGS@ # How to link an executable. LINK = @CC@ @LDFLAGS@ # "libtool" helps to compile and link libraries. LIBTOOL = ./libtool --silent # How to create a DVI file from a Texinfo file. TEXI2DVI = texi2dvi # How to create an Info file from a Texinfo file. MAKEINFO = makeinfo # How to configure for GTK+. GTK_LIBS = @GTK_LIBS@ GTK_CFLAGS = @GTK_CFLAGS@ # How to configure for GLib only. GLIB_LIBS = @GLIB_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ READLINE_LIBS = @READLINE_LIBS@ READLINE_CFLAGS = @READLINE_CFLAGS@ # The malaga binaries, the library and the header file. MALSHOW = @MALSHOW@ MALAGA_BIN = malaga mallex malmake malrul $(MALSHOW) malsym # Every binary has a manual page. MALAGA_MAN1 = $(MALAGA_BIN:=.1) # The current version of libmalaga for libtool. # Keep this in synchronisation with the versioning numbers in "malaga.h". LIBMALAGA_VERSION = 7:0:0 # The names of the current distribution. DIST = malaga-7.12 # Implicit rules. ------------------------------------------------------------- .SUFFIXES: .SUFFIXES: .o .c .c.o: @echo "Compiling $<" @$(COMPILE) $(GLIB_CFLAGS) $(READLINE_CFLAGS) $< # Primary goals. -------------------------------------------------------------- all: malaga.h malaga.el libmalaga.la $(MALAGA_BIN) clean: rm -rf *.o *.lo *.tgz libmalaga.la $(MALAGA_BIN) maldump .libs $(DIST) dvi: malaga.dvi html: malaga.html ps: malaga.ps pdf: malaga.pdf info: malaga.info install: all info $(INSTALL_DIR) $(bindir) for f in $(MALAGA_BIN); do \ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) -s $$f $(bindir)/$$f; \ done $(INSTALL_DIR) $(includedir) $(INSTALL_DATA) $(srcdir)/malaga.h $(includedir)/malaga.h $(INSTALL_DIR) $(libdir) $(LIBTOOL) --mode=install $(INSTALL_DATA) -s libmalaga.la \ $(libdir)/libmalaga.la $(INSTALL_DIR) $(datadir)/malaga $(INSTALL_DATA) $(srcdir)/malaga.el $(datadir)/malaga/malaga.el $(INSTALL_DIR) $(man1dir) for f in $(MALAGA_MAN1); do \ $(INSTALL_DATA) $(srcdir)/$$f $(man1dir)/$$f; done $(INSTALL_DIR) $(infodir) for f in malaga.info*; do $(INSTALL_DATA) $$f $(infodir)/$$f; done $(INSTALL_INFO) --info-dir=$(infodir) malaga.info uninstall: for f in $(MALAGA_BIN); do rm -f $(bindir)/$$f; done rm -f $(includedir)/malaga.h rm -Rf $(datadir)/malaga $(LIBTOOL) --mode=uninstall rm -f $(libdir)/libmalaga.la for f in $(MALAGA_MAN1) ; do rm -f $(man1dir)/$$f; done $(INSTALL_INFO) --remove --info-dir=$(infodir) malaga.info rm -f $(infodir)/malaga.info* # Private goals for the maintainer. ------------------------------------------- dist: configure info rm -rf $(DIST) $(DIST).tgz mkdir $(DIST) cp -p $(srcdir)/configure $(DIST) cp -p $(srcdir)/configure.in $(DIST) cp -p $(srcdir)/config.guess $(DIST) cp -p $(srcdir)/config.sub $(DIST) cp -p $(srcdir)/ltmain.sh $(DIST) cp -p $(srcdir)/install-sh $(DIST) cp -p $(srcdir)/Makefile.in $(DIST) cp -p $(srcdir)/*.[ch1] $(DIST) cp -p $(srcdir)/*.{txt,texi} $(DIST) cp -p malaga.info* $(DIST) cp -p $(srcdir)/malaga.el $(DIST) mkdir $(DIST)/grammars cp -rp $(srcdir)/grammars/german $(DIST)/grammars cd $(DIST)/grammars/german; rm -f .\#* \#* *~ *_[bcl] *.out cp -rp $(srcdir)/grammars/formal $(DIST)/grammars cd $(DIST)/grammars/formal; rm -f .\#* \#* *~ *_[bcl] *.out cp -rp $(srcdir)/grammars/numeral $(DIST)/grammars cd $(DIST)/grammars/numeral; rm -f .\#* \#* *~ *_[bcl] *.out tar zcf $(DIST).tgz $(DIST) rm -rf $(DIST) # malaga.dvi, malaga.info, malaga.html, malaga.ps, malaga.pdf ----------------- malaga.dvi: malaga.texi $(TEXI2DVI) $(srcdir)/malaga.texi malaga.info: malaga.texi $(MAKEINFO) $(srcdir)/malaga.texi malaga.html: malaga.texi $(MAKEINFO) --html --output=malaga.html --number-sections \ --no-headers --no-split $(srcdir)/malaga.texi malaga.ps: malaga.dvi dvips malaga.dvi malaga.pdf: malaga.dvi dvipdfm malaga.dvi # libmalaga ------------------------------------------------------------------- COMMON_OBJS = analysis.o avl_trees.o basic.o cache.o commands.o display.o \ files.o hangul.o input.o lexicon.o malaga_files.o malaga_lib.o \ options.o patterns.o pools.o processes.o rules.o scanner.o \ symbols.o transmit.o tries.o value_parser.o values.o LIBMALAGA_OBJS = $(COMMON_OBJS) libmalaga.o $(LIBMALAGA_OBJS): @echo "Compiling $<" @$(LIBTOOL) --mode=compile $(COMPILE) $(GLIB_CFLAGS) $(srcdir)/$*.c libmalaga.la: $(LIBMALAGA_OBJS) @echo "Linking libmalaga" @$(LIBTOOL) --mode=link $(LINK) $(LIBMALAGA_OBJS:.o=.lo) $(GLIB_LIBS) \ -lm -o libmalaga.la -version-info $(LIBMALAGA_VERSION) \ -rpath @libdir@ # malaga ---------------------------------------------------------------------- MALAGA_OBJS = commands_interactive.o breakpoints.o debugger.o generation.o \ malaga.o malaga: $(MALAGA_OBJS) libmalaga.la @echo "Linking malaga" @$(LIBTOOL) --mode=link $(LINK) $(MALAGA_OBJS) $(GLIB_LIBS) \ $(READLINE_LIBS) -lm libmalaga.la -o malaga # maldump --------------------------------------------------------------------- maldump: maldump.o libmalaga.la @echo "Linking maldump" @$(LIBTOOL) --mode=link $(LINK) maldump.o $(GLIB_LIBS) -lm \ libmalaga.la -o maldump # mallex ---------------------------------------------------------------------- MALLEX_OBJS = breakpoints.o commands_interactive.o debugger.o lex_compiler.o \ mallex.o mallex: $(MALLEX_OBJS) libmalaga.la @echo "Linking mallex" @$(LIBTOOL) --mode=link $(LINK) $(MALLEX_OBJS) $(GLIB_LIBS) \ $(READLINE_LIBS) -lm libmalaga.la -o mallex # malmake --------------------------------------------------------------------- malmake: malmake.o libmalaga.la @echo "Linking malmake" @$(LIBTOOL) --mode=link $(LINK) malmake.o $(GLIB_LIBS) libmalaga.la \ -o malmake # malrul ---------------------------------------------------------------------- MALRUL_OBJS = malrul.o rule_code.o rule_compiler.o rule_parser.o \ rule_symbols.o malrul: $(MALRUL_OBJS) libmalaga.la @echo "Linking malrul" @$(LIBTOOL) --mode=link $(LINK) $(MALRUL_OBJS) $(GLIB_LIBS) \ libmalaga.la -o malrul # malshow --------------------------------------------------------------------- MALSHOW_OBJS = allomorphs.o canvas.o expressions.o malshow.o result.o tree.o \ variables.o $(MALSHOW_OBJS): @echo "Compiling $<" @$(COMPILE) $(GTK_CFLAGS) $(srcdir)/$*.c malshow: $(MALSHOW_OBJS) libmalaga.la @echo "Linking malshow" @$(LIBTOOL) --mode=link $(LINK) $(MALSHOW_OBJS) $(GTK_LIBS) \ libmalaga.la -o malshow # malsym ---------------------------------------------------------------------- MALSYM_OBJS = malsym.o sym_compiler.o malsym: $(MALSYM_OBJS) libmalaga.la @echo "Linking malsym" @$(LIBTOOL) --mode=link $(LINK) $(MALSYM_OBJS) $(GLIB_LIBS) \ libmalaga.la -o malsym #============================================================================== # The dependencies are created by "gcc -MM *.c `pkg-config gtk+-2.0 --cflags`. allomorphs.o: allomorphs.c basic.h scanner.h input.h canvas.h \ allomorphs.h analysis.o: analysis.c basic.h pools.h values.h rule_type.h rules.h \ lexicon.h cache.h analysis.h avl_trees.o: avl_trees.c basic.h avl_trees.h basic.o: basic.c basic.h breakpoints.o: breakpoints.c basic.h pools.h values.h files.h \ rule_type.h rules.h input.h commands.h breakpoints.h cache.o: cache.c basic.h pools.h values.h avl_trees.h cache.h canvas.o: canvas.c basic.h scanner.h input.h files.h canvas.h commands.o: commands.c basic.h input.h files.h commands.h commands_interactive.o: basic.h commands.h commands_interactive.c \ commands_interactive.h debugger.o: debugger.c basic.h pools.h values.h symbols.h files.h \ input.h commands.h commands_interactive.h options.h rule_type.h rules.h \ display.h breakpoints.h value_parser.h scanner.h debugger.h display.o: display.c basic.h files.h input.h commands.h processes.h \ display.h expressions.o: expressions.c basic.h scanner.h input.h canvas.h \ expressions.h files.o: files.c basic.h files.h generation.o: generation.c basic.h pools.h values.h input.h commands.h \ rule_type.h rules.h lexicon.h analysis.h debugger.h hangul.h \ generation.h hangul.o: hangul.c basic.h pools.h tries.h hangul.h input.o: input.c basic.h files.h input.h lex_compiler.o: lex_compiler.c basic.h pools.h values.h tries.h \ rule_type.h rules.h scanner.h files.h malaga_files.h symbols.h \ input.h commands.h avl_trees.h options.h hangul.h lex_compiler.h lexicon.o: lexicon.c basic.h pools.h values.h tries.h files.h \ malaga_files.h lexicon.h libmalaga.o: libmalaga.c basic.h pools.h values.h symbols.h files.h \ rule_type.h rules.h analysis.h input.h commands.h options.h \ malaga_lib.h hangul.h scanner.h value_parser.h libmalaga.h malaga.o: malaga.c basic.h pools.h values.h symbols.h files.h \ rule_type.h rules.h analysis.h input.h commands.h commands_interactive.h \ options.h display.h malaga_lib.h generation.h debugger.h breakpoints.h \ cache.h transmit.h hangul.h malaga_files.o: malaga_files.c basic.h files.h malaga_files.h malaga_lib.o: malaga_lib.c basic.h pools.h values.h input.h commands.h \ options.h rule_type.h rules.h files.h analysis.h cache.h symbols.h \ lexicon.h transmit.h display.h scanner.h patterns.h hangul.h \ malaga_lib.h maldump.o: maldump.c basic.h pools.h values.h symbols.h files.h \ rule_type.h rules.h patterns.h hangul.h mallex.o: mallex.c basic.h pools.h values.h symbols.h scanner.h \ rule_type.h rules.h files.h lex_compiler.h input.h commands.h \ commands_interactive.h options.h breakpoints.h debugger.h display.h \ transmit.h patterns.h hangul.h malmake.o: malmake.c basic.h files.h malaga_files.h input.h malrul.o: malrul.c basic.h pools.h values.h symbols.h scanner.h \ files.h rule_type.h rule_code.h rule_compiler.h patterns.h hangul.h malshow.o: malshow.c basic.h input.h scanner.h files.h canvas.h \ allomorphs.h expressions.h result.h tree.h variables.h malsym.o: malsym.c basic.h pools.h values.h scanner.h files.h \ sym_compiler.h options.o: options.c basic.h pools.h values.h symbols.h input.h \ commands.h rule_type.h rules.h value_parser.h hangul.h scanner.h \ options.h patterns.o: patterns.c basic.h patterns.h pools.o: pools.c basic.h files.h pools.h processes.o: processes.c basic.h files.h input.h processes.h result.o: result.c basic.h scanner.h input.h canvas.h result.h rule_code.o: rule_code.c basic.h pools.h values.h symbols.h \ rule_type.h files.h malaga_files.h rule_code.h rule_compiler.o: rule_compiler.c basic.h pools.h values.h scanner.h \ rule_type.h rule_code.h rule_parser.h rule_symbols.h files.h \ rule_compiler.h rule_parser.o: rule_parser.c basic.h pools.h values.h symbols.h \ patterns.h files.h scanner.h rule_type.h rule_code.h rule_symbols.h \ hangul.h rule_parser.h rules.o: rules.c basic.h pools.h values.h symbols.h patterns.h files.h \ malaga_files.h rule_type.h hangul.h rules.h rule_symbols.o: rule_symbols.c basic.h pools.h files.h values.h \ rule_type.h rule_code.h avl_trees.h rule_symbols.h scanner.o: scanner.c basic.h files.h scanner.h symbols.o: symbols.c basic.h pools.h values.h files.h malaga_files.h \ symbols.h sym_compiler.o: sym_compiler.c basic.h pools.h values.h scanner.h \ files.h malaga_files.h symbols.h avl_trees.h hangul.h sym_compiler.h transmit.o: transmit.c basic.h pools.h values.h files.h input.h \ symbols.h commands.h value_parser.h scanner.h options.h rule_type.h \ rules.h processes.h transmit.h tree.o: tree.c basic.h scanner.h input.h canvas.h tree.h tries.o: tries.c basic.h pools.h tries.h value_parser.o: value_parser.c basic.h pools.h values.h symbols.h \ scanner.h hangul.h value_parser.h values.o: values.c basic.h pools.h hangul.h values.h variables.o: variables.c basic.h scanner.h input.h canvas.h \ variables.h # End of file. ================================================================ malaga-7.12/allomorphs.c0000644000175000017500000001300310436055370014531 0ustar bjoernbjoern/* Copyright (C) 2002 Bjoern Beutel. */ /* Description. =============================================================*/ /* Read in and display Malaga Allomorphs. */ /* Includes. ================================================================*/ #include #include #include #include #include #include #include "basic.h" #include "scanner.h" #include "input.h" #include "canvas.h" #include "allomorphs.h" /* Types. ===================================================================*/ typedef struct { list_node_t *next; pos_string_t *index; pos_string_t *surf; pos_value_t *value; } allomorph_t; /* Global variables. ========================================================*/ rectangle_t allomorphs_geometry; string_t allomorphs_font_family; int_t allomorphs_font_size; /* Variables. ===============================================================*/ static list_t allomorphs; static canvas_t *allomorphs_canvas; static pos_string_t *colon; static bool_t in_line; /* Functions. ===============================================================*/ static void configure_allomorphs( canvas_t *canvas, int_t *width_p, int_t *height_p ) { int_t width, height; allomorph_t *allomorph; int_t space_width = get_space_width( canvas ); int_t font_height = get_font_height( canvas ); int_t font_ascent = get_font_ascent( canvas ); int_t border_width = get_border_width( canvas ); height = border_width; width = border_width; config_pos_string( colon, canvas ); FOREACH( allomorph, allomorphs ) { if (allomorph != (allomorph_t *) allomorphs.first) height += font_height; config_pos_string( allomorph->index, canvas ); allomorph->index->x = border_width; colon->x = allomorph->index->x + allomorph->index->width; config_pos_string( allomorph->surf, canvas ); allomorph->surf->x = colon->x + colon->width + space_width; width = MAX( width, allomorph->surf->x + allomorph->surf->width ); config_pos_value( allomorph->value, canvas ); allomorph->value->x = allomorph->surf->x; if (in_line) { allomorph->index->y = allomorph->surf->y = height + allomorph->value->ascent - font_ascent; allomorph->value->x += allomorph->surf->width + 2 * space_width; } else { allomorph->index->y = allomorph->surf->y = height; height += font_height; } allomorph->value->y = height; width = MAX( width, allomorph->value->x + allomorph->value->width ); height += allomorph->value->height; } *width_p = width + border_width; *height_p = height + border_width; } /*---------------------------------------------------------------------------*/ static void expose_allomorphs( canvas_t *canvas, rectangle_t *area ) { allomorph_t *allomorph; set_color( BLACK ); FOREACH( allomorph, allomorphs ) { draw_pos_string( allomorph->index, canvas ); colon->x = allomorph->index->x + allomorph->index->width; colon->y = allomorph->index->y; draw_pos_string( colon, canvas ); draw_pos_string( allomorph->surf, canvas ); draw_pos_value( allomorph->value, canvas ); } } /*---------------------------------------------------------------------------*/ static void free_allomorphs( canvas_t *canvas ) { allomorph_t *allomorph; free_pos_string( &colon ); FOREACH_FREE( allomorph, allomorphs ) { free_pos_string( &allomorph->index ); free_pos_string( &allomorph->surf ); free_pos_value( &allomorph->value ); } } /*---------------------------------------------------------------------------*/ static void set_in_line( canvas_t *canvas, guint action, GtkWidget *item ) { in_line = GTK_CHECK_MENU_ITEM( item )->active; configure_canvas( canvas ); } /*---------------------------------------------------------------------------*/ static GtkItemFactoryEntry in_line_items[] = { { "/Style/Inline", NULL, set_in_line, 0, "" } }; /*---------------------------------------------------------------------------*/ void read_allomorphs( void ) /* Read new allomorphs from STDIN. */ { string_t line, string; allomorph_t *allomorph; free_allomorphs( NULL ); while (TRUE) { line = read_line( stdin ); if (line == NULL) complain( "Premature EOF." ); if (strcmp_no_case( line, "end" ) == 0) break; /* Read a new allomorph. */ allomorph = new_node( &allomorphs, sizeof( allomorph_t ), LIST_END ); set_scanner_input( line ); /* Read allomorph index. */ string = int_to_string( token_number ); allomorph->index = new_pos_string( string ); free_mem( &string ); read_next_token(); /* Read allomorph surface. */ test_token( TOK_STRING ); string = new_string_readable( token_string, NULL ); allomorph->surf = new_pos_string( string ); free_mem( &string ); read_next_token(); /* Read allomorph value. */ parse_token( '{' ); allomorph->value = parse_pos_value(); parse_token( '}' ); parse_token( EOF ); set_scanner_input( NULL ); free_mem( &line ); } free_mem( &line ); colon = new_pos_string( ":" ); if (allomorphs_canvas == NULL) { allomorphs_canvas = create_canvas( "Malaga Allomorphs", "allomorphs.eps", &allomorphs_geometry, configure_allomorphs, expose_allomorphs, free_allomorphs, NULL, TRUE, in_line_items, ARRAY_LENGTH( in_line_items ) ); } else { configure_canvas( allomorphs_canvas ); show_canvas( allomorphs_canvas ); } } /* End of file. =============================================================*/ malaga-7.12/allomorphs.h0000644000175000017500000000101710236624060014534 0ustar bjoernbjoern/* Copyright (C) 2002 Bjoern Beutel. */ /* Description. =============================================================*/ /* Read in and display Malaga Allomorphs. */ /* Variables. ===============================================================*/ extern rectangle_t allomorphs_geometry; /* Functions. ===============================================================*/ extern void read_allomorphs( void ); /* Read new allomorphs from STDIN. */ /* End of file. =============================================================*/ malaga-7.12/analysis.c0000644000175000017500000010732710504765004014207 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This file contains data structures and functions used for grammatical * analysis. */ /* Includes. ================================================================*/ #include #include #include #include #include #include "basic.h" #include "pools.h" #include "values.h" #include "rule_type.h" #include "rules.h" #include "lexicon.h" #include "cache.h" #include "analysis.h" /* Types. ===================================================================*/ typedef struct tree_node /* A rule application is stored in "tree_node". */ { struct tree_node *parent; /* Predecessor of this tree node. */ struct tree_node *first_child; /* First successor of this tree node. */ struct tree_node *sibling; /* Alternative tree node. */ tree_node_type_t type; /* Type of this tree node. */ int_t rule; /* Number of the executed rule. */ int_t state_index; /* Index of this node's state or -1 if node is break. */ value_t link_feat; /* Feature structure of the link. */ value_t result_feat; /* Result feature structure of the resulting state. */ int_t rule_set; /* Successor rules of resulting state (-1 for end state). */ string_t input; /* The input that is not yet analysed. */ } tree_node_t; typedef struct /* A state in morphological or syntactical analysis. */ { list_node_t *next; value_t feat; /* Feature structure of input read in so far. */ string_t input; /* Pointer to input that is analysed next. */ int_t rule_set; /* Set of rules to be applied. */ tree_node_t *tree_node; /* Tree node of rule application that created * this state (NULL if no tree). */ int_t item_index; /* Number of items read in so far. */ } state_t; typedef struct /* The structure for morphological and syntactical analysis. */ { pool_t state_pool; /* All states are saved in STATE_POOL. */ pool_t value_pool; /* All feature structures are saved in VALUE_POOL. */ list_t running_states; /* States that need further analysis * (in the order of their INPUT indexes). */ list_t end_states; /* End states */ list_t free_states; /* States that can be reused. */ } analysis_t; /* Global variables. ========================================================*/ rule_sys_t *rule_system[2]; grammar_t top_grammar; int_t state_count; int_t current_state; bool_t recognised_by_combi_rules; bool_t recognised_by_robust_rule; string_t last_analysis_input; void (*debug_state)( int_t index, bool_t enter ); char_t * (*get_surface)( surface_t surface_type ); int_t mor_pruning_min; int_t syn_pruning_min; /* Variables. ===============================================================*/ /* Structures used for LAG analysis, one for morphology and one for syntax. */ static analysis_t *analyses[2]; /* The data structure used to save the analysis tree. */ static tree_node_t *root_tree_node; /* A pointer to the root tree node. */ static pool_t tree_pool; /* Pool where tree nodes are stored. */ static state_t *next_result_state; /* Needed for "next_analysis_result". */ static tree_node_t *next_tree_node; /* Needed for "get_next_analysis_node". */ static string_t state_surface, link_surface, link_surface_end; /* Start and end position of surfaces when rule is executed. Read only! */ static struct /* Information needed to generate states and tree nodes. */ { analysis_t *analysis; bool_t count_states; bool_t create_tree; int_t rule; /* Rule just executed. */ value_t link_feat; /* Link's feature structure. */ tree_node_t *parent; /* Predecessor tree node. */ int_t item_index; /* Index of item that is added. */ string_t input; /* End of analysed input. */ } state_info; static bool_t options[ANALYSIS_OPTION_COUNT]; /* Functions for analysis options. ==========================================*/ void set_analysis_option( analysis_option_t selected, bool_t setting ) /* Set analysis option SELECTED to SETTING. */ { switch (selected) { case ROBUST_RULE_OPTION: if (rule_system[ MORPHOLOGY ]->robust_rule == -1) complain( "No morphology \"robust_rule\"." ); break; case MOR_OUT_FILTER_OPTION: if (rule_system[ MORPHOLOGY ]->output_filter == -1) complain( "No morphology \"output_filter\"." ); break; case SYN_OUT_FILTER_OPTION: if (rule_system[ SYNTAX ] == NULL || rule_system[ SYNTAX ]->output_filter == -1) { complain( "No syntax \"output_filter\"." ); } break; case SYN_IN_FILTER_OPTION: if (rule_system[ SYNTAX ] == NULL || rule_system[ SYNTAX ]->input_filter == -1) { complain( "No syntax \"input_filter\"." ); } break; case SYN_INCOMPLETE_OPTION: if (rule_system[ SYNTAX ] == NULL) complain( "No syntax rules loaded." ); break; case CACHE_OPTION: case MOR_INCOMPLETE_OPTION: break; default: complain( "Internal error." ); } options[ selected ] = setting; } /*---------------------------------------------------------------------------*/ bool_t get_analysis_option( analysis_option_t selected ) /* Return the current setting of analysis option SELECTED. */ { return options[ selected ]; } /* Functions for segmentation and preprocessing. ============================*/ void preprocess_input( char_t *input, bool_t expect_quotes ) /* Delete heading and trailing spaces in INPUT * and compress all whitespace sequences to a single space. * If EXPECT_QUOTES == TRUE, expect quoted input and remove the quotes. */ { string_t input_p; char_t *output_p; int_t i; u_int_t code; output_p = input; /* Cut heading spaces. */ input_p = next_non_space( input ); if (expect_quotes) { if (*input_p != '"') complain( "Opening '\"' in input is missing." ); input_p++; while (*input_p != '"') { if (*input_p == EOS) complain( "Closing '\"' in input is missing." ); else if (*input_p == '\\') { input_p++; if (*input_p == '\\' || *input_p == '\"') *output_p++ = *input_p++; else if (*input_p >= '0' && *input_p <= '8') { code = 0; for (i = 0; i < 3; i++) { if (*input_p >= '0' && *input_p <= '9') code = 8 * code + *input_p++ - '0'; else complain( "Escape sequence must have 3 octal digits." ); } if (! g_unichar_validate( code )) complain( "Unicode escape sequence defines invalid character." ); output_p += g_unichar_to_utf8( code, output_p ); } else complain( "Illegal escape sequence." ); } else /* No escape char. */ { /* We must copy a whole UTF-8 character since next_non_space() below * expects to be at UTF-8 character boundary. */ code = g_utf8_get_char( input_p ); input_p = g_utf8_next_char( input_p ); output_p += g_unichar_to_utf8( code, output_p ); } } input_p++; /* Read over closing double quotes. */ input_p = next_non_space( input_p ); if (*input_p != EOS) complain( "Junk after quoted string in input." ); } else { while (*input_p != EOS) { code = g_utf8_get_char( input_p ); if (g_unichar_isspace( code )) { /* Overread all whitespace and write a single space. */ input_p = next_non_space( input_p ); *output_p++ = ' '; } else { input_p = g_utf8_next_char( input_p ); output_p += g_unichar_to_utf8( code, output_p ); } } } /* Last space may be superfluous. */ if (output_p > input && output_p[-1] == ' ') output_p--; *output_p = EOS; } /*---------------------------------------------------------------------------*/ static bool_t word_may_end_here( string_t string, rule_t *rule ) /* Return whether there may be a word boundary between STRING-1 and STRING. */ { if (options[ MOR_INCOMPLETE_OPTION ] && top_grammar == MORPHOLOGY) return TRUE; if (rule->type == END_RULE && rule->param_count == 2) return TRUE; return (*string == EOS || *string == ' '); } /* Functions for state list processing. =====================================*/ static state_t * insert_state( analysis_t *analysis, list_t *state_list, value_t feat, string_t input, int_t rule_set, int_t item_index ) /* Insert a state, composed of FEAT, INPUT, RULE_SET, and ITEM_INDEX in the * list STATE_LIST, in front of all states with a higher INPUT index. Return * this state. */ { state_t *state, *prev_state, *next_state; state = remove_first_node( &analysis->free_states ); if (state == NULL) state = (state_t *) get_pool_space( analysis->state_pool, 1, NULL ); /* Set values. */ state->feat = feat; state->input = input; state->rule_set = rule_set; state->item_index = item_index; state->tree_node = NULL; /* Find position where to insert. */ FOREACH( prev_state, *state_list ) { next_state = (state_t *) prev_state->next; if (next_state == NULL || next_state->input > input) break; } insert_node( state_list, (list_node_t *) state, (list_node_t *) prev_state ); return state; } /*---------------------------------------------------------------------------*/ static tree_node_t * add_tree_node( value_t result_feat, string_t input, int_t rule_set, tree_node_type_t type ) /* Add a tree node for a rule that created a state (RESULT_FEAT and RULE_SET), * where INPUT is yet to be analysed. */ { tree_node_t **tree_node_p; tree_node_t *tree_node; /* Get a new tree node. */ tree_node = (tree_node_t *) get_pool_space( tree_pool, 1, NULL ); tree_node->parent = state_info.parent; tree_node->first_child = NULL; tree_node->sibling = NULL; tree_node->type = type; tree_node->rule = state_info.rule; if (type == BREAK_NODE) tree_node->state_index = -1; else tree_node->state_index = state_count; tree_node->link_feat = state_info.link_feat; tree_node->result_feat = result_feat; tree_node->rule_set = rule_set; tree_node->input = input; /* Link the tree node into the tree structure. */ tree_node_p = &state_info.parent->first_child; while (*tree_node_p != NULL) tree_node_p = &(*tree_node_p)->sibling; *tree_node_p = tree_node; return tree_node; } /*---------------------------------------------------------------------------*/ static void add_state( list_t *list, string_t input, value_t feat, int_t rule_set, tree_node_type_t type ) /* Add state, consisting of INPUT, FEAT and RULE_SET, to LIST. * When STATE_INFO.CREATE_TREE == TRUE, also generate a tree node. */ { value_t new_feat; state_t *state; /* Preserve the feature structure. */ new_feat = copy_value_to_pool( state_info.analysis->value_pool, feat, NULL ); /* Create a new state. */ state = insert_state( state_info.analysis, list, new_feat, input, rule_set, state_info.item_index ); if (state_info.create_tree) state->tree_node = add_tree_node( new_feat, input, rule_set, type ); if (state_info.count_states) state_count++; } /* Callback functions needed by "rules.c" ===================================*/ static void add_allo_local( string_t surface, value_t feat ) /* Add a state, consisting of SURFACE and FEAT, as an end state. */ { int_t length; length = strlen( surface ); if (length == 0) complain( "Surface is empty." ); if (strncmp_no_case( state_surface, surface, length ) != 0) complain( "Surface does not match input." ); add_state( &state_info.analysis->end_states, state_surface + length, feat, -1, FINAL_NODE ); } /*---------------------------------------------------------------------------*/ static void add_end_state_local( value_t feat ) /* Add a state, consisting of FEAT, as an end state. */ { value_t value; rule_t *rule; rule = executed_rule_sys->rules + executed_rule_number; /* Combi-rules and end-rules must check for word boundary. */ if ((rule->type != COMBI_RULE && rule->type != END_RULE) || word_may_end_here( state_info.input, rule )) { add_state( &state_info.analysis->end_states, state_info.input, feat, -1, FINAL_NODE ); } else if (state_info.create_tree) { /* Preserve the feature structure. */ value = copy_value_to_pool( state_info.analysis->value_pool, feat, NULL ); add_tree_node( value, state_info.input, -1, UNFINAL_NODE ); } } /*---------------------------------------------------------------------------*/ static void add_running_state_local( value_t feat, int_t rule_set ) /* Add a running state, consisting of FEAT and RULE_SET. */ { add_state( &state_info.analysis->running_states, state_info.input, feat, rule_set, INTER_NODE ); } /*---------------------------------------------------------------------------*/ static char_t * get_surface_local( surface_t surface_type ) /* Return surface SURFACE_TYPE for currently executed rule. * The result must be freed after use. */ { string_t state_surf_end; switch (surface_type) { case STATE_SURFACE: if (link_surface > state_surface && link_surface[-1] == ' ') state_surf_end = link_surface - 1; else state_surf_end = link_surface; return new_string_readable( state_surface, state_surf_end ); case LINK_SURFACE: if (link_surface_end == link_surface) return NULL; return new_string_readable( link_surface, link_surface_end ); case RESULT_SURFACE: return new_string_readable( state_surface, link_surface_end ); default: return NULL; } } /* Analysis functions. ======================================================*/ static analysis_t * new_analysis( void ) /* Create a new analysis structure. */ { analysis_t *analysis; analysis = new_mem( sizeof( analysis_t ) ); analysis->state_pool = new_pool( sizeof( state_t ) ); analysis->value_pool = new_pool( sizeof( cell_t ) ); clear_list( &analysis->running_states ); clear_list( &analysis->end_states ); clear_list( &analysis->free_states ); return analysis; } /*---------------------------------------------------------------------------*/ static void free_analysis( analysis_t **analysis ) /* Destroy an analysis structure. */ { if (*analysis != NULL) { free_pool( &(*analysis)->state_pool ); free_pool( &(*analysis)->value_pool ); free_mem( analysis ); } } /*---------------------------------------------------------------------------*/ void init_analysis( string_t morphology_file, string_t syntax_file ) /* Initialise the analysis module. * MORPHOLOGY_FILE and SYNTAX_FILE are the rule files to load. * SYNTAX_FILE may be NULL. */ { int_t i; /* Read rule files. */ rule_system[ MORPHOLOGY ] = read_rule_sys( morphology_file ); if (syntax_file != NULL) rule_system[ SYNTAX ] = read_rule_sys( syntax_file ); /* Init analysis structure. */ analyses[ MORPHOLOGY ] = new_analysis(); analyses[ SYNTAX ] = new_analysis(); tree_pool = new_pool( sizeof( tree_node_t ) ); /* Set analysis options to start values. */ for (i = 0; i < ANALYSIS_OPTION_COUNT; i++) options[i] = FALSE; options[ MOR_OUT_FILTER_OPTION ] = (rule_system[ MORPHOLOGY ]->output_filter != -1); options[ SYN_IN_FILTER_OPTION ] = (rule_system[ SYNTAX ] != NULL && rule_system[ SYNTAX ]->input_filter != -1); options[ SYN_OUT_FILTER_OPTION ] = (rule_system[ SYNTAX ] != NULL && rule_system[ SYNTAX ]->output_filter != -1); } /*---------------------------------------------------------------------------*/ void terminate_analysis( void ) /* Terminate the analysis module. */ { free_rule_sys( &rule_system[ MORPHOLOGY ] ); free_rule_sys( &rule_system[ SYNTAX ] ); free_analysis( &analyses[ MORPHOLOGY ] ); free_analysis( &analyses[ SYNTAX ] ); free_pool( &tree_pool ); clear_cache(); free_switches(); } /*---------------------------------------------------------------------------*/ bool_t analysis_has_results( void ) /* Return TRUE iff the last analysis has created results. */ { return (analyses[ top_grammar ]->end_states.first != NULL); } /*---------------------------------------------------------------------------*/ value_t first_analysis_result( void ) /* Return the feature structure of the first analysis result. * Return NULL if there are no results. */ { next_result_state = (state_t *) analyses[ top_grammar ]->end_states.first; return next_analysis_result(); } /*---------------------------------------------------------------------------*/ value_t next_analysis_result( void ) /* Return the feature structure of the next analysis result. * Return NULL if there are no more results. */ { value_t result; if (next_result_state == NULL) return NULL; result = next_result_state->feat; next_result_state = (state_t *) next_result_state->next; return result; } /*---------------------------------------------------------------------------*/ bool_t analysis_has_nodes( void ) /* Return TRUE iff the last analysis has created tree nodes. */ { return (root_tree_node != NULL); } /*---------------------------------------------------------------------------*/ analysis_node_t * get_first_analysis_node( void ) /* Return the first analysis tree node of the last analysis. * Return NULL if there is no node. * The node must be freed with "free_analysis_node" after use. */ { next_tree_node = root_tree_node; return get_next_analysis_node(); } /*---------------------------------------------------------------------------*/ analysis_node_t * get_next_analysis_node( void ) /* Return the next analysis tree node of the last analysis. * Return NULL if there is no more node. * The node must be freed with "free_analysis_node" after use. */ { analysis_node_t *node; string_t link_surf; rule_sys_t *rule_sys; rule_sys = rule_system[ top_grammar ]; if (next_tree_node == NULL) return NULL; node = new_mem( sizeof( analysis_node_t ) ); node->index = next_tree_node->state_index; node->type = next_tree_node->type; /* Set parent index. */ if (next_tree_node->parent == NULL) node->parent_index = -1; else node->parent_index = next_tree_node->parent->state_index; /* Set rule name. */ if (next_tree_node->rule != -1) { node->rule_name = rule_sys->strings + rule_sys->rules[ next_tree_node->rule ].name; } else if (next_tree_node->parent == NULL) node->rule_name = "(initial)"; else node->rule_name = NULL; /* Set link surface and feature structure. */ if (next_tree_node->parent == NULL) link_surf = last_analysis_input; else link_surf = next_non_space( next_tree_node->parent->input ); if (link_surf < next_tree_node->input) node->link_surf = new_string( link_surf, next_tree_node->input ); node->link_feat = next_tree_node->link_feat; /* Set result surface and feature structure. */ node->result_surf = new_string( last_analysis_input, next_tree_node->input ); node->result_feat = next_tree_node->result_feat; /* Set rule set. */ if (next_tree_node->result_feat != NULL) node->rule_set = rule_set_readable( rule_sys, next_tree_node->rule_set ); /* Update NEXT_TREE_NODE. */ if (next_tree_node->first_child != NULL) next_tree_node = next_tree_node->first_child; else { while (next_tree_node != NULL && next_tree_node->sibling == NULL) next_tree_node = next_tree_node->parent; if (next_tree_node != NULL) next_tree_node = next_tree_node->sibling; } return node; } /*---------------------------------------------------------------------------*/ void free_analysis_node( analysis_node_t **node ) /* Free the memory occupied by NODE. */ { if (*node != NULL) { free_mem( &(*node)->link_surf ); free_mem( &(*node)->result_surf ); free_mem( &(*node)->rule_set ); free_mem( node ); } } /*---------------------------------------------------------------------------*/ static string_t get_word_end( string_t input ) /* Return the end of the word that starts at INPUT. */ { string_t input_end; input_end = input; while (*input_end != EOS && *input_end != ' ') input_end++; return input_end; } /*---------------------------------------------------------------------------*/ static bool_t get_from_cache( analysis_t *analysis, string_t input ) /* If first word at INPUT is in analysis cache, * enter its results in ANALYSIS, and return TRUE. Otherwise return FALSE. */ { string_t input_end; value_t result; input_end = get_word_end( input ); if (word_in_cache( input, input_end )) { while (TRUE) { result = next_result_in_cache(); if (result == NULL) break; insert_state( analysis, &analysis->end_states, result, input_end, -1, 0 ); } return TRUE; } else return FALSE; } /*---------------------------------------------------------------------------*/ static void put_into_cache( analysis_t *analysis, string_t input ) /* Store the results in ANALYSIS for the word form that starts at INPUT * in the cache. */ { value_t *feat_vector; int_t i; state_t *state; string_t input_end; input_end = get_word_end( input ); /* Count feature structures. */ i = 0; FOREACH( state, analysis->end_states ) { /* Only put into cache if all entries will be found in cache. */ if (state->input != input_end) return; i++; } /* Allocate a new vector which takes the feature structures. */ feat_vector = new_vector( sizeof( value_t ), i ); i = 0; FOREACH( state, analysis->end_states ) { feat_vector[i] = new_value( state->feat ); i++; } enter_in_cache( input, input_end, i, feat_vector ); } /*---------------------------------------------------------------------------*/ static void execute_robust_rule( analysis_t *analysis, rule_sys_t *rule_sys, string_t input ) /* Execute robust_rule in RULE_SYS for the first word in INPUT and enter * results into ANALYSIS. */ { string_t input_end; rule_t *rule; input_end = get_word_end( input ); /* Set debugging information. */ state_surface = input; link_surface = input; link_surface_end = input_end; /* Setup STATE_INFO. */ state_info.analysis = analysis; state_info.count_states = FALSE; state_info.create_tree = FALSE; state_info.item_index = 1; state_info.input = input_end; /* Execute rule. */ rule = rule_sys->rules + rule_sys->robust_rule; top = 0; push_string_value( input, input_end ); if (rule->param_count >= 2) push_string_value( input, NULL ); execute_rule( rule_sys, rule_sys->robust_rule ); } /*---------------------------------------------------------------------------*/ static void execute_filter_rule( analysis_t *analysis, rule_sys_t *rule_sys, int_t filter_rule ) /* Execute FILTER_RULE in RULE_SYS for ANALYSIS. */ { list_t old_end_states; state_t *state; string_t input; /* Go through all results with the same length. */ old_end_states = analysis->end_states; clear_list( &analysis->end_states ); while (old_end_states.first != NULL) { state = (state_t *) old_end_states.first; input = state->input; /* Create a list with the results of all states and remove states. */ top = 0; while (old_end_states.first != NULL && ((state_t *) old_end_states.first)->input == input) { state = remove_first_node( &old_end_states ); add_node( &analysis->free_states, (list_node_t *) state, LIST_END ); push_value( state->feat ); } build_list( top ); link_surface = link_surface_end = input; /* Set debugging information. */ /* Execute filter rule. */ state_info.analysis = analysis; state_info.count_states = FALSE; state_info.create_tree = FALSE; state_info.item_index = 0; state_info.input = input; execute_rule( rule_sys, filter_rule ); } } /*---------------------------------------------------------------------------*/ static void execute_pruning_rule( analysis_t *analysis, grammar_t grammar ) /* Execute pruning_rule in GRAMMAR for the running states in ANALYSIS. */ { int_t result_count, i; state_t *state, *next_state; string_t input; rule_sys_t *rule_sys; value_t list; symbol_t symbol; state = (state_t *) analysis->running_states.first; input = state->input; /* Create a list that contains the results. */ top = 0; result_count = 0; FOREACH( state, analysis->running_states ) { if (state->input != input) break; result_count++; push_value( state->feat ); } /* Don't execute if number of states is too low. */ if (result_count < (grammar == SYNTAX ? syn_pruning_min : mor_pruning_min)) return; build_list( result_count ); rule_sys = rule_system[ grammar ]; link_surface = link_surface_end = input; /* Set debugging information. */ execute_rule( rule_sys, rule_sys->pruning_rule ); /* Execute pruning rule. */ /* Interprete the result. */ list = value_stack[ top - 1 ]; if (get_value_type( list ) != LIST_SYMBOL) complain( "Pruning rule result must be a list." ); if (get_list_length( list ) != result_count) complain( "Pruning rule result must have as many elements as argument." ); state = (state_t *) analysis->running_states.first; for (i = 0; i < result_count; i++) { next_state = (state_t *) state->next; symbol = value_to_symbol( get_element( list, i + 1 ) ); if (symbol == NO_SYMBOL) { if (state->tree_node != NULL) state->tree_node->type = PRUNED_NODE; remove_node( &analysis->running_states, (list_node_t *) state ); add_node( &analysis->free_states, (list_node_t *) state, LIST_END ); } else if (symbol != YES_SYMBOL) complain( "Pruning rule result list may only contain yes/no symbols." ); state = next_state; } } /*---------------------------------------------------------------------------*/ static void execute_rules( analysis_t *analysis, rule_sys_t *rule_sys, state_t *state, value_t link_feat, string_t link_surf, string_t link_surf_end, bool_t count_states, bool_t create_tree, rule_type_t rule_type ) /* Execute the successor rules of RULE_TYPE in RULE_SYS for STATE in ANALYSIS. * Consume the segment from LINK_SURF to LINK_SURF_END with feature structure * LINK_FEAT. */ { int_t *rule_p; bool_t rules_successful, rules_executed; rule_t *rule; /* Setup STATE_INFO. */ state_info.analysis = analysis; state_info.count_states = count_states; state_info.create_tree = create_tree; state_info.link_feat = link_feat; state_info.parent = state->tree_node; state_info.item_index = state->item_index + 1; state_info.input = link_surf_end; /* Set debugging information. */ link_surface = link_surf; link_surface_end = link_surf_end; if (state->tree_node != NULL) current_state = state->tree_node->state_index; /* Check if we are now executing the rules for a state to be debugged */ if (debug_state != NULL && state->tree_node != NULL) debug_state( state->tree_node->state_index, TRUE ); /* Execute rules in rule set. */ rules_executed = rules_successful = FALSE; for (rule_p = rule_sys->rule_sets + state->rule_set; *rule_p != -1; rule_p++) { if (*rule_p == -2) { if (rule_type == END_RULE || rules_successful) break; } else { rule = rule_sys->rules + *rule_p; if (rule->type == rule_type && (rule->type == COMBI_RULE || word_may_end_here( link_surf, rule ))) { state_info.rule = *rule_p; top = 0; push_value( state->feat ); if (rule->type == COMBI_RULE) { push_value( link_feat ); if (rule->param_count >= 3) push_string_value( link_surf, link_surf_end ); if (rule->param_count >= 4) push_number_value( state_info.item_index ); } else /* rule->type == END_RULE */ { if (rule->param_count >= 2) push_string_value( link_surf, NULL ); } execute_rule( rule_sys, *rule_p ); rules_executed = TRUE; rules_successful |= rule_successful; } } } current_state = -1; /* Save the current debug mode if we are leaving a debug state. */ if (debug_state != NULL && state->tree_node != NULL) debug_state( state->tree_node->state_index, FALSE ); /* Enter a tree node if rules where executed but did not fire. */ if (rules_executed && ! rules_successful && create_tree) { state_info.rule = -1; add_tree_node( NULL, link_surf_end, -1, BREAK_NODE ); } } /*---------------------------------------------------------------------------*/ static void check_end_states( analysis_t *analysis, grammar_t grammar, bool_t analyse_all ) /* If ANALYSE_ALL == TRUE, * delete all states in ANALYSIS that didn't consume all the input. */ { state_t *state; if (! analyse_all || (grammar == MORPHOLOGY && options[ MOR_INCOMPLETE_OPTION ]) || (grammar == SYNTAX && options[ SYN_INCOMPLETE_OPTION ])) { return; } while (TRUE) { state = (state_t *) analysis->end_states.first; if (state == NULL || *state->input == EOS) break; if (state->tree_node != NULL) state->tree_node->type = UNFINAL_NODE; remove_first_node( &analysis->end_states ); add_node( &analysis->free_states, (list_node_t *) state, LIST_END ); } } /*---------------------------------------------------------------------------*/ void analyse( grammar_t grammar, string_t input, bool_t create_tree, bool_t analyse_all ) /* Perform a LAG analysis of INPUT using GRAMMAR (MORPHOLOGY or SYNTAX). * An analysis tree will be built if CREATE_TREE == TRUE. * The whole input will be analysed if ANALYSE_ALL == TRUE. */ { rule_sys_t *rule_sys; state_t *initial_state; analysis_t *analysis; state_t *state; string_t current_input; value_t link_feat; string_t link_surf_end; /* End of the link's surface. */ string_t input_behind_space; state_t *mor_state; /* Morphology end state. */ bool_t use_cache; if (analyse_all) { top_grammar = grammar; root_tree_node = NULL; state_count = 1; /* We will insert the initial state. */ last_analysis_input = input; recognised_by_robust_rule = recognised_by_combi_rules = FALSE; } analysis = analyses[ grammar ]; rule_sys = rule_system[ grammar ]; if (rule_sys == NULL) complain( "Missing rule system." ); /* Set callback functions for "execute_rules". */ add_running_state = add_running_state_local; add_end_state = add_end_state_local; add_allo = add_allo_local; /* Reset the analysis data structures */ clear_list( &analysis->running_states ); clear_list( &analysis->end_states ); clear_list( &analysis->free_states ); clear_pool( analysis->state_pool ); clear_pool( analysis->value_pool ); /* Set debug information. */ get_surface = get_surface_local; state_surface = input; current_state = -1; /* Try to get analysis result from cache. */ use_cache = (grammar == MORPHOLOGY && options[ CACHE_OPTION ] && ! create_tree && (! analyse_all || *get_word_end( input ) == EOS)); if (use_cache && get_from_cache( analysis, input )) return; /* Enter the initial state. */ initial_state = insert_state( analysis, &analysis->running_states, rule_sys->values + rule_sys->initial_feat, input, rule_sys->initial_rule_set, 0 ); if (create_tree) { /* Clear all tree nodes and setup ROOT_TREE_NODE. */ clear_pool( tree_pool ); root_tree_node = (tree_node_t *) get_pool_space( tree_pool, 1, NULL ); root_tree_node->parent = NULL; root_tree_node->first_child = NULL; root_tree_node->sibling = NULL; root_tree_node->type = INTER_NODE; root_tree_node->rule = -1; root_tree_node->state_index = 0; root_tree_node->link_feat = NULL; root_tree_node->result_feat = rule_sys->values + rule_sys->initial_feat; root_tree_node->rule_set = rule_sys->initial_rule_set; root_tree_node->input = input; initial_state->tree_node = root_tree_node; } /* Analyse while there are running states. */ while (analysis->running_states.first != NULL) { state = (state_t *) analysis->running_states.first; current_input = state->input; if (((grammar == MORPHOLOGY && mor_pruning_min > 0) || (grammar == SYNTAX && syn_pruning_min > 0)) && current_input > input && rule_sys->pruning_rule != -1) { execute_pruning_rule( analysis, grammar ); } if (current_input > input) /* Apply end_rules if any input was parsed. */ { /* Apply all end_rules to states at CURRENT_INPUT. */ FOREACH( state, analysis->running_states ) { if (state->input != current_input) break; execute_rules( analysis, rule_sys, state, NULL, current_input, current_input, analyse_all, create_tree, END_RULE ); } } if (*current_input == EOS) break; /* If analysis ate all input, leave. */ if (grammar == MORPHOLOGY) { /* Look for prefixes of increasing length * that match the string at CURRENT_INPUT. */ search_for_prefix( current_input ); while (get_next_prefix( &link_surf_end, &link_feat )) { /* Combine that link with all morphological states. */ FOREACH( state, analysis->running_states ) { if (state->input != current_input) break; execute_rules( analysis, rule_sys, state, link_feat, current_input, link_surf_end, analyse_all, create_tree, COMBI_RULE ); } } } else /* GRAMMAR == SYNTAX */ { input_behind_space = next_non_space( current_input ); /* Call morphological analysis to get feature structures for the link. */ analyse( MORPHOLOGY, input_behind_space, FALSE, FALSE ); /* Execution of morphology rules has changed STATE_SURFACE. */ state_surface = input; /* Step through all morphological end states. */ FOREACH( mor_state, analyses[ MORPHOLOGY ]->end_states ) { /* The morphology will be cleared by next morphological analysis, * so copy STATE->FEAT to the syntax pool. */ link_feat = copy_value_to_pool( analysis->value_pool, mor_state->feat, NULL ); /* Combine the link with all syntactic states. */ FOREACH( state, analysis->running_states ) { if (state->input != current_input) break; execute_rules( analysis, rule_sys, state, link_feat, input_behind_space, mor_state->input, analyse_all, create_tree, COMBI_RULE ); } } } /* We have combined all analyses at CURRENT_INPUT with all states * that were at CURRENT_INPUT, so we can kill these states. */ while (TRUE) { state = (state_t *) analysis->running_states.first; if (state == NULL || state->input != current_input) break; remove_first_node( &analysis->running_states ); add_node( &analysis->free_states, (list_node_t *) state, LIST_END ); } } /* End of loop that consumes all running states. */ check_end_states( analysis, grammar, analyse_all ); if (analyse_all && analysis->end_states.first != NULL) recognised_by_combi_rules = TRUE; if (grammar == MORPHOLOGY) { if (analysis->end_states.first == NULL && options[ ROBUST_RULE_OPTION ]) { execute_robust_rule( analysis, rule_sys, input ); check_end_states( analysis, grammar, analyse_all ); if (analyse_all && analysis->end_states.first != NULL) recognised_by_robust_rule = TRUE; } if (options[ MOR_OUT_FILTER_OPTION ]) { execute_filter_rule( analysis, rule_system[ MORPHOLOGY ], rule_system[ MORPHOLOGY ]->output_filter ); } if (options[ SYN_IN_FILTER_OPTION ]) { execute_filter_rule( analysis, rule_system[ SYNTAX ], rule_system[ SYNTAX ]->input_filter ); } if (use_cache) put_into_cache( analysis, input ); } else /* grammar == SYNTAX */ { if (options[ SYN_OUT_FILTER_OPTION ]) { execute_filter_rule( analysis, rule_system[ SYNTAX ], rule_system[ SYNTAX ]->output_filter ); } } } /* End of file. =============================================================*/ malaga-7.12/analysis.h0000644000175000017500000001240210504700151014171 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This file contains data structures and functions used for grammatical * analysis. */ /* Types. ===================================================================*/ typedef enum {MORPHOLOGY, SYNTAX} grammar_t; /* Types of grammatic analysis. */ typedef enum {BREAK_NODE, FINAL_NODE, UNFINAL_NODE, INTER_NODE, PRUNED_NODE} tree_node_type_t; typedef struct /* A node of the analysis tree. */ { tree_node_type_t type; int_t index; /* Index of this analysis tree node's state or -1. */ int_t parent_index; /* Index of parent analysis tree node's state or -1. */ string_t link_surf; /* Link's surface or NULL. */ value_t link_feat; /* Link's feature structure or NULL. */ string_t rule_name; /* Name of the rule that created result or NULL. */ string_t result_surf; /* Surface of resulting state or NULL. */ value_t result_feat; /* Feature structure of resulting state or NULL. */ string_t rule_set; /* Successor rules of resulting state or NULL. */ } analysis_node_t; typedef enum {ROBUST_RULE_OPTION, CACHE_OPTION, MOR_OUT_FILTER_OPTION, SYN_IN_FILTER_OPTION, SYN_OUT_FILTER_OPTION, MOR_INCOMPLETE_OPTION, SYN_INCOMPLETE_OPTION, ANALYSIS_OPTION_COUNT} analysis_option_t; typedef enum {STATE_SURFACE, LINK_SURFACE, RESULT_SURFACE} surface_t; /* Kinds of surfaces that can be obtained by "get_rule_info" in "rules.h" */ /* Variables. ===============================================================*/ extern rule_sys_t *rule_system[2]; /* rule_system[ MORPHOLOGY ] and rule_system[ SYNTAX ]. Read only! */ extern grammar_t top_grammar; /* Grammar of last analysis. Read only! */ extern int_t state_count; /* Counts number of generated states. Read only! */ extern int_t current_state; /* Index of current state. Read only! */ extern bool_t recognised_by_combi_rules; /* TRUE if last analysis was recognised by combi rules. Read only! */ extern bool_t recognised_by_robust_rule; /* TRUE if last analysis was recognised by robust rule. Read only! */ extern string_t last_analysis_input; /* Start of top level input string. Read only! */ extern void (*debug_state)( int_t index, bool_t enter ); /* Callback function for "analyse". * This is called with ENTER == TRUE when successor rules for * state with analysis node INDEX will be executed. * It is called with ENTER == FALSE when successor rules for state with * analysis node INDEX have been executed. */ extern char_t * (*get_surface)( surface_t surface_type ); /* Return surface SURFACE_TYPE for currently executed rule. * The result must be freed after use. */ extern int_t mor_pruning_min; /* Minimum number of states that must have consumed same amount of input * needed to call the morphology pruning rule. Value 0 disables pruning. */ extern int_t syn_pruning_min; /* Minimum number of states that must have consumed same amount of input * needed to call the syntax pruning rule. Value 0 disables pruning. */ /* Functions. ===============================================================*/ extern void init_analysis( string_t morphology_file, string_t syntax_file ); /* Initialise the analysis module. * MORPHOLOGY_FILE and SYNTAX_FILE are the rule files to load. * SYNTAX_FILE may be NULL. */ extern void terminate_analysis( void ); /* Free analysis module. */ extern void preprocess_input( char_t *input, bool_t expect_quotes); /* Delete heading and trailing spaces in INPUT * and compress all whitespace sequences to a single space. * If EXPECT_QUOTES == TRUE, expect quoted input and remove the quotes. */ extern void set_analysis_option( analysis_option_t selected, bool_t setting ); /* Set analysis option SELECTED to SETTING. */ extern bool_t get_analysis_option( analysis_option_t selected ); /* Return the current setting of analysis option SELECTED. */ extern void analyse( grammar_t grammar, string_t input, bool_t create_tree, bool_t analyse_all ); /* Perform a LAG analysis of INPUT using GRAMMAR (MORPHOLOGY or SYNTAX). * An analysis tree will be built if CREATE_TREE == TRUE. * The whole input will be analysed if ANALYSE_ALL == TRUE. */ extern bool_t analysis_has_results( void ); /* Return TRUE iff the last analysis has created results. */ extern value_t first_analysis_result( void ); /* Return the feature structure of the first analysis result. * Return NULL if there are no results. */ extern value_t next_analysis_result( void ); /* Return the feature structure of the next analysis result. * Return NULL if there are no more results. */ extern bool_t analysis_has_nodes( void ); /* Return TRUE iff the last analysis has created tree nodes. */ extern analysis_node_t *get_first_analysis_node( void ); /* Return the first analysis tree node of the last analysis. * Return NULL if there is no node. * The node must be freed with "free_analysis_node" after use. */ extern analysis_node_t *get_next_analysis_node( void ); /* Return the next analysis tree node of the last analysis. * Return NULL if there is no more node. * The node must be freed with "free_analysis_node" after use. */ extern void free_analysis_node( analysis_node_t **node ); /* Free the memory occupied by NODE. */ /* End of file. =============================================================*/ malaga-7.12/avl_trees.c0000644000175000017500000002016710236624075014350 0ustar bjoernbjoern/* Copyright (C) 1996 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module manages AVL trees. */ /* Includes. ================================================================*/ #include #include #include "basic.h" #include "avl_trees.h" /* Functions. ===============================================================*/ static bool_t balance_left( avl_node_t **tree ) /* Balance TREE when the left subtree has shrunk. * Return TRUE iff balanced TREE has shrunk. */ { avl_node_t *root; root = *tree; root->balance++; if (root->balance <= +1) return (root->balance == 0); /* Tree is in disorder, rebalance it. */ if (root->right->balance >= 0) { (*tree) = root->right; root->right = (*tree)->left; (*tree)->left = root; if ((*tree)->balance == 0) { (*tree)->balance = -1; (*tree)->left->balance = +1; return FALSE; } else { (*tree)->balance = 0; (*tree)->left->balance = 0; return TRUE; } } else { (*tree) = root->right->left; root->right->left = (*tree)->right; (*tree)->right = root->right; root->right = (*tree)->left; (*tree)->left = root; if ((*tree)->balance == +1) (*tree)->left->balance = -1; else (*tree)->left->balance = 0; if ((*tree)->balance == -1) (*tree)->right->balance = +1; else (*tree)->right->balance = 0; (*tree)->balance = 0; return TRUE; } } /*---------------------------------------------------------------------------*/ static bool_t balance_right( avl_node_t **tree ) /* Balance TREE when the right subtree has shrunk. * Return TRUE iff balanced TREE has shrunk. */ { avl_node_t *root; root = *tree; root->balance--; if (root->balance >= -1) return (root->balance == 0); /* Tree is in disorder, rebalance it. */ if (root->left->balance <= 0) { (*tree) = root->left; root->left = (*tree)->right; (*tree)->right = root; if ((*tree)->balance == 0) { (*tree)->balance = +1; (*tree)->right->balance = -1; return FALSE; } else { (*tree)->balance = 0; (*tree)->right->balance = 0; return TRUE; } } else { (*tree) = root->left->right; root->left->right = (*tree)->left; (*tree)->left = root->left; root->left = (*tree)->right; (*tree)->right = root; if ((*tree)->balance == -1) (*tree)->right->balance = +1; else (*tree)->right->balance = 0; if ((*tree)->balance == +1) (*tree)->left->balance = -1; else (*tree)->left->balance = 0; (*tree)->balance = 0; return TRUE; } } /*---------------------------------------------------------------------------*/ static bool_t remove_largest( avl_node_t **tree, avl_node_t **result ) /* Find the largest element in TREE, remove it and return it in *RESULT. * Return TRUE iff TREE has shrunk. */ { avl_node_t *root; bool_t shrunk; root = *tree; if (root->right != NULL) { shrunk = remove_largest( &root->right, result ); if (shrunk) return balance_right( tree ); else return FALSE; } else /* root->right == NULL ===> root is largest. */ { *result = root; *tree = root->left; return TRUE; } } /*---------------------------------------------------------------------------*/ bool_t remove_avl_node( avl_node_t *node, avl_node_t **tree, int_t (*compare)( avl_node_t *, avl_node_t * ) ) /* Remove NODE from TREE. Return TRUE iff TREE has shrunk. */ { int_t comp; bool_t shrunk; avl_node_t *root; root = *tree; comp = compare( node, root ); if (comp < 0) { shrunk = remove_avl_node( node, &root->left, compare ); if (shrunk) return balance_left( tree ); else return FALSE; } else if (comp > 0) { shrunk = remove_avl_node( node, &root->right, compare ); if (shrunk) return balance_right( tree ); else return FALSE; } else /* comp == 0 */ { if (root->right == NULL) (*tree) = root->left; else if (root->left == NULL) (*tree) = root->right; else { shrunk = remove_largest( &root->left, tree ); (*tree)->balance = root->balance; (*tree)->left = root->left; (*tree)->right = root->right; if (shrunk) return balance_left( tree ); else return FALSE; } return TRUE; } } /*---------------------------------------------------------------------------*/ bool_t insert_avl_node( avl_node_t *node, avl_node_t **tree, int_t (*compare)( avl_node_t *, avl_node_t * ) ) /* Find the right place to put NODE into TREE. * Return TRUE iff TREE has grown. */ { avl_node_t *root; int_t comp; bool_t grown; if ((*tree) == NULL) { *tree = node; return TRUE; } comp = compare( node, *tree ); if (comp < 0) { grown = insert_avl_node( node, &(*tree)->left, compare ); if (grown) { root = *tree; root->balance--; if (root->balance >= -1) return (root->balance == -1); /* Tree is in disorder, rebalance it. */ if (root->left->balance == -1) { (*tree) = root->left; root->left = (*tree)->right; (*tree)->right = root; (*tree)->right->balance = 0; } else { (*tree) = root->left->right; root->left->right = (*tree)->left; (*tree)->left = root->left; root->left = (*tree)->right; (*tree)->right = root; if ((*tree)->balance == -1) (*tree)->right->balance = +1; else (*tree)->right->balance = 0; if ((*tree)->balance == +1) (*tree)->left->balance = -1; else (*tree)->left->balance = 0; } (*tree)->balance = 0; } return FALSE; } else if (comp > 0) { grown = insert_avl_node( node, &(*tree)->right, compare ); if (grown) { root = *tree; root->balance++; if (root->balance <= +1) return (root->balance == +1); /* Tree is in disorder, rebalance it. */ if (root->right->balance == +1) { (*tree) = root->right; root->right = (*tree)->left; (*tree)->left = root; (*tree)->left->balance = 0; } else { (*tree) = root->right->left; root->right->left = (*tree)->right; (*tree)->right = root->right; root->right = (*tree)->left; (*tree)->left = root; if ((*tree)->balance == +1) (*tree)->left->balance = -1; else (*tree)->left->balance = 0; if ((*tree)->balance == -1) (*tree)->right->balance = +1; else (*tree)->right->balance = 0; } (*tree)->balance = 0; } return FALSE; } complain( "Internal error." ); } /*---------------------------------------------------------------------------*/ static int_t compare_avln_nodes( avl_node_t *node1, avl_node_t *node2 ) /* Compare NODE1 and NODE2 case-insensitively by their names. */ { return strcmp_no_case( ((avln_node_t *) node1)->name, ((avln_node_t *) node2)->name ) ; } /*---------------------------------------------------------------------------*/ void remove_avln_node( avln_node_t *node, avln_node_t **tree ) /* Remove NODE from TREE. */ { remove_avl_node( (avl_node_t *) node, (avl_node_t **) tree, compare_avln_nodes ); } /*---------------------------------------------------------------------------*/ void insert_avln_node( avln_node_t *node, avln_node_t **tree ) /* Put NODE into TREE. */ { insert_avl_node( (avl_node_t *) node, (avl_node_t **) tree, compare_avln_nodes ); } /*---------------------------------------------------------------------------*/ avln_node_t * find_avln_node( string_t name, avln_node_t *tree ) /* Find and return the name node with NAME in TREE. * If no such node exists, return NULL. */ { int_t result; while (tree != NULL) { result = strcmp_no_case( name, tree->name ); if (result < 0) tree = tree->left; else if (result > 0) tree = tree->right; else return tree; } return NULL; } /* End of file. =============================================================*/ malaga-7.12/avl_trees.h0000644000175000017500000000345010236624101014337 0ustar bjoernbjoern/* Copyright (C) 1996 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module implements AVL trees. */ /* Types. ===================================================================*/ typedef struct avl_node /* An AVL tree node. */ { struct avl_node *left, *right; /* Left and right son in AVL tree. */ int_t balance; /* < 0 if left tree is deeper; > 0 if right tree is deeper. */ } avl_node_t; typedef struct avln_node /* An AVL tree node sorted by its name. */ { struct avln_node *left, *right; /* Left and right son in AVL tree. */ int_t balance; /* < 0 if left tree is deeper; > 0 if right tree is deeper. */ /* The preceeding items must be identical to the ones in "avl_node_t" and * occur in the same order. */ string_t name; /* Name of this node. It is considered case-insensitive. */ } avln_node_t; /* Functions. ===============================================================*/ extern bool_t insert_avl_node( avl_node_t *node, avl_node_t **tree, int_t (*compare)( avl_node_t*, avl_node_t* ) ); /* Put NODE into TREE. Return TRUE iff TREE has grown. */ extern bool_t remove_avl_node( avl_node_t *node, avl_node_t **tree, int_t (*compare)( avl_node_t*, avl_node_t* ) ); /* Remove NODE from TREE. Return TRUE iff TREE has shrunk. */ extern void insert_avln_node( avln_node_t *node, avln_node_t **tree ); /* Put NODE into TREE. */ extern void remove_avln_node( avln_node_t *node, avln_node_t **tree ); /* Remove NODE from TREE. */ extern avln_node_t *find_avln_node( string_t name, avln_node_t *tree ); /* Find and return the name node with NAME in TREE. * If no such node exists, return NULL. */ /* End of file. =============================================================*/ malaga-7.12/basic.c0000644000175000017500000005104410761577240013447 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This file contains basic types, macros and functions used everywhere. */ /* Includes. ================================================================*/ #include #include #include #include #include #include #include "basic.h" /* Global variables. ========================================================*/ char_t malaga_version[] = "7.12"; string_t program_name; bool_t in_emacs_malaga_mode; bool_t split_hangul_syllables; text_t *error_text; jmp_buf *current_error_handler; bool_t user_break_requested; /* List functions. ==========================================================*/ void clear_list( list_t *list ) /* Initialise LIST to be an list */ { list->first = list->last = NULL; } /*---------------------------------------------------------------------------*/ void add_node( list_t *list, list_node_t *node, position_t position ) /* Add NODE to LIST. * If POSITION = LIST_START, add it at the start of the list; * If POSITION = LIST_END, add it at the end. */ { if (list->first == NULL) { node->next = NULL; list->first = list->last = node; } else if (position == LIST_START) { node->next = list->first; list->first = node; } else /* position == LIST_END */ { node->next = NULL; list->last->next = node; list->last = node; } } /*---------------------------------------------------------------------------*/ void insert_node( list_t *list, list_node_t *node, list_node_t *prev ) /* Insert NODE in LIST, behind PREV. * If PREV == NULL, insert NODE at the beginning of the list. */ { if (prev == NULL) { node->next = list->first; list->first = node; } else { node->next = prev->next; prev->next = node; } if (node->next == NULL) list->last = node; } /*---------------------------------------------------------------------------*/ void * remove_first_node( list_t *list ) /* Remove the first node in LIST and return it. * Return NULL if LIST is empty. */ { list_node_t *node; if (list->first == NULL) return NULL; node = list->first; list->first = node->next; if (node == list->last) list->last = NULL; return node; } /*---------------------------------------------------------------------------*/ void remove_node( list_t *list, list_node_t *node ) /* Remove NODE in LIST. */ { list_node_t *prev_node; if (list->first == node) { list->first = node->next; prev_node = NULL; } else { prev_node = list->first; while (prev_node->next != node) prev_node = prev_node->next; prev_node->next = node->next; } if (node->next == NULL) list->last = prev_node; } /*---------------------------------------------------------------------------*/ void combine_lists( list_t *list1, list_t *list2 ) /* Append LIST2 to LIST1. * LIST1 will contain the concatenation; LIST2 will be empty. */ { if (list1->first == NULL) list1->first = list2->first; else list1->last->next = list2->first; if (list2->first != NULL) { list1->last = list2->last; list2->first = list2->last = NULL; } } /*---------------------------------------------------------------------------*/ void * new_node( list_t *list, int_t size, position_t position ) /* Add a node of size SIZE to LIST. * If POSITION = LIST_START, add the element at the start of the list; * If POSITION = LIST_END, add the element at the end. * Return the newly created node. */ { list_node_t *node; node = new_mem( size ); add_node( list, node, position ); return node; } /*---------------------------------------------------------------------------*/ void free_first_node( list_t *list ) /* Remove first node in LIST and free it. */ { list_node_t *node; node = remove_first_node( list ); if (node != NULL) free_mem( &node ); } /*---------------------------------------------------------------------------*/ void free_node( list_t *list, list_node_t *node ) /* Remove NODE from LIST and free it. */ { remove_node( list, node ); free_mem( &node ); } /* Memory functions. ========================================================*/ void * new_mem( int_t item_size ) /* Allocate a memory block of ITEM_SIZE bytes, clear it and return it. * If memory is out, call the function "complain". */ { void *block; if (item_size == 0) return NULL; block = calloc( 1, item_size ); if (block == NULL) complain( "Out of memory." ); return block; } /*---------------------------------------------------------------------------*/ void * new_vector( int_t item_size, int_t item_count ) /* Allocate a memory block to contain ITEM_COUNT items of size ITEM_SIZE, * clear it and return it. * If memory is out, call the function "complain". */ { void *block; if (item_size == 0 || item_count == 0) return NULL; block = calloc( item_count, item_size ); if (block == NULL) complain( "Out of memory." ); return block; } /*---------------------------------------------------------------------------*/ int_t renew_vector( void *block_p, int_t item_size, int_t item_count ) /* Realloc *BLOCK_P to contain ITEM_COUNT items of ITEM_SIZE bytes each. * Return ITEM_COUNT. * If memory is out, call the function "complain". */ { void *block; block = *((void **) block_p); block = realloc( block, item_count * item_size ); if (block == NULL) complain( "Out of memory." ); *((void **) block_p) = block; return item_count; } /*---------------------------------------------------------------------------*/ void free_mem( void *pointer ) /* Free memory *POINTER points to, and set *POINTER to NULL. */ { free( *((void **) pointer) ); *((void **) pointer) = NULL; } /* Functions for text (indefinitely growing strings). =======================*/ text_t * new_text( void ) /* Return a new text structure. */ { text_t *text; text = new_mem( sizeof( text_t ) ); text->buffer_size = 100; text->buffer = new_vector( sizeof( char_t ), text->buffer_size + 1 ); /* text->buffer[0] is set to EOS. */ text->string_size = 0; return text; } /*---------------------------------------------------------------------------*/ void clear_text( text_t *text ) /* Initialize TEXT to an empty string. */ { text->buffer[0] = EOS; text->string_size = 0; } /*---------------------------------------------------------------------------*/ void free_text( text_t **text_p ) /* Free the content of *TEXT_P. */ { if (*text_p != NULL) { free_mem( &(*text_p)->buffer ); free_mem( text_p ); } } /*---------------------------------------------------------------------------*/ void add_to_text( text_t *text, string_t string ) /* Add STRING to TEXT. */ { int_t string_len; string_len = strlen( string ); if (text->buffer_size < text->string_size + string_len + 1) { text->buffer_size = renew_vector( &text->buffer, sizeof( char_t ), 2 * (text->string_size + string_len) ); } strcpy( text->buffer + text->string_size, string ); text->string_size += string_len; } /*---------------------------------------------------------------------------*/ void add_char_to_text( text_t *text, char_t character ) /* Add CHARACTER to TEXT. */ { if (text->buffer_size < text->string_size + 2) { text->buffer_size = renew_vector( &text->buffer, sizeof( char_t ), 2 * (text->string_size + 1) ); } text->buffer[ text->string_size++ ] = character; text->buffer[ text->string_size ] = EOS; } /*---------------------------------------------------------------------------*/ void add_unichar_to_text( text_t *text, gunichar c ) /* Add C to TEXT. */ { char buf[7]; int_t n; n = g_unichar_to_utf8( c, buf ); buf[n] = EOS; if (text->buffer_size < text->string_size + n + 1) { text->buffer_size = renew_vector( &text->buffer, sizeof( char_t ), 2 * (text->string_size + n) ); } strcpy( text->buffer + text->string_size, buf ); text->string_size += n; } /*---------------------------------------------------------------------------*/ void insert_in_text( text_t *text, string_t string, int_t position ) /* Insert STRING at POSITION in TEXT (position counts bytes from 0 onward). */ { int_t string_len; string_len = strlen( string ); if (text->buffer_size < text->string_size + string_len + 1) { text->buffer_size = renew_vector( &text->buffer, sizeof( char_t ), 2 * (text->string_size + string_len) ); } if (position < 0) position = 0; if (position > text->string_size) position = text->string_size; memmove( text->buffer + position + string_len, text->buffer + position, sizeof( char_t ) * (text->string_size + 1 - position) ); memcpy( text->buffer + position, string, sizeof( char_t ) * string_len ); text->string_size += string_len; } /*---------------------------------------------------------------------------*/ void insert_char_in_text( text_t *text, char_t character, int_t position ) /* Insert CHARACTER at POSITION in TEXT. */ { if (text->buffer_size < text->string_size + 2) { text->buffer_size = renew_vector( &text->buffer, sizeof( char_t ), 2 * (text->string_size + 1) ); } if (position < 0) position = 0; if (position > text->string_size) position = text->string_size; memmove( text->buffer + position + 1, text->buffer + position, sizeof( char_t ) * (text->string_size + 1 - position) ); text->buffer[ position ] = character; text->string_size++; } /*---------------------------------------------------------------------------*/ char_t * text_to_string( text_t **text_p ) /* Return content of *TEXT_P as a string and delete *TEXT_P. * The string must be freed after use. */ { char_t *string; string = new_string( (*text_p)->buffer, NULL ); free_text( text_p ); return string; } /*---------------------------------------------------------------------------*/ /* Add string_t FORMAT to text_t TEXT, replace any "%s" with the next * "string_t" argument in va_list ARGS, any "%c" with the next "char" argument, * any "%u" with the next "gunichar" argument, and any "%d" with the next * "int_t" argument. */ #define VA_PRINT_TEXT( text, format, args ) \ do { \ string_t format_p; \ \ for (format_p = format; *format_p != EOS; format_p++) \ { \ if (*format_p == '%') \ { \ format_p++; \ switch (*format_p) \ { \ case 'c': \ add_char_to_text( text, va_arg( args, int ) ); \ break; \ case 'u': \ { \ char buf[7]; \ int n; \ \ n = g_unichar_to_utf8( va_arg( args, gunichar ), buf); \ buf[n] = EOS; \ add_to_text( text, buf ); \ break; \ } \ case 's': \ add_to_text( text, va_arg( args, string_t ) ); \ break; \ case 'd': \ { \ int_t pos, num; \ \ num = va_arg( args, int_t ); \ if (num < 0) \ { \ add_char_to_text( text, '-' ); \ num = -num; \ } \ pos = text->string_size; \ do \ { \ insert_char_in_text( text, '0' + (num % 10), pos ); \ num /= 10; \ } while (num != 0); \ break; \ } \ default: \ add_char_to_text( text, *format_p ); \ break; \ } \ } \ else \ ADD_CHAR_TO_TEXT( text, *format_p ); \ } \ } while (FALSE) /*---------------------------------------------------------------------------*/ void print_text( text_t *text, string_t format, ... ) /* Add FORMAT to TEXT, replace any "%s" with a "string_t" argument, any "%c" * with a "char" argument, any "%u" with a "gunichar" argument, and any "%d" * with an "int_t" argument. */ { va_list args; va_start( args, format ); VA_PRINT_TEXT( text, format, args ); va_end( args ); } /* String functions. ========================================================*/ char_t * new_string( string_t string, string_t end ) /* Allocate memory and copy STRING into it. * If END != NULL, it marks the end of the string. * The result string must be freed after use. */ { char_t *new_str; char_t *new_str_p; if (end == NULL) end = string + strlen( string ); new_str = new_str_p = new_vector( sizeof( char_t ), end - string + 1 ); while (string < end) *new_str_p++ = *string++; *new_str_p = EOS; return new_str; } /*---------------------------------------------------------------------------*/ char_t * new_string_readable( string_t from, string_t from_end ) /* Like "new_string", but enclose the string in double quotes, copy a "\" in * front of quotes and backslashed, and copy control chars in "\uxxxx" format. * If FROM_END != NULL, it marks the end of the string. * The result string must be freed after use. */ { text_t *text; int_t i, code, position; text = new_text(); if (from_end == NULL) from_end = from + strlen( from ); add_char_to_text( text, '\"' ); while (from < from_end) { if (*from == '\"' || *from == '\\') /* Prepend a backslash. */ { add_char_to_text( text, '\\' ); add_char_to_text( text, *from++ ); } else if ((*from >= 0 && *from < 32) || *from == 127) { /* Convert control chars to octal "\xxx" format. */ add_char_to_text( text, '\\' ); position = text->string_size; code = *from++; for (i = 0; i < 3; i++) { insert_char_in_text( text, code % 8 + '0', position ); code = code / 8; } } else { add_unichar_to_text( text, g_utf8_get_char( from ) ); from = g_utf8_next_char( from ); } } add_char_to_text( text, '\"' ); return text_to_string( &text ); } /*---------------------------------------------------------------------------*/ char_t * concat_strings( string_t first_string, ... ) /* Concatenate a list of strings and return the result string. * Must have NULL-terminated list of strings as parameters. * The result string must be freed after use. */ { va_list args; size_t length; string_t next_string; char_t *string; char_t *string_p; /* Compute length of the result string. */ va_start( args, first_string ); length = strlen( first_string ); for (next_string = va_arg( args, string_t ); next_string != NULL; next_string = va_arg( args, string_t )) { length += strlen( next_string ); } va_end( args ); /* Concatenate strings. */ va_start( args, first_string ); string = new_vector( sizeof( char_t ), length + 1 ); strcpy( string, first_string ); string_p = string + strlen( first_string ); for (next_string = va_arg( args, string_t ); next_string != NULL; next_string = va_arg( args, string_t )) { strcpy( string_p, next_string ); string_p += strlen( next_string ); } va_end( args ); return string; } /*---------------------------------------------------------------------------*/ string_t next_non_space( string_t string ) /* Return STRING, but without leading spaces. */ { while (g_unichar_isspace( g_utf8_get_char( string ) )) string = g_utf8_next_char( string ); return string; } /*---------------------------------------------------------------------------*/ int_t strcmp_no_case( string_t str1, string_t str2 ) /* Return (case insensitive) lexical order of STR1 and STR2: * Result is -1 if STR1 < STR2, * 0 if STR1 = STR2, * 1 if STR1 > STR2. */ { gunichar c1, c2; /* Find first char where STR1 and STR2 differ. */ while (TRUE) { if (*str1 == EOS) return (*str2 == EOS ? 0 : -1); else if (*str2 == EOS) return 1; c1 = g_unichar_tolower( g_utf8_get_char( str1 )); c2 = g_unichar_tolower( g_utf8_get_char( str2 )); if (c1 != c2) return (c1 < c2 ? -1 : 1); str1 = g_utf8_next_char( str1 ); str2 = g_utf8_next_char( str2 ); } } /*---------------------------------------------------------------------------*/ int_t strncmp_no_case( string_t str1, string_t str2, int_t n ) /* Return (case insensitive) lexical order of STR1 and STR2, * but compare only the first N bytes. * Result is -1 if STR1 < STR2, * 0 if STR1 = STR2, * 1 if STR1 > STR2. */ { string_t str1_end = str1 + n; gunichar c1, c2; /* Find first char where STR1 and STR2 differ. */ while (TRUE) { if (str1 == str1_end) return 0; else if (*str1 == EOS) return (*str2 == EOS ? 0 : -1); else if (*str2 == EOS) return 1; c1 = g_unichar_tolower( g_utf8_get_char( str1 )); c2 = g_unichar_tolower( g_utf8_get_char( str2 )); if (c1 != c2) return (c1 < c2 ? -1 : 1); str1 = g_utf8_next_char( str1 ); str2 = g_utf8_next_char( str2 ); } } /*---------------------------------------------------------------------------*/ char_t * replace_arguments( string_t format, string_t chars, ... ) /* Create a new string with a copy of FORMAT. * Replace each sequence "%C" in FORMAT, where C is the N-th * char in CHARS, by the N-th additional string argument. * Return the result string. It must be freed after use. */ { va_list args; int_t argument_count, i; string_t *arguments; text_t *text; string_t from; /* Copy the arguments into ARGUMENTS. */ va_start( args, chars ); argument_count = strlen( chars ); arguments = new_vector( sizeof( string_t ), argument_count ); for (i = 0; i < argument_count; i++) arguments[i] = va_arg( args, string_t ); va_end( args ); /* Copy TEXT into BUFFER. */ text = new_text(); for (from = format; *from != EOS; from++) { if (*from == '%') { from++; /* Find character *FROM in CHARS. */ for (i = 0; i < argument_count; i++) { if (*from == chars[i]) break; } if (i < argument_count) add_to_text( text, arguments[i] ); else add_char_to_text( text, *from ); } else ADD_CHAR_TO_TEXT( text, *from ); } free_mem( &arguments ); return text_to_string( &text ); } /*---------------------------------------------------------------------------*/ char_t * double_to_string( double number ) /* Convert NUMBER to a string. It must be freed after use. */ { char_t buffer[30]; sprintf( buffer, "%.11G", number ); return new_string( buffer, NULL ); } /*---------------------------------------------------------------------------*/ char_t * int_to_string( int_t number ) /* Convert NUMBER to a string. It must be freed after use. */ { char_t buffer[12]; sprintf( buffer, "%d", number ); return new_string( buffer, NULL ); } /* Error handling. ==========================================================*/ void throw( void ) /* Call the current error handler. * If there is no current error handler, print error and exit. */ { if (current_error_handler != NULL) longjmp( *current_error_handler, 1 ); else { fprintf( stderr, "%s: %s\n", program_name, error_text->buffer ); exit( 1 ); } } /*---------------------------------------------------------------------------*/ void complain( string_t message, ... ) /* Save the error MESSAGE in ERROR_TEXT. * Additional arguments to "complain" are inserted where * "%s" (string_t ARGUMENT), "%c" (char_t ARGUMENT), "%u" (gunichar ARGUMENT), * or "%d" (int_t ARGUMENT) is part of MESSAGE. */ { va_list args; clear_text( error_text ); va_start( args, message ); VA_PRINT_TEXT( error_text, message, args ); va_end( args ); throw(); } /*---------------------------------------------------------------------------*/ void program_message( void ) /* Print some information about the program. */ { printf( "This is %s, version %s.\n", program_name, malaga_version ); printf( "Copyright (C) 1995 Bjoern Beutel.\n" ); printf( "This program is part of Malaga, " "a system for Natural Language Analysis.\n" ); printf( "You can distribute it under the terms " "of the GNU General Public License.\n" ); } /* Module initialisation. ===================================================*/ void init_basic( string_t prog_name ) /* Initialise this module. PROG_NAME should be the name of the program. */ { error_text = new_text(); program_name = prog_name; in_emacs_malaga_mode = (getenv( "MALAGA_MODE" ) != NULL); #ifdef WIN32 /* We must switch off buffering by hand if we are connected to Emacs. */ if (getenv( "EMACS" ) != NULL) { setbuf( stdout, NULL ); setbuf( stderr, NULL ); } #endif } /*---------------------------------------------------------------------------*/ void terminate_basic( void ) /* Terminate this module. */ { free_text( &error_text ); } /* End of file. =============================================================*/ malaga-7.12/basic.h0000644000175000017500000002540610425350036013444 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This file contains basic types, macros and functions used everywhere. */ /* Constants. ===============================================================*/ #undef NULL #define NULL 0 /* Null pointer. */ enum {BITS_PER_BYTE = 8}; /* Attribute for a function that never returns. */ #ifdef __GNUC__ #define NO_RETURN __attribute__((noreturn)) #else #define NO_RETURN #endif /* Basic types. =============================================================*/ /* Numeric types. */ typedef signed char byte_t; /* Signed 8 bits. */ typedef unsigned char u_byte_t; /* Unsigned 8 bits. */ typedef signed short short_t; /* Signed 16 bits. */ typedef unsigned short u_short_t; /* Unsigned 16 bits. */ typedef signed int int_t; /* Signed 32 bits. */ typedef unsigned int u_int_t; /* Unsigned 32 bits. */ typedef unsigned long ptr_t; /* Pointer in arithmetic expressions. */ /* Character types. */ typedef char char_t; /* A single char. */ typedef const char_t *string_t; /* A constant EOS-terminated C string. */ enum {EOS= '\0'}; /* End-Of-String control character. */ #define ORD(c) ((u_byte_t) (c)) /* The ordinal number of character C. */ /* Boolean type. */ #undef bool_t /* conflicts with "bool_t" definition. */ #undef TRUE #undef FALSE typedef enum {FALSE, TRUE} bool_t; /* Macros. ==================================================================*/ #undef MIN #define MIN(a,b) ((a) < (b) ? (a) : (b)) /* Minimum of A and B. */ #undef MAX #define MAX(a,b) ((a) > (b) ? (a) : (b)) /* Maximum of A and B. */ #undef ABS #define ABS(a) ((a) >= 0 ? (a) : (-a)) /* Absolute value of A. */ #define ARRAY_LENGTH(a) (sizeof(a) / sizeof( (a)[0] )) /* Global variables. ========================================================*/ extern bool_t user_break_requested; /* Flag that indicates that user has send a Ctrl-C. */ extern bool_t split_hangul_syllables; /* Read-only variables. =====================================================*/ extern char_t malaga_version[]; extern string_t program_name; /* This is set by "init_basic". */ extern bool_t in_emacs_malaga_mode; /* This is set by "init_basic". */ /* Program message. =========================================================*/ extern void program_message( void ); /* Print some information about the program. */ /* Forward-linked lists. ====================================================*/ typedef struct list_node /* A node in a list of nodes. */ { struct list_node *next; /* Next list node. */ } list_node_t; typedef struct /* A list of nodes. */ { list_node_t *first, *last; /* The first and last element in the list. */ } list_t; typedef enum {LIST_START, LIST_END} position_t; /* The position where a new element is added to a list. */ extern void clear_list( list_t *list ); /* Initialise LIST to be an empty list */ extern void add_node( list_t *list, list_node_t *node, position_t position ); /* Add NODE to LIST. * If POSITION = LIST_START, add it at the start of the list; * If POSITION = LIST_END, add it at the end. */ extern void insert_node( list_t *list, list_node_t *node, list_node_t *prev ); /* Insert NODE in LIST, behind PREV. * If PREV == NULL, insert NODE at the beginning of the list. */ extern void *remove_first_node( list_t *list ); /* Remove the first node in LIST and return it. */ extern void remove_node( list_t *list, list_node_t *node ); /* Remove NODE in LIST. */ extern void combine_lists( list_t *list1, list_t *list2 ); /* Append LIST2 to LIST1. * LIST1 will contain the concatenation; LIST2 will be empty. */ extern void *new_node( list_t *list, int_t size, position_t position ); /* Add a node of size SIZE to LIST. * If POSITION = LIST_START, add the element at the start of the list; * If POSITION = LIST_END, add the element at the end. * Return the newly created node. */ extern void free_first_node( list_t *list ); /* Remove first node in LIST and free it. */ extern void free_node( list_t *list, list_node_t *node ); /* Remove NODE from LIST and free it. */ /* Iterate through a "list_t". */ #define FOREACH(var, list) \ for ((var) = (void *) (list).first; \ (var) != NULL; \ (var) = (void *) (var)->next) /* Iterate through a "list_t" and free every node in it. */ #define FOREACH_FREE(var, list) \ for ((var) = (void *) (list).first; \ (var) != NULL; \ (var) = (void *) (var)->next, free_first_node( &(list) )) /* Memory functions. ========================================================*/ extern void *new_mem( int_t item_size ); /* Allocate a memory block of ITEM_SIZE bytes, clear it and return it. * If memory is out, call the function "error". */ extern void *new_vector( int_t item_size, int_t item_count ); /* Allocate a memory block to contain ITEM_COUNT items of size ITEM_SIZE, * clear it and return it. * If memory is out, call the function "error". */ extern int_t renew_vector( void *block_p, int_t item_size, int_t item_count ); /* Realloc *BLOCK_P to contain ITEM_COUNT items of ITEM_SIZE bytes each. * Return ITEM_COUNT. * If memory is out, call the function "error". */ extern void free_mem( void *pointer ); /* Free memory *POINTER points to, and set *POINTER to NULL. */ /* String functions. ========================================================*/ extern char_t *new_string( string_t string, string_t end ); /* Allocate memory and copy STRING into it. * If END != NULL, it marks the end of the string. * The result string must be freed after use. */ extern char_t *new_string_readable( string_t from, string_t from_end ); /* Like "new_string", but copy a "\" in front of quotes * and copy any control chars in octal code: "\000". * If FROM_END != NULL, it marks the end of the string. * The result string must be freed after use. */ extern char_t *concat_strings( string_t first_string, ... ); /* Concatenate a list of strings and return the result string. * Must have NULL-terminated list of strings as parameters. * The result string must be freed after use. */ extern int_t strcmp_no_case( string_t str1, string_t str2 ); /* Return (case insensitive) lexical order of STR1 and STR2: * Result is -1 if STR1 < STR2, * 0 if STR1 = STR2, * 1 if STR1 > STR2. */ extern int_t strncmp_no_case( string_t str1, string_t str2, int_t n ); /* Return (case insensitive) lexical order of STR1 and STR2, * but compare only the first N characters. * Result is -1 if STR1 < STR2, * 0 if STR1 = STR2, * 1 if STR1 > STR2. */ extern string_t next_non_space( string_t string ); /* Return STRING, but without leading spaces. */ extern char_t *double_to_string( double number ); /* Convert NUMBER to a string. The string must be freed after use. */ extern char_t *int_to_string( int_t number ); /* Convert NUMBER to a string. The string must be freed after use. */ extern char_t *replace_arguments( string_t format, string_t chars, ... ); /* Create a new string with a copy of FORMAT. * Replace each sequence "%C" in FORMAT, where C is the N-th * char in CHARS, by the N-th additional string argument. * The result string must be freed after use. */ /* Text functions. ==========================================================*/ /* A data structure that contains a string that may grow indefinitely. */ typedef struct { char_t *buffer; int_t buffer_size; int_t string_size; } text_t; extern text_t *new_text( void ); /* Return a new text structure. */ extern void clear_text( text_t *text ); /* Initialize TEXT to an empty string. */ extern void free_text( text_t **text_p ); /* Free the content of *TEXT_P. */ extern void add_to_text( text_t *text, string_t string ); /* Add STRING to TEXT. */ extern void add_char_to_text( text_t *text, char_t character ); /* Add CHARACTER to TEXT. */ void add_unichar_to_text( text_t *text, gunichar c ); /* Add C to TEXT. */ extern void insert_in_text( text_t *text, string_t string, int_t position ); /* Insert STRING at POSITION in TEXT (position counts from 0 onward). */ extern void insert_char_in_text( text_t *text, char_t character, int_t position ); /* Insert CHARACTER at POSITION in TEXT. */ extern void print_text( text_t *text, string_t format, ... ); /* Add FORMAT to TEXT, replace any "%s" with a "string_t" argument, * and any "%d" with an "int_t" argument. */ extern char_t *text_to_string( text_t **text_p ); /* Return content of *TEXT_P as a string and delete *TEXT_P. * The string must be freed after use. */ /* Add CHARACTER to TEXT (macro version). */ #define ADD_CHAR_TO_TEXT( text, character ) \ do { \ if (text->buffer_size < text->string_size + 2) \ { \ text->buffer_size = renew_vector( &text->buffer, sizeof( char_t ), \ 2 * (text->string_size + 1) ); \ } \ text->buffer[ text->string_size++ ] = character; \ text->buffer[ text->string_size ] = EOS; \ } while (FALSE) /* Error handlers. ==========================================================*/ /* The syntax of an error handler is: * TRY STATEMENT1 * IF_ERROR STATEMENT2 * FINALLY STATEMENT3 * END_TRY; * * The parts "IF_ERROR STATEMENT2" and "FINALLY STATEMENT3" are optional. * * First, STATEMENT1 is executed. * If the function "error" is called in STATEMENT1 or in a function * called from there, STATEMENT2 and then STATEMENT3 will be executed * (if they exist). * If the function "error" is not called, STATEMENT3 will executed. * In STATEMENT2, you can use the statement "RESUME" to leave the error * state. */ #define TRY \ do { \ jmp_buf error_handler, *older_error_handler = current_error_handler; \ volatile bool_t rethrow; \ current_error_handler = &error_handler; \ if (! (rethrow = setjmp( error_handler ))) #define IF_ERROR else #define FINALLY /* Nothing. */ #define END_TRY \ current_error_handler = older_error_handler; \ if (rethrow) \ throw(); \ } while (FALSE) #define RESUME rethrow = FALSE extern text_t *error_text; /* The text of the last error. */ extern jmp_buf *current_error_handler; /* The active innermost error handler */ extern void throw( void ) NO_RETURN; /* Call the current error handler. * If there is no current error handler, print error and exit. */ extern void complain( string_t message, ... ) NO_RETURN; /* Save the error MESSAGE in ERROR_TEXT. * Additional arguments to "complain" are inserted where * "%s" (string_t ARGUMENT), "%c" (char_t ARGUMENT), "%u" (gunichar ARGUMENT), * or "%d" (int_t ARGUMENT) is part of MESSAGE. */ /* Module initialisation. ===================================================*/ extern void init_basic( string_t prog_name ); /* Initialise this module. PROG_NAME should be the name of the program. */ extern void terminate_basic( void ); /* Terminate this module. */ /* End of file. =============================================================*/ malaga-7.12/breakpoints.c0000644000175000017500000002555010236624140014677 0ustar bjoernbjoern/* Copyright (C) 1995 Gerald Schueller. */ /* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* In this file, the administration of breakpoints is managed. */ /* Includes. ================================================================*/ #include #include #include #include #include #include "basic.h" #include "pools.h" #include "values.h" #include "files.h" #include "rule_type.h" #include "rules.h" #include "input.h" #include "commands.h" #include "breakpoints.h" /* Types. ===================================================================*/ typedef struct /* Definition of a breakpoint. */ { list_node_t *next; int_t number; /* Breakpoint number. */ rule_sys_t *rule_sys; /* Rule system of breakpoint. */ int_t instr; /* Instruction to break at. */ } breakpoint_t; /* Variables. ===============================================================*/ static int_t breakpoint_count; /* Number of breakpoints so far. */ static list_t breakpoints; /* List of breakpoints. */ static int_t rule_system_count; /* Number of loaded rule systems. */ static rule_sys_name_t *rule_systems; /* Name for each rule system. */ /* Functions. ===============================================================*/ static int_t instruction_at( rule_sys_t *rule_sys, string_t file, int_t line ) /* Return the index of the first instruction at RULE_SYS, FILE, LINE * or -1 if there is no code there. */ { src_line_t *src_line; for (src_line = rule_sys->src_lines; src_line < rule_sys->src_lines + rule_sys->src_line_count; src_line++) { if (src_line->file != -1 && strcmp( rule_sys->strings + src_line->file, file ) == 0 && src_line->line >= line) { return src_line->instr; } } return -1; } /*---------------------------------------------------------------------------*/ static int_t find_rule_by_name( rule_sys_t *rule_sys, string_t rule_name ) /* Find the first line of rule RULE_NAME in RULE_SYS. * Return the first instruction of this rule. */ { int_t i; for (i = 0; i < rule_sys->rule_count; i++) { if (strcmp_no_case( rule_sys->strings + rule_sys->rules[i].name, rule_name ) == 0) { return rule_sys->rules[i].first_instr; } } return -1; } /*---------------------------------------------------------------------------*/ static string_t complete_file_name( rule_sys_t *rule_sys, string_t file_name ) /* Return FILE_NAME completed if it is in RULE_SYS, else return NULL. */ { src_line_t *src_line; for (src_line = rule_sys->src_lines; src_line < rule_sys->src_lines + rule_sys->src_line_count; src_line++) { if (src_line->file != -1 && strcmp( name_in_path( rule_sys->strings + src_line->file ), file_name ) == 0) { return rule_sys->strings + src_line->file; } } return NULL; } /*---------------------------------------------------------------------------*/ static void parse_breakpoint( string_t arguments, rule_sys_t **rule_sys, string_t *file, int_t *line ) /* Parse a breakpoint specification; ARGUMENTS must be * "" (nothing) or * "LINE_NUMBER" or * "[RULE_SYS_NAME] [FILE LINE_NUMBER | RULE_NAME]". * Set RULE_SYS, FILE and LINE according to it. */ { int_t first_instr; string_t argument; int_t i; if (pc == -1) { *rule_sys = NULL; *file = NULL; *line = -1; } else { *rule_sys = executed_rule_sys; source_of_instr( executed_rule_sys, pc, line, file, NULL ); } if (*arguments >= '0' && *arguments <= '9') *line = parse_cardinal( &arguments ); else if (*arguments != EOS) /* Read file name or rule name. */ { argument = parse_word( &arguments ); /* See if ARGUMENT is a rule system name. */ for (i = 0; i < rule_system_count; i++) { if (rule_systems[i].rule_sys != NULL && strcmp_no_case( argument, rule_systems[i].name ) == 0) { *rule_sys = rule_systems[i].rule_sys; free_mem( &argument ); argument = parse_word( &arguments ); break; } } /* If a line number follows, we have a file name. */ if (*arguments >= '0' && *arguments <= '9') { *line = parse_cardinal( &arguments ); if (*rule_sys != NULL) *file = complete_file_name( *rule_sys, argument ); else { for (i = 0; i < rule_system_count; i++) { if (rule_systems[i].rule_sys != NULL) { *rule_sys = rule_systems[i].rule_sys; *file = complete_file_name( *rule_sys, argument ); if (*file != NULL) break; } } } if (*file == NULL) complain( "No source file \"%s\".", argument ); } else /* ARGUMENT should be a rule name. */ { if (*rule_sys != NULL) first_instr = find_rule_by_name( *rule_sys, argument ); else { first_instr = -1; /* Prevent a "not initialized" warning. */ for (i = 0; i < rule_system_count; i++) { if (rule_systems[i].rule_sys != NULL) { *rule_sys = rule_systems[i].rule_sys; first_instr = find_rule_by_name( *rule_sys, argument ); if (first_instr != -1) break; } } } if (first_instr == -1) complain( "Rule \"%s\" is unknown.", argument ); /* Find the corresponding source line. */ source_of_instr( *rule_sys, first_instr, line, file, NULL ); } free_mem( &argument ); } parse_end( &arguments ); if (*file == NULL) complain( "Missing file name." ); if (*line == -1) complain( "Missing line number." ); } /*---------------------------------------------------------------------------*/ int_t at_breakpoint( rule_sys_t *rule_sys, int_t instr ) /* Return breakpoint number if INSTR in RULE_SYS hits a * breakpoint; return 0 else. */ { breakpoint_t *bp; FOREACH( bp, breakpoints ) { if (bp->rule_sys == rule_sys && bp->instr == instr) return bp->number; } return 0; } /*---------------------------------------------------------------------------*/ static void delete_all_breakpoints( void ) /* Run through breakpoint list and free all breakpoints. */ { while (breakpoints.first != NULL) free_first_node( &breakpoints ); } /*---------------------------------------------------------------------------*/ static void do_delete( string_t argument ) /* Remove a breakpoint. */ { string_t word; int_t break_num; breakpoint_t *breakpoint; if (*argument >= '0' && *argument <= '9') { while (*argument != EOS) { break_num = parse_cardinal( &argument ); /* Delete breakpoint with BREAK_NUM. */ FOREACH( breakpoint, breakpoints ) { if (breakpoint->number == break_num) break; } if (breakpoint == NULL) complain( "No breakpoint %d.", break_num ); free_node( &breakpoints, (list_node_t *) breakpoint ); } } else { word = parse_word( &argument ); if (strcmp_no_case( word, "all" ) != 0) complain( "\"all\" or breakpoint numbers expected, not \"%s\".", word ); delete_all_breakpoints(); } parse_end( &argument ); } command_t delete_command = { "delete d", do_delete, "Delete breakpoints.\n" "Usage:\n" " delete NUMBER ... -- Delete specified breakpoints.\n" " delete all -- Delete all breakpoints.\n" }; /*---------------------------------------------------------------------------*/ void get_breakpoint( string_t argument, rule_sys_t **rule_sys_p, int_t *instr_p ) /* Parse a breakpoint in ARGUMENT and set the remaining arguments. */ { string_t file; int_t line; /* Parse breakpoint ARGUMENT. */ parse_breakpoint( argument, rule_sys_p, &file, &line ); /* Find first instruction of this breakpoint */ *instr_p = instruction_at( *rule_sys_p, file, line ); if (*instr_p == -1) complain( "No code at file \"%s\", line %d.", name_in_path( file ), line ); } /*---------------------------------------------------------------------------*/ static void do_break( string_t argument ) /* Define a breakpoint. */ { rule_sys_t *rule_sys; string_t file, rule; int_t line, instr; breakpoint_t *breakpoint; /* Parse breakpoint ARGUMENT. */ get_breakpoint( argument, &rule_sys, &instr ); /* Check if other breakpoints exist at this position. */ FOREACH( breakpoint, breakpoints ) { if (breakpoint->rule_sys == rule_sys && breakpoint->instr == instr) complain( "Breakpoint %d already set here.", breakpoint->number ); } /* Add breakpoint. */ breakpoint = new_node( &breakpoints, sizeof( breakpoint_t ), LIST_END ); breakpoint->number = ++breakpoint_count; breakpoint->rule_sys = rule_sys; breakpoint->instr = instr; /* Print source position of the instruction. */ source_of_instr( rule_sys, instr, &line, &file, &rule ); printf( "Breakpoint %d in file \"%s\", line %d, rule \"%s\".\n", breakpoint->number, name_in_path( file ), line, rule ); } command_t break_command = { "break b", do_break, "Set a breakpoint at the specified position.\n" "Usage:\n" " break RULE -- Set a breakpoint at the beginning of RULE.\n" " break FILE LINE -- Set a breakpoint at LINE in FILE.\n" " break LINE -- Set a breakpoint at LINE in the current rule file.\n" " break -- Set a breakpoint at the current line in the current rule file.\n" "The first two forms may begin with a rule system specification.\n" "The last two forms can only be used in debug mode or after a rule error.\n" "You can't set two breakpoints at the same position.\n" }; /*---------------------------------------------------------------------------*/ static void do_list( string_t argument ) /* List breakpoints. */ { breakpoint_t *breakpoint; string_t file, rule; int_t line; parse_end( &argument ); if (breakpoints.first == NULL) printf( "No breakpoints.\n" ); FOREACH( breakpoint, breakpoints ) { source_of_instr( breakpoint->rule_sys, breakpoint->instr, &line, &file, &rule ); printf( "Breakpoint %d in file \"%s\", line %d, rule \"%s\".\n", breakpoint->number, name_in_path( file ), line, rule ); } } command_t list_command = { "list l", do_list, "List all breakpoints.\n" "Usage: list\n" }; /*---------------------------------------------------------------------------*/ void init_breakpoints( int_t rule_sys_count, rule_sys_name_t rule_sys[] ) /* Initialise this module. * Pass the number of rule systems in RULE_SYS_COUNT * and their names in RULE_SYS. */ { rule_system_count = rule_sys_count; rule_systems = rule_sys; clear_list( &breakpoints ); } /*---------------------------------------------------------------------------*/ void terminate_breakpoints( void ) /* Terminate this module. */ { delete_all_breakpoints(); } /* End of file. =============================================================*/ malaga-7.12/breakpoints.h0000644000175000017500000000275310236624145014711 0ustar bjoernbjoern/* Copyright (C) 1995 Gerald Schueller. */ /* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* In this file, the administration of breakpoints is managed. */ /* Types. ===================================================================*/ typedef struct /* Associates a rule system with a name. */ { rule_sys_t *rule_sys; string_t name; /* Name of the above rule system. */ } rule_sys_name_t; /* Functions. ===============================================================*/ extern void get_breakpoint( string_t argument, rule_sys_t **rule_sys_p, int_t *instr_p ); /* Parse breakpoint in ARGUMENT and set *RULE_SYS_P and *INSTR_P. */ extern int_t at_breakpoint( rule_sys_t *rule_sys, int_t instruction ); /* Return breakpoint number if INSTRUCTION in RULE_SYS hits a breakpoint; * return 0 else. */ extern void init_breakpoints( int_t rule_sys_count, rule_sys_name_t rule_sys[] ); /* Initialise this module. Pass the number of rule systems in RULE_SYS_COUNT * and their names in RULE_SYS. */ extern void terminate_breakpoints( void ); /* Terminate this module. */ /* Commands. ================================================================*/ extern command_t delete_command; /* Delete a breakpoint. */ extern command_t break_command; /* Define a breakpoint. */ extern command_t list_command; /* List breakpoints. */ /* End of file. =============================================================*/ malaga-7.12/cache.c0000644000175000017500000001704410612057241013420 0ustar bjoernbjoern/* Copyright (C) 1996 Bjoern Beutel. */ /* Description. =============================================================*/ /* Manages the storage of analysis results for faster access. */ /* Includes. ================================================================*/ #include #include #include #include #include #include #include "basic.h" #include "pools.h" #include "values.h" #include "avl_trees.h" #include "cache.h" /* Types. ===================================================================*/ typedef struct cache_entry /* An entry of the cache tree. */ { avl_node_t avl_node; /* A node in an AVL tree. */ struct cache_entry *prev_ref, *next_ref; /* LRU chain. */ string_t surface; int_t feat_count; /* Number of feature structures in feat_vector. */ value_t *feat_vector; /* A vector of feature structures. */ } cache_entry_t; /* Global Variables. ========================================================*/ int_t cache_accesses; /* Number of calls of "word_in_cache". */ int_t cache_hits; /* Number of successful calls of "word_in_cache". */ /* Variables. ===============================================================*/ static avl_node_t *cache_tree; /* The cache tree. Actually points to * cache_entry_t. */ static int_t max_entry_count; /* Maximum of entries in CACHE_TREE. */ static int_t entry_count; /* Actual number of entries in CACHE_TREE. */ static cache_entry_t *first_ref; /* The entry that was referenced first. */ static cache_entry_t *last_ref; /* The entry that was referenced last. */ /* These are needed for "next_result_in_cache". */ static cache_entry_t *current_entry; static int_t current_result; /* Functions. ===============================================================*/ static int_t compare_cache_entries( avl_node_t *node1, avl_node_t *node2 ) /* A callback function for "avl_tree_insert", "avl_tree_remove", * used to compare "cache_entry_t" nodes. */ { return strcmp( ((cache_entry_t *) node1)->surface, ((cache_entry_t *) node2)->surface ); } /*---------------------------------------------------------------------------*/ static cache_entry_t * new_cache_entry( string_t surf_start, string_t surf_end, int_t feat_count, value_t feat_vector[] ) /* Create cache entry for string at SURF_START..SURF_END. * It has FEAT_COUNT feature structures stored in FEAT_VECTOR. * Return the created entry. */ { cache_entry_t *cache_entry; /* Allocate a cache entry. */ cache_entry = new_mem( sizeof( cache_entry_t ) ); cache_entry->surface = new_string( surf_start, surf_end ); cache_entry->feat_count = feat_count; cache_entry->feat_vector = feat_vector; entry_count++; return cache_entry; } /*---------------------------------------------------------------------------*/ static void free_cache_entry( cache_entry_t **cache_entry ) /* Free the memory allocated for *CACHE_ENTRY. */ { int_t i; if (*cache_entry != NULL) { for (i = 0; i < (*cache_entry)->feat_count; i++) free_mem( &(*cache_entry)->feat_vector[i] ); free_mem( &(*cache_entry)->feat_vector ); free_mem( &(*cache_entry)->surface ); free_mem( cache_entry ); entry_count--; } } /*---------------------------------------------------------------------------*/ static void reference_entry( cache_entry_t *entry ) /* Put ENTRY at end of LRU-list if it is not already there. */ { if (entry != last_ref) { /* Remove entry from old position. */ entry->next_ref->prev_ref = entry->prev_ref; if (entry != first_ref) entry->prev_ref->next_ref = entry->next_ref; else first_ref = entry->next_ref; /* Enter entry in new position. */ entry->prev_ref = last_ref; entry->next_ref = NULL; last_ref->next_ref = entry; last_ref = entry; } } /*---------------------------------------------------------------------------*/ bool_t word_in_cache( string_t surf_start, string_t surf_end ) /* Check if word in [SURF_START..SURF_END] is in the cache. * Return TRUE if word found. Use "next_result_in_cache" to get next result. */ { cache_entry_t *entry; int_t result; cache_accesses++; entry = (cache_entry_t *) cache_tree; while (entry != NULL) { result = strncmp( surf_start, entry->surface, surf_end - surf_start ); if (result == 0 && entry->surface[ surf_end - surf_start ] != EOS) result = -1; if (result < 0) entry = (cache_entry_t *) entry->avl_node.left; else if (result > 0) entry = (cache_entry_t *) entry->avl_node.right; else /* Word found. */ { reference_entry( entry ); current_entry = entry; current_result = 0; cache_hits++; return TRUE; } } return FALSE; } /*---------------------------------------------------------------------------*/ value_t next_result_in_cache( void ) /* Return the next feature structure for the word found by "word_in_cache". * Return NULL if no more feature structure exists. */ { value_t result; if (current_result >= current_entry->feat_count) return NULL; result = current_entry->feat_vector[ current_result ]; current_result++; return result; } /*---------------------------------------------------------------------------*/ static void remove_entry_from_cache( void ) /* Delete an entry from cache. */ { cache_entry_t *entry; /* Remove first element from LRU list. */ entry = first_ref; first_ref = entry->next_ref; if (first_ref != NULL) first_ref->prev_ref = NULL; else last_ref = NULL; /* Remove ENTRY from tree. */ remove_avl_node( (avl_node_t *) entry, (avl_node_t **) &cache_tree, compare_cache_entries ); free_cache_entry( &entry ); } /*---------------------------------------------------------------------------*/ void enter_in_cache( string_t surf_start, string_t surf_end, int_t feat_count, value_t feat_vector[] ) /* Enter the word in [SURF_START..SURF_END] in the cache. * It has FEAT_COUNT feature structures, stored in FEAT_VECTOR[]. * Be sure that the word is not yet in the cache. */ { cache_entry_t *cache_entry; if (entry_count >= max_entry_count) remove_entry_from_cache(); cache_entry = new_cache_entry( surf_start, surf_end, feat_count, feat_vector ); /* Enter entry in cache tree. */ insert_avl_node( (avl_node_t *) cache_entry, (avl_node_t **) &cache_tree, compare_cache_entries ); /* Put entry at end of LRU table. */ if (last_ref != NULL) last_ref->next_ref = cache_entry; cache_entry->prev_ref = last_ref; cache_entry->next_ref = NULL; last_ref = cache_entry; if (first_ref == NULL) first_ref = cache_entry; } /*---------------------------------------------------------------------------*/ void clear_cache( void ) /* Remove all entries from the cache. */ { while (entry_count > 0) remove_entry_from_cache(); } /*---------------------------------------------------------------------------*/ void set_cache_size( int_t size ) /* Set maximum number of cache entries to SIZE. */ { max_entry_count = size; while (entry_count > max_entry_count) remove_entry_from_cache(); } /*---------------------------------------------------------------------------*/ int_t get_cache_size( void ) /* Get actual number of cache entries. */ { return entry_count; } /*---------------------------------------------------------------------------*/ int_t get_cache_maximum( void ) /* Get maximum number of cache entries. */ { return max_entry_count; } /* End of file. =============================================================*/ malaga-7.12/cache.h0000644000175000017500000000301710236624154013425 0ustar bjoernbjoern/* Copyright (C) 1996 Bjoern Beutel. */ /* Description. =============================================================*/ /* Manages the storage of analysis results for faster access. */ /* Variables. ===============================================================*/ extern int_t cache_accesses; /* Number of calls of "word_in_cache". */ extern int_t cache_hits; /* Number of successful calls of "word_in_cache". */ /* Functions. ===============================================================*/ extern bool_t word_in_cache( string_t surf_start, string_t surf_end ); /* Return whether the word form SURF_START..SURF_END is in the cache. */ extern value_t next_result_in_cache( void ); /* Return the next result feature structure for a word form. * Use this function after calling "word_in_cache". */ extern void enter_in_cache( string_t surf_start, string_t surf_end, int_t feat_count, value_t feat_vector[] ); /* Enter the word form SURF_START..SURF_END in the cache * with FEAT_COUNT feature structures FEAT_VECTOR[]. */ extern void clear_cache( void ); /* Delete all cache entries. */ extern void set_cache_size( int_t size ); /* Set maximum number of cache entries to SIZE. */ extern int_t get_cache_size( void ); /* Get actual number of cache entries. */ extern int_t get_cache_maximum( void ); /* Get maximum number of cache entries. */ /* End of file. =============================================================*/ malaga-7.12/canvas.c0000644000175000017500000024744610764164273013657 0ustar bjoernbjoern/* Copyright (C) 2002 Bjoern Beutel. */ /* Description. =============================================================*/ /* Common routines for all Malaga GTK windows. */ /* Includes. ================================================================*/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "basic.h" #include "scanner.h" #include "input.h" #include "files.h" #include "canvas.h" /* Constants. ===============================================================*/ enum {BRACKET_RATIO = 6}; /* Height:width ratio of angle brackets. */ enum {BUFFER_SIZE = 200}; /* Size of Postscript conversion buffer. */ #define CM (72.0 / 2.54) /* How many Postscript points make one centimeter. */ #define PAPER_WIDTH (20.9 * CM) /* Default width of paper. */ #define PAPER_HEIGHT (29.65 * CM) /* Default height of paper. */ #define PAPER_BORDER (1.5 * CM) #define PAGE_WIDTH (PAPER_WIDTH - 2 * PAPER_BORDER) #define PAGE_HEIGHT (PAPER_HEIGHT - 2 * PAPER_BORDER) /* Hangul code points in Unicode. */ enum {FIRST_JAMO = 0x3131, LAST_JAMO = 0x3163, JAMO_COUNT = (LAST_JAMO - FIRST_JAMO + 1), FIRST_SYLLABLE = 0xac00, LAST_SYLLABLE = 0xd7a3, SYLLABLE_COUNT = (LAST_SYLLABLE - FIRST_SYLLABLE + 1)}; /* Code points in the N3F Hangul Postscript font. */ enum {FIRST_CHOSEONG = 162, CHOSEONG_COUNT = 19, NO_CHOSEONG = 161, FIRST_JUNGSEONG = 182, JUNGSEONG_COUNT = 21, NO_JUNGSEONG = 181, FIRST_JONSEONG = 203, JONSEONG_COUNT = 28}; /*---------------------------------------------------------------------------*/ /* This table maps Unicode Hangul Jamos to the N3F encoding. It starts at * code point FIRST_JAMO. */ static char_t jamos[JAMO_COUNT] = { 162, 163, 205, 164, 207, 208, 165, 166, 167, 211, 212, 213, 214, 215, 216, 217, 168, 169, 170, 220, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202 }; /*---------------------------------------------------------------------------*/ /* Widths of Adobe Helvetica characters in Latin1 encoding. */ static int widths_latin1[256] = { 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 355, 556, 556, 889, 667, 222, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278, 584, 584, 584, 556, 1015, 667, 667, 722, 722, 667, 611, 778, 722, 278, 500, 667, 556, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 278, 278, 278, 469, 556, 222, 556, 556, 500, 556, 556, 278, 556, 556, 222, 222, 500, 222, 833, 556, 556, 556, 556, 333, 500, 278, 556, 500, 722, 500, 500, 500, 334, 260, 334, 584, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 333, 333, 333, 333, 333, 333, 333, 333, 278, 333, 333, 278, 333, 333, 333, 278, 333, 556, 556, 556, 556, 260, 556, 333, 737, 370, 556, 584, 333, 737, 333, 400, 584, 333, 333, 333, 556, 537, 278, 333, 333, 365, 556, 834, 834, 834, 611, 667, 667, 667, 667, 667, 667,1000, 722, 667, 667, 667, 667, 278, 278, 278, 278, 722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611, 556, 556, 556, 556, 556, 556, 889, 500, 556, 556, 556, 556, 278, 278, 278, 278, 556, 556, 556, 556, 556, 556, 556, 584, 611, 556, 556, 556, 556, 500, 556, 500 }; /* Widths of N3F-5 chars in N3F Encoding. Table starts at code point * FIRST_N3F. */ enum {FIRST_N3F = 161, LAST_N3F = 229, N3F_COUNT = LAST_N3F - FIRST_N3F + 1}; static int widths_n3f[N3F_COUNT] = { 436, 436, 602, 436, 436, 602, 436, 436, 436, 625, 436, 663, 436, 436, 687, 436, 436, 436, 436, 436, 80 , 370, 446, 370, 446, 286, 459, 286, 459, 80 , 370, 446, 268, 80 , 80 , 286, 459, 268, 80 , 80 , 268, 268, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }; /*---------------------------------------------------------------------------*/ static const char n3f_font_definition[] = "%%BeginResource: font n3f-5\n" "%\n" "% Copyright 1996, 1998 Lee Yongjae \n" "%\n" "% Permission to use, copy, modify, and distribute this software and its\n" "% documentation for any purpose and without fee is hereby granted,\n" "% provided that the above copyright notice appears in all copies and\n" "% that both, the copyright notice and this permission notice, appear in\n" "% supporting documentation, and that the name of the copyright holder\n" "% is not used in advertising or publicity pertaining to distribution\n" "% of the software without specific, written prior permission.\n" "%\n" "12 dict begin /FontInfo 9 dict dup begin /FullName (n3f-5) readonly def\n" "/isFixedPitch false def /Notice (Copyright 1996 Lee Yongjae) def\n" "/ItalicAngle 0 def /UnderlinePosition -100 def /UnderlineThickness 50 def\n" "end readonly def /FontName /n3f-5 def /Encoding 256 array 0 1 255 {1 index\n" "exch /.notdef put} for dup 161 /k_f1 put dup 162 /k_K put dup 163 /k_Kk put\n" "dup 164 /k_N put dup 165 /k_T put dup 166 /k_Tt put dup 167 /k_R put dup\n" "168 /k_M put dup 169 /k_P put dup 170 /k_Pp put dup 171 /k_S put dup 172\n" "/k_Ss put dup 173 /k_O put dup 174 /k_C put dup 175 /k_Cc put dup 176 /k_Ch\n" "put dup 177 /k_Kh put dup 178 /k_Th put dup 179 /k_Ph put dup 180 /k_H put\n" "dup 181 /k_f2 put dup 182 /k_a put dup 183 /k_ae put dup 184 /k_ya put dup\n" "185 /k_yae put dup 186 /k_eo put dup 187 /k_e put dup 188 /k_yeo put dup\n" "189 /k_ye put dup 190 /k_o put dup 191 /k_wa put dup 192 /k_wae put dup 193\n" "/k_oe put dup 194 /k_yo put dup 195 /k_u put dup 196 /k_weo put dup 197\n" "/k_we put dup 198 /k_wi put dup 199 /k_yu put dup 200 /k_eu put dup 201\n" "/k_yi put dup 202 /k_i put dup 203 /k_k put dup 204 /k_kk put dup 205 /k_ks\n" "put dup 206 /k_n put dup 207 /k_nc put dup 208 /k_nh put dup 209 /k_t put\n" "dup 210 /k_l put dup 211 /k_lk put dup 212 /k_lm put dup 213 /k_lp put dup\n" "214 /k_ls put dup 215 /k_lth put dup 216 /k_lph put dup 217 /k_lh put dup\n" "218 /k_m put dup 219 /k_p put dup 220 /k_ps put dup 221 /k_s put dup 222\n" "/k_ss put dup 223 /k_ng put dup 224 /k_c put dup 225 /k_ch put dup 226\n" "/k_kh put dup 227 /k_th put dup 228 /k_ph put dup 229 /k_h put readonly def\n" "/PaintType 0 def /FontType 1 def /FontMatrix [0.001 0 0 0.001 0 0] readonly\n" "def /FontBBox { -529 -252 703 701 } readonly def /UniqueID 4030051 def\n" "currentdict end currentfile eexec\n" "D9D66F633B846A989B9974B0179FC6CC445BCF7C3C3333173232E3FDBFF43949\n" "1DB866C3EF1B30F529F56D40DA3462EACD8F8BDB057A36A23611B08B42B62E04\n" "F78389045DBF331069C7CB96640FF89489B5599FD6BE8EF25688798EC4F2C13F\n" "431245DFF93AA4EF41E6D82885E1C6AB7F67F4BF4B809E88F7CBB013AA0CCEF4\n" "187B2C4653946A3B5C610D2FF1E0E7D3AB43709002F44517BE09E1C3F35D2F59\n" "70F3A4615689AA659C58AB0C3741705267C93A5D6CE9C8D3BC8F086A7492CF58\n" "003DE8CA89A1609FA0E9E6FFF90E99BA58F8C5D720E87110453D4959E5333F1F\n" "2B383165401D07AC9CB68B69A6C2E343001EA94177A6EFE9F6CB1DB741B84D6B\n" "BD1E84F5175262D86AB8AB478840A805BA8BD467219CD28A5C4B3820CD173783\n" "258C58123D0077CD375CFF73E250093D72C85E8EDE7FEE4B09F1EED41C10705D\n" "FEA2ACC563D8471B4B266DE8E655F92D3620EEF32EB23D83FB199B98894CD857\n" "7E035EA9C44A817375FCB4A9BCE3370EF65EE1F74A86B4EFAC30F091D4D34A3C\n" "EEE0BF8897E6C79DF68ACE676F3F2145304CF7E6339D1EE856ADE3DFB7F9D696\n" "2E7F000C17B4E1404C86D34ADA528F30CB522C18A00B709D05B77EF2BDD58B88\n" "2B96C6623112C67849619CA63CB8AC370617E70FFC7FBA86E5DFFBC4B2EE6062\n" "E701743060851BD8DB9DB790793CBF2DCEE3E5A755CFF7FCB5EB90E05899DEF7\n" "EA3BFD6B1B6163488E883065B81AE93C4214F0F0CD360B84B337483286EC37DD\n" "52E8DBCD28B403DDBA54E355721B6EBA71EF5B565D43BC79FD6A051673CFDBED\n" "BEF9342B3C9157EEE4954566F87AF445C8A6CC6E5537429B2527C5F3FC38108E\n" "BDE872FEE3F26A17EFDBB9D73B43B65CB13E24100DFA006BEB1832B9C45C642F\n" "239155ED4ED43F0782AF636F17EB20BE8C8967E283DC6A00B15EAF8E8D239C29\n" "944F60CB5DE69B4DF9F56EE75D274C897DB3772D7CD0E1275E30C73F0C023560\n" "917768FE34D77039619F153CD8AC0826DF1C685DCFA7A6688008E0411FCB6EC1\n" "5CFA71301D5162A04BC7B715282F4CC8EA0A5E7D36665DF8136D37227F139DC7\n" "0CBFBCA56669AE03A0F69B23E7D313BB70F754419AFD2E9E8B6E2ED827D71773\n" "24612554F335CBE16973BC44C1AADE6C2716B284777A2486BFEA7ABEE1D2E4BB\n" "8E4FF2F56DCF2767A73599268B055E856549A52A6A775C61C4A02C6AAEF3C444\n" "C709146DE1678608F5D46A50C126DC5E4161A67916D828E9BD8D3BEA2A834527\n" "CEF127D99ADADE3895DFC60447332E0E34D9F34C544FCABCE014DB9E0469E1B6\n" "9E32205941840B9BF973B5A70CFD1D2A14DAA1159517D180565ABDAB2CFB296B\n" "AFB72AB045423ED9094F0E300B7C06E1D5C32E7315A354033E02EAAFB0BBB4E6\n" "E4990C5C0C9D40406608B43835C76463EC08FBBF5A3742EB2AB231DC2B3DC3C0\n" "BD7C9793C9A12FA4200E6F59DD7ABAD4C05684D1136FD2EB7ECA405596E23784\n" "C73A815F3EFADDDE43C92BA6B1776BA381423C731F10D7F85D5853A8C9124183\n" "EFC63F8BEC944AE48AD4917F51ED03F87755CAB6FFF549BE13F92BE50B4806B3\n" "16A5DAD7A6F4D845E853C1CC115AB7E455293A1C911AACD1457282AF25336FDB\n" "B94A55F79F11B7C95CA81494697BF72C8866CAD79633F0154B6D3DBADB7EE005\n" "2A0EF550284490DD1B034946E245FC2CC1EFD485D1F376AEBDCFF96A838C3ECE\n" "4318658747C18B728784C78289C86891300D53F4EAD5A0CF90DF91632AB92FE4\n" "1BCD86336AF3DD0936B0CE6E4ADF70BFB767DC29F05E7F874A6366D8E63DA571\n" "089C6C9C49625CE9FFFBB596CE078D175A6213800E59218D7B8DBFC0640CC191\n" "DC5F095B7BD881889D00BA5B8010785626C470C7AAD7D60C054C4FF2EFE9DAEF\n" "997FBAAD4A5C6567838A49B6634BE4AAB05A0806CAC18777E87E0DC6B078F866\n" "E40537462E96004AC6097ED2E47A9725EF80C77DE8AE7898282200D23FCC3337\n" "A4CDB738445AF479009B14ADEB95B2558DEF31712B8915CBD959AFC8F8390A5A\n" "B178F926A57F6C63E84658AB33FCD3D41F3209877ADF46AD8C907C14882397C8\n" "2B2D5A7936D0B92C149ED8A751916471BA052D1302EC62EA274F04AA667821A4\n" "3533DCE8DD20901983D574283A68683D07E37FE59965710F8CAADCB7681DE258\n" "E59CAB0B1793F67F686A311296B2BE7A7D10C868F8BD39A1CEF857B8A4E027FC\n" "97BC55F1C9B2444C04C175350218C60C1944500391DDC69E7FE4455A753A66DC\n" "E85044D657B2D71AFFBA2DB53C70BD06357B687672C78B629AECF6E7C406ED52\n" "5539D9E2C1E7E7EB5B27A206164F06D850A1BC5E92C2CE65C0D3037EC911E440\n" "1C738E8824D2B910C020E1650D5853A7B5D492EC1AE1E1D5C5DB26D5777F11E4\n" "344AB9F87997D46C86C6145590C912FA35AFA2F3F96E3AE2D6A78CE53E4F1F9A\n" "F39EDAC046ACCC5A0AB801FC11C98BDC61D689263040E9633EC3779A4D537448\n" "F805224DC4A9CD3D1353E0D662865A0148B1C3DAC0987B5735DABF8BFF7A7084\n" "F47978869D6CBE9505E58ED8D56784FDA1722B76E87D4DEF3C3BA4483F8AF555\n" "ECD0017C1CBDA13C74FA98B6F1F85185404D5A37B3EA1380BB1F3DFCB977B294\n" "3CC6EBF8C4018D782D96671D2AA125E3DF8D9AE4BAFC09B85DBDA44FA7CD6493\n" "9589D3A258954FE2473F133AB1BDCBDFD79546E823395CDD248410C5D5CADF40\n" "47A5758106F0A92B0AA87F5C548D791A2594A1AAC4AFE84A91DA057724857615\n" "66633131C9A41B7C8315F04B97FBFC80B2D621F88DF6566613FCC27A08222546\n" "6EB0859B060B93EBECE5F69976BAD8BBDB1DCF36DE6A653942A3FE1B58FE88C1\n" "865EA81AEB3945B35AF29B6CAB2943F40936B43110376409CCE7A2BFA1A618CA\n" "E03BA0390E6DA539C6FB4CFE82CD5ED290505C33BDA643254305E3C27288F2AE\n" "0D22BC2C35452E5827BC119154D0953543663C4AFE36C00EF6402370E3D8C0D1\n" "077BBA2BAB79EE3C7C8F70853EDE9E85DF996674F7A5883F3C763BAE63BB22BD\n" "180AE2E1A7E787CE80784EBFD0240E595F9BC3D9750448E870413E0ECAB69004\n" "03DF2D305F6EB4361942E75B0804F1609B5DE3F2C2D4A6C9543EC20F823A87A5\n" "F695983F3FBC101C5000277D81F1EC4ADC2F105E06BC5EB528C399D138572C57\n" "E8DC7A6F41DC6F8D44534388C30BFA963C52BC2F2F786C69BBBD405C7904ADE6\n" "251C08F462A33A1D7D65D954299921053A87C2D8AAC2BDF9D713AD90608C6420\n" "48AD52351B15C2211F17867244284964870D00A19B0B2378F28E232938D0DBC4\n" "48B5FAC2207C17B6BAF3CE9EB82A315354A7EC183226EAC400067E06246BA400\n" "B64212899C7049F4C13A8C079C2A6EA22DDFE73F4EA683B053ED02837BFA669E\n" "BE87C0FBE2FD749D2BBB01CF22A8CBB3F4D543649B45E397F1F3ADAA57F98A3A\n" "0F5ACF4F92541FF903DB28F9A29EB0AAE46430083913B3CD6FAA042D2EEC48A7\n" "79CF038443F660845621E68CA56BAD5DF203A559CF770E515B726149F1821E38\n" "017F04CF73C9B146C1BAF29BC0EA6FCB06FF083201E09C67F16441C37609FF27\n" "5933986E314AC7FEB4CB45523CEC5F46F100D39BA02949F3F05AB76BC5E2F4FD\n" "B91B6EFCD17E2123B260B3B954BE200FE9A6A1AEF77D8BA16CC44E3475D15289\n" "8A6FA3D19D4CE4F3DC0325E40237647A9E2C053CBE4BEFF24F6B2E00FDA93593\n" "176F94639A40546722168D68B5608F8CE798FC5F84D7684ABE805BAD9D8B9AF5\n" "989C2233956A4DA479921ECBD922F882D0A94F9CF67457FA73673B65912D8410\n" "7AC025DF0D2DDC21453C5D251505F5CD0E268C7421AD668A33C66A524B37DCAA\n" "2F7C5557099D723FED2C7964E11D857760CEAE192FC30D685D599196324B29D9\n" "E3A44C3448091957AD6429165A7F406E39C138680C0805D54A3CF15028EA725D\n" "E88FA056E89108C0C1D23CA3C6A71B21B0EBA517D6FE77079B7088C0FC900101\n" "CB2191D9ECA7A8B82B6F6DAE2FDB01EE67809232BC5C0BB2C26E828B4A6A3A30\n" "2510326780A7A6FD6486ADD2BF76C24821791D5E1F36BAD6749A8DB20F925CFE\n" "8D7BCF9F9EFBB8E09A48DDFF0D622E76F4F1C5A400918673FB13C241941CB237\n" "FB2231A5C87D5B243DDB58AF892CA939AF35994BC6C9CF52972832FEC6D3B1D6\n" "BEBB1D1D06D98F44F435108FE3E43596E5A84141609EA0C4DF97A1BF4B117EFF\n" "B7952B3A022893E8356F8E2583B258E6738DEC7AB8EB78C35CE04495D1196156\n" "A9829343464576E626889251A472BA52A3C8ADA9646B99EE75DC5207C54938D2\n" "39E04F381C44D067F935426F4690FE1B6674FC367EBD5E93D151AD7880324F9B\n" "AAD544F08F3E5911A1A47B0C2BE61C0A988D8E3E7DC05FC9C3311AE4F7E57FA7\n" "316AFC4A7383A4C55555ABD374995B938AB0B69089420117605137B612737288\n" "81007C3444CA68D4EAE0E0A1A240B708697456B440BCD7B598BFA428D5CD28E8\n" "F96BA3A9D4A0C2728E89AFE02D14D1874639E163C09C71398C891CBEF3B8BA6D\n" "CDE95EB756B8ACB762875E559267EE8EC451A3CF7E95A1D4A9EE33C87AF036FC\n" "BFC7D0B825D86C9C277BB42D415C6D44C4F45A14320C779C1A4B0E13347B0001\n" "1DA60DEE09061F725479C403EA4973C6D450EB15EA6D033985AAC2592B012AF6\n" "8D2B854FFDF9BB03EC14805E251300760AD41804A8FA2821CA77794D150484EE\n" "EA58CBB43951DC00B9493B6DC15E200BF394E19A446DBABFF71BD75CAE3D6476\n" "E0CD659214F462A66BD348C81F97A31C3E4B8078223F00D36EC25E48D65CE127\n" "DF09839B9FFCDE6055FC4CDB136126CFE4891C0BF7DAF9D582378845361EDDF4\n" "93BDD1954DE5DBA70B98C462744FDE3DDDD6719BB00FF4A01136C36D20D00951\n" "A7EB060BAEB0965A18CAD664E6DCFAA98F496704DAA6FE0787D934FFACB0E861\n" "9753ED6BF44106206855C9E313BDC268208769E8FDD864A2A75DFFA213C0A49E\n" "C4386F1E55F5FBD43E0AD5B3EF46531D7124D22F5080220D7DC6FF9D2E03DAF1\n" "797544ACB18E060A04A5ABFAC6E20B8B374D606D555B6560EBCD7044B78D38DC\n" "AAE19EEBA625224F9E016D49B6A5710CC3A0871BD3CC00265CD8E67109F7EB61\n" "550A41FE60D2474F961264D218E302CC35205A1D655F878C8FB831DCAA33E134\n" "70E2D2C49EAB90176513B2D1A3DB731D7207F070AAAF90B7990BA77FB559221A\n" "855D62E824F18DF1A63DA56813CC79C4B990E87E41C4E8A9A6244E108D94D48D\n" "A8079D448A916F68A39B5ACB375AF61C52725B1361A0FBC5818A0052F4F0B1CA\n" "FB11446E47D6177318E3F83511BFDCE237FE94BF1223C29EF05BC57E1668A7EE\n" "C4D9B5CAEBF4F14ABCF26719D0863FDB73DB4897E02C995DEEE70CEA14C35542\n" "6D508B3CDD8F8A10A78F6219991D2133D77F6D6D4D346E2207F29478D8F071ED\n" "73B331A0D41DE6B15355F85ED54AA37C502D63B9090D53F9B025877225E6FB88\n" "6A1809D536F1F096DE2FADC386926BC07421BD0C49A01C4D77D4627BCD349528\n" "97FC9A0D7FF60C5B705E2B1A669C938733E30BC55F03476A6B8B5CD03C3150B8\n" "1236D235FE1E7EAFFF2FB5DFF9980328ECE0B627B4C178B6A95A4CF197611748\n" "959878A68FBDD8857205B75524512B896357FDA8D464244646018F6078B687E3\n" "7372A3E9792BDD3435302CB509E728BCD7B7377F2E0D5C02040033D9113AF22B\n" "BE956919AD2CA332C1FE4B5E4D6741523A884E222FA8EFDC1C24FBBDEEF6465D\n" "65D8A0E2C334DD806062ECB16A5BF6D24221141A2ACA31EF8AA7BA7A10ADED5C\n" "9CC618E69EA66BE2A7A625970751BD86412514DA8441A1DBF6F0D49112A5FF88\n" "95872BC5B995CEF7D3A27936B17E134AA66CDC3583DBA0678DFE12DFAC7514B9\n" "52D46F914F73AB0208DB3CDDE326FFF7293CA9E3C305F8275B78E7870A50BB50\n" "874E93D2D26A15F0FFE0D74345E536AD39ECDA53FFDA5A625001C26C97FC6FAF\n" "F0864403FCB78C2A7EC1727DAD5BD64762086DCF5A17D4E9035123FA43C1630C\n" "69BB2E10FAF95973AE38A13BF57A5BE8E579A43E618D4DBCAC9075D89E6CF5FF\n" "F0DEBB17E452D336CC87DB03A3C872BC63A11F5061F7E112723E1C89ACAC5679\n" "E7D98AA82A939FCD42CFE1BF81E87FA66FB3DEE9006B13E339FD9E034C485FA5\n" "04812788EA8CB1A932C94645D26528CE15408B526E8EF98B1CE8363C5FC47054\n" "8065293A984D7BB9A21F99D4BBD1B78A09FDFB18A6E8B2944D6C8D52A20E3E5F\n" "71FDFBEB31B570D0F9D7C265338A6C5E9E0CBA742A01208D560B8FCAF15BE825\n" "ED294D9613FCC511B62612EE6A4F35EC370A57DCC608963A73197C159FD9EB5B\n" "F0F0AB9A86ACE51BB0C1F89029393712E1F5EFF2335512803C27524ABA13AB32\n" "F1593B11A4996B133DD81051479A49A2459D223858A48ABBAB17E4E0B0EEE26B\n" "0EE3EF75772268FE26F6441CE2917D18EC251DCAF7D2554B2F955FFE606957AE\n" "2F86B7AE7CE8279638A0A3EDC3FABA38F24C4904B75262210FAC02D7A71DA8C8\n" "C07946A02F8C24DD5A54F751A65E0ECA012F4C80C13C0AE59120AF0790B004F1\n" "4D479EFBD046EE049B12EF9FEC70DD8196DE145A7313058A292CC7E360288C28\n" "A596430C9B9F6A06E1C37DCAB3C9154F1F228778D77AA82126AC31F860667182\n" "A74FF150224860B76429E3BE635A4A93CA6DDEA12E7E34501992F31DA9C55D43\n" "214DE92977FB118F2523123FCF45C6451FAA16447108902A96C05914FC82A62A\n" "349B3477F67C1CBCA1B3D135A649CCBC9D7BD3931EC402CAFF93974836A8E5A5\n" "00F251261273FDE7649955FE45EA108D4B3C3895EB1E1EBC4B39DFBCAD92A245\n" "75B09F873B851907139E6D430F4F928111414559B2FDB535DB222F8EED030F48\n" "27EEFE50F57597190CC790B3B1B55F21433D8DC831F30B2B0F70FBDA4160F94B\n" "36ED20D77E577E9250875DC6FC88BF280639842556AF84FF7538DCFF36D5536B\n" "9FC9B0EFC405FF23679BC1E39FBFBCB428D5F209562BE553750DC8CD6B9F6FB6\n" "BA9655CAEDCDE73757DEEE940C4F4FF04CA455AE8C3D94432FF9874872B77C20\n" "71F46663493F8ACFED7B8F1C33C5C19B139A0460CBB676F523458270BA4393B9\n" "EFFD55BD5074FB63F90827F5C9C46C9DDFA4B84AD0F48807094FC847F51C64D5\n" "E1224E16AD882A0ED6C647E0FA2A0BBBD19F461FDA5A255BAF014599DAA755E1\n" "18C52E7851D6651DDDD638EF488113772D52C41E135D4A4B587359C88F1BFBCB\n" "C7925A384EFCCB35A8EA112AC298D30263A3E9A857949EE4E04BD278BEE68307\n" "D1B351F54A233AE3FCACF2947FF6E949E6C391C24DC2CEEE5267221C30AD63C7\n" "2E09DAAB39B2A33BD4FF51441CDAB009D0F30EED102B36C77AD3EF4C30233C61\n" "D1ABDB13B7C9EF211DC7003B3A848DBAA7573778CC2518D8DD872106182914D0\n" "A8E4156D99481972BDA413F9FF42BDF74BE29A49EEAD55804BD5BBB594A0D250\n" "4B5898EE8FA5A029D850B0C6582E9EEB89B17902A94FBCBD637503C0BF334681\n" "2BDA2CED91F072946FDE2AA824B824E628D4A229C63C8ADB8F235B77AFE501FB\n" "91DD3B8D226DC0E69F9F68F12492F7659CB8BCC352DA9DBBC417914F6C8A291A\n" "3EC92956A937FA07D337240B7946C311731F681281B772E330CCF5DC918D0F51\n" "EFF203DB777EBC6267D218469675DDAD79774D0E7BCBB3C2196D8D264BC6E5CD\n" "6E3FE1DFE75A6CDF53FB3D889A723DE8017EAD77C1E67853F9A45B091B2C2A5A\n" "3FFB3C318024E34632220F1B2A470A2A00A1C28D5B61B8ABD95B060021D149A7\n" "A765D00C76D38BE872BDC55EE8C43A2F98FB291ACCBA870FCAB713ED4F6D76A4\n" "B9CB086E3B8CF4E0F1F51D43A16F56EE69373CA6D6D6AAD8B0D4DB1CF83505F5\n" "E54133E9939074D9DE2CE82AC1F8469AFF9E6C1E43C32DC2A12367CE38141616\n" "4726CE8AD13EF9F07DF45108F6DDD16677DAA5250C9351DCAD937E060D0E12A3\n" "FD0858C4C2961C1E9E0DBD611B661400E40011BCF0E9EA20EA056685502399C8\n" "4E0113757D35D7F01B753FFAF38560E6BCDAF5AF9483266645A00BC17711AC1E\n" "D4B504AAB85349A31BD73EA6516F069A9CBF808D16EEAE065B6BED42DC799904\n" "A9DC3B361557973754ED0FA022D82FFDBC454865A12A68216338F1BACBF8A9E7\n" "492DB4518DEF56FDC0AE0BA3A2A20EEF538DA7804F1F223683638E1920F28756\n" "D4926C7B9133D332502C7EE7F71EB00715704E0162ED8E1A0422FCD864F71600\n" "CA2D1D740D45FF4E0D1235B143D1F690A019E8A57C46357207C4F7DD81747392\n" "ADC44AEE8CB7586D7C4B4CB63753C5EB9271E27D34E6AED844212E8C203F2282\n" "E79E8F25C16037BF85AD0DBA4E594DBC82C2FDB4B6973C4D470EE402A19B527E\n" "BC61FC9D96C68B504CEC3406A159E2C8B6F2E79BCA75F51BBF4B61C8F5A21C56\n" "DEADECDFAD4347200532497D3FE6FBA8E9BEC3D503A97CA50BA52CA242F6CDB1\n" "90B6A5257BA4D9D18ABABFDABB4A65E1D5D3F6A6764D44D7CB6BF4AC888EB728\n" "6E396FE80939AC26C8AD2A3DF3F3EEFA38544FA28F36E577B01E944E499014C5\n" "A0F8B593151832FE49DF1EB8412012585DB9D057FBD60967893EE00D413C9FFD\n" "3076E00DE4ECF271D390655C6C661141D894DA2362D9117D21C492F43728CA7E\n" "8FAD31601D16CB92A7C53A4D388753E391106BD52C8FC44F364E75FB0B38895A\n" "C67698F992012379A68AD2CD12679D5A88973B0EA80C8CD163918D8B5E9C18A0\n" "ACB813099EC4CF63FBA34E5A1F9AF41C597FFC7843DB506CED639A1B56E77D26\n" "3F076D4391E96A1E38D7E7F9279E7593B2E9E15FE3DB0D0F3629304D914FB012\n" "EFD7628E50A1E9A62FDE38E67482CB5338880ACA34765DA71E7B3176F235365C\n" "EC6F60B7201065B459AFD536A9D1605B835793B34646484E7E500A63DF569987\n" "FB00E458300019B681E1B38DEB754C2A611E872ADEE0C300AC04341CD0410F6F\n" "165E1004EEBA0A52DCDADB4C86ABB50529A38A509BE89A4E2A35AA7899F964F3\n" "61297AA16F717BC2BDD79C23851618DD8FE9C15FA740A0F9D42FB8E620AF461A\n" "8F9744F0D92888ED96B86AE357930D0D9D2DC8917D74B4F2EED482AABEF9EC6D\n" "C1CCE9796830ED60FD27435F1280894A94C0EDD2551C1CED18B9BC713CB17537\n" "DD797DCD049D65F9D2826AE6E19BFD3105E95E4E1B747FAE3877EC12F998A267\n" "69E7E783FA612E70F43F551F66AB8B1F6B93B8F2A62A7EC67FA00F56EF464020\n" "43E6286D0A40F4401DF7A6958679205B9DB58DE63FCFBD23C171F010419DB21B\n" "42C2CE7D3F34ABD4A196A75C46363DB71CDA9CC04BF4046DE27F5CD9CF8E74B9\n" "F440DE40658E62000A9A20F5ADD6213DA6B0915F5306BC4C9824B8E0BAC64ADE\n" "88C1515DCCCD81CCB83E8E2E59655177EBE4DAC666C71BC21A8599BB2F533FE8\n" "44DB822B632AA8B85D7B938C89717B13F9EC0C4975B2404389CF9B4D40DB1A73\n" "701F3CF8FDB977AD919493746DF8952F9590E6FA4DAA82C37254BF300B65A9BC\n" "7FB93762E42C0856C4231BB1F04A03F29FB8E70B4E909372F8F1496BA47CA82F\n" "FBF3808CF096B1D5D7ADE9AED8872E6E8B3791311AFBB5DE7D0D8C3B0D8E9243\n" "3BE02526125EF34F0A575E0E789B2038DF2F4ED5182EBD5CF5A9AE771F8972F7\n" "10B6AF7BA5F0810D4E0F01465FB4A4C25F916B60CA5BA7DDE92CB24D0DE0F713\n" "A963530BB2EA13F54C1C0FBF8D9BCB94C781FFEAEE6AE48BC951317BAB88B140\n" "91343ACE736604B473CFC14A1845D648737C47B42EE4286CD7156C987704CEEF\n" "FD2BFBDC4B63CE2B633C09ACC51FBEC2F8B64E815730465F5F61C1E15A1A8632\n" "D6E55EE400D6A875D4CAF9839E53E3C28C99EBAB7E0B523D44B1270FD41FB736\n" "1DDB0EF87AEBF2F2CE2B6DBCFDAB74A65D80E82D08F2C5F0F98F84796666FAA1\n" "3C9399831AFA98B6D2FC37FE47C2C24E30020D85C7CB03F4EB85A6904AABB074\n" "6E916B55F27832DD190335B88E31BE657E560A847E1E6C21CD85B2EDAF8726F9\n" "5A1856B8D26969145B9F60E61254C57EDA7827896FFBFFC4C35F338F22175278\n" "09C5D48862BBD55F1E4ECA3A2C6092D55D4E4AAB3542CAD1B77B2338314C7102\n" "89BCE74F362C477ADECA09368945A337636DB7A5AED30DD64E3F3D4D1668492B\n" "C40F67940FC90E5E64DFFBC97B23E130D387FF6FA785515AB8116FBAE382196F\n" "B546F8B447217FD21133C1D0DAC1F45893F2A5ADFE29E73A444EC718603D0077\n" "E69FC22A22849EBA5727C6A05FECDE20A1DE131A6D4DA9A5408147B23C320366\n" "8D4C64678E2B71F757FF0E177219D3750F6A74A025ED156BFE446BBA3194ECD4\n" "C71444B4E63FA0DAA81908C395C77C6484CC26E3E52D3E1D8E341C8366338254\n" "FAEA45B6E32312C878F870B059B897F7D55F89FBE6427F40DF26310FED372B87\n" "52E15FFA84287EB0740874FD97D090FA566FDED66372FA95D1C75DA5F2A02D42\n" "2CED62419A1CA43FC1AA0B806866E07366BDAF329651C088EAB26D1F19A95D19\n" "2BB46558622D6777BBC2DF431E9457A0F617B77A87F7414759FFFD66E00A16DB\n" "9B24E997416A1BEF302768E81E252903B975275A468EC0A247BA670D8B209534\n" "2B734D767266E2241384B5893288A0D50E12C851A47990A2BAF2445BFB7C8852\n" "F2BA046AC935C119C3C6542AD6B5C339E11FCB55EB12BF753BB43F99E4B48317\n" "4C3F2A0530B5AF0D89910CFBCA2290920EA1ACB34951D175D0AEF4FEAA62CE93\n" "51F5C0ED55F0292D7F28E033D0ED773C5C5AD3E47D7DFE86C76B0C7A895F9DB6\n" "880FE08C2008DD3C2C88FA04ABAD5D3D445ABDB5860FB48C0B973C251B138EC2\n" "7FA2CE7F55BF4196D06AEE270858E9521D9E085C58F7561388650BEACCBC2687\n" "C69BBDA32CFDB923EF5052D333E9BBC3549AD32CDD53F04C7D8CA21751B47ABD\n" "C1C60A0DC155CD068EECEE0E7CA67CD539D85F2D8489C6C8F1CD0CEE611709D9\n" "A7FACD511BF663667398082BF096D13665A1502EEDB5F0EAF00264F8A803B2B0\n" "E47D4B4FEFF6761C382D73D2B430CA80207D8321A0A2EAD8B67EE5804022BE6C\n" "5235002A07AFE2D1A77D467B45FD7BBFA5BD3CB3309FC140E2D55178A091A33F\n" "5A9767BE25067AA7E12BC25AA6949F9DA0F81FB5311DF81363E117B3A383342F\n" "3E0F4462676BE061AE4716D923B2C7BAA284A247842F6BF6E7D3901D3D3BF7A7\n" "B4654D145D95B900EDB009C33540D3F5A4A1AE94E6BCAA3C85AC14CC197B467A\n" "9E43E0773EBC4FD5FF73433A26C02CEEA99F515F5C15C019FA816DFB021FDCB1\n" "047A79234BAF4952A0CC48EAED0A62EFCB4EFCCB72D4C9DF8A8803650F8543FD\n" "714D869C0F1AC1CF5FAC20503A072372D922B9C6F14FA5D379306059C9FAF228\n" "6AE1AAB6C87AD689AC039C11A6E74C8B7B726F671FF0BA4850FC9E06340D39A3\n" "66A9D572B0A6A029F95B82787D2F9F40114C4B90B763DD6169678C53AFE0FB0E\n" "105C77449EAF6F95C5C7AB06F03F3790B93617786D8AA01D92DC2F97D42CC6F1\n" "BC68E73510AE2F22A5953493207D26117B4933BAFB8311F4298A467DEBABBC29\n" "871532FA9C166056FB144016D341B0A864FB882C4114E7157E24FE046D5B65E7\n" "5879DF87597BEB6224EFD2910C206589CC828C1690F40A75A99CEDB51B46B67A\n" "C337BE8AA78C66E9652EE5C6281A0AD6432017570EBD8E9524A388360399B051\n" "7E37544EFA2DB5A87CC52245494C8FA19844506585D3F3868934D5775F4F97C2\n" "492FCFBE08E468BDF0E7765197104FBC00D963D0E9E0D778BAEF2C15CDCC4D6E\n" "12E197FED3C2022A091D65D3F9F5302E7E9A280CC8A09388DD366D5083F659AF\n" "73FB2834544914212D78ED6384EA96841ED737061D7AB0FA5B4381A38CD3EC13\n" "AAA4E19C408992F2FC189B03839B38DC15A08305609C49C0A8C2E958DF933470\n" "D535E5266F746FF5B5B4CD8FD3467B5AA1A1F4601E1532CA93FF14072DF2E7ED\n" "A154A191E27D68B61D026FF5DF0AA39C398744DBF04FA587B226337D77EF11F2\n" "2457472DC1C99E84D2E42C71A2E313EFF7E8AC506CC2BD5B585D0D58E9431DD4\n" "F9758152794FB6D27F494AEBD3EF4250F24FF01924C3F18874F5AA64A532C8FF\n" "77AF4A8641DA35622B07D4F964862F0B043C54555723887C5E67E192C28B2D9A\n" "ACDE51F21B4D09D74AEA2A2B40769C4BA5F23B46E1415229CDD439007F6DED01\n" "B4334AA5A23FF4A40D5308EA52EE0DEA1F5CEA92F9AE8A4437447FEE9464AAE6\n" "3FDD49629AF6ABBDE4F38FC2FB9C9D152C0F64F64678D5100DC9E5C3A49FDB6B\n" "5A56DB67D5126812B1D9269E6E9AC2A723AE9B296645459EF000FA9252EC9228\n" "9DB18FF27595D6E952D75AC5A5DC3A48D7F40265280E263DF90E35B8F6E081B6\n" "00633552A5BFCD6A526A46A89F8A1D7FF4F7FFABBBE1F6F4B80651B21F78B391\n" "84B46A49F7404E8EEDC3F0B710EB231CC2CE0A8C81E27C01B1210F0E05FEB4E8\n" "69D480F80DE0F4A1F4FD719902E82F2EDD0CEBDC764800F54D0594363E2BB797\n" "82C1DC01960B76A9CF4B84966DD2D1E75EE1393B0ABD4E48462A195BF28B7C48\n" "A2DFCD4163B981E785D06104F46B20F949B033C51AD5FAEE7CB3894C29E30797\n" "FE5E6FF8C455A869DDE04686C30F8CAFF428AB5BFBAF276D90DE79A4B86455D8\n" "8D94BF8D436BA46330A18BF55B393C926F1947AB996FC46D22CBD931427A4E81\n" "1009C4EE608BC868A843DD888690530E1F8FADA75FC7CC0962C1DBFDEE630DCE\n" "0BD7DC763F802548E813AE4394FC6B5CE560BF122A7D5593092C99010684070E\n" "354201416C5E6B9E4A7F804FC89F3E50A70B6A2644329C7BCE70D2E6ABEAC786\n" "4F2AA7361B71D289AE0EA5E11D6B8964B6AB1B03A455E775BC051BB7B6846CC1\n" "6C292406018A00249C21CD1357EDDBFF\n" "0000000000000000000000000000000000000000000000000000000000000000\n" "0000000000000000000000000000000000000000000000000000000000000000\n" "0000000000000000000000000000000000000000000000000000000000000000\n" "0000000000000000000000000000000000000000000000000000000000000000\n" "0000000000000000000000000000000000000000000000000000000000000000\n" "0000000000000000000000000000000000000000000000000000000000000000\n" "0000000000000000000000000000000000000000000000000000000000000000\n" "cleartomark\n" "%%EndResource\n"; /* Types. ===================================================================*/ typedef enum {GSTRING_TYPE, GRECORD_TYPE, GLIST_TYPE} gvalue_type_t; /* Type of a node in "gvalue_t". */ typedef struct value /* A Malaga value in "malshow". */ { struct value *next; /* Next element if value is record or list element. */ struct value *first; /* First element if value is record or list. */ gvalue_type_t value_type; /* Type of this value. */ PangoLayout *string; /* String (for GSTRING_TYPE). */ PangoLayout *attribute; /* Attribute name (if record element). */ int_t attrib_width; /* Width of attribute. */ int_t ascent; /* Distance between top and baseline. */ int_t width, height; /* Size of value. */ } gvalue_t; typedef struct /* Implementation type of "pos_value_t". */ { int_t x, y, width, height, ascent; /* Private items follow. */ gvalue_t *value; } pos_value_i_t; typedef struct /* Implementation type of "pos_string_t". */ { int_t x, y, width, height, ascent; /* Private items follow. */ PangoLayout *layout; } pos_string_i_t; struct canvas { GtkWidget *window; /* Toplevel window for this canvas. */ GtkWidget *draw_area; /* Drawing area widget. */ GtkWidget *file_selection; GtkWidget *hscrollbar, *vscrollbar; /* Needed for adjust_canvas(). */ GtkAdjustment *hadjust, *vadjust; GtkItemFactory *factory; /* Item factory for the pulldown menu. */ GtkItemFactory *popup_menu_factory; GdkEventButton *event; /* Button press event currently handled. */ bool_t show_hscrollbar, show_vscrollbar; int_t vscrollbar_width, hscrollbar_height; string_t ps_file_name; /* Default file name for FILE_SELECTION. */ int_t width, height; /* Current size of canvas. */ int_t area_width, area_height; /* Size of DRAW_AREA. */ int_t x, y; /* Upper left corner of canvas in drawing area. */ expose_func_t expose; configure_func_t configure; close_func_t close; mouse_func_t mouse_event; PangoFontDescription *font; int_t font_size; /* Selected font size. */ int_t font_ascent; /* Ascent of FONT. */ int_t font_height; /* Height of a line in FONT. */ int_t space_width; /* Width of a space in FONT. */ int_t comma_width; /* Width of a comma in FONT. */ int_t border_width; /* Width of record border. */ int_t line_width; /* Width of canvas lines. */ int_t border_height; /* Height of list and record borders. */ bool_t hanging_style; /* TRUE if values are "hanging down" from baseline. */ bool_t alternate_cursor; /* TRUE if alternate cursor is displayed. */ PangoLayout *comma_layout, *space_layout; }; /* Global variables. ========================================================*/ string_t font_family; int_t font_size; bool_t hanging_style; /* Variables. ===============================================================*/ /* The following variables can be shared among all canvases since there is * always only one canvas being drawn. */ static char_t ps_string[ BUFFER_SIZE ]; /* Converted PostScript string. */ static GdkDrawable *drawable; /* Drawable we currently draw into. */ static cairo_t *cairo; /* Cairo context for DRAWABLE. */ static rectangle_t area; /* The clipping rectangle of DRAWABLE, using the * coordinates of the whole canvas. */ static double canvas_shift; /* Shift if stroke width is odd. */ static GdkRectangle clip; /* The clipping rectangle of DRAWABLE, using the * coordinates of DRAWABLE. */ static GdkGC *gc; /* Graphics context used to draw. */ static GdkColor colors[4]; /* BLACK, WHITE, RED and BLUE. */ static FILE *ps_stream; /* Stream used for PostScript output. */ static bool_t ps_mode; /* TRUE => draw into PS_STREAM; * FALSE => draw into DRAWABLE. */ static bool_t use_n3f; /* TRUE iff we'll output N3F Hangul characters to * PS_STREAM. */ /* The following variables can be shared among all canvases since they are * only set up at initialisation. */ static GdkCursor *alternate_cursor; static PangoContext *pango_context; /* Forward declarations. ====================================================*/ static gvalue_t *parse_value( void ); /* Parsing Malaga values. ===================================================*/ static void free_value( gvalue_t **value_p ) /* Free *VALUE_P. */ { gvalue_t *value, *next_value; for (value = *value_p; value != NULL; value = next_value) { next_value = value->next; free_value( &value->first ); if (value->attribute != NULL) g_object_unref( value->attribute ); if (value->string != NULL) g_object_unref( value->string ); free_mem( &value ); } *value_p = NULL; } /*---------------------------------------------------------------------------*/ static string_t parse_symbol( void ) /* Parse a symbol and return it. */ { string_t symbol; test_token( TOK_IDENT ); symbol = new_string( token_name, NULL ); read_next_token(); return symbol; } /*---------------------------------------------------------------------------*/ static void value_set_string( gvalue_t *value, char_t *string ) { if (pango_context == NULL) pango_context = gdk_pango_context_get(); value->value_type = GSTRING_TYPE; value->string = pango_layout_new( pango_context ); pango_layout_set_text( value->string, string, -1 ); free( string ); } /*---------------------------------------------------------------------------*/ static void value_set_attribute( gvalue_t *value, char_t *attribute ) { if (pango_context == NULL) pango_context = gdk_pango_context_get(); value->attribute = pango_layout_new( pango_context ); pango_layout_set_text( value->attribute, attribute, -1 ); free( attribute ); } /*---------------------------------------------------------------------------*/ static gvalue_t * parse_attribute_value_pair( void ) /* Parse an attribute-value pair and return a pointer to it. */ { string_t attribute; gvalue_t *new_value; if (next_token == '(') /* Read a hidden attribute. */ { read_next_token(); attribute = parse_symbol(); parse_token( ')' ); new_value = new_mem( sizeof( gvalue_t ) ); value_set_attribute( new_value, concat_strings( attribute, ":", NULL ) ); value_set_string( new_value, new_string( "...", NULL ) ); free_mem( &attribute ); } else { attribute = parse_symbol(); parse_token( ':' ); new_value = parse_value(); value_set_attribute( new_value, concat_strings( attribute, ":", NULL ) ); free_mem( &attribute ); } return new_value; } /*---------------------------------------------------------------------------*/ static gvalue_t * parse_value( void ) /* Parse a value and return it as a "gvalue_t". */ { gvalue_t *new_value; gvalue_t *element; /* Last list or record element. */ new_value = new_mem( sizeof( gvalue_t ) ); switch (next_token) { case '<': new_value->value_type = GLIST_TYPE; read_next_token(); if (next_token != '>') { /* Insert NEW_VALUE as first list element. */ new_value->first = parse_value(); element = new_value->first; while (next_token == ',') { /* Insert NEW_VALUE as successor element. */ read_next_token(); element->next = parse_value(); element = element->next; } } parse_token( '>' ); break; case '[': new_value->value_type = GRECORD_TYPE; read_next_token(); if (next_token != ']') { new_value->first = parse_attribute_value_pair(); element = new_value->first; while (next_token == ',') { read_next_token(); element->next = parse_attribute_value_pair(); element = element->next; } } parse_token( ']' ); break; case TOK_IDENT: value_set_string( new_value, new_string( token_name, NULL ) ); read_next_token(); break; case TOK_STRING: value_set_string( new_value, new_string_readable( token_string, NULL ) ); read_next_token(); break; case TOK_NUMBER: value_set_string( new_value, double_to_string( token_number ) ); read_next_token(); break; case '-': read_next_token(); test_token( TOK_NUMBER ); value_set_string( new_value, double_to_string( -token_number ) ); read_next_token(); break; default: complain( "Value expected, not \"%s\".", token_as_text( next_token ) ); } return new_value; } /* Displaying Malaga values. ================================================*/ int_t get_line_width( canvas_t *canvas ) /* Get line width in pixels for CANVAS. */ { return canvas->line_width; } /*---------------------------------------------------------------------------*/ int_t get_space_width( canvas_t *canvas ) /* Get space width in pixels for CANVAS. */ { return canvas->space_width; } /*---------------------------------------------------------------------------*/ int_t get_font_height( canvas_t *canvas ) /* Get font height in pixels for CANVAS. */ { return canvas->font_height; } /*---------------------------------------------------------------------------*/ int_t get_font_ascent( canvas_t *canvas ) /* Get number of pixels above baseline of current font for CANVAS. */ { return canvas->font_ascent; } /*---------------------------------------------------------------------------*/ int_t get_border_width( canvas_t *canvas ) /* Get border width of CANVAS in pixels. */ { return (ps_mode ? 500 : 5); } /*---------------------------------------------------------------------------*/ void set_color( color_t color ) /* Set the current drawing color to COLOR. */ { if (ps_mode) { if (color == WHITE) fprintf( ps_stream, "1 G\n" ); else fprintf( ps_stream, "0 G\n" ); } else { gdk_gc_set_foreground( gc, &colors[ color ] ); gdk_cairo_set_source_color( cairo, &colors[ color ] ); } } /*---------------------------------------------------------------------------*/ static bool_t clip_line( double *x1, double *y1, double *x2, double *y2, double x_min, double x_max ) /* Clip the x-coordinates of the line from (X1,Y1) to (X2,Y2) to the range * [X_MIN..X_MAX]. The start point and the end point may be swapped. */ { double t; /* Make sure that *X1 <= *X2. */ if (*x2 < *x1) { t = *x1; *x1 = *x2; *x2 = t; t = *y1; *y1 = *y2; *y2 = t; } if (*x2 < x_min || *x1 > x_max) return FALSE; if (*x1 < x_min) { /* We can be sure that *X1 != *X2, since *X1 < X_MIN, but *X2 >= X_MIN. */ *y1 += ((x_min - *x1) * (*y2 - *y1)) / (*x2 - *x1); *x1 = x_min; } if (*x2 > x_max) { /* We can be sure that *X1 != *X2, since *X2 > X_MAX, but *X1 <= X_MAX. */ *y2 += ((x_max - *x2) * (*y2 - *y1)) / (*x2 - *x1); *x2 = x_max; } return TRUE; } /*---------------------------------------------------------------------------*/ static void draw_lines_clipped( GdkPoint p[], int count ) /* Draw lines from p[0] TO p[1], p[1] TO p[2], ..., p[count-2] TO p[count-1]. * Clip coordinates that are out of the current clip range. * * This algorithm clips to the exact start and end points, but it cannot * guarantee that the line is translational invariant: If a clipped line is * drawn from (x1, y1) to (x2, y2) and another line from (x1 + dx, y1 + dy) to * (x2 + dx, y2 + dy), we cannot guarantee that, for each point (x, y) which is * part of the first line, the point (x + dx, y + dy) is part of the second * line, and vice versa. */ { int_t i; double x1, y1, x2, y2; const double left = clip.x - 10; const double right = clip.x + clip.width + 10; const double top = clip.y - 10; const double bottom = clip.y + clip.height + 10; for (i = 1; i < count; i++) { x1 = p[i-1].x; y1 = p[i-1].y; x2 = p[i].x; y2 = p[i].y; if (clip_line( &x1, &y1, &x2, &y2, left, right) && clip_line( &y1, &x1, &y2, &x2, top, bottom)) { cairo_move_to( cairo, x1 + canvas_shift, y1 + canvas_shift); cairo_line_to( cairo, x2 + canvas_shift , y2 + canvas_shift); } } } /*---------------------------------------------------------------------------*/ void draw_lines( int_t count, int_t x, int_t y, ... ) /* Called as "draw_lines( COUNT, x_1, y_1, x_2, y_2, ..., x_COUNT, y_COUNT )". * Draw lines: * from (x_1, y_1) to (x_2, y_2), * from (x_2, y_2) to (x_3, y_3), * ... * from (x_COUNT-1, y_COUNT-1) to (x_COUNT, y_COUNT). */ { va_list args; int_t i; static GdkPoint *p; static int_t max_points; bool_t left, right, over, under, need_clipping; if (ps_mode) { fprintf( ps_stream, "%d %d M ", x, area.height - y ); va_start( args, y ); for (i = 1; i < count; i++) { x = va_arg( args, int_t ); y = va_arg( args, int_t ); fprintf( ps_stream, "%d %d L ", x, area.height - y ); } va_end( args ); fprintf( ps_stream, "S\n" ); } else { if (count > max_points) max_points = renew_vector( &p, sizeof( GdkPoint ), count ); left = right = over = under = FALSE; va_start( args, y ); for (i = 0; ; i++) { x -= area.x; y -= area.y; if (x >= 0) right = TRUE; if (x < area.width) left = TRUE; if (y >= 0) under = TRUE; if (y < area.height) over = TRUE; x += clip.x; y += clip.y; if (x < SHRT_MIN || x > SHRT_MAX || y < SHRT_MIN || y > SHRT_MAX) need_clipping = TRUE; p[i].x = x; p[i].y = y; if (i >= count - 1) break; x = va_arg( args, int_t ); y = va_arg( args, int_t ); } va_end( args ); if (left && right && over && under) { cairo_new_path( cairo ); if (need_clipping) draw_lines_clipped( p, count ); else { for (i = 0; i < count; i++) cairo_line_to(cairo, p[i].x + canvas_shift, p[i].y + canvas_shift); } cairo_stroke( cairo ); } } } /*---------------------------------------------------------------------------*/ void draw_rectangle( int_t x, int_t y, int_t width, int_t height ) /* Draw a rectangle with NW coordinate (X,Y), WIDTH pixels wide and HEIGHT * pixels high. */ { if (ps_mode) { fprintf( ps_stream, "%d %d M ", x, area.height - y ); fprintf( ps_stream, "%d %d R ", width, 0 ); fprintf( ps_stream, "%d %d R ", 0, -height ); fprintf( ps_stream, "%d %d R ", -width, 0 ); fprintf( ps_stream, "F\n" ); } else { x -= area.x; y -= area.y; if (x + width > 0 && x < area.width && y + height > 0 && y < area.height) { cairo_new_path( cairo ); cairo_rectangle( cairo, clip.x + x + canvas_shift, clip.y + y + canvas_shift, width, height ); cairo_fill( cairo ); } } } /*---------------------------------------------------------------------------*/ void draw_circle( bool_t filled, int_t x, int_t y, int_t r ) { if (ps_mode) { if (filled) fprintf( ps_stream, "%d %d %d D\n", x, area.height - y, r ); else fprintf( ps_stream, "%d %d %d C\n", x, area.height - y, r ); } else { x -= area.x; y -= area.y; if (x + r >= 0 && x - r <= area.width && y + r >= 0 && y - r <= area.height) { cairo_new_path( cairo ); cairo_arc( cairo, clip.x + x + canvas_shift, clip.y + y + canvas_shift, r, 0, 2 * M_PI ); cairo_close_path( cairo ); if (filled) cairo_fill( cairo ); else cairo_stroke( cairo ); } } } /*---------------------------------------------------------------------------*/ static void utf8_string_to_n3f( const char **string ) /* Convert *STRING (in UTF-8) to N3F PostScript string. * Return its length. The converted string is in PS_STRING. */ { int_t c, d, choseong, jungseong, jonseong; char *ps; ps = ps_string; while (**string != EOS && ps - ps_string < BUFFER_SIZE - 4) { c = g_utf8_get_char( *string ); if (c >= FIRST_SYLLABLE && c <= LAST_SYLLABLE) { c -= FIRST_SYLLABLE; d = c / JONSEONG_COUNT; jonseong = c % JONSEONG_COUNT; jungseong = d % JUNGSEONG_COUNT; choseong = d / JUNGSEONG_COUNT; *ps++ = choseong + FIRST_CHOSEONG; *ps++ = jungseong + FIRST_JUNGSEONG; if (jonseong > 0) *ps++ = jonseong - 1 + FIRST_JONSEONG; } else if (c >= FIRST_JAMO && c <= LAST_JAMO) { c = jamos[ c - FIRST_JAMO ]; *ps++ = (c < FIRST_JUNGSEONG ? c : NO_CHOSEONG); *ps++ = (c >= FIRST_JUNGSEONG && c < FIRST_JONSEONG ? c : NO_JUNGSEONG); if (c >= FIRST_JONSEONG) *ps++ = c; } else break; *string = g_utf8_next_char( *string ); } *ps = EOS; } /*---------------------------------------------------------------------------*/ static void utf8_string_to_latin1( const char **string ) { int_t c; char *ps; ps = ps_string; while (**string != EOS && ps - ps_string < BUFFER_SIZE - 2) { c = g_utf8_get_char( *string ); if ((c >= 32 && c <= 126) || (c >= 160 && c <= 255)) *ps++ = c; else break; *string = g_utf8_next_char( *string ); } *ps = EOS; } /*---------------------------------------------------------------------------*/ static int_t ps_string_width( const char *string ) { int_t width; const char *s, *old_pos; width = 0; while (*string != EOS) { old_pos = string; /* Convert a Latin1 segment. */ utf8_string_to_latin1( &string ); for (s = ps_string; *s != EOS; s++) width += widths_latin1[ ORD(*s) ]; /* Convert a Hangul segment. */ utf8_string_to_n3f( &string ); if (*s != EOS) use_n3f = TRUE; for (s = ps_string; *s != EOS; s++) width += widths_n3f[ ORD(*s) - FIRST_N3F ]; /* Ignore a non-convertible character. */ if (string == old_pos && string != EOS) string = g_utf8_next_char( string ); } return width; } /*---------------------------------------------------------------------------*/ static void print_ps_text( const char *string ) /* Convert STRING to Postscript format: prefix "(", ")", and "\" with "\", * insert line breaks if line gets too long. */ { int_t col; const char *s, *old_pos; while (*string != EOS) { old_pos = string; /* Print a Latin1 segment. */ utf8_string_to_latin1( &string ); if (*ps_string != EOS) { fprintf( ps_stream, "(" ); col = 1; for (s = ps_string; *s != EOS; s++) { if (col > 76) /* Insert line break if line gets too long. */ { fprintf( ps_stream, "\\\n" ); col = 0; } if (*s == '(' || *s == ')' || *s == '\\') { fputc( '\\', ps_stream ); col++; } fputc( *s, ps_stream ); col++; } fprintf( ps_stream, ")\nT\n" ); } /* Print a Hangul segment. */ utf8_string_to_n3f( &string ); if (*ps_string != EOS) { fprintf( ps_stream, "<" ); col = 1; for (s = ps_string; *s != EOS; s++) { if (col > 76) /* Insert line break if line gets too long. */ { fprintf( ps_stream, "\n" ); col = 0; } fprintf( ps_stream, "%02x", ORD( *s ) ); col += 2; } fprintf( ps_stream, ">\nH\n" ); } /* Ignore a non-convertible character. */ if (string == old_pos && string != EOS) string = g_utf8_next_char( string ); } } /*---------------------------------------------------------------------------*/ static void config_layout( canvas_t *canvas, PangoLayout *layout, int_t *width, int_t *height, int_t *ascent ) { PangoLayoutIter *iter; if (ps_mode) { if (width != NULL) *width = ps_string_width( pango_layout_get_text( layout ) ); if (height != NULL) *height = canvas->font_height; if (ascent != NULL) *ascent = canvas->font_ascent; } else { pango_layout_set_font_description( layout, canvas->font ); pango_layout_get_pixel_size( layout, width, height ); if (ascent != NULL) { iter = pango_layout_get_iter( layout ); *ascent = pango_layout_iter_get_baseline( iter ) / PANGO_SCALE; pango_layout_iter_free( iter ); } } } /*---------------------------------------------------------------------------*/ static void draw_layout( canvas_t *canvas, PangoLayout *layout, int_t x, int_t y ) /* Draw LAYOUT at position (X,Y) in CANVAS. */ { int_t width, height; if (ps_mode) { fprintf( ps_stream, "%d %d M\n", x, area.height - y - canvas->font_ascent ); print_ps_text( pango_layout_get_text( layout ) ); return; } else { pango_layout_get_pixel_size( layout, &width, &height ); x -= area.x; y -= area.y; if (x + width <= 0 || x >= area.width) return; if (y + height <= 0 || y >= area.height) return; gdk_draw_layout( drawable, gc, clip.x + x, clip.y + y, layout ); } } /*---------------------------------------------------------------------------*/ static void config_value( canvas_t *canvas, gvalue_t *value ) /* Compute the height, width and ascent of VALUE in CANVAS. */ { gvalue_t *element; int_t max_attrib_width, max_width, descent; if (value->attribute != NULL) config_layout( canvas, value->attribute, &value->attrib_width, NULL, NULL); switch (value->value_type) { case GRECORD_TYPE: value->height = 0; max_attrib_width = 0; max_width = 0; value->ascent = canvas->border_height + canvas->font_ascent; /* Default. */ for (element = value->first; element != NULL; element = element->next) { config_value( canvas, element ); max_attrib_width = MAX( max_attrib_width, element->attrib_width ); max_width = MAX( max_width, element->width ); /* Update ascent and height */ if (! canvas->hanging_style) { value->ascent = (canvas->border_height + value->height + element->ascent); } value->height += element->height; } if (canvas->hanging_style && value->first != NULL) value->ascent = canvas->border_height + value->first->ascent; value->height = (canvas->border_height + MAX( value->height, canvas->font_height ) + canvas->border_height); value->width = (canvas->border_width + max_attrib_width + canvas->space_width + max_width + canvas->border_width); break; case GLIST_TYPE: value->width = 0; descent = canvas->font_height - canvas->font_ascent; value->ascent = canvas->font_ascent; for (element = value->first; element != NULL; element = element->next) { config_value( canvas, element ); descent = MAX( descent, element->height - element->ascent ); value->ascent = MAX( value->ascent, element->ascent ); value->width += element->width; if (element->next != NULL) value->width += (canvas->comma_width + canvas->space_width); } if (value->width == 0) value->width = 2; value->ascent += canvas->border_height; value->height = value->ascent + descent + canvas->border_height; value->width += 2 * (canvas->border_width / 3 + ((value->height - canvas->border_height) / BRACKET_RATIO)); break; case GSTRING_TYPE: config_layout( canvas, value->string, &value->width, &value->height, &value->ascent ); break; } } /*---------------------------------------------------------------------------*/ static int_t max_attribute_width( gvalue_t *value ) /* Compute maximum attribute width of record VALUE. */ { gvalue_t *element; int_t max_width; max_width = 0; for (element = value->first; element != NULL; element = element->next) max_width = MAX( max_width, element->attrib_width ); return max_width; } /*---------------------------------------------------------------------------*/ static void draw_value( canvas_t *canvas, gvalue_t *value, int_t x, int_t y ) /* Draw VALUE in CANVAS at X/Y. */ { gvalue_t *element; int_t x2, bracket_width; /* If (sub)value is out of bounds, we don't need to draw it. */ if (x >= area.x + area.width || y >= area.y + area.height || x + value->width <= area.x || y + value->height <= area.y) { return; } switch (value->value_type) { case GRECORD_TYPE: /* Draw left bracket. */ draw_lines( 4, x + canvas->border_width * 5 / 6, y + canvas->border_height / 2, x + canvas->border_width / 6, y + canvas->border_height / 2, x + canvas->border_width / 6, y + value->height - 1 - canvas->border_height / 2, x + canvas->border_width * 5 / 6, y + value->height - 1 - canvas->border_height / 2 ); /* Draw right bracket. */ draw_lines( 4, x + value->width - 1 - canvas->border_width * 5 / 6, y + canvas->border_height / 2, x + value->width - 1 - canvas->border_width / 6, y + canvas->border_height / 2, x + value->width - 1 - canvas->border_width / 6, y + value->height - 1 - canvas->border_height / 2, x + value->width - 1 - canvas->border_width * 5 / 6, y + value->height - 1 - canvas->border_height / 2 ); /* Draw elements. */ x2 = (x + canvas->border_width + max_attribute_width( value ) + canvas->space_width); y += canvas->border_height; for (element = value->first; element != NULL; element = element->next) { /* Draw attribute name. */ draw_layout( canvas, element->attribute, x + canvas->border_width, y + (element->height - canvas->font_height) / 2 ); /* Draw attribute value. */ draw_value( canvas, element, x2, y ); y += element->height; } break; case GLIST_TYPE: bracket_width = (canvas->border_width / 3 + ((value->height - canvas->border_height) / BRACKET_RATIO)); /* Draw left bracket. */ draw_lines( 3, x + bracket_width - canvas->border_width / 6, y + canvas->border_height / 2, x + canvas->border_width / 6, y + value->height / 2, x + bracket_width - canvas->border_width / 6, y + value->height - 1 - canvas->border_height / 2 ); /* Draw right bracket. */ draw_lines( 3, x + value->width - 1 - (bracket_width - canvas->border_width / 6), y + canvas->border_height / 2, x + value->width - 1 - canvas->border_width / 6, y + value->height / 2, x + value->width - 1 - (bracket_width - canvas->border_width / 6), y + value->height - 1 - canvas->border_height / 2 ); /* Draw elements. */ x += bracket_width; y += value->ascent; /* Baseline. */ for (element = value->first; element != NULL; element = element->next) { draw_value( canvas, element, x, y - element->ascent ); x += element->width; if (element->next != NULL) /* Draw ",". */ { draw_layout( canvas, canvas->comma_layout, x, y - canvas->font_ascent ); x += (canvas->comma_width + canvas->space_width); } } break; case GSTRING_TYPE: draw_layout( canvas, value->string, x, y ); break; } } /*---------------------------------------------------------------------------*/ static gboolean expose_event( GtkWidget *widget, GdkEventExpose *event, canvas_t *canvas ) { GdkColormap *colormap; if (gc == NULL) { /* Allocate the shared graphics context and the shared colors. */ gc = gdk_gc_new( gtk_widget_get_parent_window( canvas->draw_area ) ); colormap = gtk_widget_get_colormap( canvas->draw_area ); colors[ BLACK ].red = colors[ BLACK ].green = colors[ BLACK ].blue = 0; if (! gdk_colormap_alloc_color( colormap, &colors[ BLACK ], FALSE, TRUE )) complain( "Could not get black." ); colors[ WHITE ].red = colors[ WHITE ].green = colors[ WHITE ].blue = 65535; if (! gdk_colormap_alloc_color( colormap, &colors[ WHITE ], FALSE, TRUE )) complain( "Could not get white." ); colors[ RED ].red = 65535; colors[ RED ].green = colors[ RED ].blue = 0; if (! gdk_colormap_alloc_color( colormap, &colors[ RED ], FALSE, TRUE )) complain( "Could not get red." ); colors[ BLUE ].blue = 65535; colors[ BLUE ].red = colors[ BLUE ].green = 0; if (! gdk_colormap_alloc_color( colormap, &colors[ BLUE ], FALSE, TRUE )) complain( "Could not get blue." ); } area.x = canvas->x + event->area.x; area.y = canvas->y + event->area.y; clip.x = event->area.x; clip.y = event->area.y; clip.width = area.width = event->area.width; clip.height = area.height = event->area.height; drawable = canvas->draw_area->window; cairo = gdk_cairo_create(drawable); cairo_set_line_width( cairo, canvas->line_width ); cairo_set_line_cap( cairo, CAIRO_LINE_CAP_SQUARE ); cairo_set_line_join( cairo, CAIRO_LINE_JOIN_BEVEL ); canvas->expose( canvas, &area ); cairo_destroy(cairo); cairo = NULL; return TRUE; } /*---------------------------------------------------------------------------*/ static void configure_draw_area( canvas_t *canvas ) { if (pango_context == NULL) pango_context = gdk_pango_context_get(); if (canvas->comma_layout == NULL) { canvas->comma_layout = pango_layout_new( pango_context ); pango_layout_set_text( canvas->comma_layout, ",", -1 ); } if (canvas->space_layout == NULL) { canvas->space_layout = pango_layout_new( pango_context ); pango_layout_set_text( canvas->space_layout, " ", -1 ); } if (ps_mode) { canvas->border_width = 600; canvas->border_height = 300; canvas->space_width = ps_string_width( " " ); canvas->comma_width = ps_string_width( "," ); canvas->font_ascent = 917; canvas->font_height = 1150; canvas->line_width = 25; } else { config_layout( canvas, canvas->space_layout, &canvas->space_width, &canvas->font_height, &canvas->font_ascent ); config_layout( canvas, canvas->comma_layout, &canvas->comma_width, NULL, NULL ); canvas->line_width = (canvas->font_height + 8) / 12; canvas->border_width = 6 * canvas->line_width; canvas->border_height = 3 * canvas->line_width; canvas_shift = ((canvas->line_width & 1) != 0) ? 0.5 : 0.0; } canvas->configure( canvas, &canvas->width, &canvas->height ); } /*---------------------------------------------------------------------------*/ static void write_postscript( canvas_t *canvas ) { double scaling; time_t now; area.x = 0; area.y = 0; area.width = canvas->width; area.height = canvas->height; scaling = 0.01; if (area.width * scaling > PAGE_WIDTH) scaling = PAGE_WIDTH / (double) area.width; if (area.height * scaling > PAGE_HEIGHT) scaling = PAGE_HEIGHT / (double) area.height; fprintf( ps_stream, "%%!PS-Adobe-3.0 EPSF-3.0\n" "%%%%BoundingBox: %d %d %d %d\n", (int_t) PAPER_BORDER, (int_t) PAPER_BORDER, (int_t) ceil( area.width * scaling + PAPER_BORDER ), (int_t) ceil( area.height * scaling + PAPER_BORDER ) ); fprintf( ps_stream, "%%%%HiResBoundingBox: %f %f %f %f\n", PAPER_BORDER, PAPER_BORDER, area.width * scaling + PAPER_BORDER, area.height * scaling + PAPER_BORDER ); fprintf( ps_stream, "%%%%Creator: malshow\n" "%%%%Title: %s\n", GTK_WINDOW( canvas->window )->title ); time( &now ); fprintf( ps_stream, "%%%%CreationDate: %s", ctime( &now ) ); fprintf( ps_stream, "%%%%DocumentData: Clean8Bit\n" "%%%%Orientation: Portrait\n" ); if ( use_n3f ) fprintf( ps_stream, "%%%%DocumentSuppliedResources: font n3f-5\n" ); fprintf( ps_stream, "%%%%DocumentNeededResources: font Helvetica\n" "%%%%EndComments\n" ); if ( use_n3f ) fprintf( ps_stream, "%s", n3f_font_definition ); fprintf( ps_stream, "save 11 dict begin\n" "/ISOLatin1Encoding where {pop} {/ISOLatin1Encoding [\n" "/space /space /space /space /space /space /space /space /space\n" "/space /space /space /space /space /space /space /space /space\n" "/space /space /space /space /space /space /space /space /space\n" "/space /space /space /space /space /space /exclam /quotedbl\n" "/numbersign /dollar /percent /ampersand /quoteright /parenleft\n" "/parenright /asterisk /plus /comma /minus /period /slash /zero\n" "/one /two /three /four /five /six /seven /eight /nine /colon\n" "/semicolon /less /equal /greater /question /at /A /B /C /D /E /F\n" "/G /H /I /J /K /L /M /N /O /P /Q /R /S /T /U /V /W /X /Y /Z\n" "/bracketleft /backslash /bracketright /asciicircum /underscore\n" "/quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o /p /q /r\n" "/s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde\n" "/space /space /space /space /space /space /space /space /space\n" "/space /space /space /space /space /space /space /space\n" "/dotlessi /grave /acute /circumflex /tilde /macron /breve\n" "/dotaccent /dieresis /space /ring /cedilla /space /hungarumlaut\n" "/ogonek /caron /space /exclamdown /cent /sterling /currency /yen\n" "/brokenbar /section /dieresis /copyright /ordfeminine\n" "/guillemotleft /logicalnot /hyphen /registered /macron /degree\n" "/plusminus /twosuperior /threesuperior /acute /mu /paragraph\n" "/periodcentered /cedilla /onesuperior /ordmasculine\n" "/guillemotright /onequarter /onehalf /threequarters\n" "/questiondown /Agrave /Aacute /Acircumflex /Atilde /Adieresis\n" "/Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis\n" "/Igrave /Iacute /Icircumflex /Idieresis /Eth /Ntilde /Ograve\n" "/Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash\n" "/Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn\n" "/germandbls /agrave /aacute /acircumflex /atilde /adieresis\n" "/aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis\n" "/igrave /iacute /icircumflex /idieresis /eth /ntilde /ograve\n" "/oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave\n" "/uacute /ucircumflex /udieresis /yacute /thorn /ydieresis\n" "] def} ifelse\n" "/Helvetica-ISOLatin1\n" "/Helvetica findfont\n" "dup length dict copy\n" "dup /FID undef\n" "dup /Encoding ISOLatin1Encoding put\n" "definefont pop\n" "/C {0 360 arc stroke} bind def\n" /* Paint a circle. */ "/D {0 360 arc fill} bind def\n" /* Paint a filled disc. */ "/F {closepath fill} bind def\n" "/G /setgray load def\n" ); if (use_n3f) fprintf( ps_stream, "/H { /n3f-5 1000 selectfont show } bind def\n" ); fprintf( ps_stream, "/L /lineto load def\n" "/M /moveto load def\n" "/R /rlineto load def\n" "/S /stroke load def\n" "/T { /Helvetica-ISOLatin1 1000 selectfont show } bind def\n" ); fprintf( ps_stream, "%d setlinewidth\n", canvas->line_width ); fprintf( ps_stream, "%f %f translate\n", PAPER_BORDER, PAPER_BORDER ); fprintf( ps_stream, "%f %f scale\n", scaling, scaling ); canvas->expose( canvas, &area ); fprintf( ps_stream, "end restore showpage\n" "%%%%EOF\n" ); } /*---------------------------------------------------------------------------*/ static void save_postscript( GtkWidget *widget, canvas_t *canvas ) { GtkWidget *dialog, *label, *okay_button; string_t file_name; file_name = (string_t) gtk_file_selection_get_filename( GTK_FILE_SELECTION( canvas->file_selection ) ); TRY { ps_stream = open_stream( file_name, "w" ); ps_mode = TRUE; use_n3f = FALSE; configure_draw_area( canvas ); write_postscript( canvas ); if (ferror( ps_stream )) complain( "Can't write to \"%s\": %s.", strerror( errno ) ); close_stream( &ps_stream, file_name ); ps_mode = FALSE; configure_draw_area( canvas ); } IF_ERROR { /* Reconfigure canvas before doing any GTK stuff, so it can be safely * exposed. */ close_stream( &ps_stream, NULL ); ps_mode = FALSE; configure_draw_area( canvas ); /* Show the error message. */ dialog = gtk_dialog_new(); gtk_window_set_title( GTK_WINDOW( dialog ), "Export Postscript" ); gtk_window_set_transient_for( GTK_WINDOW( dialog ), GTK_WINDOW( canvas->window ) ); gtk_window_set_position( GTK_WINDOW( dialog ), GTK_WIN_POS_MOUSE ); label = gtk_label_new( error_text->buffer ); gtk_misc_set_padding( GTK_MISC( label ), 10, 10 ); okay_button = gtk_button_new_with_label( "OK" ); gtk_signal_connect_object( GTK_OBJECT( okay_button ), "clicked", GTK_SIGNAL_FUNC( gtk_widget_destroy ), GTK_OBJECT( dialog ) ); gtk_container_add( GTK_CONTAINER( GTK_DIALOG( dialog )->action_area ), okay_button ); gtk_container_add( GTK_CONTAINER( GTK_DIALOG( dialog )->vbox ), label); gtk_widget_show_all( dialog ); RESUME; } END_TRY; gtk_widget_hide( canvas->file_selection ); canvas->file_selection = NULL; } /*---------------------------------------------------------------------------*/ static void export_postscript( canvas_t *canvas ) /* Open "Export Postscript" selector */ { string_t title; if (canvas->file_selection == NULL) { title = concat_strings( "Export ", GTK_WINDOW( canvas->window )->title, " as Postscript", NULL ); canvas->file_selection = gtk_file_selection_new( title ); free_mem( &title ); gtk_window_set_transient_for( GTK_WINDOW( canvas->file_selection ), GTK_WINDOW( canvas->window ) ); gtk_window_set_position( GTK_WINDOW( canvas->file_selection ), GTK_WIN_POS_MOUSE ); gtk_file_selection_hide_fileop_buttons( GTK_FILE_SELECTION( canvas->file_selection ) ); gtk_file_selection_set_filename( GTK_FILE_SELECTION( canvas->file_selection ), canvas->ps_file_name ); gtk_signal_connect( GTK_OBJECT( GTK_FILE_SELECTION( canvas->file_selection )->ok_button ), "clicked", GTK_SIGNAL_FUNC( save_postscript ), canvas ); gtk_signal_connect_object( GTK_OBJECT( GTK_FILE_SELECTION( canvas->file_selection )->cancel_button ), "clicked", GTK_SIGNAL_FUNC( gtk_widget_hide ), GTK_OBJECT( canvas->file_selection ) ); gtk_signal_connect( GTK_OBJECT( canvas->file_selection ), "delete_event", GTK_SIGNAL_FUNC( gtk_widget_hide), NULL ); } gtk_widget_show( canvas->file_selection ); } /*---------------------------------------------------------------------------*/ static void adjust_canvas( canvas_t *canvas ) { if (canvas->x + canvas->area_width > canvas->width) canvas->x = canvas->width - canvas->area_width; if (canvas->x < 0) canvas->x = 0; if (canvas->y + canvas->area_height > canvas->height) canvas->y = canvas->height - canvas->area_height; if (canvas->y < 0) canvas->y = 0; canvas->hadjust->value = canvas->x; canvas->hadjust->upper = canvas->width; canvas->hadjust->page_increment = MAX( 20, canvas->area_width - 20 ); canvas->hadjust->page_size = canvas->area_width; canvas->vadjust->value = canvas->y; canvas->vadjust->upper = canvas->height; canvas->vadjust->page_increment = MAX( 20, canvas->area_height - 20 ); canvas->vadjust->page_size = canvas->area_height; gtk_adjustment_changed( canvas->hadjust ); gtk_adjustment_changed( canvas->vadjust ); /* If the pointer is currently in the drawing area, we might update the * cursor. */ if (canvas->mouse_event != NULL) { int x, y; GdkModifierType mask; gdk_window_get_pointer( canvas->draw_area->window, &x, &y, &mask ); canvas->mouse_event( canvas, canvas->x + x, canvas->y + y, 0 ); } gtk_widget_queue_draw( canvas->draw_area ); } /*---------------------------------------------------------------------------*/ static gboolean delete_event( GtkWidget *widget, GdkEvent *event, canvas_t *canvas ) { hide_canvas( canvas ); return TRUE; } /*---------------------------------------------------------------------------*/ static gboolean key_press_event( GtkWidget *widget, GdkEventKey *event, canvas_t *canvas ) { switch (event->keyval) { case GDK_Left: if ((event->state & GDK_CONTROL_MASK) != 0) canvas->x = 0; else if ((event->state & GDK_SHIFT_MASK) != 0) canvas->x -= canvas->hadjust->page_increment; else canvas->x -= 10; break; case GDK_Right: if ((event->state & GDK_CONTROL_MASK) != 0) canvas->x = canvas->width; else if ((event->state & GDK_SHIFT_MASK) != 0) canvas->x += canvas->hadjust->page_increment; else canvas->x += 10; break; case GDK_Up: if ((event->state & GDK_CONTROL_MASK) != 0) canvas->y = 0; else if ((event->state & GDK_SHIFT_MASK) != 0) canvas->y -= canvas->vadjust->page_increment; else canvas->y -= 10; break; case GDK_Down: if ((event->state & GDK_CONTROL_MASK) != 0) canvas->y = canvas->height; else if ((event->state & GDK_SHIFT_MASK) != 0) canvas->y += canvas->vadjust->page_increment; else canvas->y += 10; break; case GDK_Home: if ((event->state & GDK_CONTROL_MASK) != 0) canvas->x -= canvas->hadjust->page_increment; else canvas->x = 0; break; case GDK_End: if ((event->state & GDK_CONTROL_MASK) != 0) canvas->x += canvas->hadjust->page_increment; else canvas->x = canvas->width; break; case GDK_Page_Up: if ((event->state & GDK_CONTROL_MASK) != 0) canvas->y = 0; else canvas->y -= canvas->vadjust->page_increment; break; case GDK_Page_Down: if ((event->state & GDK_CONTROL_MASK) != 0) canvas->y = canvas->height; else canvas->y += canvas->vadjust->page_increment; break; default: return FALSE; } adjust_canvas( canvas ); return TRUE; } /*---------------------------------------------------------------------------*/ static void set_font_size( canvas_t *canvas, guint font_size ) { canvas->font_size = font_size; configure_canvas( canvas ); } /*---------------------------------------------------------------------------*/ static void set_hanging_style( canvas_t *canvas, guint action, GtkWidget *item ) { canvas->hanging_style = GTK_CHECK_MENU_ITEM( item )->active; configure_canvas( canvas ); } /*---------------------------------------------------------------------------*/ static void configure_scrollbars( canvas_t *canvas ) { int_t width, height; bool_t show_hscrollbar, show_vscrollbar; width = canvas->area_width; if (canvas->show_vscrollbar) width += canvas->vscrollbar_width; show_hscrollbar = (canvas->width > width); height = canvas->area_height; if (canvas->show_hscrollbar) height += canvas->hscrollbar_height; show_vscrollbar = (canvas->height > height); if (show_vscrollbar && canvas->width + canvas->vscrollbar_width > width) show_hscrollbar = TRUE; if (show_hscrollbar && canvas->height + canvas->hscrollbar_height > height) show_vscrollbar = TRUE; if (show_hscrollbar != canvas->show_hscrollbar) { if (show_hscrollbar) gtk_widget_show( canvas->hscrollbar ); else gtk_widget_hide( canvas->hscrollbar ); canvas->show_hscrollbar = show_hscrollbar; } if (show_vscrollbar != canvas->show_vscrollbar) { if (show_vscrollbar) gtk_widget_show( canvas->vscrollbar ); else gtk_widget_hide( canvas->vscrollbar ); canvas->show_vscrollbar = show_vscrollbar; } } /*---------------------------------------------------------------------------*/ static void configure_event( GtkWidget *widget, GdkEventConfigure *event, canvas_t *canvas ) /* Called if CANVAS window size has changed. */ { canvas->area_width = event->width; canvas->area_height = event->height; configure_scrollbars( canvas ); adjust_canvas( canvas ); } /*---------------------------------------------------------------------------*/ static void adjust_value_changed( GtkAdjustment *adjust, canvas_t *canvas ) /* Called if ADJUST has changed its value. Draw CANVAS at the new position. */ { canvas->x = canvas->hadjust->value; canvas->y = canvas->vadjust->value; gtk_widget_queue_draw( canvas->draw_area ); } /*---------------------------------------------------------------------------*/ void make_visible( canvas_t *canvas, int_t x, int_t y ) /* Make sure the point (X,Y) is in the displayed part of CANVAS. */ { if (x < canvas->x || x > canvas->x + canvas->area_width) canvas->x = x - canvas->area_width / 2; if (y < canvas->y || y > canvas->y + canvas->area_height) canvas->y = y - canvas->area_height / 2; adjust_canvas( canvas ); } /*---------------------------------------------------------------------------*/ void go_canvas_bottom( canvas_t *canvas ) /* Go to the bottom left of CANVAS. */ { canvas->x = 0; if (canvas->height < canvas->area_height) canvas->y = 0; else canvas->y = canvas->height - canvas->area_height; adjust_canvas( canvas ); } /*---------------------------------------------------------------------------*/ void configure_canvas( canvas_t *canvas ) /* Call this if CANVAS must be reconfigured because its content has changed * its size (font size change, new content, etc.). */ { text_t *font_descriptor; if (canvas->font != NULL) pango_font_description_free( canvas->font ); font_descriptor = new_text(); print_text( font_descriptor, "%s %d", font_family, canvas->font_size ); canvas->font = pango_font_description_from_string( font_descriptor->buffer ); free_text (&font_descriptor ); configure_draw_area( canvas ); configure_scrollbars( canvas ); adjust_canvas( canvas ); } /*---------------------------------------------------------------------------*/ void show_canvas( canvas_t *canvas ) { gdk_window_raise( canvas->window->window ); gtk_widget_show( canvas->window ); } /*---------------------------------------------------------------------------*/ void hide_canvas( canvas_t *canvas ) { gtk_widget_hide( canvas->window ); canvas->file_selection = NULL; if (canvas->close != NULL) canvas->close( canvas ); } /*---------------------------------------------------------------------------*/ void redraw_canvas( canvas_t *canvas ) { gtk_widget_queue_draw( canvas->draw_area ); } /*---------------------------------------------------------------------------*/ void set_cursor( canvas_t *canvas, bool_t alternate ) /* Set cursor for CANVAS to alternate shape if ALTERNATE == TRUE. */ { if (canvas->alternate_cursor == alternate || canvas->draw_area->window == NULL) { return; } if (alternate_cursor == NULL) alternate_cursor = gdk_cursor_new( GDK_HAND2 ); gdk_window_set_cursor( canvas->draw_area->window, alternate ? alternate_cursor : NULL ); canvas->alternate_cursor = alternate; } /*---------------------------------------------------------------------------*/ void set_popup_menu( canvas_t *canvas, GtkItemFactoryEntry items[], int_t item_count ) /* Set a pop-up menu for CANVAS, consisting of ITEM_COUNT ITEMS. */ { canvas->popup_menu_factory = gtk_item_factory_new( GTK_TYPE_MENU, "
", NULL ); gtk_item_factory_create_items( canvas->popup_menu_factory, item_count, items, canvas ); } /*---------------------------------------------------------------------------*/ void popup_menu( canvas_t *canvas ) /* Pop up the pop-up menu for CANVAS as a reaction of a button press event that * is currently handled. */ { if (canvas->event != NULL) { gtk_item_factory_popup( canvas->popup_menu_factory, canvas->event->x_root, canvas->event->y_root, canvas->event->button, canvas->event->time ); } } /*---------------------------------------------------------------------------*/ static gboolean scroll_event( GtkWidget *widget, GdkEventScroll *event, canvas_t *canvas ) { switch (event->direction) { case GDK_SCROLL_UP: canvas->y -= canvas->area_height / 9; adjust_canvas( canvas ); return TRUE; case GDK_SCROLL_DOWN: canvas->y += canvas->area_height / 9; adjust_canvas( canvas ); return TRUE; default: return FALSE; } } /*---------------------------------------------------------------------------*/ static gboolean button_press_event( GtkWidget *widget, GdkEventButton *event, canvas_t *canvas ) { canvas->event = event; return canvas->mouse_event( canvas, ((int_t) event->x) + canvas->x, ((int_t) event->y) + canvas->y, event->button ); canvas->event = NULL; } /*---------------------------------------------------------------------------*/ static gboolean motion_notify_event( GtkWidget *widget, GdkEventMotion *event, canvas_t *canvas ) { return canvas->mouse_event( canvas, ((int_t) event->x) + canvas->x, ((int_t) event->y) + canvas->y, 0 ); } /*---------------------------------------------------------------------------*/ static gboolean enter_notify_event( GtkWidget *widget, GdkEventCrossing *event, canvas_t *canvas ) { return canvas->mouse_event( canvas, ((int_t) event->x) + canvas->x, ((int_t) event->y) + canvas->y, 0 ); } /*---------------------------------------------------------------------------*/ /* General menu items. */ static GtkItemFactoryEntry canvas_items[] = { { "/Window", NULL, NULL, 0, "" }, { "/Window/Export Postscript...", NULL, export_postscript, 0, NULL }, { "/Window/Close", "C", hide_canvas, 0, NULL }, { "/Style", NULL, NULL, 0, "" }, { "/Style/Font Size 8", NULL, set_font_size, 8, "" }, { "/Style/Font Size 10", NULL, set_font_size, 10, "/Style/Font Size 8" }, { "/Style/Font Size 12", NULL, set_font_size, 12, "/Style/Font Size 8" }, { "/Style/Font Size 14", NULL, set_font_size, 14, "/Style/Font Size 8" }, { "/Style/Font Size 18", NULL, set_font_size, 18, "/Style/Font Size 8" }, { "/Style/Font Size 24", NULL, set_font_size, 24, "/Style/Font Size 8" } }; static GtkItemFactoryEntry hanging_style_items[] = { { "/Style/sep1", NULL, NULL, 0, "" }, { "/Style/Hanging", NULL, set_hanging_style, 0, "" } }; /*---------------------------------------------------------------------------*/ canvas_t * create_canvas( string_t title, string_t ps_file_name, rectangle_t *geometry, configure_func_t my_configure, expose_func_t my_expose, close_func_t my_close, mouse_func_t my_mouse_event, bool_t show_hanging_option, GtkItemFactoryEntry items[], int_t item_count ) { canvas_t *canvas; GtkWidget *menu_bar, *vbox, *table; GtkAccelGroup *accel; /* Accelerator group. */ GtkRequisition requisition; canvas = new_mem( sizeof( canvas_t ) ); canvas->ps_file_name = ps_file_name; canvas->configure = my_configure; canvas->expose = my_expose; canvas->close = my_close; canvas->mouse_event = my_mouse_event; canvas->font_size = font_size; if (canvas->font_size == 0) canvas->font_size = 10; /* Create a toplevel window. */ canvas->window = gtk_window_new( GTK_WINDOW_TOPLEVEL ); gtk_signal_connect( GTK_OBJECT( canvas->window ), "delete_event", GTK_SIGNAL_FUNC( delete_event ), canvas ); gtk_window_set_title( GTK_WINDOW( canvas->window ), title ); if (geometry->x >= 0 && geometry->y >= 0) gtk_window_move( GTK_WINDOW( canvas->window ), geometry->x, geometry->y ); if (geometry->width > 0 && geometry->height > 0) { gtk_window_set_default_size( GTK_WINDOW( canvas->window), geometry->width, geometry->height ); } gtk_window_set_policy( GTK_WINDOW( canvas->window ), TRUE, TRUE, FALSE ); gtk_signal_connect( GTK_OBJECT( canvas->window ), "key_press_event", GTK_SIGNAL_FUNC( key_press_event ), canvas ); /* Fill the toplevel window with a vbox. */ vbox = gtk_vbox_new( FALSE, 0 ); gtk_container_add( GTK_CONTAINER( canvas->window ), vbox ); /* Add a menu bar to the vbox. */ accel = gtk_accel_group_new(); canvas->factory = gtk_item_factory_new( GTK_TYPE_MENU_BAR, "
", accel ); gtk_item_factory_create_items( canvas->factory, ARRAY_LENGTH( canvas_items ), canvas_items, canvas ); if (show_hanging_option) { gtk_item_factory_create_items( canvas->factory, ARRAY_LENGTH( hanging_style_items ), hanging_style_items, canvas ); } if (items != NULL) gtk_item_factory_create_items( canvas->factory, item_count, items, canvas ); gtk_window_add_accel_group( GTK_WINDOW( canvas->window ), accel ); menu_bar = gtk_item_factory_get_widget( canvas->factory, "
" ); if (menu_bar == NULL) complain( "Could not create menu bar." ); gtk_box_pack_start( GTK_BOX( vbox ), menu_bar, FALSE, FALSE, 0 ); /* Add a table with 2 rows and 2 columns to the vbox. */ table = gtk_table_new( 2, 2, FALSE ); gtk_box_pack_start_defaults( GTK_BOX( vbox ), table ); /* Add a drawing area to the table in row 1, column 1. */ canvas->draw_area = gtk_drawing_area_new(); gtk_signal_connect( GTK_OBJECT( canvas->draw_area ), "expose_event", GTK_SIGNAL_FUNC( expose_event ), canvas ); gtk_signal_connect( GTK_OBJECT( canvas->draw_area ), "configure_event", GTK_SIGNAL_FUNC( configure_event ), canvas ); gtk_signal_connect( GTK_OBJECT( canvas->draw_area ), "scroll_event", GTK_SIGNAL_FUNC( scroll_event ), canvas ); gtk_widget_add_events( canvas->draw_area, GDK_SCROLL_MASK ); if (my_mouse_event != NULL) { gtk_signal_connect( GTK_OBJECT( canvas->draw_area ), "button_press_event", GTK_SIGNAL_FUNC( button_press_event ), canvas ); gtk_signal_connect( GTK_OBJECT( canvas->draw_area ), "motion_notify_event", GTK_SIGNAL_FUNC( motion_notify_event ), canvas ); gtk_signal_connect( GTK_OBJECT( canvas->draw_area ), "enter_notify_event", GTK_SIGNAL_FUNC( enter_notify_event ), canvas ); gtk_widget_add_events( canvas->draw_area, GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK | GDK_ENTER_NOTIFY_MASK ); } gtk_table_attach( GTK_TABLE( table ), canvas->draw_area, 0, 1, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 0 ); /* Add a vscrollbar to the table in row 1, column 2. */ canvas->vadjust = GTK_ADJUSTMENT( gtk_adjustment_new( 0, 0, 0, 10, 0, 0 ) ); gtk_signal_connect( GTK_OBJECT( canvas->vadjust ), "value_changed", GTK_SIGNAL_FUNC( adjust_value_changed ), canvas ); canvas->vscrollbar = gtk_vscrollbar_new( canvas->vadjust ); gtk_widget_size_request( canvas->vscrollbar, &requisition ); canvas->vscrollbar_width = requisition.width; gtk_table_attach( GTK_TABLE( table ), canvas->vscrollbar, 1, 2, 0, 1, 0, GTK_FILL, 0, 0 ); /* Add a hscrollbar to the table in row 2, column 1. */ canvas->hadjust = GTK_ADJUSTMENT( gtk_adjustment_new( 0, 0, 0, 10, 0, 0 ) ); gtk_signal_connect( GTK_OBJECT( canvas->hadjust ), "value_changed", GTK_SIGNAL_FUNC( adjust_value_changed ), canvas ); canvas->hscrollbar = gtk_hscrollbar_new( canvas->hadjust ); gtk_widget_size_request( canvas->hscrollbar, &requisition ); canvas->hscrollbar_height = requisition.height; gtk_table_attach( GTK_TABLE( table ), canvas->hscrollbar, 0, 1, 1, 2, GTK_FILL, 0, 0, 0 ); /* Select some menu items. */ gtk_menu_item_activate( GTK_MENU_ITEM( gtk_item_factory_get_item_by_action( canvas->factory, canvas->font_size ) ) ); canvas->hanging_style = hanging_style; if (show_hanging_option && canvas->hanging_style) { canvas->hanging_style = TRUE; gtk_menu_item_activate( GTK_MENU_ITEM( gtk_item_factory_get_item( canvas->factory, "/Style/Hanging" ) ) ); } configure_canvas( canvas ); gtk_widget_show_all( canvas->window ); canvas->show_hscrollbar = canvas->show_vscrollbar = TRUE; return canvas; } /*---------------------------------------------------------------------------*/ void activate_menu_item( canvas_t *canvas, string_t path ) /* Activate the menu item PATH in CANVAS to VALUE. */ { gtk_menu_item_activate( GTK_MENU_ITEM( gtk_item_factory_get_item( canvas->factory, path ) ) ); } /*---------------------------------------------------------------------------*/ pos_string_t * new_pos_string( string_t string ) /* Create new POS_STRING_T with value STRING. */ { pos_string_i_t *pos_string_i; if (pango_context == NULL) pango_context = gdk_pango_context_get(); pos_string_i = new_mem( sizeof( pos_string_i_t ) ); if (string != NULL) { pos_string_i->layout = pango_layout_new( pango_context ); pango_layout_set_text( pos_string_i->layout, string, -1 ); } return (pos_string_t *) pos_string_i; } /*---------------------------------------------------------------------------*/ void config_pos_string( pos_string_t *pos_string, canvas_t *canvas ) /* Compute size of POS_STRING in CANVAS. */ { pos_string_i_t *pos_string_i = (pos_string_i_t *) pos_string; if (pos_string_i != NULL && pos_string_i->layout != NULL) { config_layout( canvas, pos_string_i->layout, &pos_string_i->width, &pos_string_i->height, &pos_string_i->ascent ); } } /*---------------------------------------------------------------------------*/ void draw_pos_string( pos_string_t *pos_string, canvas_t *canvas ) /* Draw POS_STRING in CANVAS. */ { pos_string_i_t *pos_string_i = (pos_string_i_t *) pos_string; if (pos_string_i != NULL && pos_string_i->layout != NULL) { draw_layout( canvas, pos_string_i->layout, pos_string_i->x, pos_string_i->y ); } } /*---------------------------------------------------------------------------*/ void free_pos_string( pos_string_t **pos_string_p ) /* Free memory allocated by "set_pos_string". */ { pos_string_i_t *pos_string_i = (pos_string_i_t *) *pos_string_p; if (pos_string_i != NULL && pos_string_i->layout != NULL) g_object_unref( pos_string_i->layout ); free_mem( pos_string_p ); } /*---------------------------------------------------------------------------*/ pos_value_t * parse_pos_value( void ) { pos_value_i_t *pos_value_i; pos_value_i = new_mem( sizeof( pos_value_i_t ) ); pos_value_i->value = parse_value(); return (pos_value_t *) pos_value_i; } /*---------------------------------------------------------------------------*/ void config_pos_value( pos_value_t *pos_value, canvas_t *canvas ) /* Compute size of POS_VALUE in CANVAS. */ { pos_value_i_t *pos_value_i = (pos_value_i_t *) pos_value; config_value( canvas, pos_value_i->value ); pos_value_i->width = pos_value_i->value->width; pos_value_i->height = pos_value_i->value->height; pos_value_i->ascent = pos_value_i->value->ascent; } /*---------------------------------------------------------------------------*/ void draw_pos_value( pos_value_t *pos_value, canvas_t *canvas ) /* Draw POS_VALUE in CANVAS. */ { pos_value_i_t *pos_value_i = (pos_value_i_t *) pos_value; draw_value( canvas, pos_value_i->value, pos_value_i->x, pos_value_i->y ); } /*---------------------------------------------------------------------------*/ void free_pos_value( pos_value_t **pos_value_p ) { pos_value_i_t *pos_value_i = (pos_value_i_t *) *pos_value_p; if (pos_value_i != NULL) { free_value( &pos_value_i->value ); free_mem( pos_value_p ); } } /* End of file. =============================================================*/ malaga-7.12/canvas.h0000644000175000017500000001352610655253563013652 0ustar bjoernbjoern/* Copyright (C) 2002 Bjoern Beutel. */ /* Description. =============================================================*/ /* Common routines for all Malaga GTK windows. */ /* types ====================================================================*/ typedef struct canvas canvas_t; /* Colors that can be set by "set_color". */ typedef enum {BLACK, WHITE, RED, BLUE} color_t; /* A value in the canvas together with its position and dimensions. */ typedef struct { int_t x, y, width, height, ascent; /* Private items follow. */ } pos_value_t; /* A string in the canvas together with its position and dimensions. */ typedef struct { int_t x, y, width, height, ascent; /* Private items follow. */ } pos_string_t; typedef struct { int_t x, y, width, height; } rectangle_t; typedef void (*expose_func_t)( canvas_t *canvas, rectangle_t *area ); /* Callback handler to draw exposed AREA in CANVAS. */ typedef void (*configure_func_t)( canvas_t *canvas, int_t *width_p, int_t *height_p ); /* Callback handler to compute *WIDTH_P and *HEIGHT_P for CANVAS. */ typedef bool_t (*mouse_func_t)( canvas_t *canvas, int_t x, int_t y, int_t button ); /* Callback handler for mouse actions in CANVAS: * BUTTON != 0 => mouse button BUTTON pressed at (X,Y). * BUTTON == 0, X >= 0, Y >= 0 => mouse has moved to (X,Y). */ typedef void (*close_func_t)( canvas_t *canvas ); /* Callback hander to release memory when CANVAS is closed. */ /* Variables. ===============================================================*/ extern string_t font_family; extern int_t font_size; extern bool_t hanging_style; /* Functions. ===============================================================*/ extern canvas_t *create_canvas( string_t title, string_t ps_file_name, rectangle_t *geometry, configure_func_t configure, expose_func_t expose, close_func_t close, mouse_func_t mouse_event, bool_t show_hanging_option, GtkItemFactoryEntry menu_items[], int_t item_count ); /* Create a new canvas with TITLE and initial GEOMETRY. * When exporting Postscript, use PS_FILE_NAME as default file name. * Install the callbacks CONFIGURE, EXPOSE, CLOSE, and MOUSE_EVENT. * Add the "Hanging" option to the "Style" menu if SHOW_HANGING_OPTION == TRUE. * Add ITEM_COUNT additional MENU_ITEMS. * The canvas is automatically configured and shown. */ extern void set_popup_menu( canvas_t *canvas, GtkItemFactoryEntry items[], int_t item_count ); /* Set a pop-up menu for CANVAS, consisting of ITEM_COUNT ITEMS. */ extern void configure_canvas( canvas_t *canvas ); /* Configure CANVAS. This must be done when its layout has changed. */ extern void redraw_canvas( canvas_t *canvas ); /* Redraw CANVAS. This must be done when the layout has remained, * but the content (e.g. marking) has changed. */ extern void show_canvas( canvas_t *canvas ); /* Show CANVAS and raise it. */ extern void hide_canvas( canvas_t *canvas ); /* Hide CANVAS. It may be shown again with "show_canvas". */ extern void make_visible( canvas_t *canvas, int_t x, int_t y ); /* Make sure the point (X,Y) is in the displayed part of CANVAS. */ extern void set_cursor( canvas_t *canvas, bool_t alternate ); /* Set cursor for CANVAS to alternate shape if ALTERNATE == TRUE. */ extern void go_canvas_bottom( canvas_t *canvas ); /* Display the bottom left of CANVAS. */ extern void activate_menu_item( canvas_t *canvas, string_t path ); /* Activate the menu item PATH in CANVAS to VALUE. */ extern void popup_menu( canvas_t *canvas ); /* Pop up the pop-up menu for CANVAS as a reaction of a button press event that * is currently handled. */ /* Primitives to lay out and draw a canvas. ---------------------------------*/ extern int_t get_line_width( canvas_t *canvas ); /* Get width of a line in CANVAS. */ extern int_t get_space_width( canvas_t *canvas ); /* Get width of space character in CANVAS. */ extern int_t get_font_height( canvas_t *canvas ); /* Get font height in CANVAS. */ extern int_t get_font_ascent( canvas_t *canvas ); /* Get ascent of font in CANVAS. */ extern int_t get_border_width( canvas_t *canvas ); /* Get border with of CANVAS in pixels. */ extern void set_color( color_t color ); /* Set the COLOR for the following graphics operations. */ extern void draw_lines( int_t count, int_t x, int_t y, ... ); /* Called as "draw_lines( COUNT, x_1, y_1, x_2, y_2, ..., x_COUNT, y_COUNT )". * Draw lines: * from (x_1, y_1) to (x_2, y_2), * from (x_2, y_2) to (x_3, y_3), * ... * from (x_COUNT-1, y_COUNT-1) to (x_COUNT, y_COUNT). */ extern void draw_rectangle( int_t x, int_t y, int_t width, int_t height ); /* Draw a filled rectangle with upper left corner (X,Y), WIDTH and HEIGHT. */ extern void draw_circle( bool_t filled, int_t x, int_t y, int_t r ); /* Draw an arc with center (X,Y) and radius R. Fill it if FILLED == TRUE. */ /* Functions for strings to draw in a canvas.--------------------------------*/ extern pos_string_t *new_pos_string( string_t string ); /* Create new POS_STRING_T with value STRING. */ extern void config_pos_string( pos_string_t *pos_string, canvas_t *canvas ); /* Compute size of POS_STRING when drawn in CANVAS. */ extern void draw_pos_string( pos_string_t *pos_string, canvas_t *canvas ); /* Draw POS_STRING in CANVAS. */ extern void free_pos_string( pos_string_t **pos_string_p ); /* Free **POS_STRING_P. */ /* Functions for malaga values to draw in a canvas. -------------------------*/ extern pos_value_t *parse_pos_value( void ); /* Parse a value and return it as a "pos_value_t". */ extern void config_pos_value( pos_value_t *pos_value, canvas_t *canvas ); /* Compute size of POS_VALUE when drawn in CANVAS. */ extern void draw_pos_value( pos_value_t *pos_value, canvas_t *canvas ); /* Draw POS_VALUE in CANVAS. */ extern void free_pos_value( pos_value_t **pos_value_p ); /* Free **POS_VALUE_P. */ /* End of file. =============================================================*/ malaga-7.12/commands.c0000644000175000017500000003254510702155535014166 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* Tools for a command line interpreter. */ /* Includes. ================================================================*/ #include #include #include #include #include #include "basic.h" #include "input.h" #include "files.h" #include "commands.h" /* Types. ===================================================================*/ typedef struct /* An alias. */ { list_node_t *next; string_t name; string_t line; /* Command line this alias stands for. */ } alias_t; /* Global variables. ========================================================*/ command_t **options; /* The options that can be set by the set command. * This has to be set before executing "set_command". */ bool_t leave_program; /* Set to TRUE if program is to leave. */ bool_t leave_command_loop; /* Set to TRUE if command loop is to leave. */ bool_t in_command_loop; /* Set to TRUE if program is in command loop. */ /* Variables. ===============================================================*/ static command_t **commands_local; /* Local copy of command table for "help_command". */ static list_t alias_list; /* Functions for user interrupts. ===========================================*/ void check_user_break( void ) /* Abort command execution if user has sent an interrupt signal. */ { if (user_break_requested) { user_break_requested = FALSE; complain( "User interrupt." ); } } /* Functions for reading and executing commands. ============================*/ static command_t * find_command( string_t command_name, command_t *commands[] ) /* Find the entry for COMMAND_NAME in COMMANDS and return it. * Return NULL if COMMAND_NAME can't be found. */ { int_t i; string_t names, name; bool_t found_command; for (i = 0; commands[i] != NULL; i++) { names = commands[i]->names; while (*names != EOS) { name = parse_word( &names ); found_command = (strcmp_no_case( command_name, name ) == 0); free_mem( &name); if (found_command) return commands[i]; } } return NULL; } /*---------------------------------------------------------------------------*/ void execute_command( string_t command_line, string_t command_type, command_t *commands[], bool_t use_aliases ) /* Execute COMMAND_LINE using COMMANDS. * If there is no such command, print an error. * COMMAND_TYPE may be "command" or "option" and is used for error messages. * If USE_ALIASES == TRUE, look for the command in the list of aliases. */ { string_t line, command_name; string_t alias_line, line_p, name_readable; command_t *command; bool_t command_found; alias_t *alias; /* Divide command line into strings COMMAND and ARGUMENTS. */ line = command_name = NULL; TRY { line_p = line = replace_vars_in_string( command_line ); parse_whitespace( &line_p ); if (*line_p != EOS) { command_name = parse_word( &line_p ); command_found = FALSE; user_break_requested = FALSE; commands_local = commands; command = find_command( command_name, commands ); if (command != NULL) /* Execute the command. */ { command_found = TRUE; command->command( line_p ); } else if (use_aliases) { FOREACH( alias, alias_list ) { if (strcmp_no_case( alias->name, command_name ) == 0) { command_found = TRUE; alias_line = replace_arguments( alias->line, "a", line_p ); execute_command( alias_line, command_type, commands, FALSE ); free_mem( &alias_line ); break; } } } if (! command_found) { name_readable = new_string_readable( command_name, NULL ); free_mem( &command_name ); command_name = name_readable; complain( "Unknown %s %s.", command_type, command_name ); } } } FINALLY { free_mem( &command_name ); free_mem( &line ); } END_TRY; } /*---------------------------------------------------------------------------*/ void execute_command_file( string_t command_file, string_t line_header, command_t *commands[] ) /* Execute commands in COMMAND_FILE using COMMANDS. * If LINE_HEADER != NULL, command lines must start with LINE_HEADER. */ { FILE *command_stream; string_t include_file, header, command_line_p; char_t *command_line; bool_t is_command_line; volatile int_t line_count; volatile bool_t leave_loop; command_stream = open_stream( command_file, "r" ); leave_loop = FALSE; line_count = 0; while (! leave_loop) { header = command_line = NULL; TRY { /* Read a command line */ command_line = read_line( command_stream ); if (command_line == NULL) leave_loop = TRUE; else { cut_comment( command_line ); line_count++; command_line_p = command_line; if (*command_line_p == EOS) is_command_line = FALSE; else if (line_header == NULL) is_command_line = TRUE; else { /* Check if current line begins with LINE_HEADER. */ header = parse_word( &command_line_p ); is_command_line = FALSE; if (strcmp_no_case( header, line_header ) == 0) is_command_line = TRUE; else if (strcmp_no_case( header, "include:" ) == 0) { include_file = parse_absolute_path( &command_line_p, command_file ); parse_end( &command_line_p ); execute_command_file( include_file, line_header, commands ); free_mem( &include_file ); } } if (is_command_line) execute_command( command_line_p, "command", commands, TRUE ); } } IF_ERROR { print_text( error_text, " (\"%s\", line %d)", name_in_path( command_file ), line_count ); } FINALLY { free_mem( &header ); free_mem( &command_line ); } END_TRY; } close_stream( &command_stream, command_file ); } /*---------------------------------------------------------------------------*/ void free_aliases( void ) /* Free all currently defined aliases. */ { alias_t *alias; FOREACH_FREE( alias, alias_list ) { free_mem( &alias->name ); free_mem( &alias->line ); } } /* General commands. ========================================================*/ static void print_help_summary( command_t *commands[] ) /* Print names of all commands in COMMANDS. */ { int i, j, n, rows, row, column; string_t names, name; enum { columns = 5 }; /* Calculate number of entries and rows. */ for (n = 0; commands[n] != NULL; n++) /* empty loop */ ; rows = (n + columns - 1) / columns; for (row = 0; row < rows; row++) { for (column = 0; column < columns; column++) { i = row + column * rows; if (i < n) { names = commands[i]->names; name = parse_word( &names ); printf( "%s", name ); for (j = g_utf8_strlen( name, -1 ); j < 15; j++) printf( " " ); free_mem( &name ); } } printf( "\n" ); } } /*---------------------------------------------------------------------------*/ static void print_help( string_t command_type, command_t *command ) /* Print help about COMMAND, * which is of COMMAND_TYPE (either "command" or "option"). */ { string_t names, name; names = command->names; /* Print full name. */ name = parse_word( &names ); printf( "%s \"%s\"", command_type, name ); free_mem( &name ); /* Print shortcuts. */ while (*names != EOS) { name = parse_word( &names ); printf( ", \"%s\"", name ); free_mem( &name ); } /* Print help text. */ printf( ":\n%s", command->help ); } /*---------------------------------------------------------------------------*/ static void do_help( string_t arguments ) /* Give help on commands. */ { string_t command_name; command_t *command, *option; if (*arguments == EOS) { printf( "Commands available: " "(Use \"help COMMAND\" to get help about COMMAND.)\n" ); print_help_summary( commands_local ); printf( "\nOptions available: " "(Use \"help OPTION\" to get help about OPTION.)\n" ); print_help_summary( options ); } else { command_name = parse_word( &arguments ); if (strcmp_no_case( command_name, "command" ) == 0) { free_mem( &command_name ); command_name = parse_word( &arguments ); parse_end( &arguments ); command = find_command( command_name, commands_local ); option = NULL; if (command == NULL) complain( "\"%s\" is no command.", command_name ); } else if (strcmp_no_case( command_name, "option" ) == 0) { free_mem( &command_name ); command_name = parse_word( &arguments ); command = NULL; option = find_command( command_name, options ); if (option == NULL) complain( "\"%s\" is no option.", command_name ); } else { command = find_command( command_name, commands_local ); option = find_command( command_name, options ); if (command != NULL && option != NULL) { complain( "Use \"help command %s\" or \"help option %s\",", command_name, command_name ); } else if (command == NULL && option == NULL) complain( "\"%s\" is neither a command nor an option.", command_name ); } parse_end( &arguments ); if (command != NULL) print_help( "Command", command ); if (option != NULL) print_help( "Option", option ); free_mem( &command_name ); } } command_t help_command = { "help h ?", do_help, "Usage:\n" " help command COMMAND -- Print help about COMMAND.\n" " help option OPTION -- Print help about OPTION.\n" " help COMMAND_OR_OPTION -- Print help about COMMAND_OR_OPTION if unique.\n" " help -- get a list of all available commands and options\n" }; /*---------------------------------------------------------------------------*/ static void do_quit( string_t arguments ) /* Quit the program. */ { parse_end( &arguments ); leave_program = TRUE; } command_t quit_command = { "quit exit q", do_quit, "Leave the program.\n" "Usage: quit\n" }; /*---------------------------------------------------------------------------*/ static void do_get( string_t arguments ) /* Get setting for ARGUMENTS. */ { int_t i; string_t option; if (*arguments == EOS) { for (i = 0; options[i] != NULL; i++) options[i]->command( "" ); } else { option = parse_word( &arguments ); parse_end( &arguments ); execute_command( option, "option", options, FALSE ); free_mem( &option ); } } command_t get_command = { "get", do_get, "Query program settings.\n" "Usage:\n" " get OPTION -- Print the setting of OPTION.\n" " get -- Print all settings.\n" }; /*---------------------------------------------------------------------------*/ static void do_set( string_t arguments ) /* Set an option. */ { string_t option_arguments, option; option_arguments = arguments; option = parse_word( &arguments ); if (*arguments == EOS) complain( "Missing arguments to set \"%s\".", option ); execute_command( option_arguments, "option", options, FALSE ); free_mem( &option ); } command_t set_command = { "set", do_set, "Change program settings.\n" "Usage:\n" " set OPTION ARGUMENT -- Change value of OPTION to ARGUMENT.\n" }; /*---------------------------------------------------------------------------*/ static command_t *set_commands[] = {&set_command, NULL}; /* The commands that can be called during initialisation. */ void execute_set_commands( string_t file_name, string_t prefix ) /* Execute set commands in file FILE_NAME that are prefixed with PREFIX. */ { execute_command_file( file_name, prefix, set_commands ); } /*---------------------------------------------------------------------------*/ static void do_alias_option( string_t arguments ) { alias_t *alias; string_t name, line; if (*arguments == EOS) { if (alias_list.first == NULL) printf( "alias: (none)\n" ); else { FOREACH( alias, alias_list ) { line = new_string_readable( alias->line, NULL ); printf( "alias \"%s\": %s\n", alias->name, line ); free_mem( &line ); } } } else { name = parse_word( &arguments ); /* Find the alias NAME. */ FOREACH( alias, alias_list ) { if (strcmp_no_case( alias->name, name ) == 0) break; } if (*arguments == EOS) { /* Delete the alias. */ if (alias == NULL) complain( "Alias \"%s\" not defined." ); free_mem( &alias->name ); free_mem( &alias->line ); free_node( &alias_list, (list_node_t *) alias ); } else { /* Define an alias. */ line = parse_word( &arguments ); parse_end( &arguments ); if (alias == NULL) /* Create alias entry if it doesn't exist. */ { alias = new_node( &alias_list, sizeof( alias_t ), LIST_END ); alias->name = new_string( name, NULL ); } else free_mem( &alias->line ); alias->line = line; } free_mem( &name ); } } command_t alias_option = { "alias", do_alias_option, "Define command line aliases.\n" "Usage:\n" " alias NAME LINE -- Define alias NAME for LINE.\n" " alias NAME -- Undefine alias NAME.\n" "The LINE may contain the following special sequence:\n" " %a -- The command line arguments when invoking the alias.\n" }; /* End of file. =============================================================*/ malaga-7.12/commands.h0000644000175000017500000000517710462570523014175 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* Tools for a command line interpreter. */ /* Types. ===================================================================*/ /* Use a vector of "command_t" command descriptions * (terminated by a {NULL, NULL} entry) as argument for "command_loop". */ typedef struct { string_t names; /* The command name followed by its * shortcuts, separated by spaces. */ void (*command)( string_t arguments ); /* The command function. */ string_t help; /* Help string or NULL. */ } command_t; /* Variables. ===============================================================*/ extern command_t **options; /* The options that can be set by the set command. * This has to be set before executing "set_command". */ extern bool_t leave_program; /* Set to TRUE if program is to quit. */ extern bool_t leave_command_loop; /* Set to TRUE if command loop is to quit. */ extern bool_t in_command_loop; /* Set to TRUE if program is in command loop. */ /* Functions for user interrupts. ===========================================*/ extern void check_user_break( void ); /* Abort command execution if user has sent an interrupt signal. */ /* Functions for reading and executing commands. ============================*/ extern void execute_command( string_t command_line, string_t command_type, command_t *commands[], bool_t use_aliases ); /* Execute COMMAND_LINE using COMMANDS. * If there is no such command, print an error. * COMMAND_TYPE may be "command" or "option" and is used for error messages. * If USE_ALIASES == TRUE, look for the command in the list of aliases. */ extern void execute_command_file( string_t command_file, string_t line_header, command_t *commands[] ); /* Execute commands in COMMAND_FILE using COMMANDS. * If LINE_HEADER != NULL, command lines must start with LINE_HEADER. */ extern void execute_set_commands( string_t file_name, string_t prefix ); /* Execute set commands in file FILE_NAME that are prefixed with PREFIX. */ extern void free_aliases( void ); /* Free all currently defined aliases. */ /* General commands. ========================================================*/ extern command_t help_command; /* Print a command summary. */ extern command_t quit_command; /* Quit the program. */ extern command_t get_command; /* Query options. */ extern command_t set_command; /* Set options. */ extern command_t alias_option; /* Define command line abbreviations. */ /* End of file. =============================================================*/ malaga-7.12/commands_interactive.c0000644000175000017500000000557710701724653016572 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* Tools for an interactive command line interpreter. */ /* Includes. ================================================================*/ #include #include #include #include "basic.h" #include "commands.h" #include "commands_interactive.h" #include "input.h" #ifdef POSIX #include #endif #ifdef WIN32 #include #endif #ifdef READLINE #include #include #endif /* Functions for reading and executing commands. ============================*/ #ifdef POSIX static void set_user_break( int signal_number ) /* Signal handler for notification that user wants to interrupt a command. */ { user_break_requested = TRUE; signal( SIGINT, set_user_break ); } #endif #ifdef WIN32 static BOOL set_user_break( DWORD signal_type ) /* Signal handler for notification that user wants to interrupt a command. */ { if (signal_type == CTRL_C_EVENT) { user_break_requested = TRUE; return TRUE; } return FALSE; } #endif /*---------------------------------------------------------------------------*/ void command_loop( string_t prompt, command_t *commands[] ) /* Read user commands, look for them in COMMANDS and execute them * until a command function returns FALSE. */ { string_t command_line; bool_t in_command_loop_save; #ifdef READLINE string_t p; #endif /* Install a Ctrl-C handler. */ #ifdef POSIX signal( SIGINT, set_user_break ); #endif #ifdef WIN32 static bool_t user_break_installed; if (! user_break_installed) SetConsoleCtrlHandler( (PHANDLER_ROUTINE) set_user_break, TRUE ); user_break_installed = TRUE; #endif #ifdef READLINE p = concat_strings( prompt, "> ", NULL ); #endif /* Repeat the command loop. */ in_command_loop_save = in_command_loop; in_command_loop = TRUE; while (! leave_command_loop && ! leave_program ) { /* Read command line. */ command_line = NULL; TRY { #ifdef READLINE command_line = readline(p); if (command_line != NULL && ! g_utf8_validate( command_line, -1, NULL )) complain( "Illegal UTF-8 character." ); #else printf( "%s> ", prompt ); command_line = read_line( stdin ); #endif if (command_line != NULL) { #ifdef READLINE if (g_utf8_strlen( command_line, -1 ) > 1) add_history( command_line ); #endif execute_command( command_line, "command", commands, TRUE ); } else { printf( "\n" ); leave_program = TRUE; } } IF_ERROR { printf( "%s\n", error_text->buffer ); RESUME; } FINALLY free_mem( &command_line ); END_TRY; } #ifdef READLINE free_mem(&p); #endif in_command_loop = in_command_loop_save; leave_command_loop = FALSE; } /* End of file. =============================================================*/ malaga-7.12/commands_interactive.h0000644000175000017500000000100110462571507016553 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* Tools for an interactive command line interpreter. */ /* Functions for reading and executing commands. ============================*/ extern void command_loop( string_t prompt, command_t *commands[] ); /* Read user commands, look for them in COMMANDS and execute them * until a command returns FALSE. */ /* End of file. =============================================================*/ malaga-7.12/debugger.c0000644000175000017500000005104010462570523014141 0ustar bjoernbjoern/* Copyright (C) 1995 Gerald Schueller. */ /* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* Debugger functions. */ /* Includes. ================================================================*/ #include #include #include #include #include #include "basic.h" #include "pools.h" #include "values.h" #include "symbols.h" #include "files.h" #include "input.h" #include "commands.h" #include "commands_interactive.h" #include "options.h" #include "rule_type.h" #include "rules.h" #include "display.h" #include "breakpoints.h" #include "value_parser.h" #include "scanner.h" #include "debugger.h" /* Global variables. ========================================================*/ bool_t in_debugger; /* Variables. ===============================================================*/ static debug_mode_t debug_mode = RUN_MODE; /* Current debug mode. */ static struct /* Definition of the step properties. */ { /* Information for NEXT_MODE */ int_t nested_subrules; /* Depth of subrule nesting when stepping started. */ int_t path_count; /* Number of inactive paths when stepping started. */ /* Information for NEXT_MODE and STEP_MODE. */ int_t line; /* Line where stepping started. */ string_t file; /* File where stepping started. */ /* Local breakpoint. */ int_t break_instr; /* Instr index of local breakpoint. */ /* Local watchpoint. */ var_scope_t *var_scope; value_t path, value; } info; static int_t debug_frame; /* Number of the current frame to be debugged. */ static void (*display_where)( void ); /* Pointer to a function that displays where rule execution now stands. */ static command_t **debugger_commands; /* Commands that can be executed when the debug mode is invoked. */ /* Functions. ===============================================================*/ static void parse_path( void ) /* Stack effects: (nothing) -> NEW_LIST. * Parse a PATH (use scanner input) and leave it on the stack. * PATH ::= {"." (SYMBOL | NUMBER)} . * NEW_LIST is the path converted to a list. */ { int_t n; n = 0; while (next_token == '.') { read_next_token(); switch (next_token) { case TOK_NUMBER: if ((int_t) token_number != token_number || token_number == 0.0) complain( "Index must be non-null integer." ); push_number_value( token_number ); read_next_token(); break; case TOK_IDENT: push_symbol_value( find_symbol( token_name ) ); read_next_token(); break; default: complain( "Index or symbol expected." ); } n++; } build_list(n); } /*---------------------------------------------------------------------------*/ static bool_t debug_now( rule_sys_t *rule_sys, int_t pos ) /* Test whether debug command loop should be entered now. */ { int_t line, instr; string_t file; value_t value; volatile bool_t condition; switch (debug_mode) { case NEXT_MODE: if (path_count < info.path_count) { /* Current path is finished. Debug older path. */ info.nested_subrules = nested_subrules; info.path_count = path_count; } if (nested_subrules <= info.nested_subrules) goto STEP_MODE; return FALSE; case STEP_MODE: STEP_MODE: source_of_instr( rule_sys, pos, &line, &file, NULL ); condition = ((line != -1 || file != NULL) && (info.line != line || info.file != file)); /* If this path terminates, let the debugger stop at next source line. */ instr = OPCODE( rule_sys->instrs[ pos ] ); if (instr == INS_TERMINATE || (instr == INS_TERMINATE_IF_NULL && value_stack[ top - 1 ] == NULL)) { info.line = -1; info.file = NULL; } else if (condition) { info.nested_subrules = nested_subrules; info.line = line; info.file = file; } return condition; case FINISH_MODE: instr = OPCODE( rule_sys->instrs[ pos ] ); return ((instr == INS_TERMINATE_IF_NULL && value_stack[ top - 1 ] == NULL) || (instr == INS_RETURN && info.nested_subrules == nested_subrules) || instr == INS_TERMINATE); case WALK_MODE: return (rule_sys->rules[ executed_rule_number ].first_instr == pos); case GO_MODE: if (info.break_instr == pos) return TRUE; /* Check if watch condition holds. */ if (info.var_scope == NULL || pos < info.var_scope->first_instr || pos >= info.var_scope->last_instr) { return FALSE; } condition = FALSE; TRY { value = get_value_part( value_stack[ base + info.var_scope->stack_index ], info.path ); if (value != NULL) condition = values_equal( value, info.value ); } IF_ERROR RESUME; END_TRY; if (! condition) return FALSE; source_of_instr( rule_sys, pos, &line, NULL, NULL ); return (line /= -1); default: return FALSE; } } /*---------------------------------------------------------------------------*/ void set_debug_mode( debug_mode_t new_debug_mode, rule_sys_t *rule_sys ) /* Set debug mode NEW_DEBUG_MODE for RULE_SYS. */ { if (new_debug_mode == RUN_MODE) debug_rule_sys = NULL; else debug_rule_sys = rule_sys; debug_mode = new_debug_mode; debug_frame = 0; } /*---------------------------------------------------------------------------*/ debug_mode_t get_debug_mode( void ) /* Get the current debug mode. */ { return debug_mode; } /*---------------------------------------------------------------------------*/ static void display_variables( void ) { string_t value_string, var_name; int_t i, first_var, last_var, pc_index, base_index; value_t value; if (use_display) { start_display_process(); fprintf( display_stream, "variables\n" ); } get_frame_info( debug_frame, &pc_index, &base_index, &first_var, &last_var ); for (i = first_var; i < last_var; i++) { var_name = variable_at_index( executed_rule_sys, i - base_index, pc_index ); value = value_stack[i]; if (var_name != NULL && value != NULL) { if (use_display) { value_string = value_to_readable( value, FALSE, -1 ); fprintf( display_stream, "\"$%s\" {%s}\n", var_name, value_string ); free_mem( &value_string ); } else { value_string = value_to_readable( value, FALSE, g_utf8_strlen( var_name, -1 ) + 4 ); printf( "$%s = %s\n", var_name, value_string ); free_mem( &value_string ); } } } if (use_display) { fprintf( display_stream, "end\n" ); fflush( display_stream ); } } /*---------------------------------------------------------------------------*/ static void debugger_debug_rule( bool_t interrupt ) /* Called from "execute_rule" before instruction at PC is executed. * If INTERRUPT == TRUE, we have been called by an interrupt. */ { int_t breakpoint_number, old_top, line; rule_t *rule; string_t file_name; in_debugger = TRUE; old_top = top; breakpoint_number = at_breakpoint( executed_rule_sys, pc ); if (interrupt || breakpoint_number != 0 || debug_now( executed_rule_sys, pc )) { rule = executed_rule_sys->rules + executed_rule_number; if (rule->first_instr == pc) display_where(); else { source_of_instr( executed_rule_sys, pc, &line, &file_name, NULL ); if (in_emacs_malaga_mode) printf( "SHOW \"%s\":%d:0\n", file_name, line ); else printf( "At \"%s\", line %d.\n", name_in_path( file_name ), line ); } if (interrupt) printf( "User interrupt.\n" ); if (breakpoint_number != 0) printf( "Hit breakpoint %d.\n", breakpoint_number ); if (auto_variables) display_variables(); command_loop( "debug", debugger_commands ); if (leave_program) set_debug_mode( RUN_MODE, NULL ); } top = old_top; in_debugger = FALSE; } /*---------------------------------------------------------------------------*/ void init_debugger( void (*my_display_where)( void ), command_t *my_debugger_commands[] ) /* Initialise the debugger module. * The function MY_DISPLAY_WHERE is a callback to display where rule * execution currently stands at. * MY_DEBUGGER_COMMANDS is an array of commands that can be invoked * in debug mode. */ { display_where = my_display_where; debugger_commands = my_debugger_commands; debug_rule = debugger_debug_rule; } /*---------------------------------------------------------------------------*/ void terminate_debugger( void ) /* Terminate the debugger module. */ { free_mem( &info.path ); free_mem( &info.value ); debug_rule = NULL; } /*---------------------------------------------------------------------------*/ static void step_or_next( debug_mode_t mode, string_t argument ) /* Execute "step" or "next" command (see MODE) with ARGUMENT. */ { int_t line; string_t file; assert_in_debug_mode(); parse_end( &argument ); source_of_instr( executed_rule_sys, pc, &line, &file, NULL ); info.path_count = path_count; info.nested_subrules = nested_subrules; info.line = line; info.file = file; set_debug_mode( mode, executed_rule_sys ); } /*---------------------------------------------------------------------------*/ static void do_run( string_t arguments ) /* Continue rule execution in non-debugging mode. */ { assert_in_debug_mode(); parse_end( &arguments ); set_debug_mode( RUN_MODE, NULL ); leave_command_loop = TRUE; } command_t run_command = { "run r", do_run, "Return to non-debug mode and complete rule execution.\n" "Usage: run\n" "\"run\" can only be used in debug mode.\n" }; /*---------------------------------------------------------------------------*/ static void do_continue( string_t arguments ) /* Continue rule execution until condition is reached. */ { rule_sys_t *rule_sys; string_t var_name; var_name = NULL; assert_in_debug_mode(); info.break_instr = -1; info.var_scope = NULL; free_mem( &info.path ); free_mem( &info.value ); if (*arguments == '$') { set_scanner_input( arguments ); TRY { test_token( TOK_VARIABLE ); var_name = new_string( token_name, NULL ); read_next_token(); parse_path(); info.var_scope = get_var_scope_by_name( executed_rule_sys, var_name, pc ); if (info.var_scope == NULL) complain( "\"$%s\" is not defined here.", var_name ); info.path = new_value( value_stack[ --top ] ); parse_token( '=' ); parse_a_value(); info.value = new_value( value_stack[ --top ] ); test_token( EOF ); } FINALLY { set_scanner_input( NULL ); free_mem( &var_name ); } END_TRY; } else if (*arguments != EOS) { get_breakpoint( arguments, &rule_sys, &info.break_instr ); if (rule_sys != executed_rule_sys) complain( "This rule system is not being debugged." ); } set_debug_mode( GO_MODE, executed_rule_sys ); leave_command_loop = TRUE; } command_t continue_command = { "continue c go g", do_continue, "Execute rules until a breakpoint is hit or analysis is completed.\n" "Usage:\n" "continue -- Continue until analysis is completed.\n" "continue BREAKPOINT -- Continue until BREAKPOINT is met.\n" "continue VAR_PATH = VALUE -- Continue until VAR_PATH = VALUE.\n" "\"continue\" can only be used in debug mode.\n" }; /*---------------------------------------------------------------------------*/ void assert_not_in_debug_mode( void ) /* Make sure we are NOT in debug mode. */ { if (in_debugger) complain( "In debug mode." ); } /*---------------------------------------------------------------------------*/ void assert_in_debug_mode( void ) /* Make sure we ARE in debug mode. */ { if (! in_debugger) complain( "Not in debug mode." ); } /*---------------------------------------------------------------------------*/ static void do_walk( string_t arguments ) /* Continue rule execution until next rule or breakpoint is met * or end is reached. */ { assert_in_debug_mode(); parse_end( &arguments ); set_debug_mode( WALK_MODE, executed_rule_sys ); leave_command_loop = TRUE; } command_t walk_command = { "walk w", do_walk, "Walk to the next rule or the next state.\n" "Usage: walk\n" "\"walk\" can only be used in debug mode.\n" }; /*---------------------------------------------------------------------------*/ static void do_step( string_t argument ) /* Continue until control reaches a different source line. */ { step_or_next( STEP_MODE, argument ); leave_command_loop = TRUE; } command_t step_command = { "step s", do_step, "Step to the next source line.\n" "Also stop when current path has terminated.\n" "Usage: step\n" "\"step\" can only be used in debug mode.\n" }; /*---------------------------------------------------------------------------*/ static void do_next( string_t argument ) /* Continue until control reaches a different source line, but jump over * subrules. */ { step_or_next( NEXT_MODE, argument ); leave_command_loop = TRUE; } command_t next_command = { "next n", do_next, "Step to the next source line, but jump over subrules.\n" "Also stop when current path has terminated.\n" "Usage: next\n" "\"next\" can only be used in debug mode.\n" }; /*---------------------------------------------------------------------------*/ static void do_finish( string_t argument ) /* Continue until path ends or returns. */ { assert_in_debug_mode(); parse_end( &argument ); set_debug_mode( FINISH_MODE, executed_rule_sys ); info.nested_subrules = nested_subrules; leave_command_loop = TRUE; } command_t finish_command = { "finish fi", do_finish, "Go until current path terminates or returns from current subrule.\n" "Usage: finish\n" "\"finish\" can only be used in debug mode.\n" }; /*---------------------------------------------------------------------------*/ static void display_frame( void ) /* Display source location and variables for current frame. */ { int_t line, pc_index; string_t file_name; get_frame_info( debug_frame, &pc_index, NULL, NULL, NULL ); source_of_instr( executed_rule_sys, pc_index, &line, &file_name, NULL ); if (in_emacs_malaga_mode) printf( "SHOW \"%s\":%d:0\n", file_name, line ); else printf( "At \"%s\", line %d.\n", name_in_path( file_name ), line ); if (auto_variables) display_variables(); } /*---------------------------------------------------------------------------*/ static void do_frame( string_t arguments ) /* Select a new debug frame. */ { int_t frame, frame_count; if (pc == -1) complain( "No rule executed." ); frame = parse_cardinal( &arguments ); parse_end( &arguments ); frame_count = get_frame_count(); if (frame < 1 || frame > frame_count) complain( "Frame %d doesn't exist.", frame ); debug_frame = frame_count - frame; display_frame(); } command_t frame_command = { "frame f", do_frame, "Select a new frame for debugging.\n" "Usage: frame NUMBER\n" "You can list the frames using \"backtrace\".\n" "\"frame\" can only be used in debug mode or after a rule execution error.\n" }; /*---------------------------------------------------------------------------*/ static void do_up( string_t arguments ) /* Go to calling frame. */ { if (pc == -1) complain( "No rule executed." ); parse_end( &arguments ); if (debug_frame + 1 >= get_frame_count()) complain( "Already at outermost frame." ); debug_frame++; display_frame(); } command_t up_command = { "up", do_up, "Select frame that called current frame for debugging.\n" "Usage: up\n" "\"up\" can only be used in debug mode or after a rule execution error.\n" }; /*---------------------------------------------------------------------------*/ static void do_down( string_t arguments ) /* Go to called frame. */ { if (pc == -1) complain( "No rule executed." ); parse_end( &arguments ); if (debug_frame <= 0) complain( "Already at innermost frame." ); debug_frame--; display_frame(); } command_t down_command = { "down", do_down, "Select frame that has been called by current frame for debugging.\n" "Usage: down\n" "\"down\" can only be used in debug mode or after a rule execution error.\n" }; /*---------------------------------------------------------------------------*/ static void do_backtrace( string_t arguments ) /* Print all active subrules and rules in reverse order. */ { string_t file, rule; int_t frame, frame_count, line, pc_index; if (pc == -1) complain( "No rule executed." ); parse_end( &arguments ); frame_count = get_frame_count(); for (frame = 0; frame < frame_count; frame++) { get_frame_info( frame, &pc_index, NULL, NULL, NULL ); source_of_instr( executed_rule_sys, pc_index, &line, &file, &rule ); printf( "%c%d: \"%s\", line %d, rule \"%s\"\n", (frame == debug_frame) ? '*' : ' ', frame_count - frame, name_in_path( file ), line, rule ); } } command_t backtrace_command = { "backtrace bt trace", do_backtrace, "Print the active subrules in reverse order.\n" "Usage: backtrace\n" "\"backtrace\" can only be used in debug mode or after an execution error.\n" }; /*---------------------------------------------------------------------------*/ static void do_print( string_t argument ) /* Print content of variables. */ { string_t value_string, path, name; value_t value; var_scope_t *var_scope; int_t base_idx, pc_idx; volatile bool_t is_constant = FALSE; if (pc == -1) complain( "No rule executed." ); if (use_display) { start_display_process(); fprintf( display_stream, "expressions\n" ); } TRY { while (*argument != EOS) { get_frame_info( debug_frame, &pc_idx, &base_idx, NULL, NULL ); path = parse_word( &argument ); set_scanner_input( path ); TRY { if (next_token != TOK_VARIABLE && next_token != TOK_CONSTANT) { complain( "variable or constant expected, not %s", token_as_text( next_token ) ); } is_constant = (next_token == TOK_CONSTANT); name = new_string( token_name, NULL ); read_next_token(); parse_path(); test_token( EOF ); } FINALLY set_scanner_input( NULL ); END_TRY; /* Get variable or constant value. */ value = NULL; if (is_constant) { value = get_constant( executed_rule_sys, name ); if (value == NULL) printf( "@%s is not defined.\n", name ); } else { var_scope = get_var_scope_by_name( executed_rule_sys, name, pc_idx ); if (var_scope == NULL) printf( "$%s is not defined.\n", name ); else value = value_stack[ base_idx + var_scope->stack_index ]; } if (value != NULL) { value = get_value_part( value, value_stack[ --top ] ); if (value == NULL) printf( "%s does not exist.\n", path ); else if (use_display) { value_string = value_to_readable( value, FALSE, -1 ); fprintf( display_stream, "\"%s\" {%s}\n", path, value_string ); free_mem( &value_string ); } else { value_string = value_to_readable( value, FALSE, g_utf8_strlen( path, -1 ) + 3 ); printf( "%s = %s\n", path, value_string ); free_mem( &value_string ); } } free_mem( &path ); free_mem( &name ); } } FINALLY { if (use_display) { fprintf( display_stream, "end\n") ; fflush( display_stream ); } } END_TRY; } command_t print_command = { "print p", do_print, "Print the values of Malaga expressions.\n" "Usage:\n" " print EXPRESSION ... -- Print the values of the specified expressions.\n" "An expression is a variable or constant with an optional attribute path.\n" "\"print\" can only be used in debug mode or after a rule execution error.\n" }; /*---------------------------------------------------------------------------*/ static void do_variables( string_t arguments ) /* Generate variables file and start program to display variables. */ { if (pc == -1) complain( "No rule executed." ); parse_end( &arguments ); display_variables(); } command_t variables_command = { "variables v", do_variables, "Show variables of current frame.\n" "Usage: variables\n" "\"variables\" can only be used in debug mode or after a rule execution " "error.\n" }; /*---------------------------------------------------------------------------*/ static void do_where( string_t arguments ) /* Print where rule execution currently stands at. */ { if (pc == -1) complain( "No rule executed." ); parse_end( &arguments ); display_where(); } command_t where_command = { "where rule", do_where, "Show where rule execution currently stands at.\n" "Usage: where\n" "\"where\" can only be used in debug mode or after a rule execution error.\n" }; /* End of file. =============================================================*/ malaga-7.12/debugger.h0000644000175000017500000000553310236624743014157 0ustar bjoernbjoern/* Copyright (C) 1995 Gerald Schueller. */ /* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* Debugger functions. */ /* Types. ===================================================================*/ typedef enum /* Debugger modes (set by "set_debug_mode"). */ { RUN_MODE, /* Ignore breakpoints. */ GO_MODE, /* Stop at breakpoints. */ WALK_MODE, /* Stop at breakpoints and rule starts. */ NEXT_MODE, /* Stop at new source lines; walk over subrules. */ STEP_MODE, /* Stop at new source lines. */ FINISH_MODE /* Stop at return from current rule or subrule */ } debug_mode_t; /* Variables ================================================================*/ extern bool_t in_debugger; /* TRUE iff in debugger loop. Read only! */ /* Functions. ===============================================================*/ extern void init_debugger( void (*my_display_where)( void ), command_t *my_debugger_commands[] ); /* Initialise the debugger module. * The function MY_DISPLAY_WHERE is a callback to display where rule * execution currently stands at. * MY_DEBUGGER_COMMANDS is an array of commands that can be invoked * in debug mode. */ extern void terminate_debugger( void ); /* Terminate the run time environment. */ extern void set_debug_mode( debug_mode_t debug_mode, rule_sys_t *rule_sys ); /* Set debug mode DEBUG_MODE for RULE_SYS. */ extern debug_mode_t get_debug_mode( void ); /* Get the current debug mode. */ extern void assert_not_in_debug_mode( void ); /* Make sure we are *not* in debug mode. */ extern void assert_in_debug_mode( void ); /* Make sure we *are* in debug mode. */ /* Commands. ================================================================*/ extern command_t variables_command; /* Generate variables file and start program to display variables. */ extern command_t run_command; /* Execute rules in non-debugging mode. */ extern command_t walk_command; /* Execute rules until different rule. */ extern command_t continue_command; /* Execute rules until breakpoint. */ extern command_t step_command; /* Execute rules until different line. */ extern command_t next_command; /* Execute rules until different line, * but jump over subrules. */ extern command_t finish_command; /* Stop at end off current rule or subrule. */ extern command_t print_command; /* Print the values of variables. */ extern command_t frame_command; /* Select a new frame for debugging. */ extern command_t down_command; /* Go to called frame. */ extern command_t up_command; /* Go to calling frame. */ extern command_t backtrace_command; /* Print all active subrules and rules in reverse order. */ extern command_t where_command; /* Print where rule execution currently stands at. */ /* End of file. =============================================================*/ malaga-7.12/display.c0000644000175000017500000000442110506407330014015 0ustar bjoernbjoern/* Copyright (C) 1996 Bjoern Beutel. */ /* Description. =============================================================*/ /* Invoke the display process from Malaga. */ /* Includes. ================================================================*/ #include #include #include #include #include #include #include "basic.h" #include "files.h" #include "input.h" #include "commands.h" #include "processes.h" #include "display.h" /* Global variables. ========================================================*/ FILE *display_stream; /* Stream to send data to the display process. */ /* Variables. ===============================================================*/ static process_t display_process; /* Functions. ===============================================================*/ void stop_display_process( void ) /* Stop the Malaga display process. */ { stop_process( &display_process ); display_stream = NULL; } /*---------------------------------------------------------------------------*/ void start_display_process( void ) /* Start the Malaga display process by executing DISPLAY_COMMAND_LINE * if it is not already running. */ { display_process.use_input = FALSE; display_process.use_output = TRUE; display_process.name = "display process"; if (display_process.command_line == NULL) display_process.command_line = new_string( "malshow", NULL ); start_process( &display_process ); display_stream = display_process.output_stream; } /*---------------------------------------------------------------------------*/ static void do_display_cmd_option( string_t arguments ) /* Set the command line to start the display process. */ { if (*arguments == EOS) { printf( "display-cmd: \"%s\"\n", (display_process.command_line == NULL ? "" : display_process.command_line) ); } else { stop_display_process(); display_process.command_line = parse_word( &arguments ); } parse_end( &arguments ); } command_t display_cmd_option = { "display-cmd display-line display", do_display_cmd_option, "Usage: set display-cmd \"DISPLAY_COMMAND_LINE\"\n" "Set the command that is used to start the display process.\n" }; /* End of file. =============================================================*/ malaga-7.12/display.h0000644000175000017500000000160510506407516014031 0ustar bjoernbjoern/* Copyright (C) 1996 Bjoern Beutel. */ /* Description. =============================================================*/ /* Managing the display process from Malaga. */ /* Variables. ===============================================================*/ extern FILE *display_stream; /* Stream to send data to the display process. */ /* Functions. ===============================================================*/ extern void start_display_process( void ); /* Start the Malaga display process by executing DISPLAY_COMMAND_LINE * if it is not already running. */ extern void stop_display_process( void ); /* Stop the Malaga display process. */ /* Commands. ================================================================*/ extern command_t display_cmd_option; /* Set the command line to start the display process. */ /* End of file. =============================================================*/ malaga-7.12/expressions.c0000644000175000017500000001512410236624743014745 0ustar bjoernbjoern/* Copyright (C) 2002 Bjoern Beutel. */ /* Description. =============================================================*/ /* Read in and display Malaga debugger expressions. */ /* Includes. ================================================================*/ #include #include #include #include #include #include #include "basic.h" #include "scanner.h" #include "input.h" #include "canvas.h" #include "expressions.h" /* Types. ===================================================================*/ typedef struct { list_node_t *next; pos_string_t *name; pos_value_t *value; bool_t is_shown; } expression_t; /* Global variables. ========================================================*/ rectangle_t expressions_geometry; string_t expressions_font_family; int_t expressions_font_size; /* Variables. ===============================================================*/ static list_t expressions; static canvas_t *expressions_canvas; static pos_string_t *equal, *dots; /* Functions. ===============================================================*/ static void configure_expressions( canvas_t *canvas, int_t *width_p, int_t *height_p ) { int_t width, height; expression_t *expression; int_t font_height = get_font_height( canvas ); int_t space_width = get_space_width( canvas ); int_t border_width = get_border_width( canvas ); config_pos_string( equal, canvas ); config_pos_string( dots, canvas ); width = height = border_width; FOREACH( expression, expressions ) { if (expression != (expression_t *) expressions.first) height += font_height; config_pos_string( expression->name, canvas ); expression->name->x = border_width; expression->name->y = height; equal->x = expression->name->x + expression->name->width + space_width; if (expression->is_shown) { config_pos_value( expression->value, canvas ); expression->value->x = equal->x + equal->width + space_width; expression->value->y = height; expression->name->y += (expression->value->height - font_height) / 2; width = MAX( width, expression->value->x + expression->value->width ); height += expression->value->height; } else { dots->x = equal->x + equal->width + space_width; width = MAX( width, dots->x + dots->width ); height += font_height; } } *width_p = width + border_width; *height_p = height + border_width; } /*---------------------------------------------------------------------------*/ static void expose_expressions( canvas_t *canvas, rectangle_t *area ) { int_t space_width = get_space_width( canvas ); expression_t *expression; set_color( BLACK ); FOREACH( expression, expressions ) { draw_pos_string( expression->name, canvas ); equal->x = expression->name->x + expression->name->width + space_width; equal->y = expression->name->y; draw_pos_string( equal, canvas ); if (expression->is_shown) draw_pos_value( expression->value, canvas ); else { dots->x = equal->x + equal->width + space_width; dots->y = equal->y; draw_pos_string( dots, canvas ); } } } /*---------------------------------------------------------------------------*/ static bool_t mouse_event( canvas_t *canvas, int_t x, int_t y, int_t button ) /* Called if mouse has moved in CANVAS at position X/Y. */ { expression_t *expression; int_t font_height = get_font_height( canvas ); FOREACH( expression, expressions ) { if (x >= expression->name->x && x < expression->name->x + expression->name->width && y >= expression->name->y && y < expression->name->y + font_height) { if (button == 0) set_cursor( canvas, TRUE ); else if (button == 1) { expression->is_shown = ! expression->is_shown; configure_canvas( canvas ); } else if (button == 3) { free_pos_string( &expression->name ); free_pos_value( &expression->value ); free_node( (list_t *) &expressions, (list_node_t *) expression ); configure_canvas( canvas ); } return TRUE; } } set_cursor( canvas, FALSE ); return FALSE; } /*---------------------------------------------------------------------------*/ static void show_all_expressions( canvas_t *canvas, guint do_show ) { expression_t *expression; FOREACH( expression, expressions ) expression->is_shown = do_show; configure_canvas( canvas ); } /*---------------------------------------------------------------------------*/ static void clear_expressions( canvas_t *canvas ) { expression_t *expression; FOREACH_FREE( expression, expressions ) { free_pos_string( &expression->name ); free_pos_value( &expression->value ); } configure_canvas( canvas ); } /*---------------------------------------------------------------------------*/ static GtkItemFactoryEntry menu_items[] = { { "/Expressions", NULL, NULL, 0, "" }, { "/Expressions/Clear All", NULL, clear_expressions, NULL, NULL }, { "/Expressions/Show All", NULL, show_all_expressions, TRUE, NULL }, { "/Expressions/Hide All", NULL, show_all_expressions, FALSE, NULL }, }; /*---------------------------------------------------------------------------*/ void read_expressions( void ) /* Read new expressions from STDIN. */ { string_t line; expression_t *expression; while (TRUE) { line = read_line( stdin ); if (line == NULL) complain( "Premature EOF." ); if (strcmp_no_case( line, "end" ) == 0) break; /* Read a new expression. */ expression = new_node( &expressions, sizeof( expression_t ), LIST_END ); set_scanner_input( line ); /* Read expression name. */ test_token( TOK_STRING ); expression->name = new_pos_string( token_string ); read_next_token(); /* Read expression value. */ parse_token( '{' ); expression->value = parse_pos_value(); parse_token( '}' ); parse_token( EOF ); set_scanner_input( NULL ); free_mem( &line ); expression->is_shown = TRUE; } free_mem( &line ); if (equal == NULL) equal = new_pos_string( "=" ); if (dots == NULL) dots = new_pos_string( "..." ); if (expressions_canvas == NULL) { expressions_canvas = create_canvas( "Malaga Expressions", "expressions.eps", &expressions_geometry, configure_expressions, expose_expressions, NULL, mouse_event, TRUE, menu_items, ARRAY_LENGTH( menu_items ) ); } else { configure_canvas( expressions_canvas ); go_canvas_bottom( expressions_canvas ); show_canvas( expressions_canvas ); } } /* End of file. =============================================================*/ malaga-7.12/expressions.h0000644000175000017500000000103410236624743014745 0ustar bjoernbjoern/* Copyright (C) 2002 Bjoern Beutel. */ /* Description. =============================================================*/ /* Read in and display Malaga debugger expressions. */ /* Variables. ===============================================================*/ extern rectangle_t expressions_geometry; /* Functions ================================================================*/ extern void read_expressions( void ); /* Read new expressions from STDIN. */ /* End of file. =============================================================*/ malaga-7.12/files.c0000644000175000017500000004104210701725430013453 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* Operations for files and file names. */ /* Includes. ================================================================*/ #define _POSIX_SOURCE #include #include #include #include #include #include #include "basic.h" #include "files.h" #ifdef POSIX #include #include #include #include #endif #ifdef WIN32 #include #endif /* Constants. ===============================================================*/ enum {MAX_PATH_SIZE = 200}; /* Maximum path size in characters. */ /* Macros. ==================================================================*/ #define IS_LETTER(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z')) /* File operations. =========================================================*/ bool_t file_exists( string_t file_name ) /* Return TRUE iff file FILE_NAME exists and can be read. */ { FILE *stream; stream = fopen( file_name, "r" ); if (stream == NULL) return FALSE; fclose( stream ); return TRUE; } /*---------------------------------------------------------------------------*/ FILE * open_stream( string_t file_name, string_t stream_mode ) /* Open file FILE_NAME and create a stream from/to it in mode STREAM_MODE. * Works like "fopen", but calls "error" if it doesn't work. */ { FILE *stream; stream = fopen( file_name, stream_mode ); if (stream == NULL) complain( "Can't open \"%s\": %s.", file_name, strerror( errno ) ); return stream; } /*---------------------------------------------------------------------------*/ void close_stream( FILE **stream_p, string_t file_name ) /* Close the stream *STREAM_P which is connected to the file FILE_NAME * and set *STREAM_P to NULL. Don't do anything if *STREAM_P == NULL. * Works like "fclose", but calls "error" if FILE_NAME != NULL and an error * occurs during closing. */ { FILE *stream = *stream_p; *stream_p = NULL; if (stream != NULL && fclose( stream ) != 0 && file_name != NULL) complain( "Can't close \"%s\": %s.", file_name, strerror( errno ) ); } /*---------------------------------------------------------------------------*/ void write_vector( const void *address, int_t item_size, int_t item_count, FILE *stream, string_t file_name ) /* Write ITEM_COUNT items, of size ITEM_SIZE each, stored at *ADDRESS, * to STREAM, which is connected to file FILE_NAME. * Works like "fwrite", but calls "error" if it doesn't work. */ { if (fwrite( address, (size_t) item_size, (size_t) item_count, stream ) < (size_t) item_count) { complain( "Can't write to \"%s\": %s.", file_name, strerror( errno ) ); } } /*---------------------------------------------------------------------------*/ void read_vector( void *address, int_t item_size, int_t item_count, FILE *stream, string_t file_name ) /* Read ITEM_COUNT items, of size ITEM_SIZE each, from STREAM, * which is connected to file FILE_NAME, and store them at *ADDRESS. * Works like "fread", but calls "error" if it doesn't work. */ { if (fread( address, (size_t) item_size, (size_t) item_count, stream ) < (size_t) item_count) { complain( "Can't read from \"%s\": %s.", file_name, strerror( errno ) ); } } /*---------------------------------------------------------------------------*/ void * read_new_vector( int_t item_size, int_t item_count, FILE *stream, string_t file_name ) /* Read ITEM_COUNT items, of size ITEM_SIZE each, from STREAM, * which is connected to file FILE_NAME, into allocated memory block, * and return a pointer to that block. * The block must be freed after use. */ { void *block; block = new_vector( item_size, item_count ); read_vector( block, item_size, item_count, stream, file_name ); return block; } /*---------------------------------------------------------------------------*/ void map_file( string_t file_name, void **address, int_t *length ) /* Map file "file_name" into the memory. It will be available in the * memory region starting at *ADDRESS and will occupy LENGTH bytes. * After usage, return the memory region via "unmap_file". */ { #ifdef POSIX int file_descriptor; /* Get a file descriptor. */ file_descriptor = open( file_name, O_RDONLY ); if (file_descriptor == -1) complain( "Can't open \"%s\": %s.", file_name, strerror( errno ) ); /* Get file length. */ *length = lseek( file_descriptor, 0, SEEK_END ); if (*length == -1) { complain( "Can't get length of \"%s\": %s.", file_name, strerror( errno ) ); } *address = mmap( NULL, *length, PROT_READ, MAP_SHARED, file_descriptor, 0 ); if (*address == (void *) -1) complain( "Can't read \"%s\": %s.", file_name, strerror( errno ) ); /* The file descriptor is no longer needed. */ close( file_descriptor ); #endif #ifdef WIN32 HANDLE file_handle, map_handle; file_handle = CreateFile( file_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if (file_handle == INVALID_HANDLE_VALUE) complain( "Can't open \"%s\".", file_name ); map_handle = CreateFileMapping( file_handle, NULL, PAGE_READONLY, 0, 0, NULL ); if (map_handle == NULL) complain( "Can't map \"%s\".", file_name ); *address = MapViewOfFile( map_handle, FILE_MAP_READ, 0, 0, 0 ); if (*address == NULL) complain( "Can't map \"%s\".", file_name ); *length = GetFileSize( file_handle, NULL ); CloseHandle( map_handle ); CloseHandle( file_handle ); #endif } /*---------------------------------------------------------------------------*/ void unmap_file( void **address, int_t length ) /* Return the memory region that has been allocated by "map_file". * The region starts at *ADDRESS and occupies LENGTH bytes. */ { #ifdef POSIX munmap( *address, length ); #endif #ifdef WIN32 UnmapViewOfFile( *address ); #endif *address = NULL; } /* File name operations. ====================================================*/ string_t name_in_path( string_t path_name ) /* Return the file name in PATH_NAME, * i.e. the name after the last separator. */ { string_t name; for (name = path_name + strlen( path_name ); name > path_name; name--) { if (name[-1] == '/') break; #ifdef WIN32 if (name[-1] == '\\' || (name == path_name + 2 && IS_LETTER( name[-2] ) && name[-1] == ':')) { break; } #endif } return name; } /*---------------------------------------------------------------------------*/ static string_t get_env( string_t name ) /* Get the content of the environment variable NAME. * Emit an error if it is not defined. */ { string_t content; content = getenv( name ); if (content == NULL) complain( "Can't read environment variable \"%s\".", name ); return content; } /*---------------------------------------------------------------------------*/ static void tidy_path( char_t *path ) /* Remove all superfluous "..", "." and "/" in PATH. * PATH must be absolute. */ { char_t *src_p; char_t *dest_p; #ifdef POSIX dest_p = src_p = path; while (*src_p != EOS) { while (*src_p == '/') src_p++; *dest_p++ = '/'; if (src_p[0] == '.' && src_p[1] == '.' && (src_p[2] == '/' || src_p[2] == EOS)) { /* Walk up only if we are not on root level. */ src_p += 2; if (dest_p > path + 1) dest_p -= 2; while (*dest_p != '/') dest_p--; } else if (src_p[0] == '.' && (src_p[1] == '/' || src_p[1] == EOS)) { src_p++; dest_p--; } else { while (*src_p != '/' && *src_p != EOS) *dest_p++ = *src_p++; } } if (dest_p > path + 1 && dest_p[-1] == '/') dest_p--; *dest_p = EOS; #endif #ifdef WIN32 /* The first two chars is the drive specification. */ if (! IS_LETTER( path[0] ) || path[1] != ':') complain( "Missing drive name." ); dest_p = src_p = path + 2; while (*src_p != EOS) { while (*src_p == '\\' || *src_p == '/') src_p++; *dest_p++ = '\\'; if (src_p[0] == '.' && src_p[1] == '.' && (src_p[2] == '\\' || src_p[2] == '/' || src_p[2] == EOS)) { /* Walk up only if we are not on root level. */ src_p += 2; if (dest_p > path + 3) dest_p -= 2; while (*dest_p != '\\') dest_p--; } else if (src_p[0] == '.' && (src_p[1] == '\\' || src_p[1] == '/' || src_p[1] == EOS)) { src_p++; dest_p--; } else { while (*src_p != '\\' && *src_p != '/' && *src_p != EOS) *dest_p++ = *src_p++; } } if (dest_p > path + 3 && dest_p[-1] == '\\') dest_p--; *dest_p = EOS; #endif } /*---------------------------------------------------------------------------*/ char_t * absolute_path( string_t src_path, string_t relative_to ) /* Return the absolute path name which is equivalent to SRC_PATH. * If SRC_PATH starts with "~", it's replaced by the home directory of the * user whose login name is following (current user if no login name). * If RELATIVE_TO is not NULL, SRC_NAME is relative to that path name. * RELATIVE_TO must be an absolute path name (a directory or a file). * The returned path must be freed after use. */ { #ifdef POSIX text_t *path; string_t src_path_p, login, login_p; char_t *dest_path; struct passwd *password; string_t relative_end, relative_dir; char_t current_dir[ MAX_PATH_SIZE ]; path = new_text(); /* Put a home directory in front. */ src_path_p = src_path; if (*src_path_p == '~') { /* Put a users home directory in front. */ src_path_p++; login_p = src_path_p; while (*src_path_p != '/' && *src_path_p != EOS) src_path_p++; if (src_path_p == login_p) add_to_text( path, get_env( "HOME" ) ); else { /* Put home directory of user LOGIN in front. */ login = new_string( login_p, src_path_p ); password = getpwnam( login ); if (password == NULL) complain( "Can't find user \"%s\".", login ); add_to_text( path, password->pw_dir ); free_mem( &login ); } } else if (*src_path_p != '/') { if (relative_to != NULL) { /* Put RELATIVE_TO ahead (strip last name). */ relative_end = relative_to + strlen( relative_to ); while (relative_end[-1] != '/') relative_end--; relative_dir = new_string( relative_to, relative_end ); add_to_text( path, relative_dir ); free_mem( &relative_dir ); } else { /* Put current directory in front. */ getcwd( current_dir, MAX_PATH_SIZE ); add_to_text( path, current_dir ); } } /* Copy rest of DEST_PATH, clean it up and return it. */ add_char_to_text( path, '/' ); add_to_text( path, src_path_p ); dest_path = text_to_string( &path ); if (*dest_path != '/') complain( "Path \"%s\" must be absolute.", src_path ); tidy_path( dest_path ); return dest_path; #endif #ifdef WIN32 text_t *path; string_t src_path_p, dest_path; string_t relative_end, relative_dir; char_t current_dir[ MAX_PATH_SIZE ]; path = new_text(); src_path_p = src_path; if (src_path_p[0] == '~' && (src_path_p[1] == '\\' || src_path_p[1] == '/')) { /* Put the users home directory in front. */ src_path_p += 2; relative_to = getenv( "USERPROFILE" ); if (relative_to == NULL) relative_to = get_env( "SYSTEMDRIVE" ); add_to_text( path, relative_to ); add_char_to_text( path, '\\' ); } else if (IS_LETTER( src_path_p[0] ) && src_path_p[1] == ':') { /* The path is already complete. */ if (src_path_p[2] != '\\' && src_path_p[2] != '/') complain( "A drive name needs an absolute path." ); } else if (src_path_p[0] == '\\' || src_path_p[0] == '/') { /* Put the current drive in front. */ src_path_p++; if (relative_to != NULL) { add_char_to_text( path, relative_to[0] ); add_char_to_text( path, relative_to[1] ); } else { GetCurrentDirectory( MAX_PATH_SIZE, current_dir ); add_char_to_text( path, current_dir[0] ); add_char_to_text( path, current_dir[1] ); } add_char_to_text( path, '\\' ); } else if (relative_to != NULL) { /* Put RELATIVE_TO ahead (strip last name). */ relative_end = relative_to + strlen( relative_to ); while (relative_end[-1] != '\\') relative_end--; relative_dir = new_string( relative_to, relative_end ); add_to_text( path, relative_dir ); add_char_to_text( path, '\\' ); free_mem( &relative_dir ); } else { /* Put current directory in front. */ GetCurrentDirectory( MAX_PATH_SIZE, current_dir ); add_to_text( path, current_dir ); add_char_to_text( path, '\\' ); } add_to_text( path, src_path_p ); dest_path = text_to_string( &path ); tidy_path( dest_path ); return dest_path; #endif } /*---------------------------------------------------------------------------*/ char_t * replace_vars_in_string( string_t string ) /* Replace environment variables of form "${X}" in STRING. * Return the resulting string. It must be freed after use. */ { text_t *text; string_t string_p, variable_p, variable; text = new_text(); for (string_p = string; *string_p != EOS; string_p++) { if (string_p[0] == '$' && string_p[1] == '{') { string_p += 2; variable_p = string_p; while (*string_p != '}') { if (*string_p == EOS) complain( "Missing \"}\" in environment variable name." ); string_p++; } variable = new_string( variable_p, string_p ); add_to_text( text, get_env( variable ) ); free_mem( &variable ); } else add_char_to_text( text, *string_p ); } return text_to_string( &text ); } /*---------------------------------------------------------------------------*/ static string_t extension_start( string_t name ) /* Return a pointer to the start (the dot) of the extension in NAME, * or to the end of the string if there is no extension. */ { string_t s, t; s = NULL; for (t = name; *t != EOS; t++) { if (*t == '/') s = NULL; #ifdef WIN32 else if (*t == '\\') s = NULL; #endif else if (*t == '.') s = t; } return (s != NULL ? s : t); } /*---------------------------------------------------------------------------*/ bool_t has_extension( string_t file_name, string_t extension ) /* Test if FILE_NAME has extension EXTENSION. */ { string_t ext; /* The real extension of FILE_NAME (including "."). */ ext = extension_start( file_name ); return (*ext != EOS && strcmp( ext + 1, extension ) == 0); } /*---------------------------------------------------------------------------*/ char_t * replace_extension( string_t file_name, string_t extension ) /* Return a new string that contains FILE_NAME with new EXTENSION. * The string must be freed after use. */ { string_t base; char_t *s; base = new_string( file_name, extension_start( file_name ) ); s = concat_strings( base, ".", extension, NULL ); free_mem( &base ); return s; } /*---------------------------------------------------------------------------*/ void set_file_name( string_t *file_name_p, string_t file_name ) /* Set *FILE_NAME_P to absolute path FILE_NAME, relative to current dir. * Print an error if *FILE_NAME_P is already set. * The created file name must be freed after use. */ { if (*file_name_p != NULL) complain( "File \"%s\" is redundant.", file_name ); *file_name_p = absolute_path( file_name, NULL ); } /*---------------------------------------------------------------------------*/ void set_binary_file_name( string_t *file_name_p, string_t file_name ) /* Set *FILE_NAME_P to * FILE_NAME plus "_l" for little endian, "_b" for big endian, "_c" else, * converted to absolute path. * Print an error if *FILE_NAME_P is already set. * The created file name must be freed after use. */ { union { char_t chars[4]; int_t integer; } format; string_t suffix, binary_file_name; if (*file_name_p != NULL) complain( "File \"%s\" is redundant.", file_name ); format.integer = 0x12345678; if (sizeof( int_t ) != 4) suffix = "_c"; else if (format.chars[0] == 0x12 && format.chars[1] == 0x34 && format.chars[2] == 0x56 && format.chars[3] == 0x78) { suffix = "_b"; } else if (format.chars[0] == 0x78 && format.chars[1] == 0x56 && format.chars[2] == 0x34 && format.chars[3] == 0x12) { suffix = "_l"; } else suffix = "_c"; binary_file_name = concat_strings( file_name, suffix, NULL ); *file_name_p = absolute_path( binary_file_name, NULL ); free_mem( &binary_file_name ); } /* End of file. =============================================================*/ malaga-7.12/files.h0000644000175000017500000001035010425346140013456 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* Operations for files and file names. */ /* File operations. =========================================================*/ extern bool_t file_exists( string_t file_name ); /* Return TRUE iff file FILE_NAME exists. */ extern FILE *open_stream( string_t file_name, string_t stream_mode ); /* Open file FILE_NAME and create a stream from/to it in mode STREAM_MODE. * Works like "fopen", but calls "error" if it doesn't work. */ extern void close_stream( FILE **stream_p, string_t file_name ); /* Close the stream *STREAM_P which is connected to the file FILE_NAME * and set *STREAM_P to NULL. Don't do anything if *STREAM_P == NULL. * Works like "fclose", but calls "error" if FILE_NAME != NULL and an error * occurs during closing. */ extern void write_vector( const void *address, int_t item_size, int_t item_count, FILE *stream, string_t file_name ); /* Write ITEM_COUNT items, of size ITEM_SIZE each, stored at *ADDRESS, * to STREAM, which is connected to file FILE_NAME. * Works like "fwrite", but calls "error" if it doesn't work. */ extern void read_vector( void *address, int_t item_size, int_t item_count, FILE *stream, string_t file_name ); /* Read ITEM_COUNT items, of size ITEM_SIZE each, from STREAM, * which is connected to file FILE_NAME, and store them at *ADDRESS. * Works like "fread", but calls "error" if it doesn't work. */ extern void *read_new_vector( int_t item_size, int_t item_count, FILE *stream, string_t file_name ); /* Read ITEM_COUNT items, of size ITEM_SIZE each, from STREAM, * which is connected to file FILE_NAME, into allocated memory block, * and return a pointer to that block. */ extern void map_file( string_t file_name, void **address, int_t *length ); /* Map file "file_name" into the memory. It will be available in the * memory region starting at *ADDRESS and will occupy LENGTH bytes. * After usage, return the memory region via "unmap_file". */ extern void unmap_file( void **address, int_t length ); /* Return the memory region that has been allocated by "map_file". * The region starts at *ADDRESS and occupies LENGTH bytes. */ /* File name operations. ====================================================*/ extern string_t name_in_path( string_t path_name ); /* Return the file name in PATH_NAME, i.e. the name after the last "/". */ extern char_t *replace_vars_in_string( string_t string ); /* Replace environment variables of form "${X}" in STRING. * Return the resulting string. It must be freed after use. */ extern char_t *absolute_path( string_t src_path, string_t relative_to ); /* Return the absolute path name which is equivalent to SRC_PATH. * If SRC_PATH starts with "~", it's replaced by the home directory of the * user whose login name is following (current user if no login name). * If RELATIVE_TO is not NULL, SRC_NAME is relative to that path name. * RELATIVE_TO must be an absolute path name (a directory or a file). * The returned path must be freed after use. */ extern bool_t has_extension( string_t file_name, string_t extension ); /* Test if FILE_NAME has extension EXTENSION. */ extern char_t *replace_extension( string_t file_name, string_t extension ); /* Return a new string that contains FILE_NAME with new EXTENSION. * The string must be freed after use. */ extern void set_file_name( string_t *file_name_p, string_t file_name ); /* Set *FILE_NAME_P to FILE_NAME, converted to absolute path. * Print an error if *FILE_NAME_P is already set. * The created file name must be freed after use. */ extern void set_binary_file_name( string_t *file_name_p, string_t file_name ); /* Set *FILE_NAME_P to * FILE_NAME plus "_l" for little endian, "_b" for big endian, "_c" else, * converted to absolute path. * Print an error if *FILE_NAME_P is already set. * The created file name must be freed after use. */ /* End of file. =============================================================*/ malaga-7.12/generation.c0000644000175000017500000002665410435517021014517 0ustar bjoernbjoern/* Copyright (C) 1996 Bjoern Beutel. */ /* Description. =============================================================*/ /* The generation commands for malaga. */ /* Includes. ================================================================*/ #include #include #include #include #include "basic.h" #include "pools.h" #include "values.h" #include "input.h" #include "commands.h" #include "rule_type.h" #include "rules.h" #include "lexicon.h" #include "analysis.h" #include "debugger.h" #include "hangul.h" #include "generation.h" /* Types. ===================================================================*/ typedef struct /* A running generation LAG state. */ { list_node_t *next; /* Next segment state. */ value_t feat; /* Feature structure of this state. */ int_t rule_set; /* Rule set of this state. */ } segment_state_t; typedef struct /* A segment of generation output. */ { list_node_t *next; /* Next segment. */ string_t surface; /* Surface of this segment. */ list_t states; /* List of running states after combination. */ } segment_t; typedef struct /* A feature structure node for an item. */ { list_node_t *next; /* Next item_feat. */ value_t value; /* Feature structure. */ } item_feat_t; typedef struct /* Segment of which a word or sentence may consist. */ { list_node_t *next; /* Next item. */ string_t surf; /* Surface of this item. */ list_t feat_list; /* Feature structures for this item. */ } item_t; /* Variables. ===============================================================*/ static grammar_t grammar; /* Grammar used for generation. */ static int_t result_count; /* Index of the current word form. */ static int_t segment_count; static int_t max_segment_count; /* User limit on segments in a word form. */ static list_t segments; static rule_type_t current_rule_type; static list_t items; /* Functions. ===============================================================*/ static void combine_surface( text_t *text, segment_t *segment ) { segment_t *next_segment; if (segment != NULL) { next_segment = (segment_t *) segment->next; combine_surface( text, next_segment ); if (grammar == SYNTAX && next_segment != NULL) add_char_to_text( text, ' ' ); add_to_text( text, segment->surface ); } } /*---------------------------------------------------------------------------*/ static char_t * get_surface_local( surface_t surface_type ) /* Return surface SURFACE_TYPE for currently executed rule. * The result must be freed after use. */ { text_t *text; char_t *string; text = new_text(); switch (surface_type) { case RESULT_SURFACE: combine_surface( text, (segment_t *) segments.first ); break; case STATE_SURFACE: if (current_rule_type == COMBI_RULE) combine_surface( text, (segment_t *) segments.first->next ); else combine_surface( text, (segment_t *) segments.first ); break; case LINK_SURFACE: if (current_rule_type == COMBI_RULE) add_to_text( text, ((segment_t *) segments.first)->surface ); break; default: complain( "Internal error." ); } string = new_string_readable( text->buffer, NULL ); free_text( &text ); return string; } /*---------------------------------------------------------------------------*/ static void add_end_state_local( value_t feat ) /* Print end state, consisting of FEAT. */ { char_t *surf; /* Print index of word form. */ surf = get_surface_local( RESULT_SURFACE ); result_count++; decode_hangul( &surf ); printf( "%d: %s\n", result_count, surf ); free_mem( &surf ); } /*---------------------------------------------------------------------------*/ static void add_running_state_local( value_t feat, int_t rule_set ) /* Add running state, consisting of FEAT and RULE_SET. */ { segment_t *segment; segment_state_t *state; segment = (segment_t *) segments.first; state = new_node( &segment->states, sizeof( segment_state_t ), LIST_END ); state->feat = new_value( feat ); state->rule_set = rule_set; } /*---------------------------------------------------------------------------*/ static void push_segment( string_t surface ) /* Push a new segment with name SURFACE. */ { segment_t *segment; segment = new_node( &segments, sizeof( segment_t ), LIST_START ); segment->surface = surface; clear_list( &segment->states ); segment_count++; } /*---------------------------------------------------------------------------*/ static void pop_segment( void ) /* Pop the topmost segment. */ { segment_state_t *state; segment_t *segment; segment = (segment_t *) segments.first; segment_count--; FOREACH_FREE( state, segment->states ) free_mem( &state->feat ); free_first_node( &segments ); } /*---------------------------------------------------------------------------*/ static void execute_rules( value_t state_feat, int_t rule_set, item_t *item ) /* Add ITEM to LAG state (STATE_FEAT, RULE_SET). * Save the resulting states in SEGMENTS.FIRST->STATES or print them * if they are end states. */ { rule_sys_t *rule_sys; int_t *rule_p; item_feat_t *link_feat; rule_t *rule; rule_sys = rule_system[ grammar ]; FOREACH( link_feat, item->feat_list ) { for (rule_p = rule_sys->rule_sets + rule_set; *rule_p >= 0; rule_p++) { rule = rule_sys->rules + *rule_p; if (rule->type == COMBI_RULE) { current_rule_type = COMBI_RULE; top = 0; push_value( state_feat ); push_value( link_feat->value); if (rule->param_count >= 3) push_string_value( item->surf, NULL ); if (rule->param_count >= 4) push_number_value( segment_count ); execute_rule( rule_sys, *rule_p ); } } } } /*---------------------------------------------------------------------------*/ static void generate_local( void ) /* Generate all word forms or sentences (according to GRAMMAR) * that are successors of STATES and print them immediately. */ { item_t *item; segment_t *segment; segment_state_t *state; int_t *rule_p; rule_sys_t *rule_sys; rule_t *rule; rule_sys = rule_system[ grammar ]; segment = (segment_t *) segments.first; check_user_break(); /* Execute end rules first. */ FOREACH( state, segment->states ) { for (rule_p = rule_sys->rule_sets + state->rule_set; *rule_p >= 0; rule_p++) { rule = rule_sys->rules + *rule_p; if (rule->type == END_RULE) { current_rule_type = END_RULE; top = 0; push_value( state->feat ); if (rule->param_count >= 2) push_string_value( "", NULL ); execute_rule( rule_sys, *rule_p ); } } } /* Don't execute combi_rules if too many segments are to be combined. */ if (segment_count >= max_segment_count) return; /* Execute rules with all ITEMS. */ FOREACH( item, items ) { push_segment( item->surf ); FOREACH( state, segment->states ) execute_rules( state->feat, state->rule_set, item ); if (((segment_t *) segments.first)->states.first != NULL) generate_local(); pop_segment(); } } /*---------------------------------------------------------------------------*/ static void generate( void ) /* Generate a sentence or a word form */ { item_t *item; rule_sys_t *rule_sys; rule_sys = rule_system[ grammar ]; while (segments.first != NULL) pop_segment(); segment_count = result_count = 0; add_running_state = add_running_state_local; add_end_state = add_end_state_local; get_surface = get_surface_local; set_debug_mode( RUN_MODE, NULL ); /* Execute all rules that add the first item to the empty start. */ FOREACH( item, items ) { push_segment( item->surf ); execute_rules( rule_sys->values + rule_sys->initial_feat, rule_sys->initial_rule_set, item ); if (((segment_t *) segments.first)->states.first != NULL) generate_local(); pop_segment(); } } /*---------------------------------------------------------------------------*/ static void free_item_feat_list( item_t *item ) /* Free the feature structures in ITEM. */ { item_feat_t *feat; FOREACH_FREE( feat, item->feat_list ) free_mem( &feat->value ); } /*---------------------------------------------------------------------------*/ static void free_items( void ) /* Free the item list. */ { item_t *item; FOREACH_FREE( item, items ) { free_item_feat_list( item ); free_mem( &item->surf ); } } /*---------------------------------------------------------------------------*/ static void generate_command( string_t arguments ) /* Generate sentences or words from items, depending on GRAMMAR. */ { item_t *item; item_feat_t *feat; value_t value; string_t surf_end; char_t *surf; assert_not_in_debug_mode(); if (rule_system[ grammar ] == NULL) { complain( "%s rule file not loaded.", grammar == SYNTAX ? "Syntax": "Morphology" ); } max_segment_count = parse_cardinal( &arguments ); if (*arguments != EOS) { /* Read new items. */ free_items(); while (*arguments != EOS) { surf = parse_word( &arguments ); encode_hangul( &surf ); item = new_node( &items, sizeof( item_t ), LIST_END ); item->surf = surf; clear_list( &item->feat_list ); } } /* Create feature structures for items. */ FOREACH( item, items ) { free_item_feat_list( item ); if (grammar == MORPHOLOGY) { search_for_prefix( item->surf ); while (get_next_prefix( &surf_end, &value )) { if (*surf_end == EOS) /* Found prefix that covers the whole string. */ { feat = new_node( &item->feat_list, sizeof( item_feat_t ), LIST_END ); feat->value = new_value( value ); } } } else { analyse( MORPHOLOGY, item->surf, FALSE, TRUE ); for (value = first_analysis_result(); value != NULL; value = next_analysis_result()) { feat = new_node( &item->feat_list, sizeof( item_feat_t ), LIST_END ); feat->value = new_value( value ); } } } generate(); FOREACH( item, items ) free_item_feat_list( item ); } /*---------------------------------------------------------------------------*/ static void do_mg( string_t arguments ) /* Generate morphologically. */ { grammar = MORPHOLOGY; generate_command( arguments ); } command_t mg_command = { "mg", do_mg, "Generate all word forms that consist only of the given allomorphs.\n" "Usage:\n" " mg MAX_ALLO_COUNT ALLOMORPHS -- Use ALLOMORPHS\n" " mg MAX_ALLO_COUNT -- Use allomorphs of last generation command.\n" "\"mg\" can't be used in debug mode.\n" }; /*---------------------------------------------------------------------------*/ static void do_sg( string_t arguments ) /* Generate syntactically. */ { grammar = SYNTAX; generate_command( arguments ); } command_t sg_command = { "sg", do_sg, "Generate all sentences that consist only of the given word forms.\n" "Usage:\n" " sg MAX_WORD_COUNT WORDS -- use WORDS\n" " sg MAX_WORD_COUNT -- Use words of last generation command.\n" "\"sg\" can't be used in debug mode.\n" }; /*---------------------------------------------------------------------------*/ void init_generation( void ) /* Initialise this module. */ {} /*---------------------------------------------------------------------------*/ void terminate_generation( void ) /* Terminate this module. */ { while (segments.first != NULL) pop_segment(); free_items(); } /* End of file. =============================================================*/ malaga-7.12/generation.h0000644000175000017500000000123110236624743014515 0ustar bjoernbjoern/* Copyright (C) 1996 Bjoern Beutel. */ /* Description. =============================================================*/ /* Generation commands for malaga. */ /* Functions. ===============================================================*/ extern void init_generation( void ); /* Initialise this module. */ extern void terminate_generation( void ); /* Terminate this module. */ /* Commands. ================================================================*/ extern command_t mg_command; /* Generate morphologically. */ extern command_t sg_command; /* Generate syntactically. */ /* End of file. =============================================================*/ malaga-7.12/hangul.c0000644000175000017500000003654110427141760013642 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module handles the splitting of Hangul syllables and multi-letter * Jamos into single Hangul letters (and back). * It also converts Romanised Hangul to single-letter Hangul (and back). * * In this conversion module, we use four representations of * Hangul letters and syllables: * 1. Unicode Hangul syllables, which occupy code points 0xac00-0xd7a3. * The syllables are sorted by their constituting letters. The sort criteria * are (from major to minor): * - the 19 different initial consonant combinations (Choseong) as defined * in the table CHOSEONGS * - the 21 different vowel combinations (Jungseong) as defined in the table * JUNGSEONGS * - the 28 different final consonant combinations (Jonseong) as defined in * the table JONSEONGS (including the empty string) * 2. Unicode alternative Jamo characters, which occupy the code points * 0x3131-0x3163. For internal representation, only the Jamos that represent * single characters are used. * 3. Roman code, which is a latin transcription; it adopts the Yale standard * for Hangul romanization. * Here, every syllable begins with a dot ".". Transcripted Hangul is * enclosed in curly brackets in order to distinguish it from original * latin characters. */ /* Includes. ================================================================*/ #include #include #include #include #include #include "basic.h" #include "pools.h" #include "tries.h" #include "hangul.h" /* Constants. ===============================================================*/ /* Intermediate representation of single Jamo letters as strings */ #define A "\x01" /* a */ #define B "\x02" /* phieuph */ #define C "\x03" /* cieuc */ #define D "\x04" /* thieuth */ #define E "\x05" /* eo */ #define G "\x06" /* kieukh */ #define H "\x07" /* hieuh */ #define I "\x08" /* i */ #define K "\x09" /* kiyeok */ #define L "\x0a" /* rieul */ #define M "\x0b" /* mieum */ #define N "\x0c" /* nieun */ #define O "\x0d" /* o */ #define P "\x0e" /* pieup */ #define S "\x0f" /* sios */ #define T "\x10" /* tikeut */ #define U "\x11" /* eu */ #define W "\x12" /* u */ #define X "\x13" /* ieung */ #define Z "\x14" /* chieuch */ #define DOT "\x15" /* syllable start */ #define VOWELS A E I O U W /* Intermediate representation of single Jamo letters as characters*/ #define A_C '\x01' /* a */ #define B_C '\x02' /* phieuph */ #define C_C '\x03' /* cieuc */ #define D_C '\x04' /* thieuth */ #define E_C '\x05' /* eo */ #define G_C '\x06' /* kieukh */ #define H_C '\x07' /* hieuh */ #define I_C '\x08' /* i */ #define K_C '\x09' /* kiyeok */ #define L_C '\x0a' /* rieul */ #define M_C '\x0b' /* mieum */ #define N_C '\x0c' /* nieun */ #define O_C '\x0d' /* o */ #define P_C '\x0e' /* pieup */ #define S_C '\x0f' /* sios */ #define T_C '\x10' /* tikeut */ #define U_C '\x11' /* eu */ #define W_C '\x12' /* u */ #define X_C '\x13' /* ieung */ #define Z_C '\x14' /* chieuch */ #define DOT_C '\x15' /* syllable start */ /* Unicode representation of single Jamo letters. */ static const u_short_t jamos_unicodes[22] = { 0, /* EOS */ 0x314f, /* a */ 0x314d, /* phieuph */ 0x3148, /* cieuc */ 0x314c, /* thieuth */ 0x3153, /* eo */ 0x314b, /* kieukh */ 0x314e, /* hieuh */ 0x3163, /* i */ 0x3131, /* kiyeok */ 0x3139, /* rieul */ 0x3141, /* mieum */ 0x3134, /* nieun */ 0x3157, /* o */ 0x3142, /* pieup */ 0x3145, /* sios */ 0x3137, /* tikeut */ 0x3161, /* eu */ 0x315c, /* u */ 0x3147, /* ieung */ 0x314a, /* chieuch */ 0x3164, /* syllable start */ }; enum {SYLLABLE_START = 0x3164}; /* Composition of Jamo characters */ enum {FIRST_JAMO = 0x3131, LAST_JAMO = 0x3163, JAMO_COUNT = (LAST_JAMO - FIRST_JAMO + 1) }; static string_t jamos[JAMO_COUNT] = { (K), (K K), (K S), (N), (N C), (N H), (T), (T T), (L), (L K), (L M), (L P), (L S), (L D), (L B), (L H), (M), (P), (P P), (P S), (S), (S S), (X), (C), (C C), (Z), (G), (D), (B), (H), (A), (A I), (I A), (I A I), (E), (E I), (I E), (I E I), (O), (O A), (O I E), (O I), (I O), (W), (W E), (W E I), (W I), (I W), (U), (U I), (I) }; enum {FIRST_SYLLABLE = 0xac00, LAST_SYLLABLE = 0xd7a3, SYLLABLE_COUNT = (LAST_SYLLABLE - FIRST_SYLLABLE + 1)}; /* The initial consonants in a syllable. */ enum {CHOSEONG_COUNT = 19}; static string_t choseongs[CHOSEONG_COUNT] = { (K), (K K), (N), (T), (T T), (L), (M), (P), (P P), (S), (S S), (X), (C), (C C), (Z), (G), (D), (B), (H), }; /* The vowels in a syllable. */ enum {JUNGSEONG_COUNT = 21}; static string_t jungseongs[JUNGSEONG_COUNT] = { (A), (A I), (I A), (I A I), (E), (E I), (I E), (I E I), (O), (O A), (O I E), (O I), (I O), (W), (W E), (W E I), (W I), (I W), (U), (U I), (I) }; /* The final consonants in a syllable. */ enum {JONSEONG_COUNT = 28}; static string_t jonseongs[JONSEONG_COUNT] = { "", (K), (K K), (K S), (N), (N C), (N H), (T), (L), (L K), (L M), (L P), (L S), (L D), (L B), (L H), (M), (P), (P S), (S), (S S), (X), (C), (Z), (G), (D), (B), (H), }; enum {SPLIT_TABLE_SIZE = (SYLLABLE_COUNT + JAMO_COUNT)}; /* Global variables. ========================================================*/ bool_t roman_hangul; /* Indicates whether Hangul output is transcribed in latin script. */ /* Variables. ===============================================================*/ static byte_t jamo_enc[JAMO_COUNT + 1]; /* Intermediate encoding of Jamo single letters and syllable start. */ static string_t split_strings[SPLIT_TABLE_SIZE]; static pool_t string_pool; /* String pool with split Syllables and Jamos. */ static int_t *split_trie; /* Trie used to segmentise Hangul syllables. */ static int_t split_trie_root; /* Root node index of SPLIT_TRIE. */ /* Functions. ===============================================================*/ static int compare_trie_entries( const void *entry1, const void *entry2 ) /* Compare two trie entries. */ { return strcmp_no_case( ((trie_entry_t *) entry1)->key, ((trie_entry_t *) entry2)->key ); } /*---------------------------------------------------------------------------*/ static void add_jamos_to_text( text_t *text, const char *jamos ) { for (; *jamos != EOS; jamos++ ) add_unichar_to_text( text, jamos_unicodes[ (int_t) *jamos ]); } /*---------------------------------------------------------------------------*/ void init_hangul( void ) /* Initialise the hangul module. */ { trie_entry_t trie_entries[ SPLIT_TABLE_SIZE ]; /* Syllable/Jamos. */ int_t c, i, choseong, jungseong, jonseong; pool_t trie_pool; text_t *text; if (! split_hangul_syllables) return; /* Fill table to convert from Jamo letter to intermediate encoding. */ for (i = A_C; i <= DOT_C; i++) jamo_enc[ jamos_unicodes[i] - FIRST_JAMO ] = i; text = new_text(); string_pool = new_pool( sizeof( char_t ) ); for (i = 0; i < SYLLABLE_COUNT; i++) { /* Build Jamos string for syllable i. */ c = i / JONSEONG_COUNT; jonseong = i % JONSEONG_COUNT; jungseong = c % JUNGSEONG_COUNT; choseong = c / JUNGSEONG_COUNT; clear_text( text ); add_unichar_to_text( text, SYLLABLE_START ); add_jamos_to_text( text, choseongs[ choseong ] ); add_jamos_to_text( text, jungseongs[ jungseong ] ); add_jamos_to_text( text, jonseongs[ jonseong ] ); split_strings[i] = copy_string_to_pool( string_pool, text->buffer, NULL ); /* Copy to trie entry table. */ trie_entries[i].key = split_strings[i]; trie_entries[i].content = i + FIRST_SYLLABLE; } for (i = SYLLABLE_COUNT; i < SPLIT_TABLE_SIZE; i++) { clear_text( text ); add_jamos_to_text( text, jamos[ i - SYLLABLE_COUNT ] ); split_strings[i] = copy_string_to_pool( string_pool, text->buffer, NULL ); trie_entries[i].key = split_strings[i]; trie_entries[i].content = i - SYLLABLE_COUNT + FIRST_JAMO; } free_text( &text ); /* Sort the Jamos strings and build the trie. */ qsort( trie_entries, SPLIT_TABLE_SIZE, sizeof( trie_entry_t ), compare_trie_entries); new_trie( SPLIT_TABLE_SIZE, trie_entries, &trie_pool, &split_trie_root ); split_trie = pool_to_vector( trie_pool ); free_pool( &trie_pool ); roman_hangul = FALSE; } /*---------------------------------------------------------------------------*/ void terminate_hangul( void ) /* Terminate the hangul module. */ { if (! split_hangul_syllables) return; free_mem( &split_trie ); free_pool( &string_pool ); } /* Conversion of Jamos to romanised Hangul. =================================*/ static char_t * jamos_to_roman( string_t jamos_string ) /* Convert Jamos string JAMOS_STRING to romanised Hangul. */ { /* Modified Yale roman representation for each of the Jamos letters. */ static string_t romans[24] = { NULL, "a", "ph", "c", "th", "e", "kh", "h", "i", "k", "l", "m", "n", "o", "p", "s", "t", "u", "wu", "ng", "ch", "." }; string_t roman_segment; text_t *roman_text; int_t c; char_t enc, prev, next; roman_text = new_text(); while (*jamos_string != EOS) { c = g_utf8_get_char( jamos_string ); if (c >= FIRST_JAMO && c <= SYLLABLE_START) { /* Convert Jamos. */ add_char_to_text( roman_text, '{' ); enc = jamo_enc[ c - FIRST_JAMO ]; prev = EOS; do { jamos_string = g_utf8_next_char( jamos_string ); c = g_utf8_get_char( jamos_string ); if (c >= FIRST_JAMO && c <= SYLLABLE_START) next = jamo_enc[ c - FIRST_JAMO ]; else next = EOS; /* Convert ENC to roman. */ roman_segment = romans[ (int_t) enc ]; switch (enc) { case X_C: if (prev == DOT_C) roman_segment = ""; break; case I_C: if ((prev != EOS && strchr( VOWELS, prev ) != NULL) || (next != EOS && strchr( VOWELS, next ) != NULL)) { roman_segment = "y"; } break; case O_C: if (next == A_C) roman_segment = "w"; break; case W_C: if (prev == I_C) roman_segment = "u"; else if (next != EOS && strchr( VOWELS, next ) != NULL) { roman_segment = "w"; } break; default: break; } add_to_text( roman_text, roman_segment ); prev = enc; enc = next; } while (enc != 0); add_char_to_text( roman_text, '}' ); } else { add_unichar_to_text( roman_text, c ); jamos_string = g_utf8_next_char( jamos_string ); } } return text_to_string( &roman_text ); } /* Conversion of romanised Hangul to Jamos. =================================*/ static char_t * roman_to_jamos( string_t roman_string ) /* Convert transcribed Hangul string ROMAN_STRING to Jamos. */ { /* All letter sequences that can be converted to hancode. */ static struct {string_t roman; string_t jamos;} romans[] = { /* Two-letter strings must come first. */ {"ch", Z}, {"kh", G}, {"th", D}, {"ph", B}, {"wu", W}, {"ng", X}, {"wa", O A}, {"yu", I W}, {"a", A}, {"c", C}, {"e", E}, {"h", H}, {"i", I}, {"k", K}, {"l", L}, {"m", M}, {"n", N}, {"o", O}, {"p", P}, {"r", L}, {"s", S}, {"t", T}, {"u", U}, {"w", W}, {"x", X}, {"y", I}, {".", DOT}, {NULL, NULL} }; int_t i; text_t *jamos_text; jamos_text = new_text(); while (*roman_string != EOS) { if (*roman_string == '{') { roman_string++; while (*roman_string != '}') { if (*roman_string == EOS) complain( "Missing \"}\" in romanised Hangul." ); /* Insert an "x" at beginning of syllable if vowel is following. */ if (roman_string[-1] == '.' && strrchr( "aeiouwy", roman_string[0] ) != NULL) { add_jamos_to_text( jamos_text, X ); } for (i = 0; romans[i].roman != NULL; i++) { if (strncmp( roman_string, romans[i].roman, strlen( romans[i].roman ) ) == 0) { add_jamos_to_text( jamos_text, romans[i].jamos ); roman_string += strlen( romans[i].roman ); break; } } if (romans[i].roman == NULL) { complain( "\"%c\" is not a romanised Hangul letter.", *roman_string ); } } /* Jump over closing "}" */ roman_string++; } else add_char_to_text( jamos_text, *roman_string++ ); } return text_to_string( &jamos_text ); } /* Conversion of Jamos to Hangul syllables. =================================*/ static char_t * jamos_to_syllables( string_t jamos_string ) /* Convert Jamos JAMOS_STRING to Unicode Hangul syllables. */ { text_t *syl_text; int_t trie_code, code, unicode; int_t trie_node; string_t string_p; syl_text = new_text(); while (*jamos_string != EOS) { /* Try to combine a syllable or a multi-consonant Jamo. */ code = g_utf8_get_char( jamos_string ); if (code >= FIRST_JAMO && code <= SYLLABLE_START) { /* Search the trie until we have found the longest segment. */ trie_node = split_trie_root; string_p = jamos_string; unicode = 0; while (lookup_trie( split_trie, &trie_node, &string_p, &trie_code )) { jamos_string = string_p; unicode = trie_code; } if (unicode != 0) add_unichar_to_text( syl_text, unicode ); else if (code == SYLLABLE_START) { add_to_text( syl_text, "{.}" ); jamos_string = g_utf8_next_char( jamos_string ); } else complain( "Internal error." ); } else { add_unichar_to_text( syl_text, code ); jamos_string = g_utf8_next_char( jamos_string ); } } return text_to_string( &syl_text ); } /* Conversion of Hangul syllables to Jamos. =================================*/ static char_t * syllables_to_jamos( string_t syl_string ) /* Convert Hangul syllables in SYL_STRING to Jamos. * The returned string remains valid until this function is called again. */ { text_t *jamos_text; int_t c; jamos_text = new_text(); while (*syl_string != EOS) { c = g_utf8_get_char( syl_string ); syl_string = g_utf8_next_char( syl_string ); if (c >= FIRST_SYLLABLE && c <= LAST_SYLLABLE) add_to_text( jamos_text, split_strings[ c - FIRST_SYLLABLE ] ); else if (c >= FIRST_JAMO && c <= LAST_JAMO) { add_to_text( jamos_text, split_strings[ c - FIRST_JAMO + SYLLABLE_COUNT] ); } else add_unichar_to_text( jamos_text, c ); } return text_to_string( &jamos_text ); } /* Global conversion routines. ==============================================*/ void decode_hangul( char_t **string_p ) /* Decode *STRING_P to external format. * *STRING_P must be a string on the heap. * It will be replaced by the new string which is also on the heap. */ { char_t *string; if (! split_hangul_syllables) return; if (roman_hangul) string = jamos_to_roman( *string_p ); else string = jamos_to_syllables( *string_p ); free_mem( string_p ); *string_p = string; } /*---------------------------------------------------------------------------*/ void encode_hangul( char_t **string_p ) /* Encode *STRING_P to internal format. * *STRING_P must be a string on the heap. * It will be replaced by the new string which is also on the heap. */ { char_t *string; if (! split_hangul_syllables) return; string = syllables_to_jamos( *string_p ); free_mem( string_p ); *string_p = roman_to_jamos( string ); free_mem( &string ); } /* End of file. =============================================================*/ malaga-7.12/hangul.h0000644000175000017500000000230310427141535013634 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module handles the splitting of Hangul syllables and multi-letter * Jamos into single Hangul letters (and back). * It also converts Romanised hangul to split Hangul (and back). */ /* Variables. ===============================================================*/ extern bool_t roman_hangul; /* Indicates whether Hangul output is transcribed to latin letters. */ /* Functions. ===============================================================*/ extern void init_hangul( void ); /* Initialise hangul conversions. */ extern void terminate_hangul( void ); /* Free memory used by hangul conversions. */ extern void decode_hangul( char_t **string_p ); /* Decode *STRING_P to external format. * *STRING_P must be a string on the heap; * it will be replaced by the new string which is also on the heap. */ extern void encode_hangul( char_t **string_p ); /* Encode *STRING_P to internal format. * *STRING_P must be a string on the heap; * it will be replaced by the new string which is also on the heap. */ /* End of file. =============================================================*/ malaga-7.12/input.c0000644000175000017500000001430210425345527013517 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module supports reading and parsing input. */ /* Includes. ================================================================*/ #include #include #include #include #include "basic.h" #include "files.h" #include "input.h" /* Variables. ===============================================================*/ static text_t *text; /* Functions. ===============================================================*/ void parse_whitespace( string_t *input ) /* Read whitespace in *INPUT and update *INPUT. */ { while (g_unichar_isspace( g_utf8_get_char( *input ) )) *input = g_utf8_next_char( *input ); } /*---------------------------------------------------------------------------*/ char_t * parse_word( string_t *input ) /* If there is a word in *INPUT, parse it up to the next space * and update *INPUT. Return the word. It must be freed after use. * If there's no word, report an error. */ { gunichar code; clear_text( text ); if (**input == EOS) complain( "Argument expected." ); if (**input == '\"') { /* A quoted word may contain spaces and quotes. */ (*input)++; while (**input != '\"') { if (**input == EOS) complain( "Missing closing '\"'." ); if ((*input)[0] == '\\' && (*input)[1] != EOS) (*input)++; add_char_to_text( text, *(*input)++ ); } (*input)++; } else { while (**input != EOS) { code = g_utf8_get_char( *input ); if (g_unichar_isspace( code )) break; add_unichar_to_text( text, code ); *input = g_utf8_next_char( *input ); } } parse_whitespace( input ); return new_string( text->buffer, NULL ); } /*---------------------------------------------------------------------------*/ char_t * parse_absolute_path( string_t *input, string_t relative_to ) /* Parse the next file name in *INPUT and update *INPUT. * Make the file name absolute (relative to RELATIVE_TO). * If there is no file name, report an error. */ { char_t * path; char_t *abs_path; path = parse_word( input ); abs_path = absolute_path( path, relative_to ); free_mem( &path ); return abs_path; } /*---------------------------------------------------------------------------*/ void parse_end( string_t *input ) /* Test if there are no more arguments in *INPUT. */ { if (**input != EOS) complain( "Unexpected argument: \"%s\".", *input ); } /*---------------------------------------------------------------------------*/ int_t parse_int( string_t *input ) /* Parse the next integer number from *INPUT and update *INPUT. * If there is no integer, an error is reported. */ { int_t number; string_t string; string = parse_word( input ); if (sscanf( string, "%d", &number ) != 1) complain( "Illegal integer value." ); free_mem( &string ); return number; } /*---------------------------------------------------------------------------*/ int_t parse_cardinal( string_t *input ) /* Parse the next positive integer number from *INPUT and update *INPUT. * If there is no integer, an error is reported. */ { int_t number; number = parse_int( input ); if (number < 1) complain( "Number must be positive." ); return number; } /*---------------------------------------------------------------------------*/ double parse_double( string_t *input ) /* Parse the next double from *INPUT and update *INPUT. * If there is no double, an error is reported. */ { double number; string_t string; string = parse_word( input ); if (sscanf( string, "%lf", &number ) != 1) complain( "Illegal double value." ); free_mem( &string ); return number; } /*---------------------------------------------------------------------------*/ bool_t parse_yes_no( string_t *input ) /* Parse next word in INPUT. It must be "yes" or "no" (or "on" or "off" for * compatibility). Return TRUE iff next word is "yes" (or "on"). */ { string_t argument; bool_t return_value; argument = parse_word( input ); if (strcmp_no_case( argument, "yes" ) == 0 || strcmp_no_case( argument, "on" ) == 0) { return_value = TRUE; } else if (strcmp_no_case( argument, "no" ) == 0 || strcmp_no_case( argument, "off" ) == 0) { return_value = FALSE; } else complain( "\"yes\" or \"no\" expected, not \"%s\".", argument ); free_mem( &argument ); return return_value; } /*---------------------------------------------------------------------------*/ char_t * read_line( FILE *stream ) /* Read user input from STREAM until eof or newline is met. * Return the result string (without final EOL or EOF). * The string must be freed after use. * If EOF is initially met, return NULL. */ { int_t c; /* Read initial char to see if it's end of file. */ c = getc( stream ); if (c == EOF) return NULL; /* There is some real result, read it in and return it. */ clear_text( text ); while (c != '\n' && c != EOF) { ADD_CHAR_TO_TEXT( text, c ); c = getc( stream ); } if (! g_utf8_validate( text->buffer, -1, NULL)) complain( "Illegal UTF-8 character." ); return new_string( text->buffer, NULL ); } /*---------------------------------------------------------------------------*/ void cut_comment( char_t *line ) /* Cut a "#"-comment in LINE if there is one. * The char "#" is ignored if it occurs within a double-quoted string. */ { while (*line != EOS) { if (*line == '#') { *line = EOS; return; } if (*line == '\"') { /* Read over double-quoted string. */ line++; while (*line != '\"') { if (*line == EOS) return; if (line[0] == '\\' && line[1] != EOS) line += 2; else line++; } line++; } else line++; } } /*---------------------------------------------------------------------------*/ void init_input( void ) /* Initialise this module. */ { text = new_text(); } /*---------------------------------------------------------------------------*/ void terminate_input( void ) /* Terminate this module. */ { free_text( &text ); } /* End of file. =============================================================*/ malaga-7.12/input.h0000644000175000017500000000425010425345415013521 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module supports reading and parsing input. */ /* Functions. ===============================================================*/ extern void parse_whitespace( string_t *input ); /* Read whitespace in *INPUT and update *INPUT. */ extern int_t parse_int( string_t *input ); /* Parse the next integer number from *INPUT and update *INPUT. * If there is no integer, an error is reported. */ extern int_t parse_cardinal( string_t *input ); /* Parse the next positive integer number from *INPUT and update *INPUT. * If there is no integer, an error is reported. */ extern double parse_double( string_t *input ); /* Parse the next double from *INPUT and update *INPUT. * If there is no double, an error is reported. */ extern char_t *parse_word( string_t *input ); /* If there is a word in *INPUT, parse it up to the next space * and update *INPUT. Return the word. It must be freed after use. * If there is no word, report an error. */ extern char_t *parse_absolute_path( string_t *input, string_t relative_to ); /* Parse the next file name in *INPUT and update *INPUT. * Make the file name absolute (relative to RELATIVE_TO). * If there is no file name, report an error. */ extern bool_t parse_yes_no( string_t *input ); /* Parse next word in INPUT. It must be "yes" or "no" (or "on" or "off" for * compatibility). Return TRUE iff next word is "yes" (or "on"). */ extern void parse_end( string_t *input ); /* Test if there are no more arguments in *INPUT. */ extern char_t *read_line( FILE *stream ); /* Read user input from STREAM until eof or newline is met. * Return the result string (without final EOL or EOF). * The string must be freed after use. * If EOF is initially met, return NULL. */ extern void cut_comment( char_t *line ); /* Cut a "#"-comment in LINE if there is one. * The char "#" is ignored if it occurs within a double-quoted string. */ extern void init_input( void ); /* Initialise this module. */ extern void terminate_input( void ); /* Terminate this module. */ /* End of file. =============================================================*/ malaga-7.12/lex_compiler.c0000644000175000017500000007651110435516476015060 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module contains data structures and functions related to the generation * of the allomorph lexicon. */ /* Includes. ================================================================*/ #include #include #include #include #include #include #include #include "basic.h" #include "pools.h" #include "values.h" #include "tries.h" #include "rule_type.h" #include "rules.h" #include "scanner.h" #include "files.h" #include "malaga_files.h" #include "symbols.h" #include "input.h" #include "commands.h" #include "avl_trees.h" #include "options.h" #include "hangul.h" #include "lex_compiler.h" /* Macros. ==================================================================*/ #define MARK_LAST_ENTRY(var) ((var) = - ((var) + 1)) /* Mark last entry of a list in FEAT_LISTS. */ /* types ====================================================================*/ typedef struct /* A feature structure for a given lexicon entry. */ { list_node_t *next; /* Next feature structure. */ value_t value; /* Feature structure of this entry as a value. */ } feat_node_t; typedef struct /* An entry in the lexicon tree. */ { avln_node_t node; /* The lexicon tree is an AVLN tree. */ list_t feat_list; /* The list of feature structures in this lexicon entry. */ } lex_node_t; typedef struct /* A node in the constants tree. */ { avln_node_t node; /* The constants tree is an AVLN tree. */ value_t value; /* Value of the node. */ bool_t fixed; /* FALSE if value is a default value only. */ } const_node_t; /* Variables. ===============================================================*/ int_t lex_entry_line_number; /* Line number of lexical entry just parsed. */ string_t lex_entry_file_name; /* Name of lexicon file just parsed. */ rule_sys_t *allo_rule_sys; static avln_node_t *const_tree; /* Root of the tree of constants. * Actually points to a const_node_t. */ static avln_node_t *lex_tree; /* Root of the lexicon tree. * Actually points to a lex_node_t. */ static pool_t string_pool; static pool_t lex_node_pool; static pool_t feat_node_pool; static list_t feat_free_list; static int_t prelex_count; /* Number of prelex entries. */ static int_t lex_entry_count; /* Number of lexicon entries. */ static int_t allomorph_count; /* Number of allomorphs. */ static int_t intermediate_count; /* Number of pre-filter allomorphs. */ static lex_node_t *current_lexicon_entry; /* Current entry when output filter is being executed. */ /* Forward declarations. ====================================================*/ static void parse_value_local( void ); /* Functions for rule execution. ============================================*/ static void free_feat_list( lex_node_t *entry ) { feat_node_t *feat; /* Free the feature structures of this lexicon entry. */ while (entry->feat_list.first != NULL) { feat = remove_first_node( &entry->feat_list ); free_mem( &feat->value ); add_node( &feat_free_list, (list_node_t *) feat, LIST_END ); } } /*---------------------------------------------------------------------------*/ static void free_lex_tree_local( avln_node_t *node ) /* Free NODE and its descendants. Do nothing if NODE == NULL. */ { if (node == NULL) return; free_lex_tree_local( node->left ); free_lex_tree_local( node->right ); free_feat_list( (lex_node_t *) node ); } /*---------------------------------------------------------------------------*/ static void free_lex_tree( void ) /* Free all memory used by the lexicon buffer. */ { free_lex_tree_local( lex_tree ); lex_tree = NULL; clear_list( &feat_free_list ); clear_pool( lex_node_pool ); clear_pool( string_pool ); clear_pool( feat_node_pool ) ; lex_entry_count = allomorph_count = 0; prelex_count = intermediate_count = -1; } /*---------------------------------------------------------------------------*/ static void add_to_feat_list( lex_node_t *entry, value_t value ) /* Add the feature structure VALUE to the feature structures in ENTRY. */ { feat_node_t *feat; if (feat_free_list.first != NULL) feat = remove_first_node( &feat_free_list ); else feat = get_pool_space( feat_node_pool, 1, NULL ); feat->value = new_value( value ); add_node( &entry->feat_list, (list_node_t *) feat, LIST_END ); } /*---------------------------------------------------------------------------*/ static void lex_add_allo( string_t surface, value_t feat ) /* Add an allomorph, consisting of SURF and FEAT, to the allomorph lexicon. */ { lex_node_t *entry; if (*surface == EOS) complain( "Allomorph surface is empty." ); /* Find the lexicon entry with the correct surface. */ entry = (lex_node_t *) find_avln_node( surface, (avln_node_t *) lex_tree ); /* If no lexicon entry was found, create a new one. */ if (entry == NULL) { entry = (lex_node_t *) get_pool_space( lex_node_pool, 1, NULL ); entry->node.name = copy_string_to_pool( string_pool, surface, NULL ); clear_list( &entry->feat_list ); insert_avln_node( (avln_node_t *) entry, (avln_node_t **) &lex_tree ); } /* Add new feature structure. */ add_to_feat_list( entry, feat ); allomorph_count++; } /*---------------------------------------------------------------------------*/ static void execute_allo_rule( void ) /* Execute the allo_rule on LEX_ENTRY. */ { add_allo = lex_add_allo; /* Set callback routine. */ execute_rule( allo_rule_sys, allo_rule_sys->allo_rule ); } /*---------------------------------------------------------------------------*/ static void lex_add_end_state( value_t feat ) /* Add a filtered allomorph, with feature structure FEAT, to the allomorph * lexicon. */ { add_to_feat_list( current_lexicon_entry, feat ); allomorph_count++; } /*---------------------------------------------------------------------------*/ static void execute_output_filter_local( avln_node_t *node ) /* Execute the output filter on the lexicon tree with root NODE. */ { feat_node_t *feat; lex_node_t *lex_node = (lex_node_t *) node; if (node == NULL) return; /* Execute the filter for entries alphabetically before LEX_NODE. */ execute_output_filter_local( node->left ); /* Create a list containing all allomorphs with SURFACE. */ top = 0; FOREACH( feat, lex_node->feat_list ) push_value( feat->value ); build_list( top ); /* Execute the output filter rule for LEX_NODE. */ free_feat_list( lex_node ); current_lexicon_entry = lex_node; execute_rule( allo_rule_sys, allo_rule_sys->output_filter ); if (! rule_successful) { complain( "Output filter generated no allomorphs for \"%s\".", node->name ); } /* Execute the filter for entries alphabetically behind LEX_NODE. */ execute_output_filter_local( node->right ); } /*---------------------------------------------------------------------------*/ static void execute_output_filter( void ) /* Execute the lexicon output filter on all entries in the lexicon tree. */ { /* If there's no allomorph filter rule, we're finished. */ if (allo_rule_sys->output_filter == -1) return; add_end_state = lex_add_end_state; intermediate_count = allomorph_count; allomorph_count = 0; execute_output_filter_local( lex_tree ); } /* Support functions for parsing. ===========================================*/ static void free_const_node( avln_node_t **const_node_p ) /* Free *CONST_NODE_P and its descendants, and set *CONST_NODE_P to NULL. */ { const_node_t *const_node = (const_node_t *) *const_node_p; if (*const_node_p == NULL) return; free_const_node( &(*const_node_p)->left ); free_const_node( &(*const_node_p)->right ); free_mem( &(*const_node_p)->name ); free_mem( &const_node->value ); free_mem( const_node_p ); } /*---------------------------------------------------------------------------*/ static const_node_t * new_const_node( string_t name ) /* Create a new const node with NAME and insert it into the const tree. */ { const_node_t *const_node; const_node = new_mem( sizeof( const_node_t ) ); const_node->node.name = new_string( name, NULL ); insert_avln_node( (avln_node_t *) const_node, (avln_node_t **) &const_tree ); return const_node; } /* Parse functions. =========================================================*/ static void parse_simple_value( void ) /* Parse a value and leave it on the value stack. */ { int_t n; /* Number of values in list or record. */ const_node_t *const_node; switch (next_token) { case '<': /* Parse a list. */ read_next_token(); n = 0; if (next_token != '>') { parse_value_local(); n++; while (next_token == ',') { read_next_token(); parse_value_local(); n++; } } parse_token( '>' ); build_list( n ); break; case '[': /* Parse a record. */ read_next_token(); n = 0; if (next_token != ']') { parse_value_local(); parse_token( ':' ); parse_value_local(); n++; while (next_token == ',') { read_next_token(); parse_value_local(); parse_token( ':' ); parse_value_local(); n++; } } parse_token( ']') ; build_record( n ); break; case TOK_IDENT: /* Parse a symbol. */ test_token( TOK_IDENT ); push_symbol_value( find_symbol( token_name ) ); read_next_token(); break; case TOK_STRING: /* Parse a string. */ encode_hangul( &token_string ); push_string_value( token_string, NULL ); read_next_token(); break; case TOK_NUMBER: /* Parse a number value. */ push_number_value( token_number ); read_next_token(); break; case TOK_CONSTANT: /* Parse a constant. */ const_node = ((const_node_t *) find_avln_node( token_name, (avln_node_t *) const_tree )); if (const_node == NULL) complain( "Constant \"@%s\" is not defined.", token_name ); push_value( const_node->value ); const_node->fixed = TRUE; read_next_token(); break; case '(': read_next_token(); parse_value_local(); parse_token( ')' ); break; default: complain( "Value expected, not %s.", token_as_text( next_token ) ); } } /*---------------------------------------------------------------------------*/ static void parse_dotted_value( void ) /* Parse a value and as suffix a sequence of ".IDENT" and/or ".NUMBER". */ { parse_simple_value(); while (next_token == '.') { read_next_token(); parse_simple_value(); dot_operation(); if (value_stack[ top - 1 ] == NULL) complain( "Component does not exist." ); } } /*---------------------------------------------------------------------------*/ static void parse_term_value( void ) /* Parse a value that may contain the "*" and "/" operator. */ { int_t operator_token ; parse_dotted_value(); while (next_token == '*' || next_token == '/') { operator_token = next_token; read_next_token(); parse_dotted_value(); if (operator_token == '*') asterisk_operation(); else slash_operation(); } } /*---------------------------------------------------------------------------*/ static void parse_value_local( void ) /* Parse any value. This function is recursive. * To get a value from outside, use "parse_value". */ { int_t operator_token; if (next_token == '-') { read_next_token(); parse_term_value(); unary_minus_operation(); } else parse_term_value(); while (next_token == '+' || next_token == '-') { operator_token = next_token; read_next_token(); parse_term_value(); if (operator_token == '-') minus_operation(); else plus_operation(); } } /*---------------------------------------------------------------------------*/ static void parse_value( void ) /* Parse a value and return it on the value stack. */ { top = 0; parse_value_local(); } /*---------------------------------------------------------------------------*/ static void parse_lex_value( void ) /* Parse a value and compile it. */ { int_t line_number; string_t file_name; /* Remember position of lexicon entry. */ line_number = current_line_number(); file_name = current_file_name(); parse_value(); /* Parse lexicon entry. */ /* Set position of lexicon entry for "where" command. */ lex_entry_file_name = file_name; lex_entry_line_number = line_number; TRY { lex_entry_count++; execute_allo_rule(); if (! rule_successful) { fprintf( stderr, "Warning: No allomorphs generated. (\"%s\", line %d)\n", name_in_path( file_name ), line_number ); } } IF_ERROR { print_text( error_text, " (\"%s\", line %d)", name_in_path( file_name ), line_number ); } END_TRY; /* Clear position of lexicon entry. */ lex_entry_file_name = NULL; lex_entry_line_number = -1; parse_token( ';' ); } /*---------------------------------------------------------------------------*/ static void parse_lex_values( void ) /* Read all values in the current file and run the allomorph rules on them. */ { const_node_t *const_node; string_t file_name; bool_t fixed; while (next_token != EOF) { if (next_token == TOK_DEFINE || next_token == TOK_DEFAULT) { fixed = (next_token == TOK_DEFINE); read_next_token(); test_token( TOK_CONSTANT ); const_node = ((const_node_t *) find_avln_node( token_name, (avln_node_t *) const_tree )); if (const_node == NULL) const_node = new_const_node( token_name ); if (const_node->fixed) complain( "Constant \"@%s\" is already defined.", token_name ); if (! fixed && const_node->value != NULL) { complain( "Constant \"@%s\" already has a default value.", token_name ); } read_next_token(); parse_token( TOK_ASSIGN ); parse_value(); free_mem( &const_node->value ); const_node->value = new_value( value_stack[ --top ] ); const_node->fixed = fixed; parse_token( ';' ); } else if (next_token == TOK_INCLUDE) { read_next_token(); test_token( TOK_STRING ); file_name = absolute_path( token_string, current_file_name() ); read_next_token(); begin_include( file_name ); parse_lex_values(); end_include(); parse_token( ';' ); free_mem( &file_name ); } else { check_user_break(); parse_lex_value(); } } } /* Functions for construction of run-time lexicon. ==========================*/ static void print_lex_tree( FILE *stream, string_t allo_format, avln_node_t *node, int_t *count ) /* Print all lexicon entries in tree NODE to STREAM using allomorph format * ALLO_FORMAT. *COUNT is the counter of entries that have been printed. * If ALLO_FORMAT == NULL, use line breaking. */ { feat_node_t *feat; string_t line_number, buffer, value_string; char_t *surface; lex_node_t *lex_node = (lex_node_t *) node; if (node == NULL) return; print_lex_tree( stream, allo_format, node->left, count ); surface = new_string_readable( node->name, NULL ); decode_hangul( &surface ); FOREACH( feat, lex_node->feat_list ) { (*count)++; if (allo_format == NULL) { value_string = value_to_readable( feat->value, FALSE, g_utf8_strlen( surface, -1 ) + 2 ); fprintf( stream, "%s: %s\n", surface, value_string ); free_mem( &value_string ); } else if (*allo_format != EOS) { value_string = value_to_readable( feat->value, FALSE, -1 ); line_number = int_to_string( *count ); buffer = replace_arguments( allo_format, "sfn", surface, value_string, line_number ); fprintf( stream, "%s\n", buffer ); free_mem( &line_number ); free_mem( &buffer ); free_mem( &value_string ); if (ferror( stream )) complain( "Can't write results: %s.", strerror( errno ) ); } } free_mem( &surface ); print_lex_tree( stream, allo_format, node->right, count ); } /*---------------------------------------------------------------------------*/ void print_lex_buffer( FILE *stream, string_t allo_format ) /* Print all lexicon entries in the buffer to STREAM using format ALLO_FORMAT. * If ALLO_FORMAT == NULL, format the feature structures. */ { int_t count; count = 0; print_lex_tree( stream, allo_format, lex_tree, &count ); } /*---------------------------------------------------------------------------*/ static void count_trie_entries( avln_node_t *tree, int_t *surf_count, int_t *feat_count ) /* Add to *SURF_COUNT the number of valid entries in subtree TREE. * Add to *FEAT_COUNT the number of feature structures in subtree TREE. */ { feat_node_t *feat; lex_node_t *lex_node = (lex_node_t *) tree; if (tree == NULL) return; count_trie_entries( tree->left, surf_count, feat_count ); if (lex_node->feat_list.first != NULL) (*surf_count)++; FOREACH( feat, lex_node->feat_list ) (*feat_count)++; count_trie_entries( tree->right, surf_count, feat_count ); } /*---------------------------------------------------------------------------*/ static void fill_trie_entries( avln_node_t *tree, trie_entry_t *trie_entries, int_t *feat_lists, int_t *surf_count, int_t *feat_count, int_t *cell_count ) /* Fill the entries in TREE and its subnodes * into the vectors TRIE_ENTRIES and FEAT_LISTS. * Increment *SURF_COUNT, *FEAT_COUNT and *CELL_COUNT accordingly. */ { feat_node_t *feat; lex_node_t *lex_node = (lex_node_t *) tree; if (tree == NULL) return; fill_trie_entries( tree->left, trie_entries, feat_lists, surf_count, feat_count, cell_count ); if (lex_node->feat_list.first != NULL) { trie_entries[ *surf_count ].key = tree->name; trie_entries[ *surf_count ].content = *feat_count; (*surf_count)++; FOREACH( feat, lex_node->feat_list ) { feat_lists[ *feat_count ] = *cell_count; (*feat_count)++; *cell_count += length_of_value( feat->value ); } MARK_LAST_ENTRY( feat_lists[ *feat_count - 1 ] ); } fill_trie_entries( tree->right, trie_entries, feat_lists, surf_count, feat_count, cell_count ); } /*---------------------------------------------------------------------------*/ static void write_feat_table( avln_node_t *tree, FILE *stream, string_t file_name ) { feat_node_t *feat; lex_node_t *lex_node = (lex_node_t *) tree; if (tree == NULL) return; write_feat_table( tree->left, stream, file_name ); FOREACH( feat, lex_node->feat_list ) { write_vector( feat->value, sizeof( cell_t ), length_of_value( feat->value ), stream, file_name ); } write_feat_table( tree->right, stream, file_name ); } /*---------------------------------------------------------------------------*/ static void write_surfaces( avln_node_t *tree, FILE *stream, string_t file_name ) { if (tree == NULL) return; write_surfaces( tree->left, stream, file_name ); write_vector( tree->name, sizeof( char_t ), strlen( tree->name ) + 1, stream, file_name ); write_surfaces( tree->right, stream, file_name ); } /*---------------------------------------------------------------------------*/ void write_lex_buffer( string_t file_name ) /* Write lexicon buffer to file FILE_NAME as a run time lexicon. */ { lexicon_header_t header; FILE *stream; pool_t trie_pool; int_t trie_root; trie_entry_t *trie_entries; /* Entries used to build the trie. */ int_t *feat_lists; int_t surf_count, feat_count, cell_count; /* Count the number of surfaces and feature structures in the lexicon * and get vectors that will get these values. */ surf_count = feat_count = 0; count_trie_entries( lex_tree, &surf_count, &feat_count ); feat_lists = new_vector( sizeof( int_t ), feat_count ); /* Create the lexicon trie. */ trie_entries = new_vector( sizeof( trie_entry_t ), surf_count ); surf_count = feat_count = cell_count = 0; fill_trie_entries( lex_tree, trie_entries, feat_lists, &surf_count, &feat_count, &cell_count ); new_trie( surf_count, trie_entries, &trie_pool, &trie_root ); free_mem( &trie_entries ); /* Create the binary file. */ stream = open_stream( file_name, "wb" ); /* Initialise the header. */ set_header( &header.common_header, LEXICON_FILE, LEXICON_CODE_VERSION ); header.trie_size = pool_item_count( trie_pool ); header.trie_root = trie_root; header.feat_lists_size = feat_count; header.values_size = cell_count; /* Write everything to the file. */ write_vector( &header, sizeof( lexicon_header_t ), 1, stream, file_name ); write_pool( trie_pool, stream, file_name ); write_vector( feat_lists, sizeof( int_t ), feat_count, stream, file_name ); write_feat_table( lex_tree, stream, file_name ); close_stream( &stream, file_name ); /* Clean up. */ free_pool( &trie_pool ); free_mem( &feat_lists ); } /*---------------------------------------------------------------------------*/ static void count_prelex_entries( avln_node_t *tree, int_t *entry_count_p, int_t *values_size_p, int_t *strings_size_p ) /* Add to *ENTRY_COUNT_P the number of entries in subtree TREE. * Add to *VALUES_SIZE_P the number of cells for feature structures in subtree * TREE. * Add to *STRINGS_SIZE_P the number of chars for surfaces in subtree TREE. */ { feat_node_t *feat; lex_node_t *lex_node = (lex_node_t *) tree; if (tree == NULL) return; count_prelex_entries( tree->left, entry_count_p, values_size_p, strings_size_p ); if (lex_node->feat_list.first != NULL) (*strings_size_p) += strlen( tree->name ) + 1; FOREACH( feat, lex_node->feat_list ) { (*entry_count_p)++; (*values_size_p) += length_of_value( feat->value ); } count_prelex_entries( tree->right, entry_count_p, values_size_p, strings_size_p ); } /*---------------------------------------------------------------------------*/ static void write_prelex_entries( avln_node_t *tree, int_t *values_size_p, int_t *strings_size_p, FILE *stream, string_t file_name ) /* Write prelex entries in subtree TREE to STREAM. * Update *VALUES_SIZE_P and *STRINGS_SIZE_P for indexing. * Use FILE_NAME for error messages. */ { feat_node_t *feat; prelex_entry_t entry; lex_node_t *lex_node = (lex_node_t *) tree; if (tree == NULL) return; write_prelex_entries( tree->left, values_size_p, strings_size_p, stream, file_name ); FOREACH( feat, lex_node->feat_list ) { entry.surface = (*strings_size_p); entry.feat = (*values_size_p); write_vector( &entry, sizeof( prelex_entry_t ), 1, stream, file_name); (*values_size_p) += length_of_value( feat->value ); } if (lex_node->feat_list.first != NULL) (*strings_size_p) += strlen( tree->name ) + 1; write_prelex_entries( tree->right, values_size_p, strings_size_p, stream, file_name ); } /*---------------------------------------------------------------------------*/ void write_prelex_file( string_t file_name ) /* Write lexicon tree to prelex file FILE_NAME. */ { prelex_header_t header; FILE *stream; int_t entry_count, values_size, strings_size; /* Count the number of surfaces and feature structures in the lexicon * and get vectors that will contain these values. */ entry_count = values_size = strings_size = 0; count_prelex_entries( lex_tree, &entry_count, &values_size, &strings_size ); /* Create the binary file. */ stream = open_stream( file_name, "wb" ); /* Initialise the header. */ set_header( &header.common_header, PRELEX_FILE, PRELEX_CODE_VERSION ); header.entry_count = entry_count; header.values_size = values_size; header.strings_size = strings_size; /* Write everything to the file. */ write_vector( &header, sizeof( prelex_header_t ), 1, stream, file_name ); values_size = strings_size = 0; write_prelex_entries( lex_tree, &values_size, &strings_size, stream, file_name ); write_feat_table( lex_tree, stream, file_name ); write_surfaces( lex_tree, stream, file_name ); close_stream( &stream, file_name ); } /*---------------------------------------------------------------------------*/ static void read_prelex_file( string_t file_name ) /* Read a prelex from FILE_NAME. */ { void *prelex_data; int_t prelex_length; prelex_header_t *header; prelex_entry_t *entries; cell_t *values; char_t *strings; int_t i; /* Map file into main memory. */ map_file( file_name, &prelex_data, &prelex_length ); header = (prelex_header_t *) prelex_data; check_header( &header->common_header, file_name, PRELEX_FILE, MIN_PRELEX_CODE_VERSION, PRELEX_CODE_VERSION ); entries = (prelex_entry_t *) (header + 1); values = (cell_t *) (entries + header->entry_count); strings = (char_t *) (values + header->values_size); /* Enter entries into tree. */ for (i = 0; i < header->entry_count; i++) lex_add_allo( strings + entries[i].surface, values + entries[i].feat ); prelex_count = header->entry_count; unmap_file( &prelex_data, prelex_length ); allomorph_count = 0; } /* Interface functions for the lexicon compiler. ============================*/ void print_lex_statistics( FILE *stream ) /* Print statistics about lexicon buffer into STREAM. */ { if (prelex_count != -1) fprintf( stream, "Prelex entries read: %d\n", prelex_count ); fprintf( stream, "Source entries read: %d\n", lex_entry_count ); if (intermediate_count != -1) fprintf( stream, "Intermediates generated: %d\n", intermediate_count ); fprintf( stream, "Allomorphs generated: %d\n", allomorph_count ); if (prelex_count == -1 && lex_entry_count > 0) { fprintf( stream, "Allomorphs per entry: %.4G\n", ((double) allomorph_count / (double) lex_entry_count) ); } } /*---------------------------------------------------------------------------*/ void generate_allos_for_file( string_t source_name, string_t prelex_name, bool_t use_filter ) /* Parse a lexicon file SOURCE_NAME and a precompiled lexicon file PRELEX_NAME. * Generate allomorphs. Write allomorphs into lexicon buffer. * Don't use the output filter if USE_FILTER == FALSE. */ { free_lex_tree(); free_const_node( &const_tree ); if (prelex_name != NULL) read_prelex_file( prelex_name ); lex_entry_file_name = NULL; begin_include( source_name ); TRY parse_lex_values(); IF_ERROR { if (lex_entry_file_name == NULL) { print_text( error_text, " (\"%s\", line %d, column %d)", name_in_path( current_file_name() ), current_line_number(), current_column() ); if (in_emacs_malaga_mode) { printf( "SHOW \"%s\":%d:%d\n", current_file_name(), current_line_number(), current_column() ); } } } FINALLY end_includes(); END_TRY; if (use_filter) execute_output_filter(); } /*---------------------------------------------------------------------------*/ void generate_allos_for_line( string_t lexicon_name, int_t line ) /* Read line LINE in lexicon file LEXICON_NAME and generate allomorphs. * Write allomorphs into lexicon buffer. */ { free_lex_tree(); lex_entry_file_name = NULL; begin_include( lexicon_name ); TRY { while (next_token != EOF && current_line_number() < line) { check_user_break(); if (next_token == TOK_INCLUDE) { read_next_token(); parse_token( TOK_STRING ); parse_token( ';' ); } else if (next_token == TOK_DEFINE || next_token == TOK_DEFAULT) { read_next_token(); parse_token( TOK_CONSTANT ); parse_token( TOK_ASSIGN ); parse_value(); parse_token( ';' ); } else { parse_value(); parse_token( ';' ); } } if (next_token == EOF) complain( "No lexicon entry at or behind line %d.", line ); parse_lex_value(); } IF_ERROR { if (lex_entry_file_name == NULL) { print_text( error_text, " (\"%s\", line %d, column %d)", name_in_path( current_file_name() ), current_line_number(), current_column() ); if (in_emacs_malaga_mode) { printf( "SHOW \"%s\":%d:%d\n", current_file_name(), current_line_number(), current_column() ); } } } FINALLY end_includes(); END_TRY; execute_output_filter(); } /*---------------------------------------------------------------------------*/ static void read_lex_constants_local( void ) /* Read all constants in current scanner input. */ { const_node_t *const_node; string_t file_name; while (next_token != EOF) { check_user_break(); if (next_token == TOK_INCLUDE) { read_next_token(); test_token( TOK_STRING ); file_name = absolute_path( token_string, current_file_name() ); read_next_token(); read_lex_constants( file_name ); parse_token( ';' ); free_mem( &file_name ); } else if (next_token == TOK_DEFINE || next_token == TOK_DEFAULT) { read_next_token(); test_token( TOK_CONSTANT ); const_node = ((const_node_t *) find_avln_node( token_name, (avln_node_t *) const_tree )); if (const_node != NULL) free_mem( &const_node->value ); else const_node = new_const_node( token_name ); read_next_token(); parse_token( TOK_ASSIGN ); parse_value(); const_node->value = new_value( value_stack[ --top ] ); parse_token( ';' ); } else { parse_value(); parse_token( ';' ); } } } /*---------------------------------------------------------------------------*/ void read_lex_constants( string_t lexicon_name ) /* Read all constants in file LEXICON_NAME. */ { begin_include( lexicon_name ); TRY read_lex_constants_local(); IF_ERROR { print_text( error_text, " (\"%s\", line %d, column %d)", name_in_path( current_file_name() ), current_line_number(), current_column() ); if (in_emacs_malaga_mode) { printf( "SHOW \"%s\":%d:%d\n", current_file_name(), current_line_number(), current_column() ); } } FINALLY end_includes(); END_TRY; } /*---------------------------------------------------------------------------*/ void generate_allos_for_string( string_t feat_string ) /* Generate allomorphs from FEAT_STRING, which should contain a readable * feature structure. Write allomorphs into lexicon buffer. */ { free_lex_tree(); set_scanner_input( feat_string ); TRY { parse_value(); if (next_token == ';') read_next_token(); test_token( EOF ); } FINALLY set_scanner_input( NULL ); END_TRY; execute_allo_rule(); if (! rule_successful) printf( "Warning: No allomorphs generated.\n" ); execute_output_filter(); } /*---------------------------------------------------------------------------*/ void init_lex_compiler( string_t allo_rule_file ) /* Initialise the "lex_compiler" module. * Use allomorph rules from ALLO_RULE_FILE. */ { allo_rule_sys = read_rule_sys( allo_rule_file ); /* Initialise lexicon tree. */ lex_tree = NULL; clear_list( &feat_free_list ); lex_node_pool = new_pool( sizeof( lex_node_t ) ); string_pool = new_pool( sizeof( char_t ) ); feat_node_pool = new_pool( sizeof( feat_node_t ) ); lex_entry_count = allomorph_count = 0; prelex_count = intermediate_count = -1; } /*---------------------------------------------------------------------------*/ void terminate_lex_compiler( void ) /* Terminate the "lex_compiler" module. */ { free_rule_sys( &allo_rule_sys ); free_lex_tree(); free_pool( &string_pool ); free_pool( &feat_node_pool ); free_pool( &lex_node_pool ); clear_list( &feat_free_list ); free_const_node( &const_tree ); } /* End of file. =============================================================*/ malaga-7.12/lex_compiler.h0000644000175000017500000000436310236624743015055 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module contains data structures and functions related to the generation * of the allomorph lexicon. */ /* Variables. ===============================================================*/ extern int_t lex_entry_line_number; /* Line number of lexical entry just parsed. Read only! */ extern string_t lex_entry_file_name; /* Name of lexicon file just parsed. Read only! */ extern rule_sys_t *allo_rule_sys; /* Read only! */ /* Functions. ===============================================================*/ extern void generate_allos_for_file( string_t source_name, string_t prelex_name, bool_t use_filter ); /* Parse a lexicon file SOURCE_NAME and a precompiled lexicon file PRELEX_NAME. * Generate allomorphs. Write allomorphs into lexicon buffer. * Don't use the output filter if USE_FILTER == FALSE. */ extern void generate_allos_for_line( string_t lexicon_name, int_t line ); /* Read line LINE in lexicon file LEXICON_NAME and generate allomorphs. * Write allomorphs into lexicon buffer. */ extern void generate_allos_for_string( string_t feat_string ); /* Generate allomorphs from FEAT_STRING, which should contain a readable * feature structure. Write allomorphs into lexicon buffer. */ extern void write_lex_buffer( string_t file_name ); /* Write lexicon buffer to file FILE_NAME as a run time lexicon. */ extern void write_prelex_file( string_t file_name ); /* Write lexicon buffer to prelex file FILE_NAME. */ extern void print_lex_buffer( FILE *stream, string_t allo_format ); /* Print all lexicon entries in the buffer to STREAM using format ALLO_FORMAT. * If ALLO_FORMAT == NULL, do line breaking. */ extern void print_lex_statistics( FILE *stream ); /* Print statistics about lexicon buffer into STREAM. */ extern void read_lex_constants( string_t lexicon_name ); /* Read all constants in file LEXICON_NAME. */ extern void init_lex_compiler( string_t allo_rule_file ); /* Initialise the lex_compiler module. * Use allomorph rules from ALLO_RULE_FILE. */ extern void terminate_lex_compiler( void ); /* Free the lex_compiler module. */ /* End of file. =============================================================*/ malaga-7.12/lexicon.c0000644000175000017500000000723110236624743014024 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module contains structures and functions for the run-time lexicon. */ /* Includes. ================================================================*/ #include #include #include #include #include #include "basic.h" #include "pools.h" #include "values.h" #include "tries.h" #include "files.h" #include "malaga_files.h" #include "lexicon.h" /* Variables. ===============================================================*/ static void *lexicon_data; /* Address of lexicon file mapped into memory. */ static int_t lexicon_length; /* Length of *LEXICON_DATA. */ static struct /* The run time lexicon. */ { int_t *trie; /* A trie with indices to FEAT_LISTS. */ int_t trie_size; int_t trie_root; /* Index of root node in TRIE. */ int_t *feat_lists; /* Lists of feature structures, stored in VALUES. * (The last index I of each list is negative, * real index is abs(I) - 1.) */ int_t feat_lists_size; cell_t *values; /* Feature structures of lexicon entries. */ int_t values_size; } lexicon; static int_t feat_list_index, trie_node; static string_t prefix_end; /* Functions. ===============================================================*/ void search_for_prefix( string_t string ) /* Search lexicon for prefixes of STRING in increasing length. * The results are obtained by calling "get_next_prefix". */ { trie_node = lexicon.trie_root; prefix_end = string; feat_list_index = -1; } /*---------------------------------------------------------------------------*/ bool_t get_next_prefix( string_t *string_p, value_t *feat ) /* Get the next lexicon entry that is a prefix of STRING. * Return FALSE iff no more entries exist. * If another entry exists, set *STRING_P to the remainder of STRING * and *FEAT to the feature structure assigned to the lexicon entry. * STRING must have been set by "search_for_prefix". */ { int_t feat_index; if (feat_list_index == -1) lookup_trie( lexicon.trie, &trie_node, &prefix_end, &feat_list_index ); if (feat_list_index == -1) return FALSE; feat_index = lexicon.feat_lists[ feat_list_index++ ]; if (feat_index < 0) { feat_list_index = -1; feat_index = - feat_index - 1; } *string_p = prefix_end; *feat = lexicon.values + feat_index; return TRUE; } /*---------------------------------------------------------------------------*/ void init_lexicon( string_t file_name ) /* Initialise this module. Read lexicon from file FILE_NAME. */ { lexicon_header_t *header; /* Lexicon file header. */ /* Map the lexicon file into memory. */ map_file( file_name, &lexicon_data, &lexicon_length ); /* Check lexicon header. */ header = (lexicon_header_t *) lexicon_data; check_header( &header->common_header, file_name, LEXICON_FILE, MIN_LEXICON_CODE_VERSION, LEXICON_CODE_VERSION ); /* Init trie. */ lexicon.trie_size = header->trie_size; lexicon.trie = (int_t *) (header + 1); lexicon.trie_root = header->trie_root; /* Init feature structure lists. */ lexicon.feat_lists_size = header->feat_lists_size; lexicon.feat_lists = (int_t *) (lexicon.trie + lexicon.trie_size); /* Init values. */ lexicon.values_size = header->values_size; lexicon.values = (cell_t *) (lexicon.feat_lists + lexicon.feat_lists_size); } /*---------------------------------------------------------------------------*/ void terminate_lexicon( void ) /* Terminate this module. */ { unmap_file( &lexicon_data, lexicon_length ); } /* End of file. =============================================================*/ malaga-7.12/lexicon.h0000644000175000017500000000207510236624743014032 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module contains structures and functions for the run-time lexicon. */ /* Functions. ===============================================================*/ extern void init_lexicon( string_t file_name ); /* Initialise this module. Read lexicon from file FILE_NAME. */ extern void terminate_lexicon( void ); /* Terminate this module. */ extern void search_for_prefix( string_t string ); /* Search lexicon for prefixes of STRING in increasing length. * The results are obtained by calling "get_next_prefix". */ extern bool_t get_next_prefix( string_t *string_p, value_t *feat ); /* Get the next lexicon entry that is a prefix of STRING. * Return FALSE iff no more entries exist. * If another entry exists, set *STRING_P to the remainder of STRING * and *FEAT to the feature structure assigned to the lexicon entry. * STRING must have been set by "search_for_prefix". */ /* End of file. =============================================================*/ malaga-7.12/libmalaga.c0000644000175000017500000000725610427141262014273 0ustar bjoernbjoern/* Copyright (C) 1997 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module defines a Malaga library to analyse words and sentences. */ /* Includes. ================================================================*/ #include #include #include #include #include #include #include "basic.h" #include "pools.h" #include "values.h" #include "symbols.h" #include "files.h" #include "rule_type.h" #include "rules.h" #include "analysis.h" #include "input.h" #include "commands.h" #include "options.h" #include "malaga_lib.h" #include "hangul.h" #include "scanner.h" #include "value_parser.h" #include "libmalaga.h" /* Variables. ===============================================================*/ string_t malaga_error; /* If one of the functions below has created an error, this variable * contains an error message. If a function did its job, it is NULL. */ /* Functions. ===============================================================*/ void init_libmalaga( string_t project_file ) /* Initialise this module. */ { string_t project_file_absolute; malaga_error = NULL; init_basic( "libmalaga" ); project_file_absolute = absolute_path( project_file, NULL ); TRY init_malaga( project_file_absolute ); IF_ERROR { malaga_error = error_text->buffer; RESUME; } END_TRY; free_mem( &project_file_absolute ); } /*---------------------------------------------------------------------------*/ void terminate_libmalaga( void ) /* Terminate this module. */ { terminate_malaga(); terminate_basic(); } /*---------------------------------------------------------------------------*/ char_t * get_value_string( value_t string ) /* Return the value of STRING as a C-style string. * The string must be freed after use. */ { char_t *s; s = new_string( value_to_string( string ), NULL ); decode_hangul( &s ); return s; } /*---------------------------------------------------------------------------*/ void analyse_item( string_t item, grammar_t grammar ) /* Analyse ITEM according to GRAMMAR. * GRAMMAR must be MORPHOLOGY or SYNTAX. */ { char_t *analysis_input; analysis_input = NULL; malaga_error = NULL; TRY { analysis_input = new_string( item, NULL ); preprocess_input( analysis_input, FALSE ); encode_hangul( &analysis_input ); analyse( grammar, analysis_input, FALSE, TRUE ); } IF_ERROR { malaga_error = error_text->buffer; RESUME; } END_TRY; free_mem( &analysis_input ); } /*---------------------------------------------------------------------------*/ void set_option( string_t option ) /* Set a libmalaga option. */ { malaga_error = NULL; TRY set_command.command( option ); IF_ERROR { malaga_error = error_text->buffer; RESUME; } END_TRY; } /*---------------------------------------------------------------------------*/ string_t get_info( void ) /* Get info about the current grammar. */ { return grammar_info->buffer; } /*---------------------------------------------------------------------------*/ value_t parse_malaga_value( string_t string ) /* Convert STRING to a Malaga value and return it. * The value must be freed after use. * This function sets "malaga_error". */ { volatile value_t value; malaga_error = NULL; set_scanner_input( string ); TRY { parse_a_value(); parse_token( EOF ); value = new_value( value_stack[ --top ] ); } IF_ERROR { malaga_error = error_text->buffer; value = NULL; RESUME; } END_TRY; set_scanner_input( NULL ); return value; } /* End of file. =============================================================*/ malaga-7.12/libmalaga.h0000644000175000017500000000300110427140335014260 0ustar bjoernbjoern/* Copyright (C) 1997 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module defines a Malaga library to analyse words and sentences. */ /* Variables. ===============================================================*/ extern string_t malaga_error; /* In case of an error, some of the functions below may set this variable to * the error message. If they worked correctly, they set it to NULL. */ /* Functions. ===============================================================*/ extern void init_libmalaga( string_t project_file ); /* Initialise this module. * This function sets "malaga_error". */ extern void terminate_libmalaga( void ); /* Terminate this module. */ extern void set_option( string_t option ); /* Set a libmalaga option. * This function sets "malaga_error". */ extern void analyse_item( string_t item, grammar_t grammar ); /* Analyse ITEM according to GRAMMAR. * GRAMMAR must be MORPHOLOGY or SYNTAX. * This function sets "malaga_error". */ extern string_t get_info( void ); /* Get info about the current grammar. */ extern char_t *get_value_string( value_t string ); /* Return the value of STRING as a C-style string in external coding. * The string must be freed after use. */ extern value_t parse_malaga_value( string_t string ); /* Convert STRING to a Malaga value and return it. * The value must be freed after use. * This function sets "malaga_error". */ /* End of file. =============================================================*/ malaga-7.12/malaga.10000644000175000017500000000471510506460212013514 0ustar bjoernbjoern.TH MALAGA 1 "26 September 2006" Malaga "Malaga quick reference" .SH NAME malaga \- natural-language word and sentence analysis .SH SYNOPSIS \fBmalaga\fP [\fB-morphology\fP|\fB-syntax\fP] [\fB-quoted\fP] [\fB-input\fP \fIinput\fP] \fIproject-file\fP .SH DESCRIPTION Malaga is a development environment for natural-language grammars based on the Left-Associative Grammar formalism. Malaga grammars can be used for automatic morphological and/or syntactic analysis. .PP The program \fBmalaga\fP is Malaga's user interface for analysing word forms and sentences, displaying the results and finding bugs in a grammar. .PP \fBmalaga\fP requires the name of a language-dependent \fIproject-file\fP as a command-line argument. .PP If no command line options are given, \fBmalaga\fP starts in interactive mode, and you can enter commands. If you are not sure about the name of a command, use the command \fBhelp\fP to get an overview of all \fBmalaga\fP commands. .PP If you want to quit \fBmalaga\fP, enter the command \fBquit\fP. .PP See \fBinfo Malaga\fP for details. .SH OPTIONS .IP "\fB-h\fP[\fBelp\fP]" Print a help text about \fBmalaga\fP's command line arguments and exit. .IP "\fB-i\fP[\fBnput\fP] \fIinput\fP" Analyse a single word or sentence given as command line argument (only valid in morphology or syntax mode). .IP "\fB-m\fP[\fBorphology\fP]" Start \fBmalaga\fP in morphology mode. In this mode word forms are read in from the standard input stream and analysed (one word form per line). The analysis result are written to the standard output stream. .IP "\fB-q\fP[\fBuoted\fP]" The input lines to be analysed are quoted (only valid in morphology or syntax mode). .IP "\fB-s\fP[\fByntax\fP]" Start \fBmalaga\fP in syntax mode. In this mode sentences are read in from the standard input stream and analysed (one sentence per line). The analysis result is written to the standard output stream. .IP "\fB-v\fP[\fBersion\fP]" Print \fBmalaga\fP's version number and exit. .SH AUTHORS Malaga was written by Bjoern Beutel. Numerous other people distributed to Malaga. This manpage was originally written for the Debian distribution by Antti-Juhani Kaijanaho. .SH SEE ALSO \fBmallex\fP(1), \fBmalmake\fP(1), \fBmalrul\fP(1), \fBmalshow\fP(1), \fBmalsym\fP(1) .PP ``Malaga 7, User's and Programmer's Manual''. Available in Debian systems via \fBinfo Malaga\fP, and, if the malaga-doc package is installed, in various formats (DVI, Postscript, PDF, HTML) under \fI/usr/share/doc/malaga-doc/\fP. malaga-7.12/malaga.c0000644000175000017500000010152210505747373013607 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This is the interactive program for morphological and syntactic analysis. */ /* Includes. ================================================================*/ #include #include #include #include #include #include #include #include #include "basic.h" #include "pools.h" #include "values.h" #include "symbols.h" #include "files.h" #include "rule_type.h" #include "rules.h" #include "analysis.h" #include "input.h" #include "commands.h" #include "commands_interactive.h" #include "options.h" #include "display.h" #include "malaga_lib.h" #include "generation.h" #include "debugger.h" #include "breakpoints.h" #include "cache.h" #include "transmit.h" #include "hangul.h" /* Macros. ==================================================================*/ #define SAFE_STRING(s) ((s) != NULL ? (s) : (string_t) "") /* Return an empty string if S == NULL. */ /* Variables. ===============================================================*/ static char_t *analysis_input; /* Input line for interactive analysis. */ static int_t debug_state_index; /* Index of state to debug or -1. */ static debug_mode_t state_debug_mode; /* Debug mode to use for states to debug. */ static string_t analysis_file_name; /* Name of input file for analysis. */ /* Analysis result output. ==================================================*/ static void display_result( void ) /* Generate result file and start program to display result. */ { char_t *input; string_t value_string; string_t count_string; value_t feat; int_t result_count; if (! analysis_has_nodes()) complain( "No analysis started." ); /* Print analysis result header. */ input = new_string_readable( analysis_input, NULL ); decode_hangul( &input ); if (use_display) { start_display_process(); fprintf( display_stream, "result\n" ); fprintf( display_stream, "%s\n", input ); } else { if (! analysis_has_results()) printf( "No analyses of %s.\n", input ); else printf( "Analyses of %s:\n", input ); } free_mem( &input ); /* Print analysis results. */ result_count = 0; for (feat = first_analysis_result(); feat != NULL; feat = next_analysis_result()) { result_count++; if (use_display) { value_string = value_to_readable( feat, FALSE, -1 ); fprintf( display_stream, "%d {%s}\n", result_count, value_string ); free_mem( &value_string ); } else { count_string = int_to_string( result_count ); value_string = value_to_readable( feat, FALSE, g_utf8_strlen( count_string, -1 ) + 2 ); printf( "%s: %s\n", count_string, value_string ); free_mem( &value_string ); free_mem( &count_string ); } } /* Print analysis results footer. */ if (use_display) { fprintf( display_stream, "end\n" ); fflush( display_stream ); } } /*---------------------------------------------------------------------------*/ static void display_tree( void ) /* Display analysis tree. */ { analysis_node_t *node; string_t node_type = NULL, value_string; char_t *input; char_t *surf_string; if (! analysis_has_nodes()) complain( "No analysis started." ); start_display_process(); fprintf( display_stream, "tree\n" ); /* Print sentence that has been analysed. */ input = new_string_readable( analysis_input, NULL ); decode_hangul( &input ); fprintf( display_stream, "%s\n", input ); free_mem( &input ); /* Print nodes. */ for (node = get_first_analysis_node(); node != NULL; node = get_next_analysis_node()) { /* Print node index and type, parent index and rule name. */ switch (node->type) { case INTER_NODE: node_type = "inter"; break; case BREAK_NODE: node_type = "break"; break; case FINAL_NODE: node_type = "final"; break; case UNFINAL_NODE: node_type = "unfinal"; break; case PRUNED_NODE: node_type = "pruned"; break; } fprintf( display_stream, "%d %s %d \"%s\" ", node->index, node_type, node->parent_index, SAFE_STRING( node->rule_name ) ); /* Print link's surface and feature structure. */ if (node->link_surf != NULL) { surf_string = new_string_readable( node->link_surf, NULL ); decode_hangul( &surf_string ); } else surf_string = new_string( "", NULL ); value_string = value_to_readable( node->link_feat, FALSE, -1 ); fprintf( display_stream, "{%s} {%s} ", surf_string, value_string ); free_mem( &value_string ); free_mem( &surf_string ); /* Print result surface and feature structure. */ if (node->result_surf != NULL) { surf_string = new_string_readable( node->result_surf, NULL ); decode_hangul( &surf_string ); } else surf_string = new_string( "", NULL ); value_string = value_to_readable( node->result_feat, FALSE, -1 ); fprintf( display_stream, "{%s} {%s} ", surf_string, value_string ); free_mem( &value_string ); free_mem( &surf_string ); /* Print rule set. */ fprintf( display_stream, "\"%s\"\n", SAFE_STRING( node->rule_set ) ); free_analysis_node( &node ); } fprintf( display_stream, "end\n" ); fflush( display_stream ); } /*---------------------------------------------------------------------------*/ static void display_after_analysis( void ) /* Display result in the modes that have been switched on after analysis. */ { if (auto_result) display_result(); if (auto_tree && use_display) display_tree(); } /*---------------------------------------------------------------------------*/ static void do_result( string_t arguments ) /* Show result of last analysis. */ { parse_end( &arguments ); if (! analysis_has_nodes()) complain( "No previous analysis." ); display_result(); } static command_t result_command = { "result res", do_result, "Show result of last analysis.\n" "Usage: result\n" }; /*---------------------------------------------------------------------------*/ static void do_tree( string_t arguments ) /* Generate analysis tree file and start program to display tree. */ { parse_end( &arguments ); if (! analysis_has_nodes()) complain( "No analysis started." ); if (! use_display) complain( "Can only show a tree when using a display process." ); display_tree(); } static command_t tree_command = { "tree t", do_tree, "Display the analysis tree.\n" "Usage: tree\n" "In debug mode or after a rule execution error, the tree may be " "incomplete.\n" }; /* Analysis functions. ======================================================*/ static void analyse_argument( grammar_t grammar, string_t arguments ) /* Analyse ARGUMENTS (or last analysis, if *ARGUMENTS == EOS). * Use GRAMMAR (SYNTAX or MORPHOLOGY). */ { if (*arguments == EOS) { if (analysis_input == NULL) complain( "No previous analysis." ); } else { free_mem( &analysis_input ); analysis_input = new_string( arguments, NULL ); preprocess_input( analysis_input, FALSE ); encode_hangul( &analysis_input ); } debug_state = NULL; analyse( grammar, analysis_input, TRUE, TRUE ); } /*---------------------------------------------------------------------------*/ static void analyse_line( grammar_t grammar, string_t arguments ) /* Analyse a word or a sentence in file FILE, line LINE_NO. * ARGUMENTS must be of format "FILE LINE_NO". * Use GRAMMAR. */ { int_t line_number, current_line_number; FILE *input_stream; char_t *input_line; input_stream = NULL; TRY { /* Read arguments. */ line_number = parse_cardinal( &arguments ); if (*arguments != EOS) { free_mem( &analysis_file_name ); analysis_file_name = parse_absolute_path( &arguments, NULL ); } parse_end( &arguments ); if (analysis_file_name == NULL) complain( "Missing input file name." ); /* Read the line from input. */ input_stream = open_stream( analysis_file_name, "r" ); current_line_number = 0; input_line = NULL; TRY { do { check_user_break(); free_mem( &input_line ); current_line_number++; input_line = read_line( input_stream ); } while (current_line_number < line_number && input_line != NULL); } IF_ERROR print_text( error_text, " (line %d)", current_line_number ); END_TRY; if (input_line == NULL) { complain( "\"%s\" contains only %d lines.", name_in_path( analysis_file_name ), current_line_number - 1 ); } preprocess_input( input_line, FALSE ); if (*input_line == EOS) complain( "Line %d is empty.", line_number ); free_mem( &analysis_input ); analysis_input = input_line; encode_hangul( &analysis_input ); } FINALLY close_stream( &input_stream, NULL ); END_TRY; debug_state = NULL; analyse( grammar, analysis_input, TRUE, TRUE ); } /*---------------------------------------------------------------------------*/ static void do_ma( string_t arguments ) /* Analyse ARGUMENTS morphologically. */ { assert_not_in_debug_mode(); set_debug_mode( RUN_MODE, NULL ); analyse_argument( MORPHOLOGY, arguments ); display_after_analysis(); } static command_t ma_command = { "ma", do_ma, "Analyse the argument morphologically.\n" "Usage:\n" " ma INPUT -- Analyse INPUT.\n" " ma -- Re-analyse last input.\n" "\"ma\" can't be used in debug mode.\n" }; /*---------------------------------------------------------------------------*/ static void do_sa( string_t arguments ) /* Analyse ARGUMENTS syntactically. */ { assert_not_in_debug_mode(); set_debug_mode( RUN_MODE, NULL ); analyse_argument( SYNTAX, arguments ); display_after_analysis(); } static command_t sa_command = { "sa", do_sa, "Analyse the argument syntactically.\n" "Usage:\n" " sa INPUT -- Analyse INPUT.\n" " sa -- Re-analyse last input.\n" "\"sa\" can't be used in debug mode.\n" }; /*---------------------------------------------------------------------------*/ static void do_ma_line( string_t arguments ) /* Analyse ARGUMENTS morphologically. */ { assert_not_in_debug_mode(); set_debug_mode( RUN_MODE, NULL ); analyse_line( MORPHOLOGY, arguments ); display_after_analysis(); } static command_t ma_line_command = { "ma-line mal", do_ma_line, "Analyse a line in a file morphologically.\n" "Usage:\n" " ma-line LINE FILE -- Analyse LINE in FILE.\n" "If FILE is omitted, the previous file name is used.\n" "\"ma-line\" can't be used in debug mode.\n" }; /*---------------------------------------------------------------------------*/ static void do_sa_line( string_t arguments ) /* Analyse ARGUMENTS syntactically. */ { assert_not_in_debug_mode(); set_debug_mode( RUN_MODE, NULL ); analyse_line( SYNTAX, arguments ); display_after_analysis(); } static command_t sa_line_command = { "sa-line sal", do_sa_line, "Analyse a line in a file syntactically.\n" "Usage:\n" " sa-line LINE [FILE] -- Analyse LINE in FILE.\n" "If FILE is omitted, the previous file name is used.\n" "\"sa-line\" can't be used in debug mode.\n" }; /*---------------------------------------------------------------------------*/ static void analyse_input( grammar_t grammar, string_t input ) { value_t value; int_t i; string_t string, count; char_t *input_readable; analysis_input = new_string( input, NULL ); input_readable = new_string_readable( input, NULL ); preprocess_input( analysis_input, FALSE ); encode_hangul( &analysis_input ); analyse( grammar, analysis_input, TRUE, TRUE ); if (analysis_has_results()) { printf( "Results for %s:\n", input_readable ); i = 0; for (value = first_analysis_result(); value != NULL; value = next_analysis_result()) { i++; count = int_to_string( i ); string = value_to_readable( value, FALSE, g_utf8_strlen( count, -1 ) + 2) ; printf( "\n%s: %s\n", count, string ); free_mem( &string ); free_mem( &count ); } } else printf( "No results for %s.\n", input_readable ); free( input_readable ); } /* Debug support. ===========================================================*/ static void display_where( void ) /* Print rule name, left and right surface. */ { char_t *surf; string_t file, rule; int_t line; source_of_instr( executed_rule_sys, pc, &line, &file, &rule ); printf( "At \"%s\", line %d, rule \"%s\".\n", name_in_path( file ), line, rule ); /* Print state number and state's surface. */ surf = get_surface( STATE_SURFACE ); decode_hangul( &surf ); if (current_state != -1) printf( "State: %d, surf: %s", current_state, surf ); else printf( "Surf: %s", surf ); free_mem( &surf ); /* Print link's surface. */ surf = get_surface( LINK_SURFACE ); if (surf != NULL) { decode_hangul( &surf ); printf( ", link: %s", surf ); free_mem( &surf ); } printf( ".\n" ); if (in_emacs_malaga_mode) printf( "SHOW \"%s\":%d:0\n", file, line ); } /*---------------------------------------------------------------------------*/ static void malaga_debug_state( int_t state, bool_t enter ) /* Callback function for "analyse". * This is called with ENTER == TRUE when successor rules for * state with analysis node INDEX will be executed. * It is called with ENTER == FALSE when successor rules for state with * analysis node INDEX have been executed. */ { if (state != debug_state_index) return; if (enter) set_debug_mode( state_debug_mode, rule_system[ top_grammar ] ); else { state_debug_mode = get_debug_mode(); set_debug_mode( RUN_MODE, NULL ); } } /*---------------------------------------------------------------------------*/ static void check_interactive_analysis( void ) { if (analysis_input == NULL || analysis_input != last_analysis_input) complain( "No interactive analysis." ); } /*---------------------------------------------------------------------------*/ static void do_debug_state( string_t arguments ) /* Analyse the last argument again and stop before executing the rules for a * state whose tree node index is specified in ARGUMENTS. */ { assert_not_in_debug_mode(); check_interactive_analysis(); debug_state_index = parse_int( &arguments ); parse_end( &arguments ); if (debug_state_index < 0 || debug_state_index >= state_count) complain( "State not found." ); state_debug_mode = WALK_MODE; debug_state = malaga_debug_state; /* Debug mode is set by "malaga_debug_state" before and after * rule application. */ analyse( top_grammar, analysis_input, TRUE, TRUE ); } static command_t debug_state_command = { "debug-state debug-node dn", do_debug_state, "Re-analyse the last analysis input.\n" "Execute successor rule for given state in debug mode.\n" "Usage: debug-state STATE_INDEX\n" "Analysis is restarted for last input and switches to debug mode\n" "when executing successor rules for state STATE_INDEX.\n" "\"debug-state\" can't be used in debug mode.\n" }; /*---------------------------------------------------------------------------*/ static void do_debug_ma( string_t arguments ) /* Analyse ARGUMENTS morphologically. * Execute morphology combination rules in debug mode. */ { assert_not_in_debug_mode(); set_debug_mode( WALK_MODE, rule_system[ MORPHOLOGY ] ); analyse_argument( MORPHOLOGY, arguments ); } static command_t debug_ma_command = { "debug-ma dma debug-mor ma-debug mad", do_debug_ma, "Analyse morphologically. " "Execute morphology combination rules in debug mode.\n" "Usage:\n" " debug-ma INPUT -- Analyse INPUT.\n" " debug-ma -- Re-analyse the last analysis argument.\n" "Rule execution stops at the first statement.\n" "\"debug-ma\" can't be used in debug mode.\n" }; /*---------------------------------------------------------------------------*/ static void do_debug_sa( string_t arguments ) /* Analyse ARGUMENTS syntactically. * Execute syntax combination rules in debug mode. */ { assert_not_in_debug_mode(); set_debug_mode( WALK_MODE, rule_system[ SYNTAX ] ); analyse_argument( SYNTAX, arguments ); } static command_t debug_sa_command = { "debug-sa dsa debug-syn sa-debug sad", do_debug_sa, "Analyse syntactically. Execute syntax combination rules in debug mode.\n" "Usage:\n" " debug-sa INPUT -- Analyse INPUT.\n" " debug-sa -- Re-analyse the last analysis argument.\n" "Rule execution stops at the first statement.\n" "\"debug-sa\" can't be used in debug mode.\n" }; /*---------------------------------------------------------------------------*/ static void do_debug_ma_line( string_t arguments ) /* Analyse a word in file FILE, line LINE_NO. * ARGUMENTS must be of format "FILE LINE_NO". * Execute morphology combination rules in debug mode. */ { assert_not_in_debug_mode(); set_debug_mode( WALK_MODE, rule_system[ MORPHOLOGY ] ); analyse_line( MORPHOLOGY, arguments ); } static command_t debug_ma_line_command = { "debug-ma-line dmal", do_debug_ma_line, "Analyse a line in a file morphologically.\n" "Execute morphology combination rules in debug mode.\n" "Usage:\n" " debug-ma-line LINE [FILE] -- Analyse LINE in FILE.\n" "If FILE is omitted, the previous file name is used.\n" "Rule execution stops at the first statement.\n" "\"debug-ma-line\" can't be used in debug mode.\n" }; /*---------------------------------------------------------------------------*/ static void do_debug_sa_line( string_t arguments ) /* Analyse a sentence in file FILE, line LINE_NO. * ARGUMENTS must be of format "FILE LINE_NO". * Execute syntax combination rules in debug mode. */ { assert_not_in_debug_mode(); set_debug_mode( WALK_MODE, rule_system[ SYNTAX ] ); analyse_line( SYNTAX, arguments ); } static command_t debug_sa_line_command = { "debug-sa-line dsal", do_debug_sa_line, "Analyse a line in a file syntactically.\n" "Execute syntax combination rules in debug mode.\n" "Usage:\n" " debug-sa-line LINE [FILE] -- Analyse LINE in FILE.\n" "If FILE is omitted, the previous file name is used.\n" "Rule execution stops at the first statement.\n" "\"debug-sa-line\" can't be used in debug mode.\n" }; /* File analysis. ===========================================================*/ static void write_output( string_t input, int_t line_number, string_t error_message, FILE *output ) /* Write the result of the last analysis on OUTPUT. */ { string_t line_number_string, state_count_string, buffer; string_t value_string, result_number_string; char_t *input_string; int_t result_count; value_t feat; input_string = new_string_readable( input, NULL ); decode_hangul( &input_string ); line_number_string = int_to_string( line_number ); state_count_string = int_to_string( state_count ); if (error_message != NULL) { /* Print error result. */ if (*error_format != EOS) { buffer = replace_arguments( error_format, "slne", input_string, line_number_string, state_count_string, error_message ); fprintf( output, "%s\n", buffer ); free_mem( &buffer ); } } else if (! analysis_has_results()) { /* Print unknown result. */ if (*unknown_format != EOS) { buffer = replace_arguments( unknown_format, "sln", input_string, line_number_string, state_count_string ); fprintf( output, "%s\n", buffer ); free_mem( &buffer ); } } else { if (result_as_list) { result_count = 0; for (feat = first_analysis_result(); feat != NULL; feat = next_analysis_result()) { result_count++; push_value( feat ); } build_list( result_count ); value_string = value_to_readable( value_stack[ --top], FALSE, -1 ); buffer = replace_arguments( result_format, "slrfn", input_string, line_number_string, "0", value_string, state_count_string ); fprintf( output, "%s\n", buffer ); free_mem( &buffer ); free_mem( &value_string ); } else { /* Print real results. */ result_count = 0; for (feat = first_analysis_result(); feat != NULL; feat = next_analysis_result()) { result_count++; if (*result_format != EOS) { result_number_string = int_to_string( result_count ); value_string = value_to_readable( feat, FALSE, -1 ); buffer = replace_arguments( result_format, "slrfn", input_string, line_number_string, result_number_string, value_string, state_count_string ); fprintf( output, "%s\n", buffer ); free_mem( &buffer ); free_mem( &value_string ); free_mem( &result_number_string ); } } } } free_mem( &input_string ); free_mem( &line_number_string ); free_mem( &state_count_string ); if (ferror( output )) complain( "Can't write result: %s.", strerror( errno ) ); } /*---------------------------------------------------------------------------*/ static void analyse_stream( grammar_t grammar, FILE *input, FILE *output, FILE *statistics, bool_t expect_quotes ) /* Analyse words or sentences in INPUT, write result to OUTPUT. * Use GRAMMAR for analysis. * If EXPECT_QUOTES == TRUE, expect quoted input lines and remove the quotes. * Write statistic information to STATISTICS. */ { volatile int_t analyses, recognised, results; /* Statistic information. */ volatile int_t combi_recognised, robust_recognised, errors, line_number; volatile string_t item, error_message; time_t start_time, stop_time; char_t *input_line; bool_t old_in_emacs_malaga_mode; value_t feat; double time_diff; item = (grammar == MORPHOLOGY ? "wordform" : "sentence"); set_debug_mode( RUN_MODE, NULL ); debug_state = NULL; robust_recognised = recognised = results = analyses = errors = 0; combi_recognised = line_number = 0; cache_hits = cache_accesses = 0; time( &start_time ); input_line = NULL; TRY { while (TRUE) { check_user_break(); free_mem( &input_line ); input_line = read_line( input ); if (input_line == NULL) break; line_number++; preprocess_input( input_line, expect_quotes ); if (*input_line != EOS) { /* Analyse a non-empty line. */ old_in_emacs_malaga_mode = in_emacs_malaga_mode; in_emacs_malaga_mode = FALSE; error_message = NULL; TRY { analyses++; encode_hangul( &input_line ); analyse( grammar, input_line, FALSE, TRUE ); if (recognised_by_combi_rules) combi_recognised++; if (recognised_by_robust_rule) robust_recognised++; if (analysis_has_results()) recognised++; for (feat = first_analysis_result(); feat != NULL; feat = next_analysis_result()) { results++; } } IF_ERROR { error_message = error_text->buffer; errors++; RESUME; } FINALLY in_emacs_malaga_mode = old_in_emacs_malaga_mode; END_TRY; write_output( input_line, line_number, error_message, output ); fflush( output ); } } } IF_ERROR { printf( "%s (line %d)\n", error_text->buffer, line_number ); RESUME; } FINALLY free_mem( &input_line ); END_TRY; time( &stop_time ); if (analyses == 0) fprintf( statistics, "No %ss analysed.\n", item ); else { time_diff = difftime( stop_time, start_time ); fprintf( statistics, "Analysed %ss: %d\n", item, analyses ); fprintf( statistics, "Recognised: %d (%.2f%%)\n", recognised, (100.0 * recognised) / analyses ); if (combi_recognised > 0) { fprintf( statistics, "Recognised by combi rules: %d (%.2f%%)\n", combi_recognised, (100.0 * combi_recognised) / analyses ); } if (robust_recognised > 0) { fprintf( statistics, "Recognised by robust rule: %d (%.2f%%)\n", robust_recognised, (100.0 * robust_recognised) / analyses ); } if (errors > 0) { fprintf( statistics, "Error-creating %ss: %d (%.2f%%)\n", item, errors, (100.0 * errors) / analyses ); } if (results > 0) { fprintf( statistics, "Results per %s: %.4G\n", item, ((double) results / (double) recognised) ); } if (time_diff > 0) { fprintf( statistics, "Analysis run time: %d sec\n", (int_t) time_diff ); fprintf( statistics, "Avg. %ss per second: %d\n", item, (int_t) (analyses / time_diff) ); } if (cache_accesses > 0) { fprintf( statistics, "Cache accesses: %d\n", cache_accesses ); fprintf( statistics, "Cache hits: %d (%.2f%%)\n", cache_hits, (100.0 * cache_hits) / cache_accesses ); } } } /*---------------------------------------------------------------------------*/ static void analyse_file( string_t arguments, grammar_t grammar ) /* Open the file with name in ARGUMENTS, which must contain a word list * or sentence list, analyse all its lines according to GRAMMAR, * and write the results to a file with extension ".out". */ { string_t result_file_name; FILE *input_stream, *output_stream; input_stream = output_stream = NULL; result_file_name = NULL; TRY { if (*arguments != EOS) { free_mem( &analysis_file_name ); analysis_file_name = parse_absolute_path( &arguments, NULL ); } if (*analysis_file_name == NULL) complain( "Missing input file name." ); if (*arguments != EOS) result_file_name = parse_absolute_path( &arguments, NULL ); else result_file_name = concat_strings( analysis_file_name, ".out", NULL ); parse_end( &arguments ); input_stream = open_stream( analysis_file_name, "r" ); output_stream = open_stream( result_file_name, "w" ); analyse_stream( grammar, input_stream, output_stream, stdout, FALSE ); } FINALLY { close_stream( &input_stream, analysis_file_name ); close_stream( &output_stream, result_file_name ); free_mem( &result_file_name ); } END_TRY; } /*---------------------------------------------------------------------------*/ static void do_ma_file( string_t arguments ) /* Analyse file in ARGUMENTS morphologically. */ { assert_not_in_debug_mode(); analyse_file( arguments, MORPHOLOGY ); } static command_t ma_file_command = { "ma-file maf", do_ma_file, "Analyse a word list file.\n" "Usage: ma-file [INPUT_FILE [OUTPUT_FILE]]\n" "INPUT_FILE must contain one word form on each line.\n" "The results are written to \"OUTPUT_FILE\".\n" "If INPUT_FILE is missing, the previous file name is used.\n" "If OUTPUT_FILE is missing, they are written to \"INPUT_FILE.out\".\n" "\"ma-file\" can't be used in debug mode.\n" }; /*---------------------------------------------------------------------------*/ static void do_sa_file( string_t arguments ) /* Analyse file in ARGUMENTS syntactically. */ { assert_not_in_debug_mode(); if (rule_system[ SYNTAX ] == NULL) complain( "Syntax rule file not loaded." ); analyse_file( arguments, SYNTAX ); } static command_t sa_file_command = { "sa-file saf", do_sa_file, "Analyse a sentence list file.\n" "Usage: sa-file [INPUT_FILE [OUTPUT_FILE]]\n" "INPUT_FILE must contain one sentence on each line.\n" "The results are written to \"OUTPUT_FILE\".\n" "If INPUT_FILE is missing, the previous file name is used.\n" "If OUTPUT_FILE is missing, they are written to \"INPUT_FILE.out\".\n" "\"sa-file\" can't be used in debug mode.\n" }; /*===========================================================================*/ static void do_clear_cache( string_t arguments ) /* Clear the wordform analysis cache. */ { parse_end( &arguments ); clear_cache(); } static command_t clear_cache_command = { "clear-cache", do_clear_cache, "Clear the wordform analysis cache.\n" "Usage: clear-cache\n" }; /*---------------------------------------------------------------------------*/ static void do_info( string_t arguments ) /* Show information about morphology and syntax. */ { parse_end( &arguments ); printf( "%s", grammar_info->buffer ); } static command_t info_command = { "info", do_info, "Show information about current grammar.\n" "Usage: info\n" }; /*---------------------------------------------------------------------------*/ /* The commands that can be called interactively, in alphabetical order. */ static command_t *malaga_commands[] = { &backtrace_command, &break_command, &clear_cache_command, &continue_command, &debug_ma_command, &debug_ma_line_command, &debug_sa_command, &debug_sa_line_command, &debug_state_command, &delete_command, &down_command, &finish_command, &frame_command, &get_command, &help_command, &info_command, &list_command, &ma_command, &ma_file_command, &ma_line_command, &mg_command, &next_command, &print_command, &quit_command, &result_command, &run_command, &sa_command, &sa_file_command, &sa_line_command, &set_command, &sg_command, &step_command, &transmit_command, &tree_command, &up_command, &variables_command, &walk_command, &where_command, NULL }; /*---------------------------------------------------------------------------*/ int main( int argc, char *argv[] ) /* The main function of "malaga". */ { enum {INTERACTIVE_MODE, MORPHOLOGY_MODE, SYNTAX_MODE} malaga_mode; int_t i; string_t project_file, input; rule_sys_name_t rule_systems[2]; /* Rule systems for debugger. */ grammar_t grammar; /* Grammar for batch mode. */ bool_t expect_quotes; expect_quotes = FALSE; malaga_mode = INTERACTIVE_MODE; input = NULL; init_basic( "malaga" ); /* Parse arguments. */ if (argc == 2) { if (strcmp_no_case( argv[1], "--version" ) == 0 || strcmp_no_case( argv[1], "-version" ) == 0 || strcmp_no_case( argv[1], "-v" ) == 0) { program_message(); exit(0); } else if (strcmp_no_case( argv[1], "--help" ) == 0 || strcmp_no_case( argv[1], "-help" ) == 0 || strcmp_no_case( argv[1], "-h" ) == 0) { printf( "Analyse words and/or sentences according to a Malaga grammar.\n" "\n" "Usage:\n" "malaga PROJECT-FILE " "-- Start interactive malaga.\n" "malaga PROJECT-FILE -m[orphology] " "-- Run as a morphology filter.\n" "malaga PROJECT-FILE -s[yntax] " "-- Run as a syntax filter.\n" "malaga -v[ersion] " "-- Print version information.\n" "malaga -h[elp] " "-- Print this help.\n\n" "Option \"-i[nput] STRING\" makes malaga analyse STRING.\n" "Option \"-q[uoted]\" expects quoted lines in filter mode.\n" "PROJECT_FILE must end on \".pro\".\n" ); exit(0); } } project_file = NULL; for (i = 1; i < argc; i++) { if (has_extension( argv[i], "pro" )) set_file_name( &project_file, argv[i] ); else if (strcmp_no_case( argv[i], "-morphology" ) == 0 || strcmp_no_case( argv[i], "-m" ) == 0) { malaga_mode = MORPHOLOGY_MODE; } else if (strcmp_no_case( argv[i], "-syntax" ) == 0 || strcmp_no_case( argv[i], "-s" ) == 0) { malaga_mode = SYNTAX_MODE; } else if (strcmp_no_case( argv[i], "-input" ) == 0 || strcmp_no_case( argv[i], "-i" ) == 0) { if (argv[ ++i ] == NULL) complain( "Missing string after \"-input\"." ); if (input != NULL) complain( "Redundant \"-input\"." ); input = argv[i]; if (! g_utf8_validate( input, -1, NULL )) complain( "Illegal UTF-8 character." ); } else if (strcmp_no_case( argv[i], "-quoted" ) == 0 || strcmp_no_case( argv[i], "-q" ) == 0) { expect_quotes = TRUE; } else complain( "Illegal argument \"%s\".", argv[i] ); } if (project_file == NULL) complain( "Missing project file name." ); init_malaga( project_file ); if (malaga_mode == INTERACTIVE_MODE) { if (input != NULL) complain( "Need \"-morphology\" or \"-syntax\"." ); init_debugger( display_where, malaga_commands ); rule_systems[0].rule_sys = rule_system[ MORPHOLOGY ]; rule_systems[0].name = "mor"; rule_systems[1].rule_sys = rule_system[ SYNTAX ]; rule_systems[1].name = "syn"; init_breakpoints( 2, rule_systems ); init_generation(); program_message(); command_loop( program_name, malaga_commands ); terminate_generation(); terminate_breakpoints(); terminate_debugger(); } else { grammar = (malaga_mode == MORPHOLOGY_MODE) ? MORPHOLOGY : SYNTAX; if (rule_system[ grammar ] == NULL) complain( "Rule file not loaded." ); if (input != NULL) analyse_input( grammar, input ); else analyse_stream( grammar, stdin, stdout, stderr, expect_quotes ); } stop_display_process(); terminate_malaga(); free_mem( &analysis_input ); free_mem( &analysis_file_name ); free_mem( &project_file ); terminate_basic(); return 0; } /* End of file. =============================================================*/ malaga-7.12/malaga_files.c0000644000175000017500000000656010236624750014771 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module defines the structure of compiled Malaga files. */ /* Includes. ================================================================*/ #include #include #include #include #include #include "basic.h" #include "files.h" #include "malaga_files.h" /* Constants. ===============================================================*/ static char_t malaga[] = "MALAGA"; /* Magic key. */ /* Variables. ===============================================================*/ static time_t sym_stamp; /* Stamp for the ".sym" file or 0. */ static time_t esym_stamp; /* Stamp for the ".esym" file or 0. */ /* Functions. ===============================================================*/ void check_header( common_header_t *header, string_t file_name, int_t file_type, int_t min_code_version, int_t max_code_version ) /* Check if HEADER is of FILE_TYPE and * between MIN_CODE_VERSION and MAX_CODE_VERSION. * FILE_NAME is needed for error messages. */ { if (memcmp( header->malaga, malaga, sizeof( char_t ) * MALAGA_LEN ) != NULL) complain( "\"%s\" is not a Malaga file.", file_name ); if (header->file_type != file_type) complain( "\"%s\" is wrong file type.", file_name ); if (header->code_version < min_code_version) complain( "\"%s\" is old code version. Maybe recompile?", file_name ); if (header->code_version > max_code_version) { complain( "\"%s\" is new code version. Use newer Malaga version.", file_name); } if (file_type == SYMBOL_FILE) { sym_stamp = header->sym_stamp; esym_stamp = header->esym_stamp; split_hangul_syllables = header->split_hangul_syllables; } else if (header->sym_stamp != sym_stamp) { complain( "\"%s\" uses %s \".sym\" file.", file_name, header->sym_stamp < sym_stamp ? "older" : "newer" ); } else if (header->esym_stamp != 0) { if (esym_stamp == 0) complain( "\"%s\" needs \".esym\" file.", file_name ); else if (header->esym_stamp != esym_stamp) { complain( "\"%s\" uses %s \".esym\" file.", file_name, header->esym_stamp < esym_stamp ? "older" : "newer" ); } } else if (header->split_hangul_syllables != split_hangul_syllables) { complain( "\"%s\" %s split Hangul syllables.", file_name, split_hangul_syllables ? "must" : "must not" ); } } /*---------------------------------------------------------------------------*/ void set_sym_stamp( void ) /* Create a stamp for the ".sym" file. */ { time( &sym_stamp ); } /*---------------------------------------------------------------------------*/ void set_esym_stamp( void ) /* Create a stamp for the ".esym" file. */ { time( &esym_stamp ); } /*---------------------------------------------------------------------------*/ void set_header( common_header_t *header, int_t file_type, int_t code_version ) /* Set HEADER to be of FILE_TYPE and CODE_VERSION. */ { memcpy( header->malaga, malaga, sizeof( char_t ) * MALAGA_LEN ); header->file_type = file_type; header->split_hangul_syllables = split_hangul_syllables; header->code_version = code_version; header->sym_stamp = sym_stamp; header->esym_stamp = esym_stamp; } /* End of file. =============================================================*/ malaga-7.12/malaga_files.h0000644000175000017500000001337010236624750014773 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module defines the structure of compiled Malaga files. */ /* Constants. ===============================================================*/ enum {MALAGA_LEN = 6}; /* Length of magic code at beginning of Malaga file. */ /* Values for FILE_TYPE. */ enum {SYMBOL_FILE, RULE_FILE, LEXICON_FILE, PRELEX_FILE}; /* Versions of compiled Malaga file types. */ enum {SYMBOL_CODE_VERSION = 8}; enum {RULE_CODE_VERSION = 47}; enum {LEXICON_CODE_VERSION = 14}; enum {PRELEX_CODE_VERSION = 1}; /* Versions of Malaga file types that are still understood. */ enum {MIN_SYMBOL_CODE_VERSION = 8}; enum {MIN_RULE_CODE_VERSION = 47}; enum {MIN_LEXICON_CODE_VERSION = 14}; enum {MIN_PRELEX_CODE_VERSION = 1}; /* Types. ===================================================================*/ typedef struct /* The common header of every Malaga file. */ { char_t malaga[ MALAGA_LEN ]; /* "MALAGA" to recognise Malaga files. */ u_byte_t split_hangul_syllables; /* Boolean field. */ byte_t file_type; /* SYMBOL_FILE, RULE_FILE or LEXICON_FILE. */ int_t code_version; /* Only load code of the current version. */ int_t sym_stamp; /* Stamp for ".sym" file. */ int_t esym_stamp; /* Stamp for ".esym" file or 0. */ } common_header_t; /*---------------------------------------------------------------------------*/ typedef struct /* The format of a Malaga rule file. */ { common_header_t common_header; int_t initial_rule_set; /* Index of the initial rule set in RULE_SETS. */ int_t initial_feat; /* Index of the initial feature structure in VALUES. */ int_t robust_rule; /* Rule number of robust_rule. */ int_t pruning_rule; /* Rule number of pruning_rule. */ int_t allo_rule; /* Rule number of allo_rule. */ int_t input_filter; /* Rule number of input_filter. */ int_t output_filter; /* Rule number of output_filter. */ int_t rule_count; /* Number of rules in this file. */ int_t rule_sets_size; /* Size of rule set table. */ int_t instr_count; /* Number of instructions in this file. */ int_t values_size; /* Size of Malaga value table. */ int_t src_line_count; /* Number of correspondences * between source lines and rule code. */ int_t var_count; /* Number of variable names. */ int_t var_scope_count; /* Number of variable scopes. */ int_t constant_count; /* Number of named constants. */ int_t strings_size; /* Size of string table. */ /* The following blocks have dynamic size: */ /* rule_t rules[ rule_count ]; */ /* int_t rule_sets[ rule_sets_size ]; */ /* instr_t instrs[ instr_count ]; */ /* cell_t values[ values_size ]; */ /* src_line_t src_lines[ src_line_count ]; */ /* var_t vars[ var_count ]; */ /* var_scope_t var_scopes[ var_scope_count ]; */ /* constant_t constants[ constant_count ]; */ /* char_t strings[ strings_size ]; */ } rule_header_t; /*---------------------------------------------------------------------------*/ typedef struct /* An entry in the symbol table. */ { int_t name; /* STRINGS index to symbol name. */ int_t atoms; /* VALUES index to list of the atomic symbols * of a multi-symbol (or -1). */ } symbol_entry_t; typedef struct /* The format of a Malaga symbol file. */ { common_header_t common_header; int_t symbol_count; /* Number of symbols in this file. */ int_t values_size; /* Size of Malaga value table (for multi-symbols). */ int_t strings_size; /* Size of string table (for symbol names). */ /* The following blocks have dynamic size: * symbol_entry_t symbols[ symbol_count ]; * cell_t values[ values_size ]; * char_t strings[ strings_size ]; */ } symbol_header_t; /*---------------------------------------------------------------------------*/ typedef struct /* An entry in the prelex file. */ { int_t surface; /* STRINGS index to surface. */ int_t feat; /* VALUES index to feature structure. */ } prelex_entry_t; typedef struct /* The format of a Malaga prelex file. */ { common_header_t common_header; int_t entry_count; /* Number of entries in this file. */ int_t values_size; /* Size of value table. */ int_t strings_size; /* Size of string table. */ /* The following blocks have dynamic size: * prelex_entry_t entries[ entry_count ]; * cell_t values[ values_size ]; * char_t strings[ strings_size ]; */ } prelex_header_t; /*---------------------------------------------------------------------------*/ typedef struct /* The format of a Malaga lexicon file. */ { common_header_t common_header; int_t trie_size; /* Size of trie table. */ int_t trie_root; /* Index of root node in TRIE. */ int_t feat_lists_size; /* Size of feature structure lists table. */ int_t values_size; /* Size of value table. */ /* The following blocks have dynamic size: * int_t trie[ trie_size ]; * int_t feat_lists[ feat_lists_size ]; * cell_t values[ values_size ]; */ } lexicon_header_t; /* Functions. ===============================================================*/ extern void set_sym_stamp( void ); /* Create a stamp for the ".sym" file */ extern void set_esym_stamp( void ); /* Create a stamp for the ".esym" file */ extern void check_header( common_header_t *header, string_t file_name, int_t file_type, int_t min_code_version, int_t max_code_version ); /* Check if HEADER is of FILE_TYPE and * between MIN_CODE_VERSION and MAX_CODE_VERSION. * FILE_NAME is needed for error messages. */ extern void set_header( common_header_t *header, int_t file_type, int_t code_version ); /* Set header to be of FILE_TYPE and CODE_VERSION. */ /* End of file. =============================================================*/ malaga-7.12/malaga.h0000644000175000017500000001705310505746503013613 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This is the header file for "libmalaga". */ /*===========================================================================*/ #ifdef __cplusplus extern "C" { #endif /* Constants. ===============================================================*/ /* Current version of libmalaga interface. */ #define LIBMALAGA_VERSION 8 /* Minimum version of libmalaga interface that is still fully supported. */ #define MIN_LIBMALAGA_VERSION 7 #undef NULL #define NULL 0 /* Null pointer. */ /* Some standard symbols. */ enum {NIL_SYMBOL, YES_SYMBOL, NO_SYMBOL, SYMBOL_SYMBOL, STRING_SYMBOL, NUMBER_SYMBOL, LIST_SYMBOL, RECORD_SYMBOL}; /* Basic types. =============================================================*/ /* Numeric types. */ typedef signed char byte_t; /* Signed 8 bits. */ typedef unsigned char u_byte_t; /* Unsigned 8 bits. */ typedef signed short int short_t; /* Signed 16 bits. */ typedef unsigned short int u_short_t; /* Unsigned 16 bits. */ typedef signed int int_t; /* Signed 32 bits. */ typedef unsigned int u_int_t; /* Unsigned 32 bits. */ /* Character types. */ typedef char char_t; /* A single byte of a char. */ typedef const char_t *string_t; /* An EOS-terminated C-style string. */ enum {EOS= '\0'}; /* End-Of-String control character. */ #define ORD(c) ((u_byte_t) (c)) /* The ordinal number of character C. */ /* Boolean type. */ #undef bool_t /* conflicts with "bool_t" definition */ #undef TRUE #undef FALSE typedef enum {FALSE, TRUE} bool_t; typedef u_short_t cell_t; /* A value is stored in one or more cells. * Use this type if you want to allocate memory (pools etc.) for values. */ typedef cell_t *value_t; /* Reference to a Malaga values by this type. */ typedef cell_t symbol_t; typedef enum {MORPHOLOGY, SYNTAX} grammar_t; /* Grammatical analysis types. */ /* Variables. ===============================================================*/ extern char_t malaga_version[]; /* Read only! */ extern string_t malaga_error; /* If one of the functions below has created an error, this variable * contains an error message. If a function did its job, it is NULL. */ extern enum {INTERNAL_ORDER, ALPHABETIC_ORDER, DEFINITION_ORDER} attribute_order; /* The order in which attributes in a record are printed. * INTERNAL_ORDER is the order in which attributes are stored internally. * ALPHABETIC_ORDER means the alphabetic order of the attribute names. * DEFINITION_ORDER is the order in which the attributes are defined in the * symbol file. * Used by "value_readable". */ /* Value functions. =========================================================*/ extern value_t new_value( value_t value ); /* Allocate space for VALUE and copy it. * Free the space occupied by this value with "free" after use. */ extern int_t length_of_value( value_t value ); /* Return the length of VALUE in cells. */ extern symbol_t get_value_type( value_t value ); /* Return the type of VALUE. Depending of the type, the result value may be * SYMBOL_SYMBOL, STRING_SYMBOL, NUMBER_SYMBOL, LIST_SYMBOL, RECORD_SYMBOL. */ extern symbol_t value_to_symbol( value_t value ); /* Return VALUE as a symbol. It is an error if VALUE is no symbol. */ extern string_t get_symbol_name( symbol_t symbol ); /* Return the name of SYMBOL. */ extern value_t get_atoms( symbol_t symbol ); /* Return the list of atoms of SYMBOL. */ extern char_t *get_value_string( value_t string ); /* Return the value of STRING as a C-style string in external encoding. * The string must be freed after use. */ extern value_t get_attribute( value_t record, symbol_t attribute ); /* Return the value of ATTRIBUTE in RECORD or NULL if it doesn't exist. */ extern int_t get_list_length( value_t list ); /* Return the number of elements in the list LIST. */ extern value_t get_element( value_t list, int_t n ); /* Return the N-th element of the list LIST, or NULL if it doesn't exist. * If N is positive, elements will be counted from the left border. * If N is negative, elements will be counted from the right border. */ extern double value_to_double( value_t value ); /* Return the value of VALUE which must be a number value. */ extern int_t value_to_int( value_t value ); /* Return the value of VALUE which must be an integral number value. */ extern value_t get_value_part( value_t value, value_t path ); /* Return the value part of VALUE that is specified by the path PATH. * If that value part does not exist, return NULL. */ extern value_t get_first_item( value_t value ); /* If VALUE is a list, then return its first element (or NULL). * If VALUE is a record, then return its first attribute (or NULL). */ extern value_t get_next_item( value_t value, value_t item ); /* If VALUE is a list, and ELEMENT one of its elements, * then NEW_ELEMENT is the successor of ELEMENT (or NULL). * If VALUE is a record, and ELEMENT one of its attributes, * then NEW_ELEMENT is the next attribute in VALUE (or NULL). */ extern bool_t values_equal( value_t value1, value_t value2 ); /* Return a truth value indicating whether VALUE1 and VALUE2 are equal. * VALUE1 an VALUE2 must be of same type or one of them must be nil. * Refer to documentation to see what "equal" in Malaga really means. */ extern bool_t values_congruent( value_t value1, value_t value2 ); /* Return a truth value indicating whether VALUE1 and VALUE2 have * at least one element in common. * VALUE1 and VALUE2 must both be symbols or lists. */ extern bool_t value_in_value( value_t value1, value_t value2 ); /* Return bool value saying if VALUE1 is element or attribute of VALUE2. * VALUE2 must be a list or a record. * If VALUE2 is a record, then VALUE1 must be a symbol. */ extern char_t *value_to_readable( value_t value, bool_t full_value, int_t indent ); /* Return VALUE in a format readable for humans. * If FULL_VALUE == TRUE, show all attributes, even those that are hidden. * If INDENT >= 0, format value, i.e. print each element of a list or record * on a line of its own. Assume the value is indented by INDENT columns. * Use "free" to free the space after use. */ extern value_t parse_malaga_value( string_t string ); /* Convert the STRING to a Malaga value and return it. * STRING must be a valid UTF-8 string. * The value must be freed after use. * This function sets "malaga_error". */ /* Functions. ===============================================================*/ extern void set_option( string_t option ); /* Set a libmalaga option. * OPTION must be a valid UTF-8 string. * This function sets "malaga_error". */ extern string_t get_info( void ); /* Get info about the current grammar. */ extern void analyse_item( string_t item, grammar_t grammar ); /* Analyse ITEM according to GRAMMAR. * GRAMMAR must be MORPHOLOGY or SYNTAX. * ITEM must be a valid UTF-8 string. * This function sets "malaga_error". */ extern value_t first_analysis_result( void ); /* Get the first result of the last call of "analyse_item". * Return NULL if there is no result. */ extern value_t next_analysis_result( void ); /* Get the next result of the last call of "analyse_item". * Return NULL if there is no more result. */ extern void init_libmalaga( string_t project_file ); /* Initialise this module. * This function sets "malaga_error". */ extern void terminate_libmalaga( void ); /* Terminate this module. */ /*===========================================================================*/ #ifdef __cplusplus } #endif /* End of file. =============================================================*/ malaga-7.12/malaga_lib.c0000644000175000017500000004451610701725065014436 0ustar bjoernbjoern/* Copyright (C) 1997 Bjoern Beutel. */ /* Description. =============================================================*/ /* Options for malaga and functions to start and terminate malaga. */ /* Includes. ================================================================*/ #include #include #include #include #include #include #include #include "basic.h" #include "pools.h" #include "values.h" #include "input.h" #include "commands.h" #include "options.h" #include "rule_type.h" #include "rules.h" #include "files.h" #include "analysis.h" #include "cache.h" #include "symbols.h" #include "lexicon.h" #include "transmit.h" #include "display.h" #include "scanner.h" #include "patterns.h" #include "hangul.h" #include "malaga_lib.h" /* Global variables. ========================================================*/ bool_t auto_tree; /* TRUE if tree is shown automatically. */ bool_t auto_result; /* TRUE if result is shown automatically. */ bool_t result_as_list; /* TRUE if results will be combined into a list. */ text_t *grammar_info; /* Information about grammar. */ string_t result_format, unknown_format, error_format; /* Format strings for output. */ /* Variables. ===============================================================*/ static string_t morphology_file, syntax_file, lexicon_file; static string_t symbol_file, extended_symbol_file; static bool_t info_in_project_file; /* Indicates whether we have read grammar info from the current project file. * Used to insert empty lines between grammar infos from different project * files. */ /* Functions. ===============================================================*/ static void do_mor_pruning_option( string_t arguments ) /* Set minimum number of states needed to call the morphology pruning rule. */ { if (*arguments == EOS) printf( "mor-pruning: %d\n", mor_pruning_min ); else { if (rule_system[MORPHOLOGY]->pruning_rule == -1) complain("No morphology pruning rule."); mor_pruning_min = parse_int( &arguments ); parse_end( &arguments ); } } static command_t mor_pruning_option = { "mor-pruning", do_mor_pruning_option, "Usage:\n" " set mor-pruning 0 -- Turn off morphology pruning.\n" " set mor-pruning N -- Call pruning rule for a minimum of N states.\n" }; /*---------------------------------------------------------------------------*/ static void do_syn_pruning_option( string_t arguments ) /* Set minimum number of states needed to call the syntax pruning rule. */ { if (*arguments == EOS) printf( "syn-pruning: %d\n", syn_pruning_min ); else { if (rule_system[SYNTAX] == NULL || rule_system[SYNTAX]->pruning_rule == -1) complain("No syntax pruning rule."); syn_pruning_min = parse_int( &arguments ); parse_end( &arguments ); } } static command_t syn_pruning_option = { "syn-pruning", do_syn_pruning_option, "Usage:\n" " set syn-pruning 0 -- Turn off syntax pruning.\n" " set syn-pruning N -- Call pruning rule for a minimum of N states.\n" }; /*---------------------------------------------------------------------------*/ static void do_robust_rule_option( string_t arguments ) /* Enable/disable robust-rule. */ { if (*arguments == EOS) { printf( "robust-rule: %s\n", get_analysis_option( ROBUST_RULE_OPTION ) ? "yes" : "no" ); } else set_analysis_option( ROBUST_RULE_OPTION, parse_yes_no( &arguments ) ); parse_end( &arguments ); } static command_t robust_rule_option = { "robust-rule robust", do_robust_rule_option, "Usage:\n" " set robust-rule yes -- Turn robust_rule on.\n" " set robust-rule no -- Turn robust_rule off.\n" }; /*---------------------------------------------------------------------------*/ static void do_mor_out_filter_option( string_t arguments ) /* Enable/disable morphology output filter. */ { if (*arguments == EOS) { printf( "mor-out-filter: %s\n", get_analysis_option( MOR_OUT_FILTER_OPTION ) ? "yes" : "no" ); } else set_analysis_option( MOR_OUT_FILTER_OPTION, parse_yes_no( &arguments ) ); parse_end( &arguments ); } static command_t mor_out_filter_option = { "mor-out-filter mofil", do_mor_out_filter_option, "Usage:\n" " set mor-out-filter yes -- Turn morphology output filter on.\n" " set mor-out-filter no -- Turn morphology output filter off.\n" }; /*---------------------------------------------------------------------------*/ static void do_syn_out_filter_option( string_t arguments ) /* Enable/disable syntax output filter. */ { if (*arguments == EOS) { printf( "syn-out-filter: %s\n", get_analysis_option( SYN_OUT_FILTER_OPTION ) ? "yes" : "no" ); } else set_analysis_option( SYN_OUT_FILTER_OPTION, parse_yes_no( &arguments ) ); parse_end( &arguments ); } static command_t syn_out_filter_option = { "syn-out-filter sofil", do_syn_out_filter_option, "Usage:\n" " set syn-out-filter yes -- Turn syntax output filter on.\n" " set syn-out-filter no -- Turn syntax output filter off.\n" }; /*---------------------------------------------------------------------------*/ static void do_syn_in_filter_option( string_t arguments ) /* Enable/disable syntax input filter. */ { if (*arguments == EOS) { printf( "syn-in-filter: %s\n", get_analysis_option( SYN_IN_FILTER_OPTION ) ? "yes" : "no" ); } else set_analysis_option( SYN_IN_FILTER_OPTION, parse_yes_no( &arguments ) ); parse_end( &arguments ); } static command_t syn_in_filter_option = { "syn-in-filter sifil", do_syn_in_filter_option, "Usage:\n" " set syn-in-filter yes -- Turn syntax input filter on.\n" " set syn-in-filter no -- Turn syntax input filter off.\n" }; /*---------------------------------------------------------------------------*/ static void do_mor_incomplete_option( string_t arguments ) /* Enable/disable acceptance of incompletely parsed words. */ { if (*arguments == EOS) { printf( "mor-incomplete: %s\n", get_analysis_option( MOR_INCOMPLETE_OPTION ) ? "yes" : "no" ); } else set_analysis_option( MOR_INCOMPLETE_OPTION, parse_yes_no( &arguments ) ); parse_end( &arguments ); } static command_t mor_incomplete_option = { "mor-incomplete", do_mor_incomplete_option, "Usage:\n" " set mor-incomplete yes -- " "Accept words that have been incompletely parsed.\n" " set mor-incomplete no -- " "Only accept words that have been completely parsed.\n" }; /*---------------------------------------------------------------------------*/ static void do_syn_incomplete_option( string_t arguments ) /* Enable/disable acceptance of incompletely parsed words. */ { if (*arguments == EOS) { printf( "syn-incomplete: %s\n", get_analysis_option( SYN_INCOMPLETE_OPTION ) ? "yes" : "no" ); } else set_analysis_option( SYN_INCOMPLETE_OPTION, parse_yes_no( &arguments ) ); parse_end( &arguments ); } static command_t syn_incomplete_option = { "syn-incomplete", do_syn_incomplete_option, "Usage:\n" " set syn-incomplete yes -- " "Accept sentences that have been incompletely parsed.\n" " set syn-incomplete no -- " "Only accept sentences that have been completely parsed.\n" }; /*---------------------------------------------------------------------------*/ static void do_result_list_option( string_t arguments ) /* Enable/disable combination of all results into a single list. */ { if (*arguments == EOS) printf( "result-list: %s\n", result_as_list ? "yes" : "no" ); else result_as_list = parse_yes_no( &arguments ); parse_end( &arguments ); } static command_t result_list_option = { "result-list", do_result_list_option, "Usage:\n" " set result-list yes -- Combine results into a single list.\n" " set result-list no -- Leave results unchanged.\n" }; /*---------------------------------------------------------------------------*/ static void do_cache_size_option( string_t arguments ) /* Change the cache size. */ { int_t size; if (*arguments == EOS) { printf( "cache-size: %d (%d used)\n", get_cache_maximum(), get_cache_size() ); } else { size = parse_int( &arguments ); set_cache_size( size ); set_analysis_option( CACHE_OPTION, (size > 0) ); } parse_end( &arguments ); } static command_t cache_size_option = { "cache-size", do_cache_size_option, "Usage: set cache-size SIZE -- Set cache size to SIZE.\n" "If SIZE == 0, cache is switched off.\n" }; /*---------------------------------------------------------------------------*/ static void do_auto_tree_option( string_t arguments ) /* Determine if tree is shown automatically. */ { if (*arguments == EOS) printf( "auto-tree: %s\n", auto_tree ? "yes" : "no" ); else auto_tree = parse_yes_no( &arguments ); parse_end( &arguments ); } static command_t auto_tree_option = { "auto-tree tree", do_auto_tree_option, "Usage:\n" " set auto-tree yes -- Show tree after analysis.\n" " set auto-tree no -- Don't show tree after analysis.\n" }; /*---------------------------------------------------------------------------*/ static void do_auto_result_option( string_t arguments ) /* Determine if result is shown automatically. */ { if (*arguments == EOS) printf( "auto-result: %s\n", auto_result ? "yes" : "no" ); else auto_result = parse_yes_no( &arguments ); parse_end( &arguments ); } static command_t auto_result_option = { "auto-result result output", do_auto_result_option, "Usage:\n" " set auto-result yes -- Show result after analysis.\n" " set auto-result no -- Don't show result after analysis.\n" }; /*---------------------------------------------------------------------------*/ static void do_error_format_option( string_t arguments ) /* Change analysis-error print format to ARGUMENTS. */ { string_t format; if (*arguments == EOS) { format = new_string_readable( error_format, NULL ); printf( "error-format: %s\n", format ); free_mem( &format ); } else { format = parse_word( &arguments ); free_mem( &error_format ); error_format = format; } parse_end( &arguments ); } static command_t error_format_option = { "error-format", do_error_format_option, "Set the format in which to print analysis input that produced an error.\n" "Usage: set error-format ERROR_FORMAT_STRING\n" "The ERROR_FORMAT_STRING may contain the following special sequences:\n" " %e -- Error message.\n" " %l -- Input line number.\n" " %n -- Number of analysis states.\n" " %s -- Surface.\n" }; /*---------------------------------------------------------------------------*/ static void do_result_format_option( string_t arguments ) /* Change analysis result format to ARGUMENTS. */ { string_t format; if (*arguments == EOS) { format = new_string_readable( result_format, NULL ); printf( "result-format: %s\n", format ); free_mem( &format ); } else { format = parse_word( &arguments ); free_mem( &result_format ); result_format = format; } parse_end( &arguments ); } static command_t result_format_option = { "result-format output-format", do_result_format_option, "Describe the format in which analysis results will be printed.\n" "Usage: set result-format RESULT_FORMAT_STRING\n" "The RESULT_FORMAT_STRING may contain the following special sequences:\n" " %f -- Result feature structure.\n" " %l -- Input line number.\n" " %n -- Number of analysis states.\n" " %r -- Ambiguity index.\n" " %s -- Surface.\n" }; /*---------------------------------------------------------------------------*/ static void do_unknown_format_option( string_t arguments ) /* Change unknown analysis format to ARGUMENTS. */ { string_t format; if (*arguments == EOS) { format = new_string_readable( unknown_format, NULL ); printf( "unknown-format: %s\n", format ); free_mem( &format ); } else { format = parse_word( &arguments ); free_mem( &unknown_format ); unknown_format = format; } parse_end( &arguments ); } static command_t unknown_format_option = { "unknown-format", do_unknown_format_option, "Describe the format in which unknown forms will be printed.\n" "Usage: set unknown-format UNKNOWN_FORMAT_STRING\n" "The UNKNOWN_FORMAT_STRING may contain the following special sequences:\n" " %l -- Input line number.\n" " %n -- Number of analysis states.\n" " %s -- Surface.\n" }; /*---------------------------------------------------------------------------*/ static void read_project_file( string_t project_file ) /* Read the project file. */ { FILE *project_stream; char_t *project_line; string_t project_line_p, argument, include_file, extension; string_t *name_p; volatile int_t line_count; static bool_t err_pos_printed; info_in_project_file = err_pos_printed = FALSE; project_stream = open_stream( project_file, "r" ); line_count = 0; while (TRUE) { TRY project_line = read_line( project_stream ); IF_ERROR { print_text( error_text, " (\"%s\", line %d)", name_in_path( project_file ), line_count + 1 ); err_pos_printed = TRUE; } END_TRY; if (project_line == NULL) break; line_count++; cut_comment( project_line ); project_line_p = project_line; if (*project_line_p != EOS) { argument = NULL; TRY { argument = parse_word( &project_line_p ); extension = NULL; name_p = NULL; if (strcmp_no_case( argument, "sym:" ) == 0) { extension = "sym"; name_p = &symbol_file; } else if (strcmp_no_case( argument, "esym:" ) == 0) { extension = "esym"; name_p = &extended_symbol_file; } else if (strcmp_no_case( argument, "lex:" ) == 0) { extension = "lex"; name_p = &lexicon_file; } else if (strcmp_no_case( argument, "mor:" ) == 0) { extension = "mor"; name_p = &morphology_file; } else if (strcmp_no_case( argument, "syn:" ) == 0) { extension = "syn"; name_p = &syntax_file; } else if (strcmp_no_case( argument, "include:" ) == 0) { include_file = parse_absolute_path( &project_line_p, project_file ); parse_end( &project_line_p ); read_project_file( include_file ); free_mem( &include_file ); } else if (strcmp_no_case( argument, "info:" ) == 0) { /* Insert an empty line if we already have info that stems from a * different project file. */ if (grammar_info->string_size > 0 && ! info_in_project_file) add_char_to_text( grammar_info, '\n' ); add_to_text( grammar_info, project_line_p ); add_char_to_text( grammar_info, '\n' ); info_in_project_file = TRUE; } free_mem( &argument ); if (name_p != NULL && *name_p == NULL && *project_line_p != EOS) { argument = parse_absolute_path( &project_line_p, project_file ); if (! has_extension( argument, extension )) { complain( "\"%s\" should have extension \"%s\".", name_in_path( argument ), extension ); } set_binary_file_name( name_p, argument ); free_mem( &argument ); } } IF_ERROR { if (! err_pos_printed) { print_text( error_text, " (\"%s\", line %d)", name_in_path( project_file ), line_count ); err_pos_printed = TRUE; } } END_TRY; } free_mem( &project_line ); } close_stream( &project_stream, project_file ); info_in_project_file = FALSE; } /*---------------------------------------------------------------------------*/ /* The commands that can be called on startup, in alphabetical order. */ static command_t *malaga_options[] = { &alias_option, &auto_result_option, &auto_tree_option, &auto_variables_option, &cache_size_option, &display_cmd_option, &error_format_option, &hidden_option, &mor_incomplete_option, &mor_out_filter_option, &mor_pruning_option, &result_format_option, &result_list_option, &robust_rule_option, &roman_hangul_option, &sort_records_option, &switch_option, &syn_incomplete_option, &syn_in_filter_option, &syn_out_filter_option, &syn_pruning_option, &transmit_cmd_option, &unknown_format_option, &use_display_option, NULL }; /*---------------------------------------------------------------------------*/ void init_malaga( string_t project_file ) /* Initialise this module. */ { string_t malagarc_path; init_input(); grammar_info = new_text(); /* Read project file. */ if (! has_extension( project_file, "pro" )) { complain( "Project file \"%s\" must have extension \".pro\".", project_file ); } read_project_file( project_file ); if (morphology_file == NULL) complain( "Missing morphology rules." ); if (lexicon_file == NULL) complain( "Missing lexicon." ); if (symbol_file == NULL) complain( "Missing symbol file." ); /* Init modules. */ init_values(); if (extended_symbol_file != NULL) init_symbols( extended_symbol_file ); else init_symbols( symbol_file ); init_hangul(); init_lexicon( lexicon_file ); init_scanner(); init_transmit(); init_analysis( morphology_file, syntax_file ); /* Set options to default values. */ error_format = new_string( "%l: %s: error: %e", NULL ); result_format = new_string( "%l: %s: %f", NULL ); unknown_format = new_string( "%l: %s: unknown", NULL ); use_display = auto_tree = FALSE; auto_result = TRUE; /* Execute startup files. */ options = malaga_options; execute_set_commands( project_file, "malaga:" ); malagarc_path = NULL; #ifdef POSIX TRY malagarc_path = absolute_path( "~/.malagarc", NULL ); IF_ERROR RESUME; END_TRY; #endif #ifdef WIN32 TRY malagarc_path = absolute_path( "~\\malaga.ini", NULL ); IF_ERROR RESUME; END_TRY; #endif if (malagarc_path != NULL && file_exists( malagarc_path )) execute_set_commands( malagarc_path, "malaga:" ); free_mem( &malagarc_path ); } /*---------------------------------------------------------------------------*/ void terminate_malaga( void ) /* Terminate this module. */ { free_aliases(); free_mem( &error_format ); free_mem( &result_format ); free_mem( &unknown_format ); terminate_analysis(); free_mem( &syntax_file ); free_mem( &morphology_file ); terminate_patterns(); terminate_transmit(); terminate_scanner(); terminate_lexicon(); free_mem( &lexicon_file ); terminate_hangul(); terminate_symbols(); free_mem( &extended_symbol_file ); free_mem( &symbol_file ); terminate_values(); free_text( &grammar_info ); terminate_input(); } /* End of file. =============================================================*/ malaga-7.12/malaga_lib.h0000644000175000017500000000172210236624750014435 0ustar bjoernbjoern/* Copyright (C) 1997 Bjoern Beutel. */ /* Description. =============================================================*/ /* Options for malaga and functions to start and terminate malaga. */ /* Variables. ===============================================================*/ extern bool_t auto_tree; /* TRUE if tree is shown automatically. */ extern bool_t auto_result; /* TRUE if result is shown automatically. */ extern bool_t result_as_list; /* TRUE if results will be combined into * a list. */ extern text_t *grammar_info; /* Information about grammar. */ extern string_t result_format, unknown_format, error_format; /* Format strings for output. */ /* Functions. ===============================================================*/ extern void init_malaga( string_t project_file ); /* Initialise this module. */ extern void terminate_malaga( void ); /* Terminate this module. */ /* End of file. =============================================================*/ malaga-7.12/maldump.c0000644000175000017500000002577710236624750014037 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* Program to dump a compiled Malaga rule file with intermediate code. */ /* Includes. ================================================================*/ #include #include #include #include #include #include #include #include "basic.h" #include "pools.h" #include "values.h" #include "symbols.h" #include "files.h" #include "rule_type.h" #include "rules.h" #include "patterns.h" #include "hangul.h" /* Functions. ===============================================================*/ static void print_instruction( int_t pos, rule_sys_t *rule_sys ) /* Print the instruction at POS in RULE_SYS. */ { int_t opcode, info; string_t string; opcode = OPCODE( rule_sys->instrs[ pos ] ); info = INSTR_INFO( rule_sys->instrs[ pos ] ); switch (opcode) { case INS_SYSTEM_ERROR: switch (info) { case ASSERTION_ERROR: string = "assertion_error"; break; case NO_RETURN_ERROR: string = "no_return_error"; break; } printf( "error %s", string ); break; case INS_ERROR: printf( "error" ); break; case INS_TERMINATE: printf( "terminate" ); break; case INS_NOP: printf( "nop" ); break; case INS_TERMINATE_IF_NULL: printf( "terminate_if_null" ); break; case INS_ADD_END_STATE: printf( "add_end_state" ); break; case INS_ADD_STATE: string = rule_set_readable( rule_sys, info ); printf( "add_state %s", string ); free_mem( &string ); break; case INS_ADD_ALLO: printf( "add_allo" ); break; case INS_ACCEPT: printf( "accept" ); break; case INS_PUSH_NULL: printf( "push_null %d", info ); break; case INS_PUSH_VAR: printf( "push_var %d", info ); break; case INS_PUSH_CONST: string = value_to_readable( rule_sys->values + info, TRUE, 30 ); printf( "push_const %s", string ); free_mem( &string ); break; case INS_PUSH_SYMBOL: printf( "push_symbol %s", get_symbol_name( info ) ); break; case INS_PUSH_PATTERN_VAR: printf( "push_pattern_var %d", info ); break; case INS_POP: printf( "pop %d", info ); break; case INS_POP_TO: printf( "pop_to %d", info ); break; case INS_BUILD_LIST: printf( "build_list %d", info ); break; case INS_DECOMPOSE_LIST: printf( "decompose_list %d", info ); break; case INS_BUILD_RECORD: printf( "build_record %d", info ); break; case INS_BUILD_PATH: printf( "build_path %d", info ); break; case INS_DOT_OPERATION: printf( "dot_operation" ); break; case INS_PLUS_OPERATION: printf( "plus_operation" ); break; case INS_MINUS_OPERATION: printf( "minus_operation" ); break; case INS_ASTERISK_OPERATION: printf( "asterisk_operation" ); break; case INS_SLASH_OPERATION: printf( "slash_operation" ); break; case INS_UNARY_MINUS_OP: printf( "unary_minus_op" ); break; case INS_GET_ATTRIBUTE: printf( "get_attribute %s", get_symbol_name( info ) ); break; case INS_REMOVE_ATTRIBUTE: printf( "remove_attribute %s", get_symbol_name( info ) ); break; case INS_STD_FUNCTION: switch (info) { case FUNC_TO_ATOMS: string = "to_atoms"; break; case FUNC_IS_CAPITAL: string = "is_capital"; break; case FUNC_GET_LENGTH: string = "get_length"; break; case FUNC_TO_MULTI: string = "to_multi"; break; case FUNC_TO_SET: string = "to_set"; break; case FUNC_GET_SWITCH: string = "get_switch"; break; case FUNC_GET_VALUE_STRING: string = "get_value_string"; break; case FUNC_GET_VALUE_TYPE: string = "get_value_type"; break; case FUNC_TRANSMIT: string = "transmit"; break; case FUNC_FLOOR: string = "floor"; break; case FUNC_SUBSTRING: string = "substring"; break; default: complain( "Internal error." ); } printf( "std_function %s", string ); break; case INS_MATCH: string = new_string_readable( rule_sys->strings + info, NULL ); printf( "match %s", string ); free_mem( &string ); break; case INS_SET_VAR: printf( "set_var %d", info ); break; case INS_PLUS_VAR: printf( "plus_var %d", info ); break; case INS_MINUS_VAR: printf( "minus_var %d", info ); break; case INS_ASTERISK_VAR: printf( "asterisk_var %d", info ); break; case INS_SLASH_VAR: printf( "slash_var %d", info ); break; case INS_SET_VAR_PATH: printf( "set_var_path %d", info ); break; case INS_PLUS_VAR_PATH: printf( "plus_var_path %d", info ); break; case INS_MINUS_VAR_PATH: printf( "minus_var_path %d", info ); break; case INS_ASTERISK_VAR_PATH: printf( "asterisk_var_path %d", info ); break; case INS_SLASH_VAR_PATH: printf( "slash_var_path %d", info ); break; case INS_GET_1ST_ELEMENT: printf( "get_1st_element" ); break; case INS_ITERATE: printf( "iterate %d", info ); break; case INS_JUMP: printf( "jump %d", info ); break; case INS_JUMP_IF_EQUAL: printf( "jump_if_equal %d", info ); break; case INS_JUMP_IF_NOT_EQUAL: printf( "jump_if_not_equal %d", info ); break; case INS_JUMP_IF_CONGR: printf( "jump_if_congr %d", info ); break; case INS_JUMP_IF_NOT_CONGR: printf( "jump_if_not_congr %d", info ); break; case INS_JUMP_IF_IN: printf( "jump_if_in %d", info ); break; case INS_JUMP_IF_NOT_IN: printf( "jump_if_not_in %d", info ); break; case INS_JUMP_IF_LESS: printf( "jump_if_less %d", info ); break; case INS_JUMP_IF_NOT_LESS: printf( "jump_if_not_less %d", info ); break; case INS_JUMP_IF_GREATER: printf( "jump_if_greater %d", info ); break; case INS_JUMP_IF_NOT_GREATER: printf( "jump_if_not_greater %d", info ); break; case INS_JUMP_IF_NULL: printf( "jump_if_null %d", info ); break; case INS_JUMP_IF_NOT_NULL: printf( "jump_if_not_null %d", info ); break; case INS_JUMP_IF_YES: printf( "jump_if_yes %d", info ); break; case INS_JUMP_IF_NO: printf( "jump_if_no %d", info ); break; case INS_JUMP_NOW: printf( "jump_now %d", info ); break; case INS_JUMP_LATER: printf( "jump_later %d", info ); break; case INS_JUMP_SUBRULE: printf( "jump_subrule %s", rule_sys->strings + rule_sys->rules[ info ].name ); break; case INS_RETURN: printf( "return %d", info ); break; default: printf( "ILLEGAL INSTRUCTION %d", opcode ); break; } } /*---------------------------------------------------------------------------*/ static void print_rules( string_t source_name, rule_sys_t *rule_sys ) /* Print all rules of SOURCE_NAME. */ { string_t next_source_name; int_t instr, next_instr; int_t source_line, next_source_line; FILE *stream; int_t c; if (source_name != NULL) stream = open_stream( source_name, "r" ); else stream = NULL; source_line = 1; next_instr = next_source_line = 0; for (instr = 0; instr < rule_sys->instr_count; instr++) { if (stream != NULL) { if (instr >= next_instr) /* NEXT_INSTR has a new source location. */ { for (next_instr = instr; next_instr < rule_sys->instr_count; next_instr++) { source_of_instr( rule_sys, next_instr, &next_source_line, &next_source_name, NULL ); if (next_source_name != NULL && strcmp( name_in_path( next_source_name ), name_in_path( source_name ) ) == 0 && next_source_line > source_line) { break; } } } while (source_line < next_source_line) { c = getc( stream ); if (c == EOF) break; if (c == '\n') source_line++; putchar( c ); } } printf( "|%6d: ", instr ); print_instruction( instr, rule_sys ); printf( "\n" ); } if (stream != NULL) { /* Print remainder of source file. */ while ((c = getc( stream )) != EOF) putchar( c ); close_stream( &stream, source_name ); } } /* Top level functions. =====================================================*/ int main( int argc, char *argv[] ) /* The main function of "maldump". */ { rule_sys_t *rule_sys; string_t rule_file, symbol_file, source_file; int_t i; init_basic( "maldump" ); /* Parse arguments. */ if (argc == 2) { if (strcmp_no_case( argv[1], "--version" ) == 0 || strcmp_no_case( argv[1], "-version" ) == 0 || strcmp_no_case( argv[1], "-v" ) == 0) { program_message(); exit(0); } else if (strcmp_no_case( argv[1], "--help" ) == 0 || strcmp_no_case( argv[1], "-help" ) == 0 || strcmp_no_case( argv[1], "-h" ) == 0) { printf( "Dump a compiled rule file of a Malaga grammar.\n\n" "Usage:\n" "maldump SYM_FILE RULE_FILE " "-- Disassemble RULE_FILE on stdout.\n" "maldump -v[ersion] " "-- Print version information.\n" "maldump -h[elp] " "-- Print this help.\n\n" "SYM_FILE may end on \".sym\" or \".esym\".\n" "RULE_FILE may end on \".all\", \"mor\" or \"syn\".\n" "Option \"-s[ource] SOURCE_FILE\" gives " "a source file for RULE_FILE.\n" ); exit(0); } } rule_file = symbol_file = source_file = NULL; for (i = 1; i < argc; i++) { if (has_extension( argv[i], "all" ) || has_extension( argv[i], "mor" ) || has_extension( argv[i], "syn" )) { set_binary_file_name( &rule_file, argv[i] ); } else if (has_extension( argv[i], "sym" ) || has_extension( argv[i], "esym" )) { set_binary_file_name( &symbol_file, argv[i] ); } else if (strcmp_no_case( argv[i], "-source" ) == 0 || strcmp_no_case( argv[i], "-s" ) == 0) { if (argv[ ++i ] == NULL) complain( "Missing file name after \"-source\"." ); set_file_name( &source_file, argv[i] ); } else complain( "Illegal argument \"%s\".", argv[i] ); } if (rule_file == NULL) complain( "Missing rule file name." ); if (symbol_file == NULL) complain( "Missing symbol file name." ); init_values(); init_symbols( symbol_file ); rule_sys = read_rule_sys( rule_file ); init_hangul(); print_rules( source_file, rule_sys ); terminate_hangul(); free_rule_sys( &rule_sys ); terminate_symbols(); free_mem( &symbol_file ); free_mem( &rule_file ); free_mem( &source_file ); terminate_values(); terminate_patterns(); terminate_basic(); return 0; } /* End of file. =============================================================*/ malaga-7.12/mallex.10000644000175000017500000000662310506412033013552 0ustar bjoernbjoern.TH MALLEX 1 "26 September 2006" Malaga "Malaga quick reference" .SH NAME mallex \- generate a Malaga run-time lexicon .SH SYNOPSIS \fBmallex\fP [\fB-binary\fP|\fB-readable\fP|\fB-prelex\fP] \fIproject-file\fP .PP \fBmallex\fP [\fB-binary\fP|\fB-readable\fP|\fB-prelex\fP] \fIsymbol-file\fP \fIrule-file\fP [\fIlexicon-file\fP] [\fIprelex-file\fP] .SH DESCRIPTION Malaga is a development environment for natural-language grammars based on the Left-Associative Grammar formalism. Malaga grammars can be used for automatic morphological and/or syntactic analysis. .PP The program \fBmallex\fP generates a Malaga run-time lexicon by letting allomorph rules process a base-form lexicon. It can be started in \fIinteractive mode\fP to help find bugs in the base-form lexicon or in the allomorph rules. .PP \fBmallex\fP uses the following grammar components: .IP \fIsymbol-file\fP The \fIsymbol-file\fP has the suffix \fB.sym\fP and contains the symbols that are used in the lexicon and/or the allomorph rules. .IP \fIrule-file\fP The \fIrule-file\fP has the suffix \fB.all\fP and contains the allomorph rules used to create the runtime-lexicon. .IP \fIlexicon-file\fP The \fIlexicon-file\fP has the suffix \fB.lex\fP and contains the base-form lexicon entries that are used as input for the allomorph rules. .IP "\fIprelex-file\fP (optional)" The \fIprelex-file\fP has the suffix \fB.prelex\fP and contains precompiled allomorph entries, which have been created by a former run of \fBmallex\fP with the option \fB-prelex\fP. .PP You can give the names of the grammar components as command line arguments, in any order. Alternatively, you can describe these components in a \fIproject-file\fP and use the name of the project file as \fBmallex\fP' single command-line argument. A project file has the suffix \fB.pro\fP. .PP If no command line options are given, \fBmallex\fP runs in interactive mode, and you can enter commands. The \fIlexicon-file\fP and \fIprelex-file\fP are not used in interactive mode. If you are not sure about the name of a command, use the command \fBhelp\fP to get an overview of all \fBmallex\fP commands. .PP If you want to quit \fBmallex\fP, enter the command \fBquit\fP. .PP See \fBinfo Malaga\fP for details. .SH OPTIONS .IP "\fB-b\fP[\fBinary\fP]" Create the run time lexicon file from the base form lexicon file and the optional prelex file, and save it as a binary run-time lexicon, which can be used by \fBmalaga\fP. .IP "\fB-h\fP[\fBelp\fP]" Print a help text about \fBmallex\fP' command line arguments and exit. .IP "\fB-p\fP[\fBrelex\fP]" Create the run time lexicon, and save it as a binary \fIprelex-file\fP, which can be read in later by another \fBmallex\fP run. output stream. .IP "\fB-r\fP[\fBeadable\fP]" Create the run time lexicon but don't save it, but print its entries in human-readable form on the standard output stream. .IP "\fB-v\fP[\fBersion\fP]" Print \fBmallex\fP' version number and exit. .SH AUTHORS Malaga has been developed by Bjoern Beutel. Numerous other people distributed to it. This manpage was originally written for the Debian distribution by Antti-Juhani Kaijanaho. .SH SEE ALSO \fBmalaga\fP(1), \fBmalmake\fP(1), \fBmalrul\fP(1), \fBmalshow\fP(1), \fBmalsym\fP(1) .PP ``Malaga 7, User's and Programmer's Manual''. Available in Debian systems via \fBinfo Malaga\fP, and, if the malaga-doc package is installed, in various formats (DVI, Postscript, PDF, HTML) under \fI/usr/share/doc/malaga-doc/\fP. malaga-7.12/mallex.c0000644000175000017500000004755510701725076013660 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This program takes a lexicon file and compiles it to binary format. * It also includes an interactive allomorph rules debugger. */ /* Includes. ================================================================*/ #include #include #include #include #include #include #include #include "basic.h" #include "pools.h" #include "values.h" #include "symbols.h" #include "scanner.h" #include "rule_type.h" #include "rules.h" #include "files.h" #include "lex_compiler.h" #include "input.h" #include "commands.h" #include "commands_interactive.h" #include "options.h" #include "breakpoints.h" #include "debugger.h" #include "display.h" #include "transmit.h" #include "patterns.h" #include "hangul.h" /* Variables. ===============================================================*/ static string_t allo_format; /* Format of allomorph output. */ static bool_t lex_tree_to_output = FALSE; /* Indicates whether the lexicon tree can be printed. */ static string_t lexicon_file, rule_file, symbol_file, project_file; static string_t prelex_file; static string_t base_feat_string; /* Last base feature structure. */ /* Functions. ===============================================================*/ static void display_where( void ) /* Print the name of the current rule. */ { string_t file, rule; int_t line; source_of_instr( executed_rule_sys, pc, &line, &file, &rule ); printf( "At \"%s\", line %d, rule \"%s\".", name_in_path( file ), line, rule ); if (lex_entry_file_name != NULL) { printf( " (\"%s\", line %d)", name_in_path( lex_entry_file_name ), lex_entry_line_number ); } printf( "\n" ); if (in_emacs_malaga_mode) printf( "SHOW \"%s\":%d:0\n", file, line ); } /*---------------------------------------------------------------------------*/ static void read_lexicon_file_name( string_t *arguments ) { if (**arguments != EOS) { free_mem( &lexicon_file ); lexicon_file = parse_absolute_path( arguments, NULL ); } if (lexicon_file == NULL) complain( "Missing lexicon file name." ); } /*---------------------------------------------------------------------------*/ static void display_result( void ) /* Display result in the modes that have been switched on after analysis. */ { if (use_display) { start_display_process(); fprintf( display_stream, "allomorph\n" ); print_lex_buffer( display_stream, "%n %s {%f}" ); fprintf( display_stream, "end\n" ); fflush( display_stream ); } else print_lex_buffer( stdout, NULL ); } /*---------------------------------------------------------------------------*/ static void do_result( string_t arguments ) /* Show result of last allomorph generation. */ { parse_end( &arguments ); if (! lex_tree_to_output) complain( "No previous allomorph generation." ); display_result(); } static command_t result_command = { "result res", do_result, "Show result of last allomorph generation.\n" "Usage: result\n" }; /*---------------------------------------------------------------------------*/ static void do_read_constants( string_t arguments ) /* Read the constants in the lexicon with name on line ARGUMENTS. */ { assert_not_in_debug_mode(); read_lexicon_file_name( &arguments ); parse_end( &arguments ); read_lex_constants( lexicon_file ); } static command_t read_constants_command = { "read-constants", do_read_constants, "Read the constants from the definitions in a lexicon file.\n" "Usage: read-constants [LEXICON_FILE]\n" "If LEXICON_FILE is omitted, the previous lexicon file name is used.\n" "\"read-constants\" can't be used in debug mode.\n" }; /*---------------------------------------------------------------------------*/ static void do_ga_file( string_t arguments ) /* Generate allomorphs of a base lexicon. * Write the allomorphs readably into file. */ { string_t output_name; FILE *output_stream; assert_not_in_debug_mode(); output_stream = NULL; output_name = NULL; TRY { read_lexicon_file_name( &arguments ); if (*arguments != EOS) output_name = parse_absolute_path( &arguments, NULL ); parse_end( &arguments ); set_debug_mode( RUN_MODE, NULL ); lex_tree_to_output = FALSE; generate_allos_for_file( lexicon_file, NULL, TRUE ); lex_tree_to_output = TRUE; if (output_name != NULL) { output_stream = open_stream( output_name, "w" ); print_lex_buffer( output_stream, allo_format ); print_lex_statistics( stdout ); close_stream( &output_stream, output_name ); } } FINALLY { close_stream( &output_stream, NULL ); free_mem( &output_name ); } END_TRY; } static command_t ga_file_command = { "ga-file gaf", do_ga_file, "Generate allomorphs from the entries in a lexicon file.\n" "Usage: ga-file [LEXICON_FILE [ALLO_FILE]]\n" "If LEXICON_FILE is omitted, the previous lexicon file name is used.\n" "If ALLO_FILE is given, the results are written to \"ALLO_FILE\".\n" "The results can also be displayed by the command \"result\".\n" "\"ga-file\" can't be used in debug mode.\n" }; /*---------------------------------------------------------------------------*/ static void do_debug_ga_file( string_t arguments ) /* Generate allomorphs of the base lexicon with name in ARGUMENTS. * Execute rules in debug mode. */ { assert_not_in_debug_mode(); read_lexicon_file_name( &arguments ); parse_end( &arguments ); set_debug_mode( WALK_MODE, allo_rule_sys ); lex_tree_to_output = FALSE; generate_allos_for_file( lexicon_file, NULL, TRUE ); lex_tree_to_output = TRUE; } static command_t debug_ga_file_command = { "debug-ga-file dgaf", do_debug_ga_file, "Generate allomorphs from the entries in a lexicon file.\n" "Execute the rules in debug mode.\n" "Usage: debug-ga-file [LEXICON_FILE]\n" "If LEXICON_FILE is omitted, the previous lexicon file name is used.\n" "\"debug-ga-file\" can't be used in debug mode.\n" }; /*---------------------------------------------------------------------------*/ static void generate_allomorphs_for_line( string_t arguments ) /* Generate allomorphs for ARGUMENTS, which should consist * of a file name and a line number. */ { int_t line; line = parse_cardinal( &arguments ); read_lexicon_file_name( &arguments ); parse_end( &arguments ); lex_tree_to_output = FALSE; generate_allos_for_line( lexicon_file, line ); lex_tree_to_output = TRUE; } /*---------------------------------------------------------------------------*/ static void do_ga_line( string_t arguments ) /* Generate allomorphs for ARGUMENTS, which should consist * of a file name and a line number. */ { assert_not_in_debug_mode(); set_debug_mode( RUN_MODE, NULL ); generate_allomorphs_for_line( arguments ); display_result(); } static command_t ga_line_command = { "ga-line gal", do_ga_line, "Generate allomorphs from a single entry in a file.\n" "Usage: ga-line LINE [FILE]\n" "The first lexicon entry at or behind LINE in FILE is read in.\n" "If FILE is omitted, the previous file name is used.\n" "\"ga-line\" can't be used in debug mode.\n" }; /*---------------------------------------------------------------------------*/ static void do_debug_ga_line( string_t arguments ) /* Generate an allomorph for ARGUMENTS, which should consist * of a file name and a line number, in debugger mode. */ { assert_not_in_debug_mode(); set_debug_mode( WALK_MODE, allo_rule_sys ); generate_allomorphs_for_line( arguments ); } static command_t debug_ga_line_command = { "debug-ga-line dgal", do_debug_ga_line, "Generate allomorphs from a single entry in a file.\n" "Execute allomorph rules in debug mode.\n" "Usage: debug-ga-line LINE [FILE]\n" "The first lexicon entry at or behind LINE in FILE is read in.\n" "Allomorph rule execution stops at the first statement.\n" "If FILE is omitted, the previous file name is used.\n" "\"debug-line\" can't be used in debug mode.\n" }; /*---------------------------------------------------------------------------*/ static void generate_allomorphs( string_t arguments ) /* Generate allomorphs for lexicon entry ARGUMENTS. */ { /* If no argument given, re-analyze last argument */ if (*arguments == EOS) { if (base_feat_string == NULL) complain( "No previous base feature structure." ); } else { free_mem( &base_feat_string ); base_feat_string = new_string( arguments, NULL ); } lex_tree_to_output = FALSE; generate_allos_for_string( base_feat_string ); lex_tree_to_output = TRUE; } /*---------------------------------------------------------------------------*/ static void do_ga( string_t arguments ) /* Generate allomorphs for ARGUMENTS. */ { assert_not_in_debug_mode(); set_debug_mode( RUN_MODE, NULL ); generate_allomorphs( arguments ); display_result(); } static command_t ga_command = { "ga", do_ga, "Generate allomorphs from a feature structure argument.\n" "Usage:\n" " ga FEAT -- Generate allomorphs for feature structure FEAT.\n" " ga -- Re-generate allomorphs for the last argument.\n" "The allomorphs are shown on screen.\n" "\"ga\" can't be used in debug mode.\n" }; /*---------------------------------------------------------------------------*/ static void do_debug_ga( string_t arguments ) /* Generate allomorphs for ARGUMENTS. * Execute allomorph rules in debug mode. */ { assert_not_in_debug_mode(); set_debug_mode( WALK_MODE, allo_rule_sys ); generate_allomorphs( arguments ); } static command_t debug_ga_command = { "debug-ga dga ga-debug gad", do_debug_ga, "Generate allomorphs from the feature structure argument. " "Execute allomorph rules in debug mode.\n" "Usage:\n" " debug-ga FEAT -- Generate allomorphs for feature structure FEAT.\n" " debug-ga -- Re-generate allomorphs for the last argument.\n" "Rule execution stops at the first statement.\n" "The allomorphs are shown on screen.\n" "\"debug-ga\" can't be used in debug mode.\n" }; /*---------------------------------------------------------------------------*/ static void do_allo_format_option( string_t arguments ) /* Change allomorph output line to "arguments" */ { string_t format; if (*arguments == EOS) { format = new_string_readable( allo_format, NULL ); printf( "allo-format: %s\n", format ); free_mem( &format ); } else { format = parse_word( &arguments ); free_mem( &allo_format ); allo_format = format; } } static command_t allo_format_option = { "allo-format", do_allo_format_option, "Describe the format in which generated allomorphs will be printed.\n" "Usage: allo-format STRING\n" "STRING may contain the following special sequences:\n" " %f -- Allomorph feature structure.\n" " %n -- Allomorph number.\n" " %s -- Allomorph surface.\n" }; /* Commands. ================================================================*/ static command_t *mallex_options[] = { &alias_option, &allo_format_option, &auto_variables_option, &display_cmd_option, &hidden_option, &roman_hangul_option, &sort_records_option, &switch_option, &transmit_cmd_option, &use_display_option, NULL }; static command_t *mallex_commands[] = { &backtrace_command, &break_command, &continue_command, &debug_ga_command, &debug_ga_file_command, &debug_ga_line_command, &delete_command, &down_command, &finish_command, &frame_command, &ga_command, &ga_file_command, &ga_line_command, &get_command, &help_command, &list_command, &next_command, &print_command, &quit_command, &read_constants_command, &result_command, &run_command, &set_command, &step_command, &transmit_command, &up_command, &variables_command, &walk_command, &where_command, NULL }; /*---------------------------------------------------------------------------*/ static void read_project_file( string_t file_name ) /* Read the project file FILE_NAME. */ { FILE *project_stream; string_t include_file; string_t project_line_p, argument, extension; char_t *project_line; string_t *name_p; volatile bool_t binary = FALSE; volatile int_t line_count; static bool_t err_pos_printed; err_pos_printed = FALSE; project_stream = open_stream( file_name, "r" ); line_count = 0; while (TRUE) { TRY project_line = read_line( project_stream ); IF_ERROR { print_text( error_text, " (\"%s\", line %d)", name_in_path( file_name ), line_count + 1 ); err_pos_printed = TRUE; } END_TRY; if (project_line == NULL) break; line_count++; cut_comment( project_line ); project_line_p = project_line; if (*project_line_p != EOS) { argument = NULL; TRY { argument = parse_word( &project_line_p ); extension = NULL; name_p = NULL; if (strcmp_no_case( argument, "sym:" ) == 0) { name_p = &symbol_file; extension = "sym"; binary = TRUE; } else if (strcmp_no_case( argument, "lex:" ) == 0) { name_p = &lexicon_file; extension = "lex"; binary = FALSE; } else if (strcmp_no_case( argument, "all:" ) == 0) { name_p = &rule_file; extension = "all"; binary = TRUE; } else if (strcmp_no_case( argument, "prelex:" ) == 0) { if (prelex_file != NULL) complain( "Prelex file already defined." ); name_p = &prelex_file; extension = "prelex"; binary = TRUE; } else if (strcmp_no_case( argument, "include:" ) == 0) { include_file = parse_absolute_path( &project_line_p, file_name ); parse_end( &project_line_p ); read_project_file( include_file ); free_mem( &include_file ); } free_mem( &argument ); if (name_p != NULL && *name_p == NULL && *project_line_p != EOS) { argument = parse_absolute_path( &project_line_p, file_name ); if (! has_extension( argument, extension )) { complain( "\"%s\" should have extension \"%s\".", name_in_path( argument ), extension ); } if (binary) set_binary_file_name( name_p, argument ); else set_file_name( name_p, argument ); free_mem( &argument ); } } IF_ERROR { if (! err_pos_printed) { print_text( error_text, " (\"%s\", line %d)", name_in_path( file_name ), line_count ); err_pos_printed = TRUE; } } END_TRY; } free_mem( &project_line ); } close_stream( &project_stream, file_name ); } /*---------------------------------------------------------------------------*/ int main( int argc, char *argv[] ) /* The main function of "mallex". */ { volatile enum {INTERACTIVE_MODE, BINARY_MODE, TEXT_MODE, PRELEX_MODE} mallex_mode; int_t i; string_t malagarc_path, s; rule_sys_name_t rule_systems[1]; /* Rule system for debugger. */ string_t object_file = NULL; /* Object file for binary and prelex mode. */ mallex_mode = INTERACTIVE_MODE; init_basic( "mallex" ); init_input(); /* Parse arguments. */ if (argc == 2) { if (strcmp_no_case( argv[1], "--version" ) == 0 || strcmp_no_case( argv[1], "-version" ) == 0 || strcmp_no_case( argv[1], "-v" ) == 0) { program_message(); exit( 0 ); } else if (strcmp_no_case( argv[1], "--help" ) == 0 || strcmp_no_case( argv[1], "-help" ) == 0 || strcmp_no_case( argv[1], "-h" ) == 0) { printf( "Apply the allomorph rules on the entries of a Malaga lexicon.\n" "\n" "Usage:\n" "mallex GRAMMAR " "-- Start interactive mallex.\n" "mallex GRAMMAR -b[inary] " "-- Create binary allomorph lexicon.\n" "mallex GRAMMAR -r[eadable] " "-- Output readable allomorph lexicon.\n" "mallex GRAMMAR -p[relex] " "-- Output precompiled lexicon.\n" "mallex -v[ersion] " "-- Print version information.\n" "mallex -h[elp] " "-- Print this help.\n\n" "GRAMMAR may be \"PROJECT_FILE\" " "or \"SYM_FILE ALLO_FILE LEX_FILE [PRELEX_FILE]\".\n" "PROJECT_FILE must end on \".pro\".\n" "SYM_FILE must end on \".sym\".\n" "ALLO_FILE must end on \".all\".\n" "LEX_FILE must end on \".lex\".\n" "PRELEX_FILE must end on \".prelex\".\n" ); exit( 0 ); } } for (i = 1; i < argc; i++) { if (has_extension( argv[i], "pro" )) set_file_name( &project_file, argv[i] ); else if (has_extension( argv[i], "lex" )) set_file_name( &lexicon_file, argv[i] ); else if (has_extension( argv[i], "all" )) set_binary_file_name( &rule_file, argv[i] ); else if (has_extension( argv[i], "sym" )) set_binary_file_name( &symbol_file, argv[i] ); else if (has_extension( argv[i], "prelex") ) set_binary_file_name( &prelex_file, argv[i] ); else if (strcmp_no_case( argv[i], "-binary" ) == 0 || strcmp_no_case( argv[i], "-b" ) == 0) { mallex_mode = BINARY_MODE; } else if (strcmp_no_case( argv[i], "-readable" ) == 0 || strcmp_no_case( argv[i], "-r" ) == 0) { mallex_mode = TEXT_MODE; } else if (strcmp_no_case( argv[i], "-prelex" ) == 0 || strcmp_no_case( argv[i], "-p" ) == 0) { mallex_mode = PRELEX_MODE; } else complain( "Illegal argument \"%s\".", argv[i] ); } if (project_file != NULL) read_project_file( project_file ); if (rule_file == NULL) complain( "Missing allomorph rule file name." ); if (symbol_file == NULL) complain( "Missing symbol file name." ); /* Init modules. */ init_values(); init_symbols( symbol_file ); init_hangul(); init_transmit(); init_lex_compiler( rule_file ); init_scanner(); /* Set mallex options to default values. */ options = mallex_options; allo_format = new_string( "%s: %f", NULL ); use_display = FALSE; /* Set mallex options by user scripts. */ if (project_file != NULL) execute_set_commands( project_file, "mallex:" ); malagarc_path = NULL; #ifdef POSIX TRY malagarc_path = absolute_path( "~/.malagarc", NULL ); IF_ERROR RESUME; END_TRY; #endif #ifdef WIN32 TRY malagarc_path = absolute_path( "~\\malaga.ini", NULL ); IF_ERROR RESUME; END_TRY; #endif if (malagarc_path != NULL && file_exists( malagarc_path )) execute_set_commands( malagarc_path, "mallex:" ); free_mem( &malagarc_path ); if (mallex_mode == INTERACTIVE_MODE) { init_debugger( display_where, mallex_commands ); rule_systems[0].rule_sys = allo_rule_sys; rule_systems[0].name = "all"; init_breakpoints( 1, rule_systems ); program_message(); command_loop( program_name, mallex_commands ); terminate_breakpoints(); terminate_debugger(); } else { if (lexicon_file == NULL) complain( "missing lexicon file name" ); switch (mallex_mode) { case TEXT_MODE: generate_allos_for_file( lexicon_file, NULL, TRUE ); print_lex_buffer( stdout, allo_format ); break; case BINARY_MODE: generate_allos_for_file( lexicon_file, prelex_file, TRUE ); set_binary_file_name( &object_file, lexicon_file ); write_lex_buffer( object_file ); free_mem( &object_file ); break; case PRELEX_MODE: generate_allos_for_file( lexicon_file, prelex_file, FALSE ); s = replace_extension( lexicon_file, "prelex" ); set_binary_file_name( &object_file, s ); free_mem( &s ); write_prelex_file( object_file ); free_mem( &object_file ); break; default: complain( "Internal error." ); } print_lex_statistics( stderr ); } free_aliases(); free_mem( &base_feat_string ); free_mem( &allo_format ); stop_display_process(); terminate_lex_compiler(); terminate_hangul(); terminate_symbols(); terminate_transmit(); terminate_values(); terminate_scanner(); terminate_patterns(); free_switches(); free_mem( &rule_file ); free_mem( &symbol_file ); free_mem( &lexicon_file ); free_mem( &project_file ); terminate_input(); terminate_basic(); return 0; } /* End of file. =============================================================*/ malaga-7.12/malmake.10000644000175000017500000000313310506412060013670 0ustar bjoernbjoern.TH MALMAKE 1 "26 September 2006" Malaga "Malaga quick reference" .SH NAME malmake \- compile a Malaga project .SH SYNOPSIS \fBmalmake\fP [\fB-new\fP] \fIproject-file\fP .SH DESCRIPTION Malaga is a development environment for natural-language grammars based on the Left-Associative Grammar formalism. Malaga grammars can be used for automatic morphological and/or syntactic analysis. .PP The program \fBmalmake\fP reads a project file, checks if all grammar files needed do exist, and translates all grammar files that have not yet been translated or whose source files have changed since they have been translated. It calls the programs \fBmalsym\fP(1), \fBmallex\fP(1) and \fBmalrul\fP(1) if needed. It is in essence a \fBmake\fP(1) for the Malaga programming language. .PP See \fBinfo Malaga\fP for details. .SH OPTIONS .IP "\fB-h\fP[\fBelp\fP]" Print a help text about \fBmalmake\fP's command line arguments and exit. .IP "\fB-n\fP[\fBew\fP]" (Re)compile all files, even if their sources have not changed meanwhile. .IP "\fB-v\fP[\fBersion\fP]" Print \fBmalmake\fP's version number and exit. .SH AUTHORS Malaga has been developed by Bjoern Beutel. Numerous other people distributed to it. This manpage was originally written for the Debian distribution by Antti-Juhani Kaijanaho. .SH SEE ALSO \fBmalaga\fP(1), \fBmallex\fP(1), \fBmalrul\fP(1), \fBmalshow\fP(1), \fBmalsym\fP(1) .PP ``Malaga 7, User's and Programmer's Manual''. Available in Debian systems via \fBinfo Malaga\fP, and, if the malaga-doc package is installed, in various formats (DVI, Postscript, PDF, HTML) under \fI/usr/share/doc/malaga-doc/\fP. malaga-7.12/malmake.c0000644000175000017500000003360410701725657014000 0ustar bjoernbjoern/* Copyright (C) 1996 Bjoern Beutel. */ /* Description. =============================================================*/ /* This program reads a project file and compiles all symbol files, rule files, * and lexicon files that must be updated. */ /* Includes. ================================================================*/ #define _POSIX_SOURCE #include #include #include #include #include #include #include #include "basic.h" #include "files.h" #include "malaga_files.h" #include "input.h" #ifdef POSIX #include #include #include #include #endif #ifdef WIN32 #include #include #endif /* Types. ===================================================================*/ typedef struct /* A file name on which a malaga file depends. */ { list_node_t *next; /* Next dependency in this list. */ string_t name; /* File name of dependency. */ } dependency_t; typedef struct /* Source file names and object file name of a Malaga file. */ { list_t dependencies; string_t source_file; string_t object_file; } files_t; /* Variables. ===============================================================*/ /* The names of the files needed by Malaga. */ static files_t symbol_files; static files_t extended_symbol_files; static files_t lexicon_files; static files_t allomorph_files; static files_t morphology_files; static files_t syntax_files; static string_t prelex_file; /* Functions. ===============================================================*/ static void execute( string_t command_name, string_t arg1, string_t arg2, string_t arg3, string_t file_name ) /* Execute a process and wait for successful termination. */ { #ifdef POSIX pid_t pid; int status; if (file_name == NULL) file_name = arg1; fprintf( stderr, "Compiling \"%s\".\n", name_in_path( file_name ) ); switch (pid = fork()) { case -1: complain( "Can't execute \"%s\".", command_name ); break; case 0: execlp( command_name, command_name, arg1, arg2, arg3, NULL ); complain( "Can't execute \"%s\".", command_name ); break; default: waitpid( pid, &status, 0 ); if (! WIFEXITED( status ) || WEXITSTATUS( status ) != 0) complain( "Compilation failed." ); break; } #endif #ifdef WIN32 int status; string_t a1, a2, a3; a1 = (arg1 != NULL ? new_string_readable( arg1, NULL ) : NULL); a2 = (arg2 != NULL ? new_string_readable( arg2, NULL ) : NULL); a3 = (arg3 != NULL ? new_string_readable( arg3, NULL ) : NULL); if (file_name == NULL) file_name = arg1; fprintf( stderr, "Compiling \"%s\".\n", name_in_path( file_name ) ); status = _spawnlp( P_WAIT, command_name, command_name, a1, a2, a3, NULL ); if (status == -1) complain( "Can't execute \"%s\".", command_name ); if (status != 0) complain( "Compilation failed." ); free( a1 ); free( a2 ); free( a3 ); #endif } /*---------------------------------------------------------------------------*/ static void free_files( files_t *files ) /* Free the space occupied by FILES. */ { dependency_t *file; free_mem( &files->source_file ); free_mem( &files->object_file ); FOREACH_FREE( file, files->dependencies ) free_mem( &file->name ); } /*---------------------------------------------------------------------------*/ static void free_all_files( void ) /* Free the space occupied by the file names. */ { free_files( &syntax_files ); free_files( &morphology_files ); free_files( &lexicon_files ); free_files( &extended_symbol_files ); free_files( &symbol_files ); free_files( &allomorph_files ); } /*---------------------------------------------------------------------------*/ static time_t file_time( string_t file_name ) /* Get the last modification time of FILE_NAME. */ { struct stat status; /* Assume earliest possible time for non-existing files. */ if (stat( file_name, &status ) == 0) return status.st_mtime; else return 0; } /*---------------------------------------------------------------------------*/ static void read_project_file( string_t project_file ) /* Read the project file. */ { FILE *project_stream; string_t project_line_p, argument, extension; char_t *project_line; files_t *files; dependency_t *dependency; string_t s; volatile int_t line_count; static bool_t err_pos_printed; err_pos_printed = FALSE; project_stream = open_stream( project_file, "r" ); line_count = 0; while (TRUE) { project_line = read_line( project_stream ); if (project_line == NULL) break; line_count++; cut_comment( project_line ); project_line_p = project_line; if (*project_line_p != EOS) { argument = NULL; TRY { argument = parse_word( &project_line_p ); extension = NULL; files = NULL; if (strcmp_no_case( argument, "sym:" ) == 0) { extension = "sym"; files = &symbol_files; } else if (strcmp_no_case( argument, "esym:" ) == 0) { extension = "esym"; files = &extended_symbol_files; } else if (strcmp_no_case( argument, "all:" ) == 0) { extension = "all"; files = &allomorph_files; } else if (strcmp_no_case( argument, "lex:" ) == 0) { extension = "lex"; files = &lexicon_files; } else if (strcmp_no_case( argument, "mor:" ) == 0) { extension = "mor"; files = &morphology_files; } else if (strcmp_no_case( argument, "syn:" ) == 0) { extension = "syn"; files = &syntax_files; } else if (strcmp_no_case( argument, "prelex:" ) == 0) { s = parse_absolute_path( &project_line_p, project_file ); parse_end( &project_line_p ); if (! has_extension( s, "prelex" )) { complain( "\"%s\" should have extension \"prelex\".", name_in_path( s ) ); } set_binary_file_name( &prelex_file, s ); free_mem( &s ); } else if (strcmp_no_case( argument, "split-hangul-syllables:" ) == 0) { split_hangul_syllables = parse_yes_no( &project_line_p ); parse_end( &project_line_p ); } else if (strcmp_no_case( argument, "include:" ) == 0) { s = parse_absolute_path( &project_line_p, project_file ); parse_end( &project_line_p ); read_project_file( s ); free_mem( &s ); } free_mem( &argument ); if (files != NULL) { /* Read the files in the current line * and include them into the appropriate file_list. */ while (*project_line_p != EOS) { /* Read the next file name in the project file. */ argument = parse_absolute_path( &project_line_p, project_file ); /* Add file to dependency list . */ dependency = new_node( &files->dependencies, sizeof( dependency_t ), LIST_END ); dependency->name = argument; /* Set the object file if it's the first source file. */ if (files->source_file == NULL) { if (! has_extension( argument, extension )) { complain( "\"%s\" should have extension \"%s\".", name_in_path( argument ), extension ); } set_file_name( &files->source_file, argument ); set_binary_file_name( &files->object_file, argument ); if (! file_exists( files->source_file ) && ! file_exists( files->object_file )) { complain( "Files \"%s\" and \"%s\" do not exist.", name_in_path( files->source_file ), name_in_path( files->object_file ) ); } } else if (file_exists( files->source_file ) && ! file_exists( argument )) { /* The source file exists, but the include file doesn't. */ complain( "File \"%s\" does not exist.", name_in_path( argument ) ); } } } } IF_ERROR { if (! err_pos_printed) { print_text( error_text, " (\"%s\", line %d)", name_in_path( project_file ), line_count ); err_pos_printed = TRUE; } } END_TRY; } free_mem( &project_line ); } close_stream( &project_stream, project_file ); } /*---------------------------------------------------------------------------*/ static bool_t current_code_version( string_t file, string_t binary_file ) /* Return if FILE is compiled with the current code version. */ { FILE *stream; common_header_t header; bool_t up_to_date; int_t min_code_version, max_code_version; struct stat status; if (has_extension( file, "sym" ) || has_extension( file, "esym" )) { min_code_version = MIN_SYMBOL_CODE_VERSION; max_code_version = SYMBOL_CODE_VERSION; } else if (has_extension( file, "lex" )) { min_code_version = MIN_LEXICON_CODE_VERSION; max_code_version = LEXICON_CODE_VERSION; } else if (has_extension( file, "all" ) || has_extension( file, "mor" ) || has_extension( file, "syn" )) { min_code_version = MIN_RULE_CODE_VERSION; max_code_version = RULE_CODE_VERSION; } else complain( "Internal error." ); /* Assume earliest possible time for non-existing files. */ if (stat( binary_file, &status ) == -1) return FALSE; stream = open_stream( binary_file, "rb" ); read_vector( &header, sizeof( header ), 1, stream, binary_file ); up_to_date = (header.code_version >= min_code_version && header.code_version <= max_code_version && header.split_hangul_syllables == split_hangul_syllables); close_stream( &stream, binary_file ); return up_to_date; } /*---------------------------------------------------------------------------*/ static bool_t is_obsolete( files_t *files, ... ) /* Check if FILES->OBJECT_FILE is older than one of FILES * or one of the files given as optional arguments. */ { va_list arg; time_t object_time; dependency_t *dependency; string_t file_name; bool_t obsolete; if (! file_exists( files->source_file )) return FALSE; object_time = file_time( files->object_file ); obsolete = FALSE; FOREACH( dependency, files->dependencies ) { if (object_time < file_time( dependency->name )) obsolete = TRUE; } va_start( arg, files ); for (file_name = va_arg( arg, string_t ); file_name != NULL; file_name = va_arg( arg, string_t )) { if (object_time < file_time( file_name )) obsolete = TRUE; } va_end( arg ); if (! current_code_version( files->source_file, files->object_file )) obsolete = TRUE; return obsolete; } /*---------------------------------------------------------------------------*/ int main( int argc, char *argv[] ) /* The main function of "malmake". */ { string_t project_file; int_t i; bool_t recompile; init_basic( "malmake" ); init_input(); /* Parse arguments. */ if (argc == 2) { if (strcmp_no_case( argv[1], "--version" ) == 0 || strcmp_no_case( argv[1], "-version" ) == 0 || strcmp_no_case( argv[1], "-v" ) == 0) { program_message(); exit(0); } else if (strcmp_no_case( argv[1], "--help" ) == 0 || strcmp_no_case( argv[1], "-help" ) == 0 || strcmp_no_case( argv[1], "-h" ) == 0) { printf( "Compile all files of a Malaga grammar.\n\n" "Usage:\n" "malmake PROJECT_FILE " "-- Compile files in PROJECT_FILE if needed.\n" "malmake -v[ersion] " "-- Print version information.\n" "malmake -h[elp] " "-- Print this help.\n\n" "Option \"-n[ew]\" makes malmake recompile the whole project.\n" "PROJECT_FILE must end on \".pro\".\n" ); exit(0); } } project_file = NULL; recompile = FALSE; for (i = 1; i < argc; i++) { if (has_extension( argv[i], "pro" )) set_file_name( &project_file, argv[i] ); else if (strcmp_no_case( argv[i], "-new" ) == 0 || strcmp_no_case( argv[i], "-n" ) == 0) { recompile = TRUE; } else complain( "Illegal argument \"%s\".", argv[i] ); } if (project_file == NULL) complain( "Missing project file name." ); read_project_file( project_file ); /* Test dependencies and compile files. */ if (symbol_files.source_file == NULL) complain( "Missing symbol file names in project file." ); if (is_obsolete( &symbol_files, NULL ) || recompile) { execute( "malsym", symbol_files.source_file, (split_hangul_syllables ? "-split-hangul-syllables" : NULL), NULL, NULL ); } if (allomorph_files.source_file == NULL) complain( "Missing allomorph file names in project file." ); if (is_obsolete( &allomorph_files, symbol_files.object_file, NULL ) || recompile) { execute( "malrul", allomorph_files.source_file, symbol_files.source_file, NULL, NULL ); } if (lexicon_files.source_file == NULL) complain( "Missing lexicon file names in project file." ); if (is_obsolete( &lexicon_files, symbol_files.object_file, allomorph_files.object_file, prelex_file, NULL ) || recompile) { execute( "mallex", project_file, "-binary", NULL, lexicon_files.source_file ); } if (morphology_files.source_file != NULL && (is_obsolete( &morphology_files, symbol_files.object_file, NULL ) || recompile)) { execute( "malrul", morphology_files.source_file, symbol_files.source_file, NULL, NULL ); } if (extended_symbol_files.source_file != NULL) { if (is_obsolete( &extended_symbol_files, symbol_files.object_file, NULL ) || recompile) { execute( "malsym", extended_symbol_files.source_file, "-use", symbol_files.source_file, NULL ); } } else { extended_symbol_files.source_file = new_string( symbol_files.source_file, NULL ); extended_symbol_files.object_file = new_string( symbol_files.object_file, NULL ); } if (syntax_files.source_file != NULL && (is_obsolete( &syntax_files, extended_symbol_files.object_file, NULL ) || recompile)) { execute( "malrul", syntax_files.source_file, extended_symbol_files.source_file, NULL, NULL ); } fprintf( stderr, "\"%s\" is up to date.\n", name_in_path( project_file ) ); free_all_files(); free_mem( &project_file ); terminate_input(); terminate_basic(); return 0; } /* End of file. =============================================================*/ malaga-7.12/malrul.10000644000175000017500000000262110506412106013557 0ustar bjoernbjoern.TH MALRUL 1 "26 September 2006" Malaga "Malaga quick reference" .SH NAME malrul \- compile a Malaga rule file .SH SYNOPSIS \fBmalrul\fP \fIsymbol-file\fP \fIrule-file\fP .SH DESCRIPTION Malaga is a development environment for natural-language grammars based on the Left-Associative Grammar formalism. Malaga grammars can be used for automatic morphological and/or syntactic analysis. .PP The program \fBmalrul\fP compiles a Malaga rule file. Give it the rule file that is to be translated (suffix \fB.mor\fP, \fB.syn\fP or \fB.all\fP) and the associated symbol file (suffix \fB.sym\fP or \fB.esym\fP) as command-line arguments. The order of the arguments is arbitrary. .PP See \fBinfo Malaga\fP for details. .SH OPTIONS .IP "\fB-h\fP[\fBelp\fP]" Print a help text about \fBmalrul\fP's command line arguments and exit. .IP "\fB-v\fP[\fBersion\fP]" Print \fBmalrul\fP's version number and exit. .SH AUTHORS Malaga has been developed by Bjoern Beutel. Numerous other people distributed to it. This manpage was originally written for the Debian distribution by Antti-Juhani Kaijanaho. .SH SEE ALSO \fBmalaga\fP(1), \fBmallex\fP(1), \fBmalmake\fP(1), \fBmalshow\fP(1), \fBmalsym\fP(1) .PP ``Malaga 7, User's and Programmer's Manual''. Available in Debian systems via \fBinfo Malaga\fP, and, if the malaga-doc package is installed, in various formats (DVI, Postscript, PDF, HTML) under \fI/usr/share/doc/malaga-doc/\fP. malaga-7.12/malrul.c0000644000175000017500000000631210236624750013654 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This program takes a rule file and compiles it to an intermediate code * file. */ /* Includes. ================================================================*/ #include #include #include #include #include #include #include #include "basic.h" #include "pools.h" #include "values.h" #include "symbols.h" #include "scanner.h" #include "files.h" #include "rule_type.h" #include "rule_code.h" #include "rule_compiler.h" #include "patterns.h" #include "hangul.h" /* Functions. ===============================================================*/ int main( int argc, char *argv[] ) /* The main function of "malrul". */ { string_t rule_file, object_file, symbol_file; int_t file_type = 0, i; init_basic( "malrul" ); if (argc == 2) { if (strcmp_no_case( argv[1], "--version" ) == 0 || strcmp_no_case( argv[1], "-version" ) == 0 || strcmp_no_case( argv[1], "-v" ) == 0) { program_message(); exit(0); } else if (strcmp_no_case( argv[1], "--help" ) == 0 || strcmp_no_case( argv[1], "-help" ) == 0 || strcmp_no_case( argv[1], "-h" ) == 0) { printf( "Compile a rule file of a Malaga grammar.\n\n" "Usage:\n" "malrul SYM_FILE RULE_FILE " "-- Compile RULE_FILE using SYM_FILE.\n" "malrul -v[ersion] " "-- Print version information.\n" "malrul -h[elp] " "-- Print this help.\n\n" "SYM_FILE may end on \".sym\" or \".esym\".\n" "RULE_FILE may end on \".all\", \".mor\", or \".syn\".\n" ); exit(0); } } rule_file = object_file = symbol_file = NULL; for (i = 1; i < argc; i++) { if (has_extension( argv[i], "all" )) { set_file_name( &rule_file, argv[i] ); set_binary_file_name( &object_file, argv[i] ); file_type = ALLO_RULE_FILE; } else if (has_extension( argv[i], "mor" )) { set_file_name( &rule_file, argv[i] ); set_binary_file_name( &object_file, argv[i] ); file_type = MORPHO_RULE_FILE; } else if (has_extension( argv[i], "syn" )) { set_file_name( &rule_file, argv[i] ); set_binary_file_name( &object_file, argv[i] ); file_type = SYNTAX_RULE_FILE; } else if (has_extension( argv[i], "sym" )) set_binary_file_name( &symbol_file, argv[i] ); else if (has_extension( argv[i], "esym" )) set_binary_file_name( &symbol_file, argv[i] ); else complain( "Illegal argument \"%s\".", argv[i] ); } if (object_file == NULL) complain( "No file to compile." ); if (symbol_file == NULL) complain( "Missing symbol file name." ); init_values(); init_symbols( symbol_file ); init_hangul(); init_scanner(); compile_rule_file( rule_file, object_file, file_type ); terminate_hangul(); terminate_symbols(); terminate_values(); terminate_scanner(); terminate_patterns(); free_mem( &symbol_file ); free_mem( &object_file ); free_mem( &rule_file ); terminate_basic(); return 0; } /* End of file. =============================================================*/ malaga-7.12/malshow.10000644000175000017500000000247110506415307013746 0ustar bjoernbjoern.TH MALSHOW 1 "26 September 2006" Malaga "Malaga quick reference" .SH NAME malshow \- show Malaga's results and/or debugging state .SH SYNOPSIS \fBmalshow\fP .SH DESCRIPTION Malaga is a development environment for natural-language grammars based on the Left-Associative Grammar formalism. Malaga grammars can be used for automatic morphological and/or syntactic analysis. .PP The program \fBmalshow\fP is usually called by \fBmalaga\fP(1) or \fBmallex\fP(1). It's a GUI to display their results and/or debugging states. \fBmalshow\fP reads the data to display from standard input. .PP See \fBinfo Malaga\fP for details. .SH OPTIONS .IP "\fB-h\fP[\fBelp\fP]" Print a help text about \fBmalshow\fP's command line arguments and exit. .IP "\fB-v\fP[\fBersion\fP]" Print \fBmalshow\fP's version number and exit. .SH AUTHORS Malaga has been developed by Bjoern Beutel. Numerous other people distributed to it. This manpage was originally written for the Debian distribution by Antti-Juhani Kaijanaho. .SH SEE ALSO \fBmalaga\fP(1), \fBmallex\fP(1), \fBmalmake\fP(1), \fBmalrul\fP(1), \fBmalsym\fP(1) .PP ``Malaga 7, User's and Programmer's Manual''. Available in Debian systems via \fBinfo Malaga\fP, and, if the malaga-doc package is installed, in various formats (DVI, Postscript, PDF, HTML) under \fI/usr/share/doc/malaga-doc/\fP. malaga-7.12/malshow.c0000644000175000017500000002371710701725673014045 0ustar bjoernbjoern/* Copyright (C) 2002 Bjoern Beutel. */ /* Description. =============================================================*/ /* This is a GTK program that displays Malaga values. */ /* Includes. ================================================================*/ #define _POSIX_SOURCE #include #include #include #include #include #include #include #include #include "basic.h" #include "input.h" #include "scanner.h" #include "files.h" #include "canvas.h" #include "allomorphs.h" #include "expressions.h" #include "result.h" #include "tree.h" #include "variables.h" #ifdef POSIX #include #endif /* Variables. ===============================================================*/ #ifdef WIN32 static bool_t input_consumed; /* Set by consumer, reset by pipe thread. */ static GCond *input_consumed_cond; /* Signals that "input_consumed" is set. */ static GMutex *input_consumed_mutex; #endif /* Functions. ===============================================================*/ static void parse_font_size( string_t input, int_t *font_size ) { int_t size; size = parse_cardinal( &input ); parse_end( &input ); if (size != 8 && size != 10 && size != 12 && size != 14 && size != 18 && size != 24) { complain( "Illegal font size, valid sizes are 8, 10, 12, 14, 18, 24." ); } *font_size = size; } /*---------------------------------------------------------------------------*/ static int_t my_parse_int( string_t *input_p ) /* Parse an integer number in *INPUT_P, adjust *INPUT_P. * Parsing stops when the first non-digit is encountered. */ { int_t number; if (**input_p < '0' || **input_p > '9') complain( "Number expected." ); number = 0; while (**input_p >= '0' && **input_p <= '9') number = 10 * number + (*(*input_p)++ - '0'); return number; } /*---------------------------------------------------------------------------*/ static void parse_geometry( string_t input, rectangle_t *geometry ) { static char_t malformed[] = "Malformed geometry."; string_t arg, arg_p; arg_p = arg = parse_word( &input ); parse_end( &input ); if ((*arg_p < '0' || *arg_p > '9') && *arg_p != '+') complain( malformed ); if (*arg_p >= '0' && *arg_p <= '9') { /* Parse size. */ geometry->width = my_parse_int( &arg_p ); if (*arg_p != 'x') complain( malformed ); arg_p++; geometry->height = my_parse_int( &arg_p ); } if (*arg_p == '+') { /* Parse position. */ arg_p++; geometry->x = my_parse_int( &arg_p ); if (*arg_p != '+') complain( malformed ); arg_p++; geometry->y = my_parse_int( &arg_p ); } if (*arg_p != EOS) complain( malformed ); free_mem( &arg ); } /*---------------------------------------------------------------------------*/ static void read_profile( string_t file_name ) { FILE *stream; string_t line_p, argument, value; char_t *line; volatile int_t line_count; /* Initialise positions to be ignored. */ allomorphs_geometry.x = allomorphs_geometry.y = -1; expressions_geometry.x = expressions_geometry.y = -1; path_geometry.x = path_geometry.y = -1; result_geometry.x = result_geometry.y = -1; tree_geometry.x = tree_geometry.y = -1; variables_geometry.x = variables_geometry.y = -1; stream = open_stream( file_name, "r" ); line_count = 0; while (TRUE) { line = read_line( stream ); if (line == NULL) break; line_count++; cut_comment( line ); line_p = line; if (*line_p != EOS) { argument = NULL; TRY { argument = parse_word( &line_p ); if (strcmp_no_case( argument, "allomorphs_geometry:" ) == 0) parse_geometry( line_p, &allomorphs_geometry ); else if (strcmp_no_case( argument, "expressions_geometry:" ) == 0) parse_geometry( line_p, &expressions_geometry ); else if (strcmp_no_case( argument, "path_geometry:" ) == 0) parse_geometry( line_p, &path_geometry ); else if (strcmp_no_case( argument, "result_geometry:" ) == 0) parse_geometry( line_p, &result_geometry ); else if (strcmp_no_case( argument, "tree_geometry:" ) == 0) parse_geometry( line_p, &tree_geometry ); else if (strcmp_no_case( argument, "variables_geometry:" ) == 0) parse_geometry( line_p, &variables_geometry ); else if (strcmp_no_case( argument, "font_size:" ) == 0) parse_font_size( line_p, &font_size ); else if (strcmp_no_case( argument, "font:" ) == 0) { if (font_family != NULL) complain( "Font family already defined." ); font_family = parse_word( &line_p ); parse_end( &line_p ); } else if (strcmp_no_case( argument, "show_indexes:" ) == 0) { show_state_indexes = parse_yes_no( &line_p ); parse_end( &line_p ); } else if (strcmp_no_case( argument, "hanging_style:" ) == 0) { hanging_style = parse_yes_no( &line_p ); parse_end( &line_p ); } else if (strcmp_no_case( argument, "inline_path:" ) == 0) { inline_path = parse_yes_no( &line_p ); parse_end( &line_p ); } else if (strcmp_no_case( argument, "show_tree:" ) == 0) { value = parse_word( &line_p ); if (strcmp_no_case( value, "full" ) == 0) tree_mode = FULL_TREE; else if (strcmp_no_case( value, "no_dead_ends" ) == 0) tree_mode = NO_DEAD_ENDS; else if (strcmp_no_case( value, "result_paths" ) == 0) tree_mode = RESULT_PATHS; else complain( "\"full\", \"no_dead_ends\" or \"result_paths\" " "expected." ); free_mem( &value ); } } IF_ERROR { print_text( error_text, " (\"%s\", line %d)\n", name_in_path( file_name ), line_count ); } FINALLY free_mem( &argument ); END_TRY; } free_mem( &line ); } close_stream( &stream, file_name ); } /*---------------------------------------------------------------------------*/ static void read_input( string_t input_type ) /* Read and show INPUT_TYPE from STDIN. */ { if (strcmp_no_case( input_type, "allomorph" ) == 0) read_allomorphs(); else if (strcmp_no_case( input_type, "expressions" ) == 0) read_expressions(); else if (strcmp_no_case( input_type, "result" ) == 0) read_result(); else if (strcmp_no_case( input_type, "tree" ) == 0) read_tree(); else if (strcmp_no_case( input_type, "variables" ) == 0) read_variables(); } /*---------------------------------------------------------------------------*/ #ifdef POSIX static void read_on_condition( gpointer data, gint source, GdkInputCondition condition ) /* This is called by GDK whenever there is something to read. * It reads input from malaga and displays the appropriate canvas. */ { string_t input_type; input_type = read_line( stdin ); if (input_type == NULL) gtk_exit(0); read_input( input_type ); free_mem( &input_type ); } #endif /*---------------------------------------------------------------------------*/ #ifdef WIN32 static bool_t read_input_notify( string_t input_type ) /* Read INPUT_TYPE from stdin, display it, and notify waiting thread. */ { if (input_type == NULL) gtk_exit(0); read_input( input_type ); g_mutex_lock( input_consumed_mutex ); input_consumed = TRUE; g_cond_signal( input_consumed_cond ); g_mutex_unlock( input_consumed_mutex ); return FALSE; } #endif /*---------------------------------------------------------------------------*/ #ifdef WIN32 static void * input_thread( void *dummy ) /* Read one line from STDIN, inform main thread when new input has arrived. */ { string_t input_type; while (TRUE) { input_type = read_line( stdin ); g_idle_add( (GSourceFunc) read_input_notify, input_type ); g_mutex_lock( input_consumed_mutex ); while (! input_consumed) g_cond_wait( input_consumed_cond, input_consumed_mutex ); input_consumed = FALSE; g_mutex_unlock( input_consumed_mutex ); free_mem( &input_type ); } return NULL; } #endif /*---------------------------------------------------------------------------*/ int main( int argc, char *argv[] ) { string_t malagarc_path, input_type; init_basic( "malshow" ); init_input(); init_scanner(); if (argc == 2) { if (strcmp_no_case( argv[1], "--version" ) == 0 || strcmp_no_case( argv[1], "-version" ) == 0 || strcmp_no_case( argv[1], "-v" ) == 0) { program_message(); exit(0); } else if (strcmp_no_case( argv[1], "--help" ) == 0 || strcmp_no_case( argv[1], "-help" ) == 0 || strcmp_no_case( argv[1], "-h" ) == 0) { printf( "Display results of a Malaga process in a graphical format.\n\n" "Usage:\n" "malshow -- Display results from malaga.\n" "malshow -v[ersion] -- Print the version number.\n" "malshow -h[elp] -- Print this help.\n\n" "This program is usually started by malaga or mallex.\n" ); exit(0); } } gtk_init( &argc, &argv ); /* Read Malaga profile. */ malagarc_path = NULL; #ifdef POSIX TRY malagarc_path = absolute_path( "~/.malagarc", NULL ); IF_ERROR RESUME; END_TRY; #endif #ifdef WIN32 TRY malagarc_path = absolute_path( "~\\malaga.ini", NULL ); IF_ERROR RESUME; END_TRY; #endif if (malagarc_path != NULL && file_exists( malagarc_path )) read_profile( malagarc_path ); free_mem( &malagarc_path ); /* Determine font name. */ if (font_family == NULL) { #ifdef POSIX font_family = new_string( "Sans", NULL ); #endif #ifdef WIN32 font_family = new_string( "Arial", NULL ); #endif } /* Read first input. */ input_type = read_line( stdin ); read_input( input_type ); free_mem( &input_type ); /* Prepare to read again whenever there is new input. */ #ifdef POSIX gdk_input_add( STDIN_FILENO, GDK_INPUT_READ, read_on_condition, NULL ); #endif #ifdef WIN32 g_thread_init( NULL ); input_consumed_cond = g_cond_new(); input_consumed_mutex = g_mutex_new(); g_thread_create( input_thread, NULL, FALSE, NULL ); #endif gtk_main(); free_mem( &font_family ); terminate_scanner(); terminate_input(); terminate_basic(); return 0; } /* End of file. =============================================================*/ malaga-7.12/malsym.10000644000175000017500000000312510506412071013566 0ustar bjoernbjoern.TH MALSYM 1 "26 September 2006" Malaga "Malaga quick reference" .SH NAME malsym \- compile a Malaga symbol file .SH SYNOPSIS \fBmalsym\fP \fIsymbol-file\fP .PP \fBmalsym\fP \fIextended-symbol-file\fP \fB-use\fP \fIsymbol-file\fP .SH DESCRIPTION Malaga is a development environment for natural-language grammars based on the Left-Associative Grammar formalism. Malaga grammars can be used for automatic morphological and/or syntactic analysis. .PP The program \fBmalsym\fP compiles a Malaga symbol file. Give it the symbol file (suffix \fB.sym\fP or \fB.esym\fP) that is to be translated as argument. If an \fIextended-symbol-file\fP (suffix \fB.esym\fP) is to be compiled, you must add the option \fB-use\fP. .PP See \fBinfo Malaga\fP for details. .SH OPTIONS .IP "\fB-h\fP[\fBelp\fP]" Print a help text about \fBmalsym\fP's command line arguments and exit. .IP "\fB-u\fP[\fBse\fP] \fIsymbol-file\fP" Use the already compiled \fIsymbol-file\fP as the base symbol file when compiling an \fIextended symbol file\fP. .IP "\fB-v\fP[\fBersion\fP]" Print \fBmalsym\fP's version number and exit. .SH AUTHORS Malaga has been developed by Bjoern Beutel. Numerous other people distributed to it. This manpage was originally written for the Debian distribution by Antti-Juhani Kaijanaho. .SH SEE ALSO \fBmalaga\fP(1), \fBmallex\fP(1), \fBmalmake\fP(1), \fBmalrul\fP(1), \fBmalshow\fP(1) .PP ``Malaga 7, User's and Programmer's Manual''. Available in Debian systems via \fBinfo Malaga\fP, and, if the malaga-doc package is installed, in various formats (DVI, Postscript, PDF, HTML) under \fI/usr/share/doc/malaga-doc/\fP. malaga-7.12/malsym.c0000644000175000017500000000555110236624754013672 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This program takes a symbol file and compiles it to internal format. */ /* Includes. ================================================================*/ #include #include #include #include #include #include #include #include "basic.h" #include "pools.h" #include "values.h" #include "scanner.h" #include "files.h" #include "sym_compiler.h" /* Functions. ===============================================================*/ int main( int argc, char *argv[] ) /* The main function of "malsym". */ { string_t symbol_file, object_file, old_symbol_file; int_t i; init_basic( "malsym" ); if (argc == 2) { if (strcmp_no_case( argv[1], "--version" ) == 0 || strcmp_no_case( argv[1], "-version" ) == 0 || strcmp_no_case( argv[1], "-v" ) == 0) { program_message(); exit(0); } else if (strcmp_no_case( argv[1], "--help" ) == 0 || strcmp_no_case( argv[1], "-help" ) == 0 || strcmp_no_case( argv[1], "-h" ) == 0) { printf( "Compile a symbol file of a Malaga grammar.\n\n" "Usage:\n" "malsym SYM_FILE " "-- Compile SYM_FILE.\n" "malsym ESYM_FILE -u[se] SYM_FILE " "-- Compile ESYM_FILE using SYM_FILE.\n" "malsym -v[ersion] " "-- Print version information.\n" "malsym -h[elp] " "-- Print this help.\n\n" "SYM_FILE must end on \".sym\".\n" "ESYM_FILE must end on \".esym\".\n" "Option \"-split-hangul-syllables\" makes Malaga split Hangul " "syllables.\n" ); exit(0); } } symbol_file = object_file = old_symbol_file = NULL; for (i = 1; i < argc; i++) { if (has_extension( argv[i], "sym" ) || has_extension( argv[i], "esym" )) { set_file_name( &symbol_file, argv[i] ); set_binary_file_name( &object_file, argv[i] ); } else if (strcmp_no_case( argv[i], "-use" ) == 0 || strcmp_no_case( argv[i], "-u" ) == 0) { if (argv[ ++i ] == NULL) complain( "Missing file name after \"-use\"." ); set_binary_file_name( &old_symbol_file, argv[i] ); } else if (strcmp_no_case( argv[i], "-split-hangul-syllables" ) == 0) split_hangul_syllables = TRUE; else complain( "Illegal argument \"%s\".", argv[i] ); } if (object_file == NULL) complain( "Missing symbol file name." ); init_values(); init_scanner(); compile_symbol_file( symbol_file, object_file, old_symbol_file ); terminate_values(); terminate_scanner(); free_mem( &object_file ); free_mem( &symbol_file ); free_mem( &old_symbol_file ); terminate_basic(); return 0; } /* End of file. =============================================================*/ malaga-7.12/options.c0000644000175000017500000001666510435764257014077 0ustar bjoernbjoern/* Copyright (C) 1996 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module contains options that can be set by both malaga and mallex. */ /* Includes. ================================================================*/ #include #include #include #include #include #include "basic.h" #include "pools.h" #include "values.h" #include "symbols.h" #include "input.h" #include "commands.h" #include "rule_type.h" #include "rules.h" #include "value_parser.h" #include "hangul.h" #include "scanner.h" #include "options.h" /* Global variables. ========================================================*/ bool_t auto_variables; /* TRUE if variables are shown automatically */ bool_t use_display; /* TRUE if "variables" and "result" use the display process */ /* Commands. ================================================================*/ static void do_sort_records_option( string_t arguments ) /* Select the order in which attributes in a record are printed. */ { string_t argument; if (*arguments == EOS) { printf( "sort-records: %s\n", attribute_order == INTERNAL_ORDER ? "internal" : attribute_order == ALPHABETIC_ORDER ? "alphabetic" : attribute_order == DEFINITION_ORDER ? "definition" : "" ); } else { argument = parse_word( &arguments ); if (strcmp_no_case( argument, "internal" ) == 0) attribute_order = INTERNAL_ORDER; else if (strcmp_no_case( argument, "alphabetic" ) == 0) attribute_order = ALPHABETIC_ORDER; else if (strcmp_no_case( argument, "definition" ) == 0) attribute_order = DEFINITION_ORDER; else { complain( "\"internal\", \"alphabetic\" or \"definition\" expected, " "not \"%s\".", argument ); } free_mem( &argument ); } parse_end( &arguments ); } command_t sort_records_option = { "sort-records", do_sort_records_option, "Usage:\n" " set sort-records internal -- Print attributes in internal order.\n" " set sort-records alphabetic -- Print attributes in alphabetic order.\n" " set sort-records definition -- Print attributes in symbol-table order.\n" }; /*---------------------------------------------------------------------------*/ static void do_hidden_option( string_t arguments ) /* Hide specified attributes when printing values. */ { symbol_t *attribs; int_t i; string_t argument; if (*arguments == EOS) { /* Get list of hidden attributes, terminated by value SYMBOL_MAX. */ attribs = get_hidden_attributes(); printf( "hidden:" ); if (attribs[0] == SYMBOL_MAX) printf( " (none)" ); else { for (i = 0; attribs[i] != SYMBOL_MAX; i++) printf( " %s", get_symbol_name( attribs[i] ) ); } printf( "\n" ); free_mem( &attribs ); } else { while (*arguments != EOS) { argument = parse_word( &arguments ); if (strcmp_no_case( argument, "none" ) == 0) clear_hidden_attributes(); else if (*argument == '+') add_hidden_attribute( find_symbol( argument + 1 ) ); else if (*argument == '-') remove_hidden_attribute( find_symbol( argument + 1 ) ); else { complain( "\"+...\", \"-...\" or \"none\" expected, not \"%s\".", argument ); } free_mem( &argument ); } } } command_t hidden_option = { "hidden", do_hidden_option, "Set hidden attributes in feature structures.\n" "Usage: set hidden ARGUMENT...\n" "ARGUMENT may be:\n" " none -- Don't hide any attributes.\n" " +ATTRIBUTE -- Hide ATTRIBUTE.\n" " -ATTRIBUTE -- Don't hide ATTRIBUTE any longer.\n" }; /*---------------------------------------------------------------------------*/ static void do_roman_hangul_option( string_t arguments ) /* Switch for Latin Hangul transcription. */ { if (*arguments == EOS) printf( "roman-hangul: %s\n", (roman_hangul ? "yes" : "no") ); else roman_hangul = parse_yes_no( &arguments ); parse_end( &arguments ); } command_t roman_hangul_option = { "roman-hangul", do_roman_hangul_option, "This option only has an effect when the project file uses the option\n" "\"split-hangul-syllables: yes\".\n" "Usage:\n" " set roman-hangul yes -- Display output in romanised Hangul.\n" " set roman-hangul no -- Display output in Hangul syllables.\n" }; /*---------------------------------------------------------------------------*/ static void do_use_display_option( string_t arguments ) /* Determine whether output is shown using the Display process. */ { bool_t u; if (*arguments == EOS) printf( "use-display: %s\n", (use_display ? "yes" : "no") ); else { u = parse_yes_no( &arguments ); if (getenv("DISPLAY") != NULL) use_display = u; else if (in_command_loop) complain( "Environment variable DISPLAY is not set."); } parse_end( &arguments ); } command_t use_display_option = { "use-display", do_use_display_option, "Usage:\n" " set use-display yes -- Show output using display process.\n" " set use-display no -- Show output using malaga itself.\n" }; /*---------------------------------------------------------------------------*/ static void do_auto_variables_option( string_t arguments ) /* Determine if variables are displayed in debug mode. */ { if (*arguments == EOS) printf( "auto-variables: %s\n", (auto_variables ? "yes" : "no") ); else auto_variables = parse_yes_no( &arguments ); parse_end( &arguments ); } command_t auto_variables_option = { "auto-variables variables", do_auto_variables_option, "Usage:\n" " set auto-variables yes -- Show variables automatically in debug mode.\n" " set auto-variables no -- Don't show variables automatically.\n" }; /*---------------------------------------------------------------------------*/ static void do_switch_option( string_t arguments ) /* Set switches that can be read from Malaga rules. */ { symbol_t key; value_t value; string_t value_string, key_name; if (*arguments == EOS) { /* No switch name follows: list all switches. */ get_first_switch( &value, &key ); if (value == NULL) printf( "switch: (none defined)\n" ); else { do { key_name = get_symbol_name( key ); value_string = value_to_readable( value, FALSE, 11 + g_utf8_strlen( key_name, -1 ) ); printf( "switch \"%s\": %s\n", key_name, value_string ); free_mem( &value_string ); get_next_switch( &value, &key ); } while (value != NULL); } } else { /* A switch name follows: read it. */ key_name = parse_word( &arguments ); if (*arguments == EOS) { /* Print value of given switch. */ value = get_switch( find_symbol( key_name ) ); value_string = value_to_readable( value, FALSE, 11 + g_utf8_strlen( key_name, -1 ) ); printf( "switch \"%s\": %s\n", key_name, value_string ); free_mem( &value_string ); } else { /* A value follows: read it. */ set_scanner_input( arguments ); TRY { parse_a_value(); test_token( EOF ); } FINALLY set_scanner_input( NULL ); END_TRY; set_switch( find_symbol( key_name ), value_stack[ --top ] ); } free_mem( &key_name ); } } command_t switch_option = { "switch", do_switch_option, "Set a switch that can be read from Malaga rule files.\n" "Usage: set switch SWITCH VALUE\n" }; /* End of file. =============================================================*/ malaga-7.12/options.h0000644000175000017500000000224610236624754014066 0ustar bjoernbjoern/* Copyright (C) 1996 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module contains options that can be set by both malaga and mallex. */ /* Variables. ===============================================================*/ extern bool_t auto_variables; /* TRUE if variables are shown automatically. */ extern bool_t use_display; /* TRUE if "variables" and "result" use the display process. */ /* Commands. ================================================================*/ extern command_t sort_records_option; /* Select the order in which attributes in a record are printed. */ extern command_t hidden_option; /* Select which attributes to hide when printing values. */ extern command_t use_display_option; /* Determine if output is shown using Display process. */ extern command_t auto_variables_option; /* Determine if variables are shown automatically in debug mode. */ extern command_t switch_option; /* Set switches that can be read from Malaga rules. */ extern command_t roman_hangul_option; /* Select latin Hangul transcription. */ /* End of file. =============================================================*/ malaga-7.12/patterns.c0000644000175000017500000003336410236624754014233 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module contains function to compile and execute pattern matching * strings (regular expressions). */ /* Includes. ================================================================*/ #include #include #include #include #include #include "basic.h" #include "patterns.h" /* Constants. ===============================================================*/ #define SPECIAL_CHARS ".[]-^()*?+|\\" /* Characters with a special meaning. */ /* These are the instructions for matching a pattern. * * A pattern is a 0-terminated sequence of CHARs, defined as follows: * - P[] is the coded pattern string. * - PI is the current index into P[]. * - PS[] is the stack of indexes into P[], used for backtracking. * - T[] is the text to be examined. * - TI is the current index into T[]. * - TS[] is the stack of indexes into T[], used for backtracking. * - SI is the stack index, used for PIS[] and TIS[]. * - VB[I] and VE[I] store beginning and end, resp., for variable no. I. */ enum { /* code 0 is EOS */ PAT_JUMP = 1, /* PI += (byte_t) P[PI+1]; */ PAT_JUMP_NOW, /* SI++; PS[SI] = PI+2; TS[SI] = TI; PI += (byte_t) P[PI+1]; */ PAT_JUMP_LATER, /* SP++; PS[SI] = PI + (byte_t) P[PI]; TS[SI] = I; PI++; */ PAT_MATCH_ANY, /* if T[TI] != EOS then TI++; else fail; */ PAT_MATCH_CLASS, /* if (T[TI] in {P[ PI + 1 ],..,P[ PI + P[PI] ]}) * { TI++; PI += P[PI]+1; } else fail; */ PAT_MATCH_NOT_CLASS, /* if (T[TI] in {P[ PI + 1 ],..,P[ PI + P[PI] ]}) * fail; else { TI++; PI += P[PI]+1; } */ PAT_START_VAR_0, /* VB[0] = I; PI++; */ PAT_START_VAR_1, /* VB[1] = I; PI++; */ PAT_START_VAR_2, /* VB[2] = I; PI++; */ PAT_START_VAR_3, /* VB[3] = I; PI++; */ PAT_START_VAR_4, /* VB[4] = I; PI++; */ PAT_END_VAR_0, /* VE[0] = I; PI++; */ PAT_END_VAR_1, /* VE[1] = I; PI++; */ PAT_END_VAR_2, /* VE[2] = I; PI++; */ PAT_END_VAR_3, /* VE[3] = I; PI++; */ PAT_END_VAR_4, /* VE[4] = I; PI++; */ PAT_COUNT }; /* Types. ===================================================================*/ typedef struct {string_t string, pattern;} pattern_state_t; /* Global variables. ========================================================*/ string_t pattern_var[ PATTERN_VAR_MAX ]; /* Pattern variables. */ /* Variables. ===============================================================*/ static pattern_state_t *stack; /* Stack used for backtracking. */ static int_t stack_size; /* Forwards. ================================================================*/ static void compile_pattern_local( text_t *text, string_t *string_p, bool_t *may_be_empty ); /* Functions. ===============================================================*/ static bool_t is_pattern_char( string_t s ) { /* The following expression is true for each non-ASCII character. */ return ((*s == '\\' && s[1] != EOS && strchr( SPECIAL_CHARS, s[1] ) != NULL) || (ORD(*s) >= PAT_COUNT && strchr( SPECIAL_CHARS, *s ) == NULL)); } /*---------------------------------------------------------------------------*/ static gunichar pattern_char( string_t *string_p ) /* See if *STRING_P points to a valid char or to an escape sequence. * Return the character code. Show an error if not valid. */ { string_t s; gunichar c; s = *string_p; if (s[0] == '\\' && s[1] != EOS && strchr( SPECIAL_CHARS, s[1] ) != NULL) { c = s[1]; s += 2; } else if (ORD(*s) >= PAT_COUNT && strchr( SPECIAL_CHARS, s[0] ) == NULL) { c = g_unichar_tolower( g_utf8_get_char( s ) ); s = g_utf8_next_char( s ); } else if (s[0] == EOS) complain( "Unexpected end of pattern." ); else complain( "Invalid char \"%u\" in pattern.", g_utf8_get_char(s) ); *string_p = s; return c; } /*---------------------------------------------------------------------------*/ static char_t offset( int_t offs ) /* Return OFFS as a char. */ { /* See if OFFS can be stored in a char. */ if ((byte_t) offs != offs || offs == 0) complain( "Pattern too complex." ); return (byte_t) offs; } /*---------------------------------------------------------------------------*/ static void compile_char_class( text_t *text, string_t *string_p ) /* Compile a character class at *STRING_P. * Save the resulting pattern in TEXT. */ { string_t s; gunichar ca, ce, c; /* First char, last char and current char for ranges. */ int_t patch_index; s = *string_p; s++; if (*s == '^') { s++; add_char_to_text( text, PAT_MATCH_NOT_CLASS ); } else add_char_to_text( text, PAT_MATCH_CLASS ); patch_index = text->string_size; /* Read chars and ranges. */ do { if (*s == EOS) complain( "Missing \"]\" in pattern." ); ca = pattern_char( &s ); if (*s == '-') { s++; ce = pattern_char( &s ); if (ca > ce) complain( "Invalid range \"%u-%u\" in pattern.", ca, ce ); } else ce = ca; for (c = ca; c <= ce; c++) add_unichar_to_text( text, c ); } while (*s != ']'); *string_p = ++s; insert_char_in_text( text, offset( text->string_size - patch_index ), patch_index ); } /*---------------------------------------------------------------------------*/ static bool_t check_greedy( string_t *string_p ) { if (**string_p == '?') { (*string_p)++; return FALSE; } else return TRUE; } /*---------------------------------------------------------------------------*/ static void compile_atom( text_t *text, string_t *string_p, bool_t *may_be_empty ) /* Compile an atom at *STRING_P. * Save the resulting pattern in TEXT. * MAY_BE_EMPTY becomes TRUE iff the atom may match an empty string. */ { string_t s; int_t start, length; bool_t may_be_empty_local, greedy; s = *string_p; *may_be_empty = TRUE; while (TRUE) { may_be_empty_local = FALSE; start = text->string_size; if (*s == '[') compile_char_class( text, &s ); else if (*s == '.') { s++; add_char_to_text( text, PAT_MATCH_ANY ); } else if (*s == '(') { s++; compile_pattern_local( text, &s, &may_be_empty_local ); if (*s++ != ')') complain( "Missing \")\" in pattern." ); } else if (is_pattern_char( s )) add_unichar_to_text( text, pattern_char( &s ) ); else break; length = text->string_size - start; /* There may be a postfix operator. */ if (*s == '?') { s++; greedy = check_greedy( &s ); if (greedy) insert_char_in_text( text, PAT_JUMP_LATER, start ); else insert_char_in_text( text, PAT_JUMP_NOW, start ); insert_char_in_text( text, offset( 2 + length ), start + 1 ); } else if (*s == '*') { s++; if (may_be_empty_local) complain( "Pattern argument for \"*\" may match empty string." ); greedy = check_greedy( &s ); insert_char_in_text( text, PAT_JUMP, start ); insert_char_in_text( text, offset( 2 + length ), start + 1 ); if (greedy) add_char_to_text( text, PAT_JUMP_NOW ); else add_char_to_text( text, PAT_JUMP_LATER ); add_char_to_text( text, offset( -length ) ); } else if (*s == '+') { s++; if (may_be_empty_local) complain( "Pattern argument for \"+\" may match empty string."); greedy = check_greedy( &s ); if (greedy) add_char_to_text( text, PAT_JUMP_NOW ); else add_char_to_text( text, PAT_JUMP_LATER ); add_char_to_text( text, offset( -length ) ); *may_be_empty = FALSE; } else *may_be_empty &= may_be_empty_local; } *string_p = s; } /*---------------------------------------------------------------------------*/ static void compile_pattern_local (text_t *text, string_t *string_p, bool_t *may_be_empty) /* Convert STRING_P to a pattern to be used as input to "match_pattern". * If PATTERN_VAR_NO != -1, mark the pattern so the string matching this * pattern will be stored in PATTERN_VAR[ PATTERN_VAR_NO ]. * The result pattern must be freed after usage. */ { string_t s; int_t start, length; bool_t may_be_empty_local; s = *string_p; start = text->string_size; compile_atom( text, &s, may_be_empty ); length = text->string_size - start; while (*s == '|') { s++; /* Add jump from start of last alternative to start of this alternative. */ insert_char_in_text( text, PAT_JUMP_LATER, start++ ); insert_char_in_text( text, offset( length + 4 ), start++ ); /* Compile this alternative. */ start = text->string_size; compile_atom( text, &s, &may_be_empty_local ); length = text->string_size - start; *may_be_empty |= may_be_empty_local; /* Add jump from end of last alternative to end of this alternative. */ insert_char_in_text( text, PAT_JUMP, start++ ); if (*s == '|') insert_char_in_text( text, offset( length + 4 ), start++ ); else insert_char_in_text( text, offset( length + 2 ), start++ ); } *string_p = s; } /*---------------------------------------------------------------------------*/ string_t compile_pattern( string_t string, int_t pattern_var_no ) /* Convert STRING to a pattern to be used as input to "match_pattern". * If PATTERN_VAR_NO != -1, mark the pattern so the string matching this * pattern will be stored in PATTERN_VAR[ PATTERN_VAR_NO ]. * The result pattern must be freed after usage. */ { text_t *text; bool_t may_be_empty; text = new_text(); if (pattern_var_no != -1) add_char_to_text( text, PAT_START_VAR_0 + pattern_var_no ); compile_pattern_local( text, &string, &may_be_empty ); if (*string != EOS) complain( "Illegal char \"%u\" in pattern.", g_utf8_get_char( string ) ); if (pattern_var_no != -1) add_char_to_text( text, PAT_END_VAR_0 + pattern_var_no ); return text_to_string( &text ); } /*---------------------------------------------------------------------------*/ bool_t match_pattern( string_t string, string_t pattern ) /* Test whether STRING matches PATTERN (a string of chars compiled with * "compile_pattern") and set substrings in PATTERN_VAR. * The substrings can be freed after usage. */ { struct {string_t start; string_t end;} var[ PATTERN_VAR_MAX ]; int_t sp, i; bool_t found_mismatch; string_t index; gunichar c; sp = 0; found_mismatch = FALSE; /* Clear all variables. */ for (i = 0; i < PATTERN_VAR_MAX; i++) var[i].start = var[i].end = NULL; while (! found_mismatch) { switch (*pattern) { case EOS: if (*string == EOS) { for (i = 0; i < PATTERN_VAR_MAX; i++) { if (var[i].start != NULL && var[i].end != NULL) { free_mem( &pattern_var[i] ); pattern_var[i] = new_string( var[i].start, var[i].end ); } } return TRUE; } else found_mismatch = TRUE; break; case PAT_JUMP: pattern += (byte_t) pattern[1]; break; case PAT_JUMP_NOW: if (sp == stack_size) { stack_size = renew_vector( &stack, sizeof( pattern_state_t ), stack_size + 100 ); } stack[ sp ].string = string; stack[ sp ].pattern = pattern + 2; sp++; pattern += (byte_t) pattern[1]; break; case PAT_JUMP_LATER: if (sp == stack_size) { stack_size = renew_vector( &stack, sizeof( pattern_state_t ), stack_size + 100 ); } stack[ sp ].string = string; stack[ sp ].pattern = pattern + (byte_t) pattern[1]; sp++; pattern += 2; break; case PAT_MATCH_ANY: if (*string == EOS) found_mismatch = TRUE; else { pattern++; string = g_utf8_next_char( string ); } break; case PAT_MATCH_CLASS: if (*string == EOS) found_mismatch = TRUE; else { index = pattern + 2; c = g_unichar_tolower( g_utf8_get_char( string ) ); string = g_utf8_next_char( string ); pattern += (byte_t) pattern[1] + 2; while (index < pattern && c != g_utf8_get_char( index )) index = g_utf8_next_char( index ); if (index >= pattern) found_mismatch = TRUE; } break; case PAT_MATCH_NOT_CLASS: if (*string == EOS) found_mismatch = TRUE; else { index = pattern + 2; c = g_unichar_tolower( g_utf8_get_char( string ) ); string = g_utf8_next_char( string ); pattern += (byte_t) pattern[1] + 2; while (index < pattern && c != g_utf8_get_char( index )) index = g_utf8_next_char( index ); if (index < pattern) found_mismatch = TRUE; } break; case PAT_START_VAR_0: case PAT_START_VAR_1: case PAT_START_VAR_2: case PAT_START_VAR_3: case PAT_START_VAR_4: var[ *pattern++ - PAT_START_VAR_0 ].start = string; break; case PAT_END_VAR_0: case PAT_END_VAR_1: case PAT_END_VAR_2: case PAT_END_VAR_3: case PAT_END_VAR_4: var[ *pattern++ - PAT_END_VAR_0 ].end = string; break; default: if (*string == EOS) found_mismatch = TRUE; else { c = g_unichar_tolower( g_utf8_get_char( string ) ); string = g_utf8_next_char( string ); if (c != g_utf8_get_char( pattern )) found_mismatch = TRUE; else pattern = g_utf8_next_char( pattern ); } break; } /* If this path was not successful and there is another path, try it. */ if (found_mismatch && sp > 0) { sp--; string = stack[ sp ].string; pattern = stack[ sp ].pattern; found_mismatch = FALSE; } } return FALSE; } /*---------------------------------------------------------------------------*/ void terminate_patterns( void ) /* Terminate this module. */ { int_t i; for (i = 0; i < PATTERN_VAR_MAX; i++) free_mem( &pattern_var[i] ); free_mem( &stack ); stack_size = 0; } /* End of file. =============================================================*/ malaga-7.12/patterns.h0000644000175000017500000000254610236624754014236 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module contains function to compile and execute pattern matching * strings (regular expressions). */ /* Constants. ===============================================================*/ enum {PATTERN_VAR_MAX = 5}; /* Maximum number of pattern variables. */ /* Variables. ===============================================================*/ extern string_t pattern_var[ PATTERN_VAR_MAX ]; /* Pattern variables. */ /* Functions. ===============================================================*/ extern string_t compile_pattern( string_t string, int_t pattern_var_no ); /* Convert STRING to a pattern to be used as input to "match_pattern". * If PATTERN_VAR_NO != -1, mark the pattern so the string matching this * pattern will be stored in PATTERN_VAR[ PATTERN_VAR_NO ]. * The result pattern must be freed after usage. */ extern bool_t match_pattern( string_t string, string_t pattern ); /* Test whether STRING matches PATTERN (a string of chars compiled with * "compile_pattern") and set substring indices in PATTERN_VAR. * The substrings remain valid until "compile_pattern" is called again. */ extern void terminate_patterns( void ); /* Terminate this module. */ /* End of file. =============================================================*/ malaga-7.12/pools.c0000644000175000017500000001676410425344311013520 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module defines a new data type, "pool_t", for growing vectors of items * of an arbitrary type. * A pool is implemented as a linked list of chunks each of which is of fixed * size once allocated. Individual subvectors of items may be allocated at * once, and it is guaranteed that these subvectors are contiguous (like * arrays) .*/ /* Includes. ================================================================*/ #include #include #include #include #include #include "basic.h" #include "files.h" #include "pools.h" /* Constants. ===============================================================*/ enum {MIN_CHUNK_SIZE = 400}; /* The minimum size of the data area in a chunk. */ /* Macros. ==================================================================*/ #define CHUNK_DATA(chunk_p) ((u_byte_t *) ((chunk_p) + 1)) /* Use this macro to access the data in a chunk. */ /* Types. ===================================================================*/ typedef struct /* A block of memory that is part of a pool. */ { list_node_t *next; int_t chunk_size; /* The maximum number of items in this chunk. */ int_t item_count; /* The actual number of items in this chunk. */ /* For 64-bit pointers, we are 8-byte aligned here. * For 32-bit pointers, we are 4-byte aligned here. */ /* Items follow here. */ } chunk_t; /* The pool implementation type. * (Use "new_pool" before you use any other functions on a pool variable.) */ struct pool { int_t item_size; /* Size of the items that are stored in this pool. */ int_t item_count; /* The overall number of items stored in this pool. */ int_t chunk_size; /* The size of new chunks. */ list_t chunk_list; /* The chunks of this pool. */ }; /* Functions. ===============================================================*/ pool_t new_pool( int_t item_size ) /* Create a new pool that records items of size ITEM_SIZE. */ { pool_t pool; pool = new_mem( sizeof( struct pool ) ); pool->item_size = item_size; pool->item_count = 0; pool->chunk_size = MIN_CHUNK_SIZE / item_size; clear_list( &pool->chunk_list ); return pool; } /*---------------------------------------------------------------------------*/ void clear_pool( pool_t pool ) /* Clear POOL. Do not free any memory used by the pool. */ { /* Free all chunks of this pool. */ while (pool->chunk_list.first != NULL) free_first_node( &pool->chunk_list ); pool->item_count = 0; } /*---------------------------------------------------------------------------*/ void * pool_to_vector( pool_t pool ) /* Return pool as a C vector (contiguous memory). * The vector must be freed after use. */ { void *vector; u_byte_t *vector_p; /* Position where next chunk is to be copied. */ chunk_t *chunk; /* Collect all chunks in a new vector. */ vector = new_vector( pool->item_size, pool->item_count ); vector_p = (u_byte_t *) vector; FOREACH( chunk, pool->chunk_list ) { memcpy( vector_p, CHUNK_DATA( chunk ), pool->item_size * chunk->item_count ); vector_p += pool->item_size * chunk->item_count; } return vector; } /*---------------------------------------------------------------------------*/ void write_pool( pool_t pool, FILE *stream, string_t file_name ) /* Write POOL to STREAM. FILE_NAME is given for error messages. */ { chunk_t *chunk; /* Collect all chunks to the new vector. */ FOREACH( chunk, pool->chunk_list ) { write_vector( CHUNK_DATA( chunk ), pool->item_size, chunk->item_count, stream, file_name ); } } /*---------------------------------------------------------------------------*/ void * get_pool_space( pool_t pool, int_t item_count, int_t *index ) /* Get space for ITEM_COUNT contiguous items in POOL. * Return its address as the function's result. * Return its index in *INDEX, if INDEX != NULL. */ { void *new_p; /* Pointer to the pool space. */ chunk_t *chunk; /* Address of a chunk pointer. */ /* Check if there is enough space in the last chunk. */ chunk = (chunk_t *) pool->chunk_list.last; if (chunk == NULL || chunk->item_count + item_count > chunk->chunk_size) { if (pool->chunk_size < item_count) pool->chunk_size = item_count; chunk = new_node( &pool->chunk_list, sizeof( chunk_t ) + pool->item_size * pool->chunk_size, LIST_END ); chunk->chunk_size = pool->chunk_size; chunk->item_count = 0; } /* Remember address and index of current position in pool. */ new_p = (void *) (CHUNK_DATA( chunk ) + pool->item_size * chunk->item_count); if (index != NULL) *index = pool->item_count; /* Adjust indices. */ chunk->item_count += item_count; pool->item_count += item_count; return new_p; } /*---------------------------------------------------------------------------*/ int_t pool_item_count( pool_t pool ) /* Return the number of the items in POOL. */ { return pool->item_count; } /*---------------------------------------------------------------------------*/ void * pool_item( pool_t pool, int_t index ) /* Return the address of item with INDEX in pool POOL, * or NULL if there is no such item. */ { chunk_t *chunk; if (index < 0 || index >= pool->item_count) return NULL; /* Find the right chunk. */ chunk = (chunk_t *) pool->chunk_list.first; while (index >= chunk->item_count) { index -= chunk->item_count; chunk = (chunk_t *) chunk->next; } /* Return the address of the item. */ return CHUNK_DATA( chunk ) + pool->item_size * index; } /*---------------------------------------------------------------------------*/ int_t pool_index( pool_t pool, const void *item ) /* Return the index of ITEM in POOL. * Report an error if ITEM doesn't exist in POOL. */ { int_t index; chunk_t *chunk; const u_byte_t *item_i; item_i = (const u_byte_t *) item; index = 0; FOREACH( chunk, pool->chunk_list ) { if (item_i >= CHUNK_DATA( chunk ) && item_i < CHUNK_DATA( chunk ) + pool->item_size * chunk->item_count) { return index + (item_i - CHUNK_DATA( chunk )) / pool->item_size; } else index += chunk->item_count; } complain( "Internal error." ); } /*---------------------------------------------------------------------------*/ void * copy_to_pool( pool_t pool, const void *address, int_t item_count, int_t *index ) /* Copy the vector *ADDRESS which contains ITEM_COUNT items into POOL. * The items of *ADDRESS must have the same size as the items in POOL. * Return the address of the copy as the function's result. * Return the index in *INDEX, if INDEX != NULL. */ { void *new_address = get_pool_space( pool, item_count, index ); memcpy( new_address, address, pool->item_size * item_count ); return new_address; } /*---------------------------------------------------------------------------*/ string_t copy_string_to_pool( pool_t pool, string_t string, int_t *index ) /* Copy STRING into POOL, which must be a *string* pool. * Return the copy of the string as the function's result. * Return its index in *INDEX, if INDEX != NULL. */ { return (string_t) copy_to_pool( pool, string, strlen( string ) + 1, index ); } /*---------------------------------------------------------------------------*/ void free_pool( pool_t *pool ) /* Free all memory used by *POOL. */ { if (*pool == NULL) return; clear_pool( *pool ); free_mem( pool ); } /* End of file. =============================================================*/ malaga-7.12/pools.h0000644000175000017500000000456610425343770013532 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module defines a new data type, "pool_t", for growing vectors of items * of an arbitrary type. */ /* Types. ===================================================================*/ typedef struct pool *pool_t; /* The abstract data type. */ /* Functions. ===============================================================*/ extern pool_t new_pool( int_t item_size ); /* Create a new pool that records items of size ITEM_SIZE. */ extern void free_pool( pool_t *pool ); /* Free all memory used by *POOL. */ extern void clear_pool( pool_t pool ); /* Clear POOL. */ extern void *pool_to_vector( pool_t pool ); /* Return POOL as a C vector (contiguous memory). * The vector must be freed after use. */ extern void write_pool( pool_t pool, FILE *stream, string_t file_name ); /* Write POOL to STREAM. FILE_NAME is needed for error messages. */ extern void *get_pool_space( pool_t pool, int_t item_count, int_t *index ); /* Get space for ITEM_COUNT contiguous items in POOL. * Return its address as the function's result. * Return its index in *INDEX, if INDEX != NULL. */ extern int_t pool_item_count( pool_t pool ); /* Return the number of the items in POOL. */ extern void *pool_item( pool_t pool, int_t index ); /* Return the address of item with INDEX in pool POOL, * or NULL if there is no such item. */ extern int_t pool_index( pool_t pool, const void *item ); /* Return the index of ITEM in POOL. * Report an error if ITEM doesn't exist in POOL. */ extern void *copy_to_pool( pool_t pool, const void *address, int_t item_count, int_t *index ); /* Copy the vector *ADDRESS with ITEM_COUNT items into POOL. * The items of *ADDRESS must be of same size as the items in POOL. * Return the address of the copy as the function's result. * Return the index in *INDEX, if INDEX != NULL. */ extern string_t copy_string_to_pool( pool_t pool, string_t string, int_t *index ); /* Copy STRING into POOL, which must be a *string* pool. * Return the copy of the string as the function's result. * Return its index in *INDEX, if INDEX != NULL. */ /* End of file. =============================================================*/ malaga-7.12/processes.c0000644000175000017500000001774410701725700014373 0ustar bjoernbjoern/* Copyright (C) 2005 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module manages child processes with optional input and/or output * pipes. */ /* Includes. ================================================================*/ #define _POSIX_SOURCE #include #include #include #include #include #include #include "basic.h" #include "files.h" #include "input.h" #include "processes.h" #ifdef POSIX #include #include #include #include #include #include #endif #ifdef WIN32 #include #include #include #endif /* Functions. ===============================================================*/ bool_t start_process( process_t *process ) /* Check whether PROCESS is still running. If not, start PROCESS anew by * executing PROCESS->COMMAND_LINE. * The fields PROCESS->USE_INPUT, PROCESS->USE_OUTPUT, PROCESS->NAME and * PROCESS->COMMAND_LINE must have been set. * If PROCESS->USE_INPUT == TRUE, open a pipe from the child process to the * parent process. Connect it to stdout in the child process and to * INPUT_STREAM in the parent process. * If PROCESS->USE_OUTPUT == TRUE, open a pipe from the parent process to the * child process. Connect it to OUTPUT_STREAM in the parent process and to * stdin in the child process. * Return TRUE if process has actually been started now. */ { #ifdef POSIX int to_child_fd[2]; int from_child_fd[2]; string_t arguments, argument; string_t *args; int_t arg_count, i; if (process->id != 0) { if (waitpid( (pid_t) process->id, NULL, WNOHANG ) == 0) return FALSE; process->id = 0; close_stream( &process->input_stream, NULL ); close_stream( &process->output_stream, NULL ); } if (process->command_line == NULL) complain( "Missing %s command line.", process->name ); if (process->use_output && pipe( to_child_fd ) == -1) { complain( "Can't create pipe to %s: %s.", process->name, strerror( errno ) ); } if (process->use_input && pipe( from_child_fd ) == -1) { complain( "Can't create pipe from %s: %s.", process->name, strerror( errno ) ); } signal( SIGPIPE, SIG_IGN ); switch (process->id = (ptr_t) fork()) { case -1: complain( "Can't create %s: %s.", process->name, strerror( errno ) ); break; case 0: if (process->use_output) { dup2( to_child_fd[0], STDIN_FILENO ); close( to_child_fd[0] ); close( to_child_fd[1] ); } if (process->use_input) { dup2( from_child_fd[1], STDOUT_FILENO ); close( from_child_fd[0] ); close( from_child_fd[1] ); } signal( SIGINT, SIG_IGN ); /* Count arguments. */ arg_count = 0; arguments = process->command_line; while (*arguments != EOS) { argument = parse_word( &arguments ); free_mem( &argument ); arg_count++; } /* Create argument vector. */ args = new_vector( sizeof( string_t ), arg_count + 1 ); arguments = process->command_line; for (i = 0; i < arg_count; i++) args[i] = parse_word( &arguments ); args[i] = NULL; /* Execute command line. */ execvp( args[0], (char **) args ); fprintf( stderr, "Can't start %s \"%s\": %s.\n", process->name, args[0], strerror( errno ) ); exit(1); default: if (process->use_output) { close( to_child_fd[0] ); process->output_stream = fdopen( to_child_fd[1], "w" ); if (process->output_stream == NULL) { complain( "Can't open pipe to %s: %s.", process->name, strerror( errno ) ); } } if (process->use_input) { close( from_child_fd[1] ); process->input_stream = fdopen( from_child_fd[0], "r" ); if (process->input_stream == NULL) { complain( "Can't open pipe from %s: %s.", process->name, strerror( errno ) ); } } } return TRUE; #endif #ifdef WIN32 HANDLE parent_read, parent_write, parent_read_local, parent_write_local; HANDLE child_read, child_write, old_stdin, old_stdout; SECURITY_ATTRIBUTES security; STARTUPINFO startup_info; PROCESS_INFORMATION process_info; DWORD status; int fd; /* Check if the process is still running. */ if (process->id != 0) { if (GetExitCodeProcess( (HANDLE) process->id, &status ) && status == STILL_ACTIVE) { return FALSE; } CloseHandle( (HANDLE) process->id ); process->id = 0; close_stream( &process->input_stream, NULL ); close_stream( &process->output_stream, NULL ); } /* Check command line. */ if (process->command_line == NULL) complain( "Missing transmit command line." ); /* We need pipes with inherited handles. */ security.nLength = sizeof( SECURITY_ATTRIBUTES ); security.bInheritHandle = TRUE; security.lpSecurityDescriptor = NULL; /* Create a pipe from the parent to the child. */ if (process->use_output) { if (! CreatePipe( &child_read, &parent_write, &security, 0 )) complain( "Can't create pipe to %s.", process->name ); /* Change STDIN for the child process. */ old_stdin = GetStdHandle( STD_INPUT_HANDLE ); SetStdHandle( STD_INPUT_HANDLE, child_read ); /* Make sure the parent's handle is not inherited. */ DuplicateHandle( GetCurrentProcess(), parent_write, GetCurrentProcess(), &parent_write_local, 0, FALSE, DUPLICATE_SAME_ACCESS ); CloseHandle( parent_write ); } /* Create a pipe from the child to the parent. */ if (process->use_input) { if (! CreatePipe( &parent_read, &child_write, &security, 0 )) complain( "Can't create pipe from %s.", process->name ); /* Change STDOUT for the child process. */ old_stdout = GetStdHandle( STD_OUTPUT_HANDLE ); SetStdHandle( STD_OUTPUT_HANDLE, child_write ); /* Make sure the parent's handle is not inherited. */ DuplicateHandle( GetCurrentProcess(), parent_read, GetCurrentProcess(), &parent_read_local, 0, FALSE, DUPLICATE_SAME_ACCESS ); CloseHandle( parent_read ); } /* Start the process as child. */ ZeroMemory( &startup_info, sizeof( startup_info ) ); startup_info.cb = sizeof( startup_info ); if (! CreateProcess( NULL, process->command_line, NULL, NULL, TRUE, CREATE_NEW_PROCESS_GROUP, NULL, NULL, &startup_info, &process_info )) { complain( "Can't create %s.", process->name ); } process->id = (ptr_t) process_info.hProcess; CloseHandle( process_info.hThread ); if (process->use_output) { /* Reset stdin for parent. */ SetStdHandle( STD_INPUT_HANDLE, old_stdin ); CloseHandle( child_read ); /* Open stream to write to. */ fd = _open_osfhandle( (long) parent_write_local, O_TEXT ); process->output_stream = _fdopen( fd, "w" ); if (process->output_stream == NULL) { complain( "Can't open pipe to %s: %s.", process->name, strerror( errno ) ); } } if (process->use_input) { /* Reset stdout for parent. */ SetStdHandle( STD_OUTPUT_HANDLE, old_stdout ); CloseHandle( child_write ); /* Open stream to read from. */ fd = _open_osfhandle( (long) parent_read_local, O_TEXT ); process->input_stream = _fdopen( fd, "r" ); if (process->input_stream == NULL) { complain( "Can't open pipe from %s: %s.", process->name, strerror( errno ) ); } } return TRUE; #endif } /*---------------------------------------------------------------------------*/ void stop_process( process_t *process ) /* Stop the Malaga PROCESS. */ { close_stream( &process->input_stream, NULL ); close_stream( &process->output_stream, NULL ); free_mem( &process->command_line ); if (process->id != 0) { #ifdef POSIX kill( (pid_t) process->id, SIGTERM ); waitpid( (pid_t) process->id, NULL, 0 ); #endif #ifdef WIN32 TerminateProcess( (HANDLE) process->id, 0 ); CloseHandle( (HANDLE) process->id ); #endif process->id = 0; } } /* End of file. =============================================================*/ malaga-7.12/processes.h0000644000175000017500000000365210236625535014401 0ustar bjoernbjoern/* Copyright (C) 2005 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module manages child processes with optional input and/or output * pipes. */ /* Types. ===================================================================*/ /* The description of a Malaga child process. */ typedef struct { bool_t use_input; /* If TRUE, open a pipe from the child process to the * parent process. Connect it to stdout in the child * process and to INPUT_STREAM in the parent process. */ FILE *input_stream; bool_t use_output; /* If TRUE, open a pipe from the parent process to the * child process. Connect it to OUTPUT_STREAM in the * parent process and to stdin in the child process. */ FILE *output_stream; string_t name; /* Child process name, e.g. "display process". */ string_t command_line; /* Command line that is executed when the child * process is started. */ ptr_t id; /* OS-dependent child process id. */ } process_t; /* Functions. ===============================================================*/ bool_t start_process( process_t *process ); /* Check whether PROCESS is still running. If not, start PROCESS anew by * executing PROCESS->COMMAND_LINE. * The fields PROCESS->USE_INPUT, PROCESS->USE_OUTPUT, PROCESS->NAME and * PROCESS->COMMAND_LINE must have been set. * If PROCESS->USE_INPUT == TRUE, open a pipe from the child process to the * parent process. Connect it to stdout in the child process and to * INPUT_STREAM in the parent process. * If PROCESS->USE_OUTPUT == TRUE, open a pipe from the parent process to the * child process. Connect it to OUTPUT_STREAM in the parent process and to * stdin in the child process. * Return TRUE if process has actually been started now. */ void stop_process( process_t *process ); /* Stop the Malaga PROCESS. */ /* End of file. =============================================================*/ malaga-7.12/result.c0000644000175000017500000001100110236624453013665 0ustar bjoernbjoern/* Copyright (C) 2002 Bjoern Beutel. */ /* Description. =============================================================*/ /* Read in and display Malaga Results. */ /* Includes. ================================================================*/ #include #include #include #include #include #include #include "basic.h" #include "scanner.h" #include "input.h" #include "canvas.h" #include "result.h" /* Types. ===================================================================*/ typedef struct { list_node_t *next; pos_string_t *index; pos_value_t *value; } result_t; /* Global variables. ========================================================*/ rectangle_t result_geometry; string_t result_font_family; int_t result_font_size; /* Variables. ===============================================================*/ static pos_string_t *result_surf; static list_t results; static canvas_t *result_canvas; static pos_string_t *colon; /* Functions. ===============================================================*/ static void configure_result( canvas_t *canvas, int_t *width_p, int_t *height_p ) { int_t width, height; result_t *result; int_t font_height = get_font_height( canvas ); int_t space_width = get_space_width( canvas ); int_t border_width = get_border_width( canvas ); config_pos_string( colon, canvas ); height = border_width; width = border_width; if (result_surf != NULL) { config_pos_string( result_surf, canvas ); result_surf->x = border_width; result_surf->y = border_width; width = MAX( width, border_width + result_surf->width ); height += result_surf->height; } FOREACH( result, results ) { height += font_height; config_pos_string( result->index, canvas ); result->index->x = border_width; result->index->y = height; config_pos_value( result->value, canvas ); result->value->x = (result->index->x + result->index->width + colon->width + space_width); result->value->y = height; width = MAX( width, result->value->x + result->value->width ); height += result->value->height; result->index->y += (result->value->height - font_height) / 2; } *width_p = width + border_width; *height_p = height + border_width; } /*---------------------------------------------------------------------------*/ static void expose_result( canvas_t *canvas, rectangle_t *area ) { result_t *result; set_color( BLACK ); if (result_surf != NULL) draw_pos_string( result_surf, canvas ); FOREACH( result, results ) { colon->x = result->index->x + result->index->width; colon->y = result->index->y; draw_pos_string( result->index, canvas ); draw_pos_string( colon, canvas ); draw_pos_value( result->value, canvas ); } } /*---------------------------------------------------------------------------*/ static void free_result( canvas_t *canvas ) { result_t *result; free_pos_string( &colon ); free_pos_string( &result_surf ); FOREACH_FREE( result, results ) { free_pos_string( &result->index ); free_pos_value( &result->value ); } } /*---------------------------------------------------------------------------*/ void read_result( void ) /* Read new results from STDIN. */ { result_t *result; string_t line, string; free_result( NULL ); line = read_line( stdin ); result_surf = new_pos_string( line ); free_mem( &line ); while (TRUE) { line = read_line( stdin ); if (line == NULL) complain( "Premature EOF." ); if (strcmp_no_case( line, "end" ) == 0) break; /* Read a new result. */ result = new_node( &results, sizeof( result_t ), LIST_END ); set_scanner_input( line ); /* Read result index. */ test_token( TOK_NUMBER ); string = int_to_string( token_number ); result->index = new_pos_string( string ); free_mem( &string ); read_next_token(); /* Read result value. */ parse_token( '{' ); result->value = parse_pos_value(); parse_token( '}' ); parse_token( EOF ); set_scanner_input( NULL ); free_mem( &line ); } free_mem( &line ); colon = new_pos_string( ":" ); if (result_canvas == NULL) { result_canvas = create_canvas( "Malaga Result", "result.eps", &result_geometry, configure_result, expose_result, free_result, NULL, TRUE, NULL, 0 ); } else { configure_canvas( result_canvas ); show_canvas( result_canvas ); } } /* End of file. =============================================================*/ malaga-7.12/result.h0000644000175000017500000000110410236624452013674 0ustar bjoernbjoern/* Copyright (C) 2002 Bjoern Beutel. */ /* Description. =============================================================*/ /* Read in and display Malaga Results. */ /* Variables. ===============================================================*/ extern rectangle_t result_geometry; extern string_t result_font_family; extern int_t result_font_size; /* Functions. ===============================================================*/ extern void read_result( void ); /* Read new results from STDIN. */ /* End of file. =============================================================*/ malaga-7.12/rule_code.c0000644000175000017500000003237610236624450014327 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module manages the emission of instructions and keeps track of the * stack index. * It supports constant folding. * It also holds buffers for the compiled code. */ /* Includes. ================================================================*/ #include #include #include #include #include #include "basic.h" #include "pools.h" #include "values.h" #include "symbols.h" #include "rule_type.h" #include "files.h" #include "malaga_files.h" #include "rule_code.h" /* Global variables. ========================================================*/ code_t code; /* Variables. ===============================================================*/ static instr_t *instr_stack; /* The instruction stack. The associated constant values are stored in * VALUES_STACK. */ static int_t instr_stack_size; /* The size of INSTR_STACK. */ /* Functions. ===============================================================*/ void init_rule_code( int_t file_type ) /* Initialise this module. * CODE will contain compilation data for a file of FILE_TYPE. * FILE_TYPE may be ALLO_RULE_FILE, MORPHO_RULE_FILE, or SYNTAX_RULE_FILE. */ { code.file_type = file_type; code.stack_index = 0; code.instr_count = 0; code.rule_pool = new_pool( sizeof( rule_t ) ); code.rule_set_pool = new_pool( sizeof( int_t ) ); code.instr_pool = new_pool( sizeof( instr_t ) ); code.value_pool = new_pool( sizeof( cell_t ) ); code.string_pool = new_pool( sizeof( char_t ) ); code.src_line_pool = new_pool( sizeof( src_line_t ) ); code.var_pool = new_pool( sizeof( var_t ) ); code.var_scope_pool = new_pool( sizeof( var_scope_t ) ); code.constant_pool = new_pool( sizeof( constant_t ) ); instr_stack_size = 50; instr_stack = new_vector( sizeof( instr_t ), instr_stack_size ); top = 0; } /*---------------------------------------------------------------------------*/ void terminate_rule_code( void ) /* Terminate this module. */ { free_pool( &code.rule_pool ); free_pool( &code.rule_set_pool ); free_pool( &code.instr_pool ); free_pool( &code.value_pool ); free_pool( &code.src_line_pool ); free_pool( &code.var_pool ); free_pool( &code.var_scope_pool ); free_pool( &code.constant_pool ); free_pool( &code.string_pool ); free_mem( &instr_stack ); } /*---------------------------------------------------------------------------*/ void write_code( string_t file_name ) /* Write CODE to FILE_NAME. */ { FILE *stream; rule_header_t rule_header; stream = open_stream( file_name, "wb" ); /* Set rule file header data. */ set_header( &rule_header.common_header, RULE_FILE, RULE_CODE_VERSION ); rule_header.initial_rule_set = code.initial_rule_set; rule_header.initial_feat = code.initial_feat; rule_header.robust_rule = code.robust_rule; rule_header.pruning_rule = code.pruning_rule; rule_header.allo_rule = code.allo_rule; rule_header.input_filter = code.input_filter; rule_header.output_filter = code.output_filter; rule_header.rule_count = pool_item_count( code.rule_pool ); rule_header.rule_sets_size = pool_item_count( code.rule_set_pool ); rule_header.instr_count = pool_item_count( code.instr_pool ); rule_header.values_size = pool_item_count( code.value_pool ); rule_header.src_line_count = pool_item_count( code.src_line_pool ); rule_header.var_count = pool_item_count( code.var_pool ); rule_header.var_scope_count = pool_item_count( code.var_scope_pool ); rule_header.constant_count = pool_item_count( code.constant_pool ); rule_header.strings_size = pool_item_count( code.string_pool ); /* Write the header. */ write_vector( &rule_header, sizeof( rule_header ), 1, stream, file_name ); /* Write the tables. */ write_pool( code.rule_pool, stream, file_name ); write_pool( code.rule_set_pool, stream, file_name ); write_pool( code.instr_pool, stream, file_name ); write_pool( code.value_pool, stream, file_name ); write_pool( code.src_line_pool, stream, file_name ); write_pool( code.var_pool, stream, file_name ); write_pool( code.var_scope_pool, stream, file_name ); write_pool( code.constant_pool, stream, file_name ); write_pool( code.string_pool, stream, file_name ); close_stream( &stream, file_name ); } /*---------------------------------------------------------------------------*/ static void set_stack_index( int_t opcode, int_t info ) /* Set the stack index according to the given instruction. */ { /* The stack index is not always correct, because "parse_choose" * and "parse_foreach" in "rule_parser.c" patch an INS_PUSH_NULL that they * have previously emitted. They will also correct the stack index. */ switch (opcode) { case INS_SYSTEM_ERROR: case INS_TERMINATE: case INS_NOP: case INS_UNARY_MINUS_OP: case INS_GET_ATTRIBUTE: case INS_REMOVE_ATTRIBUTE: case INS_MATCH: case INS_GET_1ST_ELEMENT: case INS_ITERATE: case INS_JUMP: case INS_JUMP_NOW: case INS_JUMP_LATER: /* These instructions leave the stack size unchanged. */ return; case INS_PUSH_VAR: case INS_PUSH_CONST: case INS_PUSH_SYMBOL: case INS_PUSH_PATTERN_VAR: case INS_JUMP_SUBRULE: /* This has to decrement the STACK_INDEX by the number * of parameters manually. */ code.stack_index++; return; case INS_PUSH_NULL: code.stack_index += info; return; case INS_ERROR: case INS_ADD_END_STATE: case INS_ADD_STATE: case INS_TERMINATE_IF_NULL: case INS_DOT_OPERATION: case INS_PLUS_OPERATION: case INS_MINUS_OPERATION: case INS_ASTERISK_OPERATION: case INS_SLASH_OPERATION: case INS_SET_VAR: case INS_PLUS_VAR: case INS_MINUS_VAR: case INS_ASTERISK_VAR: case INS_SLASH_VAR: case INS_JUMP_IF_NULL: case INS_JUMP_IF_NOT_NULL: case INS_JUMP_IF_YES: case INS_JUMP_IF_NO: case INS_ACCEPT: /* No instruction after this instruction is executed. */ case INS_RETURN: /* No instruction after this instruction is executed. */ code.stack_index--; return; case INS_ADD_ALLO: case INS_SET_VAR_PATH: case INS_PLUS_VAR_PATH: case INS_MINUS_VAR_PATH: case INS_ASTERISK_VAR_PATH: case INS_SLASH_VAR_PATH: case INS_JUMP_IF_EQUAL: case INS_JUMP_IF_NOT_EQUAL: case INS_JUMP_IF_CONGR: case INS_JUMP_IF_NOT_CONGR: case INS_JUMP_IF_IN: case INS_JUMP_IF_NOT_IN: case INS_JUMP_IF_LESS: case INS_JUMP_IF_NOT_LESS: case INS_JUMP_IF_GREATER: case INS_JUMP_IF_NOT_GREATER: code.stack_index -= 2; return; case INS_POP: code.stack_index -= info; return; case INS_POP_TO: code.stack_index = info; return; case INS_BUILD_LIST: case INS_BUILD_PATH: code.stack_index -= (info - 1); return; case INS_DECOMPOSE_LIST: code.stack_index += (info - 1); return; case INS_BUILD_RECORD: code.stack_index -= (2*info - 1); return; case INS_STD_FUNCTION: switch (info) { case FUNC_TO_ATOMS: case FUNC_IS_CAPITAL: case FUNC_GET_LENGTH: case FUNC_TO_MULTI: case FUNC_TO_SET: case FUNC_GET_SWITCH: case FUNC_GET_VALUE_TYPE: case FUNC_GET_VALUE_STRING: case FUNC_TRANSMIT: case FUNC_FLOOR: /* These functions leave the stack size unchanged. */ return; case FUNC_SUBSTRING: code.stack_index -= 2; return; } } complain( "Internal error." ); } /*---------------------------------------------------------------------------*/ static instr_t * emit_instr_local( int_t opcode, int_t info ) /* Emit an instruction to the instruction pool. Do not flush the buffer! * Return the address of the instruction in the pool. */ { instr_t instr; instr_t *instr_p; if (info < INSTR_INFO_MIN || info > INSTR_INFO_MAX) complain( "Internal error." ); /* Create the next instruction. */ instr = INSTR( opcode, info ); /* Generate instruction. */ instr_p = (instr_t *) copy_to_pool( code.instr_pool, &instr, 1, NULL ); set_stack_index( opcode, info ); code.instr_count = pool_item_count( code.instr_pool ); return instr_p; } /* Functions that support constant folding. =================================*/ static void put_instr( int_t opcode, int_t info ) /* Put the instruction (OPCODE, INFO) at INSTR_STACK[ TOP - 1 ]. */ { if (top > instr_stack_size) { instr_stack_size = renew_vector( &instr_stack, sizeof( u_int_t ), 2 * top ); } instr_stack[ top - 1 ] = INSTR( opcode, info ); } /*---------------------------------------------------------------------------*/ void buffer_instr( int_t opcode, int_t info ) /* Buffer the instructions BUILD_LIST, BUILD_RECORD, PUSH_SYMBOL, * and PUSH_CONST for constant folding. */ { switch (opcode) { case INS_PUSH_SYMBOL: push_symbol_value( info ); put_instr( INS_PUSH_SYMBOL, info ); break; case INS_PUSH_CONST: push_value( pool_item( code.value_pool, info ) ); put_instr( INS_PUSH_CONST, info ); break; case INS_BUILD_LIST: if (top >= info) { /* Execute the operation in the buffer. */ build_list( info ); put_instr( INS_PUSH_CONST, -1 ); } else emit_instr( opcode, info ); break; case INS_BUILD_RECORD: if (top >= 2 * info) { /* Execute the operation in the buffer. */ build_record( info ); put_instr( INS_PUSH_CONST, -1 ); } else emit_instr( opcode, info ); break; case INS_BUILD_PATH: if (top >= info) { /* Execute the operation in the buffer. */ build_path( info ); put_instr( INS_PUSH_CONST, -1 ); } else emit_instr( opcode, info ); break; case INS_DOT_OPERATION: case INS_PLUS_OPERATION: case INS_MINUS_OPERATION: case INS_ASTERISK_OPERATION: case INS_SLASH_OPERATION: if (top >= 2) { /* Execute the operation in the buffer. */ switch (opcode) { case INS_DOT_OPERATION: dot_operation(); if (value_stack[ top - 1 ] == NULL) complain( "Component doesn't exist." ); break; case INS_PLUS_OPERATION: plus_operation(); break; case INS_MINUS_OPERATION: minus_operation(); break; case INS_ASTERISK_OPERATION: asterisk_operation(); break; case INS_SLASH_OPERATION: slash_operation(); break; default: complain( "Internal error." ); } put_instr( INS_PUSH_CONST, -1 ); } else emit_instr( opcode, info ); break; case INS_UNARY_MINUS_OP: case INS_GET_ATTRIBUTE: case INS_REMOVE_ATTRIBUTE: if (top >= 1) { /* Execute the operation in the buffer. */ switch (opcode) { case INS_UNARY_MINUS_OP: unary_minus_operation(); break; case INS_GET_ATTRIBUTE: push_value( get_attribute( value_stack[ --top ], info ) ); if (value_stack[ top - 1 ] == NULL) { complain( "No attribute \"%s\" in record.", get_symbol_name( info ) ); } break; case INS_REMOVE_ATTRIBUTE: remove_attribute( info ); break; default: complain( "Internal error." ); } put_instr( INS_PUSH_CONST, -1 ); } else emit_instr( opcode, info ); break; default: emit_instr( opcode, info ); break; } } /*---------------------------------------------------------------------------*/ void buffer_push_number_instr( double number ) /* Buffer the instruction PUSH_CONST with NUMBER converted to a value. */ { push_number_value( number ); put_instr( INS_PUSH_CONST, -1 ); } /*---------------------------------------------------------------------------*/ void buffer_push_string_instr( string_t string, string_t string_end ) /* Buffer the instruction PUSH_CONST with STRING converted to a value. * STRING_END points to the string end if STRING_END != NULL. */ { push_string_value( string, string_end ); put_instr( INS_PUSH_CONST, -1 ); } /*---------------------------------------------------------------------------*/ void flush_buffer( void ) /* Emit the instructions that are still in the buffer. */ { int_t i, value_index; for (i = 0; i < top; i++) { switch (OPCODE( instr_stack[i] )) { case INS_PUSH_CONST: if (INSTR_INFO( instr_stack[i] ) == -1) copy_value_to_pool( code.value_pool, value_stack[i], &value_index ); else value_index = INSTR_INFO( instr_stack[i] ); emit_instr_local( INS_PUSH_CONST, value_index ); break; case INS_PUSH_SYMBOL: emit_instr_local( INS_PUSH_SYMBOL, INSTR_INFO( instr_stack[i] ) ); break; } } top = 0; } /*---------------------------------------------------------------------------*/ value_t get_buffer_top_value( void ) /* Test if the buffer contains a value and return the top value. */ { if (top == 0) complain( "Internal error." ); return value_stack[ top - 1 ]; } /*---------------------------------------------------------------------------*/ value_t pop_buffer_top_value( void ) /* Pop the top value in the buffer. */ { if (top == 0) complain( "Internal error." ); return value_stack[ --top ]; } /*---------------------------------------------------------------------------*/ instr_t * emit_instr( int_t opcode, int_t info ) /* Emit an instruction to the instruction pool (flushes buffer before) * and return the address of the instruction in the pool. */ { flush_buffer(); return emit_instr_local( opcode, info ); } /* End of file. =============================================================*/ malaga-7.12/rule_code.h0000644000175000017500000000711610236624446014333 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module manages the emission of instructions and keeps track of the * stack index. * It supports constant folding. * It also holds buffers for the compiled code. */ /* Constants. ===============================================================*/ /* Possible values of file_type. */ enum {ALLO_RULE_FILE, MORPHO_RULE_FILE, SYNTAX_RULE_FILE}; /* Types. ===================================================================*/ typedef struct /* Structure that contains compiled Malaga rule code. */ { int_t file_type; /* ALLO_RULE_FILE, MORPHO_RULE_FILE or SYNTAX_RULE_FILE. */ int_t rule_count; /* The number of rules currently defined. */ int_t stack_index; /* The current stack index. */ int_t instr_count; /* The number of instraction already emitted. */ /* The following values must be copied to the rule file: */ int_t initial_rule_set; /* Index into RULE_SET_POOL. */ int_t initial_feat; /* Index into VALUE_POOL. */ int_t robust_rule; /* Index into RULE_POOL. */ int_t pruning_rule; /* Index into RULE_POOL. */ int_t allo_rule; /* Index into RULE_POOL. */ int_t input_filter; /* Index into RULE_POOL. */ int_t output_filter; /* Index into RULE_POOL. */ pool_t rule_pool; /* The pool of all rules. */ pool_t rule_set_pool; /* The pool of rule sets. */ pool_t instr_pool; /* The pool of all instructions. */ pool_t value_pool; /* The pool of all constant Malaga values. */ pool_t src_line_pool; /* The pool of all associations * between source lines and rule code. */ pool_t var_pool; /* The pool of all variables */ pool_t var_scope_pool; /* The pool of all variable scopes. */ pool_t string_pool; /* The pool of all strings: * variable and rule names, patterns. */ pool_t constant_pool; /* The pool of all named constants. */ } code_t; /* Variables. ===============================================================*/ extern code_t code; /* Functions. ===============================================================*/ extern void init_rule_code( int_t file_type ); /* Initialise this module. * CODE will contain compilation data for a file of FILE_TYPE. * FILE_TYPE may be ALLO_RULE_FILE, MORPHO_RULE_FILE, or SYNTAX_RULE_FILE. */ extern void terminate_rule_code( void ); /* Terminate this module. */ extern void write_code( string_t file_name ); /* Write CODE to FILE_NAME. */ /* Functions for constant folding. ==========================================*/ extern void buffer_instr( int_t opcode, int_t info ); /* Buffer the instructions BUILD_LIST, BUILD_RECORD, PUSH_SYMBOL, * and PUSH_CONST for constant folding. */ extern void buffer_push_number_instr( double number ); /* Buffer the instruction PUSH_CONST with NUMBER converted to a value. */ extern void buffer_push_string_instr( string_t string, string_t string_end ); /* Buffer the instruction PUSH_CONST with STRING converted to a value. * STRING_END points to the string end if STRING_END != NULL. */ extern void flush_buffer( void ); /* Emit the instructions that are still in the buffer. */ extern value_t get_buffer_top_value( void ); /* Test if the buffer contains a value and return the top value. */ extern value_t pop_buffer_top_value( void ); /* Pop the top value in the buffer and return it. */ extern instr_t *emit_instr( int_t opcode, int_t info ); /* Emit an instruction to the instruction pool (flushes buffer before) * and return the address of the instruction in the pool. */ /* End of file. =============================================================*/ malaga-7.12/rule_compiler.c0000644000175000017500000002457310236624444015232 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module compiles Malaga rule files. */ /* Includes. ================================================================*/ #include #include #include #include #include #include "basic.h" #include "pools.h" #include "values.h" #include "scanner.h" #include "rule_type.h" #include "rule_code.h" #include "rule_parser.h" #include "rule_symbols.h" #include "files.h" #include "rule_compiler.h" /* Types. ===================================================================*/ typedef struct /* A rule's first instruction. */ { int_t number; /* The rule number. */ int_t first_instr; /* The index of the first instruction. */ } rule_instr_t; typedef struct /* A rule reference, part of a list. */ { list_node_t *next; int_t rule_number; /* The actual rule number. */ } reference_t; /* Functions. ===============================================================*/ static string_t rule_name( int_t rule_index ) /* Return the rule name of rule RULE_INDEX. */ { rule_t *rule; rule = pool_item( code.rule_pool, rule_index ); return pool_item( code.string_pool, rule->name ); } /*---------------------------------------------------------------------------*/ static void mark_reachable( bool_t reachable[], list_t *references, int_t rule ) /* Mark RULE as reachable in the vector REACHABLE. * If it has not been reachable before, add it to list NEW_RULES. */ { reference_t *reference; if (reachable[ rule ]) return; reachable[ rule ] = TRUE; reference = new_node( references, sizeof( reference_t ), LIST_END ); reference->rule_number = rule; } /*---------------------------------------------------------------------------*/ static void add_reference( list_t *references, int_t rule ) /* Add a reference to RULE to *REFERENCES if it is not already there. */ { reference_t *reference; /* Check if a reference to RULE already exists in <*references>. */ FOREACH( reference, *references ) { if (reference->rule_number == rule) return; } /* Add a new reference to the front of the list. */ reference = new_node( references, sizeof( reference_t ), LIST_END ); reference->rule_number = rule; } /*---------------------------------------------------------------------------*/ static void check_all_rules_reachable( int_t rule_count, list_t references[] ) /* Check if every rule can be reached. * REFERENCES[I] is the reference list for rule I, * i.e., the list of all rules that may be called from rule I. */ { bool_t *reachable; int_t *rule_set; list_t new_rules; reference_t *reference; string_t name; int_t i; /* Create a vector initialised with FALSE. */ reachable = new_vector( sizeof( bool_t ), rule_count ); clear_list( &new_rules ); if (code.pruning_rule != -1) mark_reachable( reachable, &new_rules, code.pruning_rule ); if (code.robust_rule != -1) mark_reachable( reachable, &new_rules, code.robust_rule ); if (code.allo_rule != -1) mark_reachable( reachable, &new_rules, code.allo_rule ); if (code.input_filter != -1) mark_reachable( reachable, &new_rules, code.input_filter ); if (code.output_filter != -1) mark_reachable( reachable, &new_rules, code.output_filter ); /* Mark the initial rules in the REACHABLE vector. */ if (code.initial_rule_set != -1) { for (rule_set = pool_item( code.rule_set_pool, code.initial_rule_set ); *rule_set != -1; rule_set++) { if (*rule_set >= 0) mark_reachable( reachable, &new_rules, *rule_set ); } } /* Mark all rules that may be called by other rules. */ while (new_rules.first != NULL) { i = ((reference_t *) new_rules.first)->rule_number; free_first_node( &new_rules ); FOREACH( reference, references[i] ) mark_reachable( reachable, &new_rules, reference->rule_number ); } /* Check if any rule is not reachable. */ for (i = 0; i < rule_count; i++) { if (! reachable[i]) { name = rule_name( i ); fprintf( stderr, "Warning: Rule \"%s\" can't be reached. (\"%s\", line %d)\n", name, name_in_path( get_rule_file( name ) ), get_rule_line( name ) ); } } free_mem( &reachable ); } /*---------------------------------------------------------------------------*/ static void check_no_circular_calls( int_t rule_count, list_t calls[] ) /* Check if there are no circular call chains in the rules. * CALLS[I] is the list of subrules that may be called by rule I. */ { bool_t *reachable; list_t new_rules; int_t n, i; reference_t *called; string_t name; reachable = new_vector( sizeof( bool_t ), rule_count ); clear_list( &new_rules ); for (n = 0; n < rule_count; n++) { /* Mark all rules as unreachable. */ for (i = 0; i < rule_count; i++) reachable[i] = FALSE; /* Mark all rules called from RULE as reachable. */ FOREACH( called, calls[n] ) mark_reachable( reachable, &new_rules, called->rule_number ); /* Mark all rules that are called from rules already marked. */ while (new_rules.first != NULL) { i = ((reference_t *) new_rules.first)->rule_number; free_first_node( &new_rules ); FOREACH( called, calls[i] ) mark_reachable( reachable, &new_rules, called->rule_number ); } if (reachable[n]) { name = rule_name( n ); fprintf( stderr, "Warning: Rule \"%s\" is recursive. (\"%s\", line %d)\n", name, name_in_path( get_rule_file( name ) ), get_rule_line( name ) ); } } free_mem( &reachable ); } /*---------------------------------------------------------------------------*/ static int compare_first_instr( const void *key1, const void *key2 ) /* Returns (-1/0/1) when the first instruction KEY1 is * (lower than/same as/higher than) the first instruction KEY2. */ { rule_instr_t *rule_1, *rule_2; rule_1 = (rule_instr_t *) key1; rule_2 = (rule_instr_t *) key2; if (rule_1->first_instr < rule_2->first_instr) return -1; else if (rule_1->first_instr > rule_2->first_instr) return 1; else return 0; } /*---------------------------------------------------------------------------*/ static void check_rule_calls( void ) /* Report a warning if the rules in CODE contain a circular call chain. * Report a warning if a rule can't be reached. */ { int_t rule_count, i, rule_index, rule_index2; rule_instr_t *rules; list_t *references, *calls; /* Vectors for references and calls. */ reference_t *reference; rule_t *rule; instr_t instr; int_t *rule_set; /* Initialise RULES and sort them for FIRST_INSTR. */ rule_count = pool_item_count( code.rule_pool ); rules = new_vector( sizeof( rule_instr_t ), rule_count ); for (i = 0; i < rule_count; i++) { rule = pool_item( code.rule_pool, i ); rules[i].number = i; rules[i].first_instr = rule->first_instr; } qsort( rules, rule_count, sizeof( rule_instr_t ), compare_first_instr ); /* Allocate a vector of rule references and a vector of calls. * The structs are NULL-initialised, so we don't need to use "clear_list". */ references = new_vector( sizeof( list_t ), rule_count ); calls = new_vector( sizeof( list_t ), rule_count ); /* Fill references. */ rule_index = 0; for (i = 0; i < pool_item_count( code.instr_pool ); i++) { /* Increment RULE if instruction belongs to next rule. */ while (rule_index + 1 < rule_count && rules[ rule_index + 1 ].first_instr <= i) { rule_index++; } rule_index2 = rules[ rule_index ].number; instr = *((instr_t *) pool_item( code.instr_pool, i )); /* Check each instruction: is it a add_state instruction? */ if (OPCODE( instr ) == INS_ADD_STATE && INSTR_INFO( instr ) != -1) { /* Examine the rule set of this result statement. */ for (rule_set = pool_item( code.rule_set_pool, INSTR_INFO( instr ) ); *rule_set != -1; rule_set++) { if (*rule_set >= 0) add_reference( &references[ rule_index2 ], *rule_set ); } } else if (OPCODE( instr ) == INS_JUMP_SUBRULE) { add_reference( &references[ rule_index2 ], INSTR_INFO( instr ) ); add_reference( &calls[ rule_index2 ], INSTR_INFO( instr ) ); } } check_all_rules_reachable( rule_count, references ); check_no_circular_calls( rule_count, calls ); free_mem( &rules ); for (i = 0; i < rule_count; i++) { FOREACH_FREE( reference, references[i] ) ; /* empty */ FOREACH_FREE( reference, calls[i] ) ; /* empty */ } free_mem( &references ); free_mem( &calls ); } /*---------------------------------------------------------------------------*/ void compile_rule_file( string_t source_file_name, string_t object_file_name, int_t file_type ) /* Compile file SOURCE_FILE_NAME. * Save compiled data in a file OBJECT_FILE_NAME. */ { string_t file_name; int_t file_name_index; init_rule_code( file_type ); enter_function( "atoms", FUNC_TO_ATOMS ); enter_function( "capital", FUNC_IS_CAPITAL ); enter_function( "length", FUNC_GET_LENGTH ); enter_function( "multi", FUNC_TO_MULTI ); enter_function( "set", FUNC_TO_SET ); enter_function( "switch", FUNC_GET_SWITCH ); enter_function( "value_type", FUNC_GET_VALUE_TYPE ); enter_function( "value_string", FUNC_GET_VALUE_STRING ); enter_function( "transmit", FUNC_TRANSMIT ); enter_function( "floor", FUNC_FLOOR ); enter_function( "substring", FUNC_SUBSTRING ); /* Copy file name into string pool. */ file_name = copy_string_to_pool( code.string_pool, source_file_name, &file_name_index ); /* Parse the rule file (and all included files). */ begin_include( file_name ); TRY parse_rule_file(); IF_ERROR { print_text( error_text, " (\"%s\", line %d, column %d)", name_in_path( current_file_name() ), current_line_number(), current_column() ); if (in_emacs_malaga_mode) { printf( "SHOW \"%s\":%d:%d\n", current_file_name(), current_line_number(), current_column() ); } } FINALLY end_includes(); END_TRY; check_rules_defined(); /* Check if all used rules are also defined. */ check_rule_calls(); /* Check for recursive and/or unreachable rules. */ dump_variables_and_constants(); write_code( object_file_name ); free_symbols(); terminate_rule_code(); } /* End of file. =============================================================*/ malaga-7.12/rule_compiler.h0000644000175000017500000000114310236624442015221 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module compiles Malaga rule files. */ /* Functions. ===============================================================*/ extern void compile_rule_file( string_t source_file_name, string_t object_file_name, int_t file_type ); /* Compile file SOURCE_FILE_NAME of FILE_TYPE * and save compiled data in a file with name OBJECT_FILE_NAME. */ /* End of file. =============================================================*/ malaga-7.12/rule_parser.c0000644000175000017500000015652510504310276014710 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module parses Malaga rule files. */ /* Includes. ================================================================*/ #include #include #include #include #include #include #include "basic.h" #include "pools.h" #include "values.h" #include "symbols.h" #include "patterns.h" #include "files.h" #include "scanner.h" #include "rule_type.h" #include "rule_code.h" #include "rule_symbols.h" #include "hangul.h" #include "rule_parser.h" /* Types. ===================================================================*/ typedef struct /* Information about a variable, for list assignments. */ { list_node_t *next; int_t var_index, path_index; } var_node_t; typedef struct /* A pointer to an instruction to be patched. */ { list_node_t *next; instr_t *instr; } instr_node_t; typedef struct /* Chains of instructions to patch in a condition. */ { list_t true_jumps; /* Instrs that jump if condition is TRUE. */ list_t false_jumps; /* Instrs that jump if condition is FALSE. */ instr_t *last_jump; /* The last jump (not included above). */ } condition_t; typedef struct /* An open scope. */ { list_node_t *next; int_t initial_index; /* Index of the stack as the scope was opened. */ list_t var_name_list; /* The names of all variables in the scope. */ } scope_node_t; typedef struct /* A label for a "foreach" statement. */ { list_node_t *next; string_t name; /* Label of this loop or NULL. */ list_t repeat_jumps; /* Pointers to instrs that repeat this loop. */ list_t out_jumps; /* Pointers to instrs that jump out of this loop. */ } loop_node_t; typedef struct /* A name in a list of names. */ { list_node_t *next; string_t name; } name_node_t; typedef struct /* A rule index in a list of indexes. */ { list_node_t *next; int_t index; } rule_node_t; typedef enum {VALUE, CONST_VALUE, CONDITION} expr_type_t; /* The type of a Malaga expression. */ /* Variables. ===============================================================*/ /* File name and line number at the beginning of the last statement. */ static int_t last_statement_line; static string_t last_statement_file_name; static rule_type_t rule_type; /* Type of rule that is to be parsed. */ static list_t scope_list; /* List of variables currently defined. */ static list_t loop_list; /* List of loops currently open. */ static struct /* The pattern variables defined in a "matches" condition. */ { int_t count; /* Number of pattern variables. * Will be reset when variables are defined. */ string_t name[ PATTERN_VAR_MAX ]; /* Names of the pattern variables. */ } pattern_vars; /* Forward declarations. ====================================================*/ static expr_type_t parse_value_local( condition_t *condition ); static expr_type_t parse_expression( condition_t *condition ); static void parse_statements( void ); /* Support for source line associations. ====================================*/ static void new_source_line( void ) /* Associate the next instructions with the current source line. */ { src_line_t src_line; if (current_line_number() != last_statement_line || current_file_name() != last_statement_file_name) { src_line.file = pool_index( code.string_pool, current_file_name() ); src_line.line = current_line_number(); src_line.instr = code.instr_count; copy_to_pool( code.src_line_pool, &src_line, 1, NULL ); last_statement_line = current_line_number(); last_statement_file_name = current_file_name(); } } /*---------------------------------------------------------------------------*/ static void no_source_line( void ) /* Associate the next instructions generated with no source. */ { src_line_t src_line; if (last_statement_line != -1 || last_statement_file_name != NULL) { src_line.file = -1; src_line.line = -1; src_line.instr = code.instr_count; copy_to_pool( code.src_line_pool, &src_line, 1, NULL ); last_statement_line = -1; last_statement_file_name = NULL; } } /* Support for parsing conditions. ==========================================*/ static void add_instr_to_list( list_t *instr_list, instr_t *instr ) /* Add instruction INSTR to INSTR_LIST. */ { instr_node_t *instr_node; instr_node = new_node( instr_list, sizeof( instr_node_t ), LIST_END ); instr_node->instr = instr; } /*---------------------------------------------------------------------------*/ static void patch_instr( instr_t *instr, int_t info ) /* Patch *INSTR to have its info set to INFO. */ { if (info >= INSTR_INFO_MAX) complain( "Internal error." ); *instr = INSTR( OPCODE( *instr ), info ); } /*---------------------------------------------------------------------------*/ static void patch_instr_list( list_t *instr_list, int_t info ) /* Patch all instructions in INSTR_LIST to have their info set to INFO. * INSTR_LIST is freed by this function. */ { instr_node_t *instr_node; FOREACH_FREE( instr_node, *instr_list ) patch_instr( instr_node->instr, info ); } /*---------------------------------------------------------------------------*/ static void negate_jump( instr_t *jump ) /* If *JUMP is a conditional jump, negate its condition. */ { int_t opcode; opcode = OPCODE( *jump ); switch (opcode) { case INS_JUMP_IF_EQUAL: opcode = INS_JUMP_IF_NOT_EQUAL; break; case INS_JUMP_IF_NOT_EQUAL: opcode = INS_JUMP_IF_EQUAL; break; case INS_JUMP_IF_CONGR: opcode = INS_JUMP_IF_NOT_CONGR; break; case INS_JUMP_IF_NOT_CONGR: opcode = INS_JUMP_IF_CONGR; break; case INS_JUMP_IF_IN: opcode = INS_JUMP_IF_NOT_IN; break; case INS_JUMP_IF_NOT_IN: opcode = INS_JUMP_IF_IN; break; case INS_JUMP_IF_LESS: opcode = INS_JUMP_IF_NOT_LESS; break; case INS_JUMP_IF_NOT_LESS: opcode = INS_JUMP_IF_LESS; break; case INS_JUMP_IF_GREATER: opcode = INS_JUMP_IF_NOT_GREATER; break; case INS_JUMP_IF_NOT_GREATER: opcode = INS_JUMP_IF_GREATER; break; case INS_JUMP_IF_NULL: opcode = INS_JUMP_IF_NOT_NULL; break; case INS_JUMP_IF_NOT_NULL: opcode = INS_JUMP_IF_NULL; break; case INS_JUMP_IF_YES: opcode = INS_JUMP_IF_NO; break; case INS_JUMP_IF_NO: opcode = INS_JUMP_IF_YES; break; default: break; } *jump = INSTR( opcode, INSTR_INFO( *jump ) ); } /* Variable scopes. =========================================================*/ static void open_scope( void ) /* Open a new scope. */ { scope_node_t *scope_node; scope_node = new_node( &scope_list, sizeof( scope_node_t ), LIST_START ); scope_node->initial_index = code.stack_index; clear_list( &scope_node->var_name_list ); } /*---------------------------------------------------------------------------*/ static void close_scope( bool_t do_pop ) /* Close the current scope. Emit a pop instruction that resets * the stack index to the initial stack index if DO_POP is TRUE. */ { scope_node_t *scope_node; name_node_t *name_node; scope_node = (scope_node_t *) scope_list.first; FOREACH_FREE( name_node, scope_node->var_name_list ) undefine_variable( name_node->name ); /* See if we have to pop to reach the start index again. */ if (do_pop && code.stack_index > scope_node->initial_index) { no_source_line(); emit_instr( INS_POP, code.stack_index - scope_node->initial_index ); } /* Reset stack index. */ code.stack_index = scope_node->initial_index; free_first_node( &scope_list ); } /*---------------------------------------------------------------------------*/ static void define_var_in_scope( string_t name, int_t var_index ) /* Define a variable and add it to the current scope. */ { name_node_t *name_node; scope_node_t *scope_node; scope_node = (scope_node_t *) scope_list.first; name_node = new_node( &scope_node->var_name_list, sizeof( name_node_t ), LIST_END ); name_node->name = define_variable( name, var_index ); } /* Simple Malaga parse functions. ===========================================*/ static void parse_var_name( string_t *var_name ) /* Parse variable name and allocate memory to save its name in *VAR_NAME. */ { test_token( TOK_VARIABLE ); *var_name = new_string( token_name, NULL ); read_next_token(); } /*---------------------------------------------------------------------------*/ static int_t parse_rule_name( list_t *rule_list ) /* Parse a rule name which must not be part of RULE_LIST. */ { rule_node_t *rule_node; rule_t *rule; int_t rule_number; test_token( TOK_IDENT ); rule = find_combi_rule( token_name, &rule_number, current_line_number(), current_file_name() ); /* Check if we already have this rule in this rule set. */ FOREACH( rule_node, *rule_list ) { if (rule_node->index == rule_number) complain( "Rule \"%s\" twice in rule set.", token_name ); } read_next_token(); return rule_number; } /*---------------------------------------------------------------------------*/ static void parse_rule_set( int_t *rule_set_index ) /* Parse a list of rule names and enter it into CODE.RULE_SET_POOL. * Return the index of the rule set in *RULE_SET_INDEX. */ { list_t rule_list; rule_node_t *rule_node; bool_t has_parentheses; int_t i, rule_count; int_t *rules; rule_count = 0; clear_list( &rule_list ); parse_token( TOK_RULES ); has_parentheses = (next_token == '('); if (has_parentheses) parse_token( '(' ); while (TRUE) { while (TRUE) { i = parse_rule_name( &rule_list ); rule_node = new_node( &rule_list, sizeof( rule_node_t ), LIST_END ); rule_node->index = i; rule_count++; if (next_token != ',') break; read_next_token(); } if (next_token != TOK_ELSE) break; read_next_token(); rule_node = new_node( &rule_list, sizeof( rule_node_t ), LIST_END ); rule_node->index = -2; rule_count++; } if (has_parentheses) parse_token( ')' ); rule_node = new_node( &rule_list, sizeof( rule_node_t ), LIST_END ); rule_node->index = -1; rule_count++; rules = get_pool_space( code.rule_set_pool, rule_count, rule_set_index ); i = 0; FOREACH_FREE( rule_node, rule_list ) rules[ i++ ] = rule_node->index; } /* Functions to parse Malaga values. ========================================*/ /* Functions to parse a value do not always emit instructions immediately. * Instead, they sometimes write instructions in a buffer, * so they can do constant folding. * Use the functions "parse_value", "parse_constant_value" * and "parse_condition" to get values or conditions. */ /*---------------------------------------------------------------------------*/ static void convert_to_condition( expr_type_t *type, condition_t *condition ) /* Make sure an expression is a condition. */ { if (*type != CONDITION) { clear_list( &condition->true_jumps ); clear_list( &condition->false_jumps ); condition->last_jump = emit_instr( INS_JUMP_IF_YES, 0 ); *type = CONDITION; } } /*---------------------------------------------------------------------------*/ static expr_type_t parse_value_no_flush( void ) /* Parse any value. Convert conditions into yes/no symbols. Do *not* flush the * instruction buffer. */ { expr_type_t type; condition_t condition; int_t pattern_var_count; pattern_var_count = pattern_vars.count; type = parse_value_local( &condition ); if (pattern_vars.count > pattern_var_count) complain( "Variable definition not allowed in values." ); if (type == CONDITION) { negate_jump( condition.last_jump ); patch_instr_list( &condition.true_jumps, code.instr_count ); emit_instr( INS_PUSH_SYMBOL, YES_SYMBOL ); emit_instr( INS_JUMP, code.instr_count + 2 ); code.stack_index--; patch_instr( condition.last_jump, code.instr_count ); patch_instr_list( &condition.false_jumps, code.instr_count ); emit_instr( INS_PUSH_SYMBOL, NO_SYMBOL ); return VALUE; } else return type; } /*---------------------------------------------------------------------------*/ static expr_type_t parse_value( void ) /* Parse any value. Convert conditions into yes/no symbols. Flush the * instruction buffer. */ { expr_type_t type; type = parse_value_no_flush(); flush_buffer(); return type; } /*---------------------------------------------------------------------------*/ static void parse_constant_value( int_t *value_index ) /* Parse a constant value and save its index in *VALUE_INDEX. */ { expr_type_t type; condition_t condition; type = parse_value_local( &condition ); if (type != CONST_VALUE) complain( "Constant value expected." ); copy_value_to_pool( code.value_pool, pop_buffer_top_value(), value_index ); } /*---------------------------------------------------------------------------*/ static void parse_condition( condition_t *condition ) /* Parse any condition and set CONDITION. */ { expr_type_t type; type = parse_expression( condition ); convert_to_condition( &type, condition ); } /*---------------------------------------------------------------------------*/ static void parse_subrule_call( string_t ident ) /* Parse a subrule call. * The subrule name IDENT has already been parsed. */ { int_t param_count, rule_number; rule_t *rule; rule = find_subrule( ident, &rule_number, current_line_number(), current_file_name()); parse_token( '(' ); param_count = 0; if (next_token != ')') { while (TRUE) { parse_value(); param_count++; if (next_token != ',') break; read_next_token(); } } parse_token( ')' ); if (rule == NULL) { /* Call a standard function. */ switch (rule_number) { case FUNC_TO_ATOMS: case FUNC_IS_CAPITAL: case FUNC_GET_LENGTH: case FUNC_TO_MULTI: case FUNC_TO_SET: case FUNC_GET_SWITCH: case FUNC_GET_VALUE_TYPE: case FUNC_GET_VALUE_STRING: case FUNC_TRANSMIT: case FUNC_FLOOR: if (param_count != 1) complain( "Function \"%s\" takes one parameter.", ident ); break; case FUNC_SUBSTRING: if (param_count < 2 || param_count > 3) complain( "Function \"%s\" takes 2 or 3 parameters.", ident ); if (param_count == 2) emit_instr( INS_PUSH_NULL, 1 ); break; } emit_instr( INS_STD_FUNCTION, rule_number ); } else { /* Call a real subrule. */ if (rule->param_count == -1) rule->param_count = param_count; else if (param_count != rule->param_count) complain( "\"%s\" takes %d parameters.", ident, rule->param_count ); code.stack_index -= param_count; /* Subrule jump kills all parameters. */ emit_instr( INS_JUMP_SUBRULE, rule_number ); } } /*---------------------------------------------------------------------------*/ static void parse_if_expression( void ) /* Parse an "if" expression. */ { condition_t condition; list_t end_jumps; list_t else_jumps; instr_t *end_jump; int_t pattern_var_count; clear_list( &else_jumps ); clear_list( &end_jumps ); test_token( TOK_IF ); do { read_next_token(); /* Jump here if previous conditions were false. */ patch_instr_list( &else_jumps, code.instr_count ); pattern_var_count = pattern_vars.count; parse_condition( &condition ); if (pattern_vars.count > pattern_var_count) complain( "No variable definitions allowed in if-expressions." ); parse_token( TOK_THEN ); /* Fall through if condition is true. */ else_jumps = condition.false_jumps; negate_jump( condition.last_jump ); add_instr_to_list( &else_jumps, condition.last_jump ); patch_instr_list( &condition.true_jumps, code.instr_count ); parse_value(); code.stack_index--; /* Emit jump to end. */ end_jump = emit_instr( INS_JUMP, 0 ); add_instr_to_list( &end_jumps, end_jump ); } while (next_token == TOK_ELSEIF); parse_token( TOK_ELSE ); patch_instr_list( &else_jumps, code.instr_count ); parse_value(); parse_token( TOK_END ); if (next_token == TOK_IF) read_next_token(); patch_instr_list( &end_jumps, code.instr_count ); } /*---------------------------------------------------------------------------*/ static expr_type_t parse_simple_value( condition_t *condition ) /* Parse a simple value or a condition in parentheses. * If CONSTANT is TRUE, the value must be constant. * Any jumps are returned in CONDITION. */ { int_t i; /* Number of values in list or record. */ expr_type_t type, elem_type; /* Result type of expression. */ string_t ident, var_name; int_t var_index; switch (next_token) { case '<': /* Parse a list. */ read_next_token(); type = CONST_VALUE; i = 0; if (next_token != '>') { while (TRUE) { elem_type = parse_value_no_flush(); if (elem_type == VALUE) type = VALUE; i++; if (next_token != ',') break; read_next_token(); } } parse_token( '>' ); buffer_instr( INS_BUILD_LIST, i ); return type; case '[': /* Parse a record. */ read_next_token(); type = CONST_VALUE; i = 0; if (next_token != ']') { while (TRUE) { elem_type = parse_value_local( condition ); if (elem_type == CONDITION) complain( "No conditions allowed as attribute names." ); else if (elem_type == VALUE) type = VALUE; parse_token( ':' ); elem_type = parse_value_no_flush(); if (elem_type == VALUE) type = VALUE; i++; if (next_token != ',') break; read_next_token(); } } parse_token( ']' ); buffer_instr( INS_BUILD_RECORD, i ); return type; case TOK_IDENT: ident = new_string( token_name, NULL ); read_next_token(); if (next_token == '(') { /* Parse a subrule call. */ parse_subrule_call( ident ); type = VALUE; } else { buffer_instr( INS_PUSH_SYMBOL, find_symbol( ident ) ); type = CONST_VALUE; } free_mem( &ident ); return type; case TOK_STRING: encode_hangul( &token_string ); buffer_push_string_instr( token_string, NULL ); read_next_token(); return CONST_VALUE; case TOK_NUMBER: buffer_push_number_instr( token_number ); read_next_token(); return CONST_VALUE; case TOK_CONSTANT: buffer_instr( INS_PUSH_CONST, find_constant( token_name ) ); read_next_token(); return CONST_VALUE; case TOK_VARIABLE: parse_var_name( &var_name ); var_index = find_variable( var_name ); emit_instr( INS_PUSH_VAR, var_index ); free_mem( &var_name ); return VALUE; case '(': read_next_token(); type = parse_expression( condition ); parse_token( ')' ); return type; case TOK_IF: parse_if_expression(); return VALUE; default: complain( "Value expected, not %s.", token_as_text( next_token ) ); } } /*---------------------------------------------------------------------------*/ static expr_type_t parse_unary_value( condition_t *condition ) /* Parse a value that may be prefixed by a unary "-". */ { expr_type_t type; if (next_token == '-') { read_next_token(); type = parse_simple_value( condition ); if (type == CONDITION) complain( "Conditions not allowed after unary \"-\"." ); buffer_instr( INS_UNARY_MINUS_OP, 0 ); } else type = parse_simple_value( condition ); return type; } /*---------------------------------------------------------------------------*/ static expr_type_t parse_dotted_value( condition_t *condition ) /* Parse a value and a sequence of following ".IDENT" or ".NUMBER". */ { expr_type_t type, elem_type; type = parse_unary_value( condition ); if (type == CONDITION) return type; while (next_token == '.') { read_next_token(); elem_type = parse_unary_value( condition ); if (elem_type == CONDITION) complain( "Conditions not allowed after \".\"." ); else if (elem_type == VALUE) type = VALUE; if (elem_type == CONST_VALUE && get_value_type( get_buffer_top_value() ) == SYMBOL_SYMBOL) { buffer_instr( INS_GET_ATTRIBUTE, value_to_symbol( pop_buffer_top_value() ) ); } else buffer_instr( INS_DOT_OPERATION, 0 ); } return type; } /*---------------------------------------------------------------------------*/ static expr_type_t parse_term_value( condition_t *condition ) /* Parse a value that may contain the "*" and the "/" operator. */ { expr_type_t type, elem_type; int_t operator_token; type = parse_dotted_value( condition ); if (type == CONDITION) return type; while (next_token == '*' || next_token == '/') { operator_token = next_token; read_next_token(); elem_type = parse_dotted_value( condition ); if (elem_type == CONDITION) complain( "Conditions not allowed after \"*\" and \"/\"." ); else if (elem_type == VALUE) type = VALUE; if (operator_token == '*') buffer_instr( INS_ASTERISK_OPERATION, 0 ); else buffer_instr( INS_SLASH_OPERATION, 0 ); } return type; } /*---------------------------------------------------------------------------*/ static expr_type_t parse_value_local( condition_t *condition ) /* Parse any value. * The code is not necessarily emitted, it may still be in the buffer. * Use "parse_value" to get real code. */ { expr_type_t type, elem_type; int_t operator_token; type = parse_term_value( condition ); if (type == CONDITION) return type; while (next_token == '+' || next_token == '-') { operator_token = next_token; read_next_token(); if (operator_token == '-') { elem_type = parse_term_value( condition ); if (elem_type == CONDITION) complain( "Conditions not allowed after \"-\"." ); else if (elem_type == VALUE) type = VALUE; if (elem_type == CONST_VALUE && get_value_type( get_buffer_top_value() ) == SYMBOL_SYMBOL) { buffer_instr( INS_REMOVE_ATTRIBUTE, value_to_symbol( pop_buffer_top_value() ) ); } else buffer_instr( INS_MINUS_OPERATION, 0 ); } else /* operator_token == '+' */ { elem_type = parse_term_value( condition ); if (elem_type == CONDITION) complain( "Conditions not allowed after \"+\"." ); else if (elem_type == VALUE) type = VALUE; buffer_instr( INS_PLUS_OPERATION, 0 ); } } return type; } /*---------------------------------------------------------------------------*/ static void parse_string_or_var( int_t *var_number, string_t *string ) /* Parse a constant string or a variable name and return it in * *VAR_NUMBER or *STRING. */ { condition_t condition; expr_type_t type; if (next_token == TOK_VARIABLE) { if (*var_number != -1) complain( "Constant string expected." ); if (pattern_vars.count == PATTERN_VAR_MAX) complain( "Too many variables in pattern." ); parse_var_name( pattern_vars.name + pattern_vars.count ); *var_number = pattern_vars.count++; } else { if (*string != NULL) complain( "Variable expected." ); type = parse_value_local( &condition ); if (type != CONST_VALUE || get_value_type( get_buffer_top_value() ) != STRING_SYMBOL) { complain( "Constant string expected." ); } *string = value_to_string( pop_buffer_top_value() ); } } /*---------------------------------------------------------------------------*/ static void parse_pattern( string_t *pattern ) /* Parse a pattern and return it in PATTERN. */ { int_t var_number; string_t segment, string; text_t *text; text = new_text(); while (TRUE) { string = NULL; var_number = -1; parse_string_or_var( &var_number, &string ); if (var_number != -1 || next_token == ':') { parse_token( ':' ); parse_string_or_var( &var_number, &string ); } segment = compile_pattern( string, var_number ); add_to_text( text, segment ); free_mem( &segment ); if (next_token != ',') break; read_next_token(); } *pattern = text_to_string( &text ); } /*---------------------------------------------------------------------------*/ static void define_pattern_vars( void ) /* Generate code to define the pattern variables PATTERN_VARS. */ { int_t i; for (i = 0; i < pattern_vars.count; i++) { emit_instr( INS_PUSH_PATTERN_VAR, i ); define_var_in_scope( pattern_vars.name[i], code.stack_index - 1 ); free_mem( &pattern_vars.name[i] ); } pattern_vars.count = 0; } /*---------------------------------------------------------------------------*/ static expr_type_t parse_comparison( condition_t *condition ) /* Parse a malaga comparison and set CONDITION accordingly. */ { int_t opcode; expr_type_t type, type2; string_t pattern; int_t pattern_index; type = parse_value_local( condition ); if (type == CONDITION) return type; switch (next_token) { case '=': opcode = INS_JUMP_IF_EQUAL; break; case TOK_NOT_EQUAL: opcode = INS_JUMP_IF_NOT_EQUAL; break; case '~': opcode = INS_JUMP_IF_CONGR; break; case TOK_NOT_CONGRUENT: opcode = INS_JUMP_IF_NOT_CONGR; break; case TOK_IN: opcode = INS_JUMP_IF_IN; break; case TOK_LESS: opcode = INS_JUMP_IF_LESS; break; case TOK_LESS_EQUAL: opcode = INS_JUMP_IF_NOT_GREATER; break; case TOK_GREATER: opcode = INS_JUMP_IF_GREATER; break; case TOK_GREATER_EQUAL: opcode = INS_JUMP_IF_NOT_LESS; break; case TOK_MATCHES: read_next_token(); if (next_token == '(') { read_next_token(); parse_pattern( &pattern ); parse_token( ')' ); } else parse_pattern( &pattern ); copy_string_to_pool( code.string_pool, pattern, &pattern_index ); free_mem( &pattern ); emit_instr( INS_MATCH, pattern_index ); clear_list( &condition->true_jumps ); clear_list( &condition->false_jumps ); condition->last_jump = emit_instr( INS_JUMP_IF_YES, 0 ); return CONDITION; default: return type; } read_next_token(); type2 = parse_value_local( condition ); if (type2 == CONDITION) complain( "Conditions not allowed in comparisons." ); /* Emit code and produce CONDITION. */ clear_list( &condition->true_jumps ); clear_list( &condition->false_jumps ); condition->last_jump = emit_instr( opcode, 0 ); return CONDITION; } /*---------------------------------------------------------------------------*/ static expr_type_t parse_simple_condition( condition_t *condition ) /* Parse a malaga comparison that may be negated and return CONDITION. */ { expr_type_t type; int_t pattern_var_count; condition_t condition2; pattern_var_count = pattern_vars.count; if (next_token == TOK_NOT) { read_next_token(); type = parse_comparison( &condition2 ); if (pattern_vars.count > pattern_var_count) complain( "No variable definition allowed in negations." ); convert_to_condition( &type, &condition2 ); negate_jump( condition2.last_jump ); condition->last_jump = condition2.last_jump; condition->true_jumps = condition2.false_jumps; condition->false_jumps = condition2.true_jumps; } else type = parse_comparison( condition ); return type; } /*---------------------------------------------------------------------------*/ static expr_type_t parse_expression( condition_t *condition ) /* Parse any expression, i.e., a value or a regular condition. */ { condition_t condition2; expr_type_t type, type2; int_t pattern_var_count; pattern_var_count = pattern_vars.count; type = parse_simple_condition( condition ); if (next_token == TOK_OR) { /* There may be a chain of "or"s behind the first simple condition. */ convert_to_condition( &type, condition ); while (next_token == TOK_OR) { read_next_token(); /* All jumps in FALSE_JUMP should point to next instruction. */ patch_instr_list( &condition->false_jumps, code.instr_count ); type2 = parse_simple_condition( &condition2 ); convert_to_condition( &type2, &condition2 ); /* Create a new TRUE_JUMP list. */ combine_lists( &condition->true_jumps, &condition2.true_jumps ); combine_lists( &condition->false_jumps, &condition2.false_jumps ); add_instr_to_list( &condition->true_jumps, condition->last_jump ); condition->last_jump = condition2.last_jump; } if (pattern_vars.count > pattern_var_count) complain( "No variable definition allowed in disjunctions." ); } else if (next_token == TOK_AND) { /* There may be a chain of "and"s behind the first simple condition. */ convert_to_condition( &type, condition ); while (next_token == TOK_AND) { read_next_token(); /* All jumps in TRUE_JUMP should point to next instruction. */ patch_instr_list( &condition->true_jumps, code.instr_count ); type2 = parse_simple_condition( &condition2 ); convert_to_condition( &type2, &condition2 ); /* Create a new FALSE_JUMP list. */ negate_jump( condition->last_jump ); combine_lists( &condition->true_jumps, &condition2.true_jumps ); combine_lists( &condition->false_jumps, &condition2.false_jumps ); add_instr_to_list( &condition->false_jumps, condition->last_jump ); condition->last_jump = condition2.last_jump; } } return type; } /*---------------------------------------------------------------------------*/ static void parse_attribute_path( void ) /* Parse a sequence of values separated by a ".", * it will be returned on the stack as a list. */ { int_t path_length; condition_t condition; expr_type_t type; path_length = 0; while (TRUE) { type = parse_unary_value( &condition ); if (type == CONDITION) complain( "Conditions not allowed in paths." ); path_length++; if (next_token != '.') break; read_next_token(); } /* Emit the instruction that pushes the selection path. */ buffer_instr( INS_BUILD_PATH, path_length ); flush_buffer(); } /* Parse functions for statements. ==========================================*/ static void parse_assert_statement( void ) /* Parse an assert statement. */ { condition_t condition; new_source_line(); if (next_token != TOK_ASSERT && next_token != '!') { complain( "\"!\" or \"assert\" expected, not %s.", token_as_text( next_token ) ); } read_next_token(); parse_condition( &condition ); patch_instr_list( &condition.false_jumps, code.instr_count ); emit_instr( INS_SYSTEM_ERROR, ASSERTION_ERROR ); patch_instr_list( &condition.true_jumps, code.instr_count ); patch_instr( condition.last_jump, code.instr_count ); define_pattern_vars(); parse_token( ';' ); } /*---------------------------------------------------------------------------*/ static void parse_assignment( void ) /* Parse an assignment. */ { string_t var_name; /* The name of the variable. */ int_t index; int_t assignment; /* Type of assignment token. */ bool_t has_path; new_source_line(); parse_var_name( &var_name ); index = find_variable( var_name ); free_mem( &var_name ); has_path = (next_token == '.'); if (has_path) { read_next_token(); parse_attribute_path(); } /* Read the assignment token. */ assignment = next_token; if (assignment != TOK_ASSIGN && assignment != TOK_ASSIGN_PLUS && assignment != TOK_ASSIGN_MINUS && assignment != TOK_ASSIGN_ASTERISK && assignment != TOK_ASSIGN_SLASH) { complain( "\":=\", \":=+\", \":=-\", \":=*\", or \":=/\" expected, " "not %s.", token_as_text( next_token ) ); } read_next_token(); parse_value(); if (has_path) { switch (assignment) { case TOK_ASSIGN: emit_instr( INS_SET_VAR_PATH, index ); break; case TOK_ASSIGN_PLUS: emit_instr( INS_PLUS_VAR_PATH, index ); break; case TOK_ASSIGN_MINUS: emit_instr( INS_MINUS_VAR_PATH, index ); break; case TOK_ASSIGN_ASTERISK: emit_instr( INS_ASTERISK_VAR_PATH, index ); break; case TOK_ASSIGN_SLASH: emit_instr( INS_SLASH_VAR_PATH, index ); break; } } else { switch (assignment) { case TOK_ASSIGN: emit_instr( INS_SET_VAR, index ); break; case TOK_ASSIGN_PLUS: emit_instr( INS_PLUS_VAR, index ); break; case TOK_ASSIGN_MINUS: emit_instr( INS_MINUS_VAR, index ); break; case TOK_ASSIGN_ASTERISK: emit_instr( INS_ASTERISK_VAR, index ); break; case TOK_ASSIGN_SLASH: emit_instr( INS_SLASH_VAR, index ); break; } } parse_token( ';' ); } /*---------------------------------------------------------------------------*/ static void parse_break_statement( void ) /* Parse a "break" statement. */ { loop_node_t *loop; new_source_line(); parse_token( TOK_BREAK ); if (next_token == TOK_IDENT) { FOREACH( loop, loop_list ) { if (loop->name != NULL && strcmp_no_case( token_name, loop->name ) == 0) break; } read_next_token(); } else loop = (loop_node_t *) loop_list.first; if (loop == NULL) complain( "\"break\" must be within a loop." ); add_instr_to_list( &loop->out_jumps, emit_instr( INS_JUMP, 0 ) ); parse_token( ';' ); } /*---------------------------------------------------------------------------*/ static void parse_choose_statement( void ) /* Parse a "choose" statement. */ { string_t var_name; instr_t *patch_p; int_t label; int_t var_index; new_source_line(); parse_token( TOK_CHOOSE ); parse_var_name( &var_name ); parse_token( TOK_IN ); /* Reserve place for variables. */ var_index = code.stack_index; emit_instr( INS_PUSH_NULL, 1 ); parse_value(); emit_instr( INS_PUSH_VAR, var_index + 1 ); emit_instr( INS_GET_1ST_ELEMENT, 0 ); emit_instr( INS_PUSH_VAR, var_index + 2 ); emit_instr( INS_TERMINATE_IF_NULL, 0 ); label = code.instr_count; emit_instr( INS_PUSH_VAR, var_index + 2 ); emit_instr( INS_SET_VAR, var_index ); emit_instr( INS_ITERATE, var_index + 2 ); emit_instr( INS_PUSH_VAR, var_index + 2 ); patch_p = emit_instr( INS_JUMP_IF_NULL, 0 ); emit_instr( INS_JUMP_LATER, label ); patch_instr( patch_p, code.instr_count ); define_var_in_scope( var_name, var_index ); free_mem( &var_name ); emit_instr( INS_POP, 2 ); /* Pop list and element of this list. */ parse_token( ';' ); } /*---------------------------------------------------------------------------*/ static void parse_continue_statement( void ) /* Parse a "continue" statement. */ { loop_node_t *loop; new_source_line(); parse_token( TOK_CONTINUE ); if (next_token == TOK_IDENT) { FOREACH( loop, loop_list ) { if (loop->name != NULL && strcmp_no_case( token_name, loop->name ) == 0) break; } read_next_token(); } else loop = (loop_node_t *) loop_list.first; if (loop == NULL) complain( "\"continue\" must be within a loop." ); add_instr_to_list( &loop->repeat_jumps, emit_instr( INS_JUMP, 0 ) ); parse_token( ';' ); } /*---------------------------------------------------------------------------*/ static void parse_define_statement( void ) /* Parse a "define" statement. */ { int_t var_count; /* Number of variables to be assigned. */ list_t var_name_list; name_node_t *name_node; int_t base_index; string_t var_name; new_source_line(); parse_token( TOK_DEFINE ); if (next_token == '<') { /* Parse a list assignment. */ base_index = code.stack_index; var_count = 0; clear_list( &var_name_list ); parse_token( '<' ); while (TRUE) { name_node = new_node( &var_name_list, sizeof( name_node_t ), LIST_END ); parse_var_name( &name_node->name ); var_count++; if (next_token != ',') break; read_next_token(); } parse_token( '>' ); parse_token( TOK_ASSIGN ); parse_value(); emit_instr( INS_DECOMPOSE_LIST, var_count ); FOREACH_FREE( name_node, var_name_list ) { define_var_in_scope( name_node->name, base_index ); free_mem( &name_node->name ); base_index++; } } else { /* Parse a regular assignment. */ parse_var_name( &var_name ); parse_token( TOK_ASSIGN ); parse_value(); define_var_in_scope( var_name, code.stack_index - 1 ); free_mem( &var_name ); } parse_token( ';' ); } /*---------------------------------------------------------------------------*/ static void parse_foreach_statement( void ) /* Parse a "foreach" statement. */ { string_t loop_name; /* Name of loop. */ string_t var_name; /* Name of iteration variable. */ int_t label; /* PC to jump to when repeating loop. */ int_t list_index; loop_node_t *loop; new_source_line(); if (next_token == TOK_IDENT) { FOREACH( loop, loop_list ) { if (loop->name != NULL && strcmp_no_case( token_name, loop->name ) == 0) complain( "No nested loops of same name allowed." ); } loop_name = new_string( token_name, NULL ); read_next_token(); parse_token( ':' ); } else loop_name = NULL; /* Create loop list. */ loop = new_node( &loop_list, sizeof( loop_node_t ), LIST_START ); loop->name = loop_name; clear_list( &loop->repeat_jumps ); clear_list( &loop->out_jumps ); parse_token( TOK_FOREACH ); parse_var_name( &var_name ); parse_token( TOK_IN ); parse_value(); parse_token( ':' ); list_index = code.stack_index - 1; emit_instr( INS_PUSH_VAR, list_index ); emit_instr( INS_GET_1ST_ELEMENT, 0 ); /* Emit code to test if loop will be repeated. */ label = code.instr_count; emit_instr( INS_PUSH_VAR, list_index + 1 ); add_instr_to_list( &loop->out_jumps, emit_instr( INS_JUMP_IF_NULL, 0 ) ); /* Open a new scope, create visible copies of iteration variables, * parse statements and close scope. */ open_scope(); emit_instr( INS_PUSH_VAR, list_index + 1 ); define_var_in_scope( var_name, code.stack_index - 1 ); parse_statements(); close_scope( TRUE ); parse_token( TOK_END ); if (next_token == TOK_FOREACH) read_next_token(); parse_token( ';' ); no_source_line(); /* Patch the jumps to repeat the loop. */ if (loop->repeat_jumps.first != NULL) { patch_instr_list( &loop->repeat_jumps, code.instr_count ); emit_instr( INS_POP_TO, list_index + 2 ); } /* Iterate variables. */ emit_instr( INS_ITERATE, list_index + 1 ); emit_instr( INS_JUMP, label ); /* Patch the jumps to exit. */ patch_instr_list( &loop->out_jumps, code.instr_count ); free_first_node( &loop_list ); free_mem( &loop_name ); /* Pop iteration variable and list. */ emit_instr( INS_POP_TO, list_index ); free_mem( &var_name ); } /*---------------------------------------------------------------------------*/ static void parse_if_statement( void ) /* Parse an "if" statement. */ { condition_t condition; list_t end_jumps; list_t else_jumps; instr_t *end_jump; bool_t need_jump_to_end; clear_list( &else_jumps ); clear_list( &end_jumps ); need_jump_to_end = FALSE; test_token( TOK_IF ); do { if (need_jump_to_end) { /* Emit jump if there is already another branch. */ no_source_line(); end_jump = emit_instr( INS_JUMP, 0 ); add_instr_to_list( &end_jumps, end_jump ); } read_next_token(); new_source_line(); /* Jump here if previous conditions were false. */ patch_instr_list( &else_jumps, code.instr_count ); parse_condition( &condition ); parse_token( TOK_THEN ); /* Fall through if condition is true. */ else_jumps = condition.false_jumps; negate_jump( condition.last_jump ); add_instr_to_list( &else_jumps, condition.last_jump ); patch_instr_list( &condition.true_jumps, code.instr_count ); open_scope(); define_pattern_vars(); parse_statements(); close_scope( TRUE ); need_jump_to_end = TRUE; } while (next_token == TOK_ELSEIF); if (next_token == TOK_ELSE) { /* Emit a jump to the end. */ no_source_line(); end_jump = emit_instr( INS_JUMP, 0 ); add_instr_to_list( &end_jumps, end_jump ); read_next_token(); patch_instr_list( &else_jumps, code.instr_count ); open_scope(); parse_statements(); close_scope( TRUE ); } else patch_instr_list( &else_jumps, code.instr_count ); parse_token( TOK_END ); if (next_token == TOK_IF) read_next_token(); patch_instr_list( &end_jumps, code.instr_count ); parse_token( ';' ); } /*---------------------------------------------------------------------------*/ static void parse_list_assignment( void ) /* Parse a list assignment. */ { int_t var_count; /* Number of variables to be assigned. */ int_t path_var_count; /* Number of variables that have a path. */ int_t i; list_t var_list; var_node_t *var_node; string_t var_name; int_t base_index, path_index, var_index; base_index = code.stack_index; new_source_line(); var_count = path_var_count = 0; clear_list( &var_list ); parse_token( '<' ); while (TRUE) { parse_var_name( &var_name ); var_index = find_variable( var_name ); free_mem( &var_name ); if (next_token == '.') { read_next_token(); path_index = base_index + path_var_count; parse_attribute_path(); path_var_count++; } else path_index = -1; var_node = new_node( &var_list, sizeof( var_node_t ), LIST_END ); var_node->var_index = var_index; var_node->path_index = path_index; var_count++; if (next_token != ',') break; read_next_token(); } parse_token( '>' ); parse_token( TOK_ASSIGN ); parse_value(); emit_instr( INS_DECOMPOSE_LIST, var_count ); for (i = 0; i < var_count; i++) { var_node = (var_node_t *) var_list.first; var_index = var_node->var_index; path_index = var_node->path_index; if (path_index != -1) { emit_instr( INS_PUSH_VAR, path_index ); emit_instr( INS_PUSH_VAR, base_index + path_var_count + i ); emit_instr( INS_SET_VAR_PATH, var_index ); } else { emit_instr( INS_PUSH_VAR, base_index + path_var_count + i ); emit_instr( INS_SET_VAR, var_index ); } free_first_node( &var_list ); } emit_instr( INS_POP, path_var_count + var_count ); parse_token( ';' ); } /*---------------------------------------------------------------------------*/ static void parse_select_statement( void ) /* Parse a "select" or "parallel" statement. */ { list_t end_jumps; instr_t *last_jump; int_t start_token; last_jump = NULL; clear_list( &end_jumps ); if (next_token != TOK_SELECT && next_token != TOK_PARALLEL) complain( "Missing \"select\" or \"parallel\"." ); start_token = next_token; do { read_next_token(); /* Read over "select, "parallel", "or" or "and". */ if (last_jump != NULL) { /* Jump to end and patch JUMP_LATER if there is already a subrule. */ no_source_line(); add_instr_to_list( &end_jumps, emit_instr( INS_JUMP, 0 ) ); patch_instr( last_jump, code.instr_count ); } else new_source_line(); last_jump = emit_instr( INS_JUMP_LATER, 0 ); open_scope(); parse_statements(); close_scope( TRUE ); } while ((start_token == TOK_PARALLEL && next_token == TOK_AND) || (start_token == TOK_SELECT && next_token == TOK_OR)); /* The last patch is invalid, replace it by an INS_NOP. */ *last_jump = INSTR( INS_NOP, 0 ); patch_instr_list( &end_jumps, code.instr_count ); parse_token( TOK_END ); if (next_token == start_token) read_next_token(); parse_token( ';' ); } /*---------------------------------------------------------------------------*/ static void parse_repeat_statement( void ) /* Parse a "repeat" statement. */ { condition_t condition; int_t label; /* Label where to jump back. */ int_t values_to_pop; /* Number of values to pop when exiting. */ scope_node_t *scope; /* No need for "new_source_line" since no code is generated here. */ parse_token( TOK_REPEAT ); label = code.instr_count; open_scope(); parse_statements(); scope = (scope_node_t *) scope_list.first; values_to_pop = code.stack_index - scope->initial_index; new_source_line(); parse_token( TOK_WHILE ); parse_condition( &condition ); parse_token( ';' ); patch_instr_list( &condition.true_jumps, code.instr_count ); define_pattern_vars(); parse_statements(); close_scope( TRUE ); parse_token( TOK_END ); if (next_token == TOK_REPEAT) read_next_token(); parse_token( ';' ); no_source_line(); emit_instr( INS_JUMP, label ); patch_instr_list( &condition.false_jumps, code.instr_count ); negate_jump( condition.last_jump ); patch_instr( condition.last_jump, code.instr_count ); /* We have to pop manually, since we jumped from midst a scope. */ if (values_to_pop > 0) emit_instr( INS_POP, values_to_pop ); } /*---------------------------------------------------------------------------*/ static void parse_require_statement( void ) /* Parse a "require" statement. */ { condition_t condition; new_source_line(); if (next_token != TOK_REQUIRE && next_token != '?') { complain( "\"require\" or \"?\" expected, not %s.", token_as_text( next_token ) ); } read_next_token(); parse_condition( &condition ); patch_instr_list( &condition.false_jumps, code.instr_count ); emit_instr( INS_TERMINATE, 0 ); patch_instr_list( &condition.true_jumps, code.instr_count ); patch_instr( condition.last_jump, code.instr_count ); define_pattern_vars(); parse_token( ';' ); } /*---------------------------------------------------------------------------*/ static void parse_result_statement( void ) /* Parse a "result" statement. */ { int_t rule_set; new_source_line(); parse_token( TOK_RESULT ); switch (rule_type) { case COMBI_RULE: parse_value(); parse_token( ',' ); if (next_token == TOK_ACCEPT) { read_next_token(); emit_instr( INS_ADD_END_STATE, 0 ); } else { parse_rule_set( &rule_set ); emit_instr( INS_ADD_STATE, rule_set ); } break; case END_RULE: parse_value(); parse_token( ',' ); parse_token( TOK_ACCEPT ); emit_instr( INS_ADD_END_STATE, 0 ); break; case ALLO_RULE: parse_value(); parse_token( ',' ); parse_value(); emit_instr( INS_ADD_ALLO, 0 ); break; case ROBUST_RULE: parse_value(); if (next_token == ',') { read_next_token(); parse_value(); emit_instr( INS_ADD_ALLO, 0 ); } else emit_instr( INS_ADD_END_STATE, 0 ); break; case FILTER_RULE: parse_value(); emit_instr( INS_ADD_END_STATE, 0 ); break; default: complain( "\"result\" not allowed in this rule." ); } parse_token( ';' ); } /*---------------------------------------------------------------------------*/ static void parse_return_statement( void ) /* Parse a "return" statement. */ { rule_t *rule; new_source_line(); parse_token( TOK_RETURN ); parse_value(); if (rule_type == SUBRULE) { rule = pool_item( code.rule_pool, code.rule_count ); emit_instr( INS_RETURN, rule->param_count ); } else if (rule_type == PRUNING_RULE) emit_instr( INS_ACCEPT, 0 ); else complain( "\"return\" is only allowed in subrules and pruning rules." ); parse_token( ';' ); } /*---------------------------------------------------------------------------*/ static void parse_statements( void ) /* Parse a statement sequence. */ { while (TRUE) { switch (next_token) { case TOK_ASSERT: case '!': parse_assert_statement(); break; case TOK_VARIABLE: parse_assignment(); break; case TOK_BREAK: parse_break_statement(); break; case TOK_CHOOSE: parse_choose_statement(); break; case TOK_CONTINUE: parse_continue_statement(); break; case TOK_DEFINE: parse_define_statement(); break; case TOK_ERROR: new_source_line(); read_next_token(); parse_value(); emit_instr( INS_ERROR, 0 ); parse_token( ';' ); break; case TOK_FOREACH: case TOK_IDENT: parse_foreach_statement(); break; case TOK_IF: parse_if_statement(); break; case '<': parse_list_assignment(); break; case TOK_SELECT: case TOK_PARALLEL: parse_select_statement(); break; case TOK_REPEAT: parse_repeat_statement(); break; case TOK_REQUIRE: case '?': parse_require_statement(); break; case TOK_RESULT: parse_result_statement(); break; case TOK_RETURN: parse_return_statement(); break; case TOK_STOP: new_source_line(); read_next_token(); emit_instr( INS_TERMINATE, 0 ); parse_token( ';' ); break; default: return; } } } /* Parse functions for rules. ===============================================*/ static void parse_rule( void ) /* Parse a rule. */ { int_t rule_token; string_t rule_name, rule_file; int_t param_count, i, rule_line; list_t params; name_node_t *param; rule_line = current_line_number(); rule_file = current_file_name(); rule_token = next_token; switch (rule_token) { case TOK_ALLO_RULE: if (code.file_type != ALLO_RULE_FILE) complain( "\"allo_rule\" only allowed in allo rule files." ); rule_type = ALLO_RULE; break; case TOK_COMBI_RULE: if (code.file_type == ALLO_RULE_FILE) complain( "\"combi_rule\" not allowed in allo rule files." ); rule_type = COMBI_RULE; break; case TOK_END_RULE: if (code.file_type == ALLO_RULE_FILE) complain( "\"end_rule\" not allowed in allo rule files." ); rule_type = END_RULE; break; case TOK_INPUT_FILTER: if (code.file_type != SYNTAX_RULE_FILE) complain( "\"input_filter\" only allowed in syntax rule files." ); rule_type = FILTER_RULE; break; case TOK_OUTPUT_FILTER: rule_type = FILTER_RULE; break; case TOK_PRUNING_RULE: if (code.file_type == ALLO_RULE_FILE) complain( "\"pruning_rule\" not allowed in allo rule files." ); rule_type = PRUNING_RULE; break; case TOK_ROBUST_RULE: if (code.file_type != MORPHO_RULE_FILE) complain( "\"robust_rule\" only allowed in morphology rule files." ); rule_type = ROBUST_RULE; break; case TOK_SUBRULE: rule_type = SUBRULE; break; } read_next_token(); /* Remember rule name. */ test_token( TOK_IDENT ); rule_name = new_string( token_name, NULL ); read_next_token(); /* Read parameter list. */ clear_list( ¶ms ); param_count = 0; parse_token( '(' ); while (next_token != ')') { test_token( TOK_VARIABLE ); param = new_node( ¶ms, sizeof( name_node_t ), LIST_END ); param->name = new_string( token_name, NULL ); param_count++; read_next_token(); if (next_token != ',') break; read_next_token(); } parse_token( ')' ); switch (rule_type) { case ALLO_RULE: case FILTER_RULE: case PRUNING_RULE: if (param_count != 1) complain( "%s takes one parameter.", token_as_text( rule_token ) ); break; case END_RULE: case ROBUST_RULE: if (param_count < 1 || param_count > 2) complain( "%s takes 1 or 2 parameters.", token_as_text( rule_token ) ); break; case COMBI_RULE: if (param_count < 2 || param_count > 4) complain( "\"combi_rule\" takes 2 to 4 parameters." ); break; case SUBRULE: break; } code.rule_count = enter_rule( rule_name, code.instr_count, rule_type, param_count, rule_line, rule_file ); /* Save rule number if this is a special rule. */ switch (rule_token) { case TOK_PRUNING_RULE: if (code.pruning_rule != -1) complain( "\"pruning_rule\" defined twice." ); code.pruning_rule = code.rule_count; break; case TOK_ROBUST_RULE: if (code.robust_rule != -1) complain( "\"robust_rule\" defined twice." ); code.robust_rule = code.rule_count; break; case TOK_ALLO_RULE: if (code.allo_rule != -1) complain( "\"allo_rule\" defined twice." ); code.allo_rule = code.rule_count; break; case TOK_INPUT_FILTER: if (code.input_filter != -1) complain( "\"input_filter\" defined twice." ); code.input_filter = code.rule_count; break; case TOK_OUTPUT_FILTER: if (code.output_filter != -1) complain( "\"output_filter\" defined twice." ); code.output_filter = code.rule_count; break; } parse_token( ':' ); /* Parse rule body. */ open_scope(); if (rule_type == SUBRULE) i = - (param_count + 2); else { i = code.stack_index; code.stack_index += param_count; } FOREACH_FREE( param, params ) { define_var_in_scope( param->name, i ); i++; free_mem( ¶m->name ); } parse_statements(); close_scope( FALSE ); /* Parse rule end. */ new_source_line(); if (rule_type == SUBRULE || rule_type == PRUNING_RULE) emit_instr( INS_SYSTEM_ERROR, NO_RETURN_ERROR ); else emit_instr( INS_TERMINATE, 0 ); parse_token( TOK_END ); if (next_token == rule_token) read_next_token(); if (next_token == TOK_IDENT) { if (strcmp_no_case( token_name, rule_name ) != 0) complain( "\"%s\" expected, not \"%s\".", rule_name, token_name ); read_next_token(); } free_mem( &rule_name ); parse_token( ';' ); } /*---------------------------------------------------------------------------*/ static void parse_constant_definition( bool_t fixed ) /* Parse a constant definition. If FIXED == FALSE, define a default value. */ { string_t const_name; int_t const_index; read_next_token(); test_token( TOK_CONSTANT ); const_name = new_string( token_name, NULL ); read_next_token(); parse_token( TOK_ASSIGN ); parse_constant_value( &const_index ); define_constant( const_name, const_index, fixed ); free_mem( &const_name ); parse_token( ';' ); } /*---------------------------------------------------------------------------*/ static void parse_rules( void ) /* Parse rules, constant definitions and includes until EOF. */ { string_t file_name, path; while (next_token != EOF) { if (next_token == TOK_INCLUDE) { /* Parse file name and expand to an absolute file name. */ read_next_token(); test_token( TOK_STRING ); path = absolute_path( token_string, current_file_name() ); file_name = copy_string_to_pool( code.string_pool, path, NULL ); free_mem( &path ); read_next_token(); begin_include( file_name ); parse_rules(); end_include(); parse_token( ';' ); } else if (next_token == TOK_DEFINE || next_token == TOK_DEFAULT) parse_constant_definition( (next_token == TOK_DEFINE) ); else if (next_token == TOK_INITIAL) { if (code.file_type != MORPHO_RULE_FILE && code.file_type != SYNTAX_RULE_FILE) { complain( "\"initial\" only allowed in combi rule files." ); } if (code.initial_rule_set != -1) complain( "Initial state is already defined." ); read_next_token(); parse_constant_value( &code.initial_feat ); parse_token( ',' ); parse_rule_set( &code.initial_rule_set ); parse_token( ';' ); } else parse_rule(); } } /*---------------------------------------------------------------------------*/ void parse_rule_file( void ) /* Parse a rule file. */ { last_statement_line = -1; last_statement_file_name = NULL; code.initial_rule_set = -1; code.robust_rule = code.pruning_rule = -1; code.allo_rule = code.input_filter = code.output_filter = -1; parse_rules(); if ((code.file_type == MORPHO_RULE_FILE || code.file_type == SYNTAX_RULE_FILE) && code.initial_rule_set == -1) { complain( "Missing initial state." ); } else if (code.file_type == ALLO_RULE_FILE && code.allo_rule == -1) complain( "Missing allo rule." ); } /* End of file. =============================================================*/ malaga-7.12/rule_parser.h0000644000175000017500000000060710236624435014711 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module parses Malaga rule files. */ /* Functions. ===============================================================*/ extern void parse_rule_file( void ); /* Parse a rule file. */ /* End of file. =============================================================*/ malaga-7.12/rules.c0000644000175000017500000007246010425347473013525 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module contains the Malaga rule interpreter. */ /* Includes. ================================================================*/ #include #include #include #include #include #include #include #include "basic.h" #include "pools.h" #include "values.h" #include "symbols.h" #include "patterns.h" #include "files.h" #include "malaga_files.h" #include "rule_type.h" #include "hangul.h" #include "rules.h" /* Types. ===================================================================*/ typedef struct /* Used to hold the value for a "switch". */ { list_node_t *next; symbol_t key; value_t value; } switch_node_t; typedef struct { list_node_t *next; int_t pc; int_t nested_subrules; int_t base; int_t bottom; } path_node_t; /* Global variables. ========================================================*/ void (*add_end_state)( value_t feat ); void (*add_running_state)( value_t feat, int_t rule_set ); void (*add_allo)( string_t surf, value_t feat ); void (*debug_rule)( bool_t interrupt ); void (*transmit)( void ); rule_sys_t *executed_rule_sys; int_t executed_rule_number = -1; int_t pc = -1; /* Current instruction index. */ int_t base; /* Current frame base. */ int_t nested_subrules; /* Current nesting level. */ int_t path_count; /* Current number of alternative paths. */ rule_sys_t *debug_rule_sys; bool_t rule_successful; /* Variables. ===============================================================*/ static int_t bottom; /* Index of first stack element used in this branch. */ static list_t path_list; /* List of nodes for alternative paths. */ static list_t switch_list; /* The list of switches. */ static switch_node_t *current_switch; /* Needed for "get_first_switch" and "get_next_switch". */ /* Functions. ===============================================================*/ void set_switch( symbol_t key, value_t value ) /* Set the switch KEY to VALUE. */ { switch_node_t *node; switch_node_t *pre; /* predecessor node */ string_t name = get_symbol_name( key ); pre = NULL; FOREACH( node, switch_list ) { if (strcmp_no_case( name, get_symbol_name( node->key ) ) <= 0) break; pre = node; } if (node != NULL && key == node->key) free_mem( &node->value ); else { node = new_mem( sizeof( switch_node_t ) ); node->key = key; insert_node( &switch_list, (list_node_t *) node, (list_node_t *) pre ); } node->value = new_value( value ); } /*---------------------------------------------------------------------------*/ value_t get_switch( symbol_t key ) /* Return the value of the switch KEY. * Report an error if this switch doesn't exist. */ { switch_node_t *switch_node; FOREACH( switch_node, switch_list ) { if (switch_node->key == key) return switch_node->value; } complain( "Switch \"%s\" is not defined.", get_symbol_name( key ) ); } /*---------------------------------------------------------------------------*/ void get_first_switch( value_t *value, symbol_t *key ) /* Return the first switch in *VALUE and its key in *KEY. * If there is no switch, *VALUE is NULL. */ { current_switch = (switch_node_t *) switch_list.first; get_next_switch( value, key ); } /*---------------------------------------------------------------------------*/ void get_next_switch( value_t *value, symbol_t *key ) /* Return the value of the next switch in *VALUE and its key in *KEY. * If there is no more switch, *VALUE is NULL. */ { if (current_switch == NULL) *value = NULL; else { *key = current_switch->key; *value = current_switch->value; current_switch = (switch_node_t *) current_switch->next; } } /*---------------------------------------------------------------------------*/ void free_switches( void ) /* Free all switches. */ { switch_node_t *my_switch; FOREACH_FREE( my_switch, switch_list ) free_mem( &my_switch->value ); } /* Rule execution. ==========================================================*/ static void standard_function( int_t function ) /* Stack effect: VALUE -> NEW_VALUE. * Perform function FUNCTION on VALUE yielding NEW_VALUE. */ { char_t *buffer; string_t string; int_t start, end, len; gunichar code; switch (function) { case FUNC_TO_ATOMS: push_value( get_atoms( value_to_symbol( value_stack[ --top ] ) ) ); break; case FUNC_TO_MULTI: push_symbol_value( find_multi_symbol( value_stack[ --top ] ) ); break; case FUNC_TO_SET: convert_list_to_set(); break; case FUNC_IS_CAPITAL: code = g_utf8_get_char( value_to_string( value_stack[ --top ] ) ); if (g_unichar_tolower( code ) != code) push_symbol_value( YES_SYMBOL ); else push_symbol_value( NO_SYMBOL ); break; case FUNC_GET_SWITCH: push_value( get_switch( value_to_symbol( value_stack[ --top ] ) ) ); break; case FUNC_GET_LENGTH: if (get_value_type( value_stack[ top - 1 ] ) == STRING_SYMBOL) { push_number_value( g_utf8_strlen( value_to_string( value_stack[ --top ] ), -1 ) ); } else push_number_value( get_list_length( value_stack[ --top ] ) ); break; case FUNC_GET_VALUE_TYPE: push_symbol_value( get_value_type( value_stack[ --top ] ) ); break; case FUNC_GET_VALUE_STRING: buffer = value_to_readable( value_stack[ --top ], TRUE, -1 ); encode_hangul( &buffer ); push_string_value( buffer, NULL ); free_mem( &buffer ); break; case FUNC_TRANSMIT: if (transmit == NULL) complain( "No transmit function available." ); transmit(); break; case FUNC_FLOOR: push_number_value( floor( value_to_double( value_stack[ --top ] ) ) ); break; case FUNC_SUBSTRING: string = value_to_string( value_stack[ top - 3 ] ); start = value_to_int( value_stack[ top - 2 ] ); if (value_stack[ top - 1 ] == NULL) end = start; else end = value_to_int( value_stack[ top - 1 ] ); len = g_utf8_strlen( string, -1 ); if (start < 0) start += len + 1; if (end < 0) end += len + 1; if (end < start) push_string_value( "", NULL ); else if (start <= 0 || end > len) complain( "Substring indexes out of bounds." ); else push_string_value( g_utf8_offset_to_pointer( string, start - 1 ), g_utf8_offset_to_pointer( string, end ) ); value_stack[ top - 4 ] = value_stack[ top - 1 ]; top -= 3; break; default: complain( "Internal error." ); } } /*---------------------------------------------------------------------------*/ void execute_rule( rule_sys_t *rule_sys, int_t rule_number ) /* Execute rule RULE_NUMBER in the rule system RULE_SYS. * Any parameters must be on the value stack. */ { static symbol_t nil = NIL_SYMBOL; /* The "nil" symbol. */ bool_t terminate; /* Shall we terminate the current rule internal path? */ int_t i, info, new_pc, old_top, old_base, line; instr_t instruction; symbol_t symbol; path_node_t *path; string_t file; /* Initialise the value stack. */ top = rule_sys->rules[ rule_number ].param_count; base = bottom = 0; /* Reset nesting and alternative paths. */ nested_subrules = path_count = 0; while (path_list.first != NULL) free_first_node( &path_list ); /* Copy RULE_SYS and RULE_NUMBER for debugger and error messages. */ executed_rule_sys = rule_sys; executed_rule_number = rule_number; pc = rule_sys->rules[ rule_number ].first_instr; TRY { rule_successful = FALSE; terminate = FALSE; while (! terminate) { if (user_break_requested) { source_of_instr( rule_sys, pc, NULL, &file, NULL ); if (file != NULL) { if (debug_rule_sys == rule_sys) debug_rule( TRUE ); else complain( "User break." ); } } else if (debug_rule_sys == rule_sys) debug_rule( FALSE ); instruction = rule_sys->instrs[ pc ]; new_pc = pc + 1; info = INSTR_INFO( instruction ); switch (OPCODE( instruction ) ) { case INS_SYSTEM_ERROR: switch (info) { case ASSERTION_ERROR: complain( "Assertion failed." ); case NO_RETURN_ERROR: complain( "Missing return statement." ); } case INS_ERROR: complain( "%s", value_to_string( value_stack[ --top ] ) ); case INS_TERMINATE: terminate = TRUE; break; case INS_NOP: break; case INS_TERMINATE_IF_NULL: if (value_stack[ --top ] == NULL) terminate = TRUE; break; case INS_ADD_END_STATE: add_end_state( value_stack[ --top ] ); rule_successful = TRUE; break; case INS_ADD_STATE: add_running_state( value_stack[ --top ], info ); rule_successful = TRUE; break; case INS_ADD_ALLO: add_allo( value_to_string( value_stack[ top - 2 ] ), value_stack[ top - 1] ); top -= 2; rule_successful = TRUE; break; case INS_ACCEPT: path_count = 0; while (path_list.first != NULL) free_first_node( &path_list ); terminate = TRUE; break; case INS_PUSH_NULL: for (i = 0; i < info; i++) push_value( NULL ); break; case INS_PUSH_VAR: push_value( value_stack[ base + info ] ); break; case INS_PUSH_CONST: push_value( rule_sys->values + info ); break; case INS_PUSH_SYMBOL: push_symbol_value( info ); break; case INS_PUSH_PATTERN_VAR: push_string_value( pattern_var[ info ], NULL ); break; case INS_POP: top -= info; break; case INS_POP_TO: top = base + info; break; case INS_BUILD_LIST: build_list( info ); break; case INS_BUILD_RECORD: build_record( info ); break; case INS_BUILD_PATH: build_path( info ); break; case INS_DOT_OPERATION: dot_operation(); if (value_stack[ top - 1 ] == NULL) value_stack[ top - 1 ] = &nil; break; case INS_PLUS_OPERATION: plus_operation(); break; case INS_MINUS_OPERATION: minus_operation(); break; case INS_ASTERISK_OPERATION: asterisk_operation(); break; case INS_SLASH_OPERATION: slash_operation(); break; case INS_UNARY_MINUS_OP: unary_minus_operation(); break; case INS_GET_ATTRIBUTE: value_stack[ top - 1 ] = get_attribute( value_stack[ top - 1 ], (symbol_t) info ); if (value_stack[ top - 1 ] == NULL) value_stack[ top - 1 ] = &nil; break; case INS_REMOVE_ATTRIBUTE: remove_attribute( (symbol_t) info ); break; case INS_STD_FUNCTION: standard_function( info ); break; case INS_MATCH: if (match_pattern( value_to_string( value_stack[ --top ] ), rule_sys->strings + info )) { push_symbol_value( YES_SYMBOL ); } else push_symbol_value( NO_SYMBOL ); break; case INS_SET_VAR: value_stack[ base + info ] = value_stack[ --top ]; break; case INS_PLUS_VAR: insert_value( 1, value_stack[ base + info ] ); plus_operation(); value_stack[ base + info ] = value_stack[ --top ]; break; case INS_MINUS_VAR: insert_value( 1, value_stack[ base + info ]); minus_operation(); value_stack[ base + info ] = value_stack[ --top ]; break; case INS_ASTERISK_VAR: insert_value( 1, value_stack[ base + info ] ); asterisk_operation(); value_stack[ base + info ] = value_stack[ --top ]; break; case INS_SLASH_VAR: insert_value( 1, value_stack[ base + info ] ); slash_operation(); value_stack[ base + info ] = value_stack[ --top ]; break; case INS_SET_VAR_PATH: insert_value( 2, value_stack[ base + info ] ); modify_value_part( right_value ); value_stack[ base + info ] = value_stack[ --top ]; break; case INS_PLUS_VAR_PATH: insert_value( 2, value_stack[ base + info ] ); modify_value_part( plus_operation ); value_stack[ base + info ] = value_stack[ --top ]; break; case INS_MINUS_VAR_PATH: insert_value( 2, value_stack[ base + info ] ); modify_value_part( minus_operation ); value_stack[ base + info ] = value_stack[ --top ]; break; case INS_ASTERISK_VAR_PATH: insert_value( 2, value_stack[ base + info ] ); modify_value_part( asterisk_operation ); value_stack[ base + info ] = value_stack[ --top ]; break; case INS_SLASH_VAR_PATH: insert_value( 2, value_stack[ base + info ] ); modify_value_part( slash_operation ); value_stack[ base + info ] = value_stack[ --top ]; break; case INS_DECOMPOSE_LIST: if (info != decompose_list()) complain( "List doesn't contain %d elements.", info ); break; case INS_GET_1ST_ELEMENT: get_first_element(); break; case INS_ITERATE: get_next_element( base + info ); break; case INS_JUMP: new_pc = info; break; case INS_JUMP_IF_EQUAL: if (values_equal( value_stack[top - 2], value_stack[top - 1] )) new_pc = info; top -= 2; break; case INS_JUMP_IF_NOT_EQUAL: if (! values_equal( value_stack[top - 2], value_stack[top - 1] )) new_pc = info; top -= 2; break; case INS_JUMP_IF_CONGR: if (values_congruent( value_stack[top - 2], value_stack[top - 1] )) new_pc = info; top -= 2; break; case INS_JUMP_IF_NOT_CONGR: if (! values_congruent( value_stack[top - 2], value_stack[top - 1] )) new_pc = info; top -= 2; break; case INS_JUMP_IF_IN: if (value_in_value( value_stack[top - 2], value_stack[top - 1] )) new_pc = info; top -= 2; break; case INS_JUMP_IF_NOT_IN: if (! value_in_value( value_stack[top - 2], value_stack[top - 1] )) new_pc = info; top -= 2; break; case INS_JUMP_IF_LESS: if (value_to_double( value_stack[top - 2] ) < value_to_double( value_stack[top - 1] )) { new_pc = info; } top -= 2; break; case INS_JUMP_IF_NOT_LESS: if (! (value_to_double( value_stack[top - 2] ) < value_to_double( value_stack[top - 1] ))) { new_pc = info; } top -= 2; break; case INS_JUMP_IF_GREATER: if (value_to_double( value_stack[top - 2] ) > value_to_double( value_stack[top - 1] )) { new_pc = info; } top -= 2; break; case INS_JUMP_IF_NOT_GREATER: if (! (value_to_double( value_stack[top - 2] ) > value_to_double( value_stack[top - 1] ))) { new_pc = info; } top -= 2; break; case INS_JUMP_IF_NULL: if (value_stack[ --top ] == NULL) new_pc = info; break; case INS_JUMP_IF_NOT_NULL: if (value_stack[ --top ] != NULL) new_pc = info; break; case INS_JUMP_IF_YES: symbol = value_to_symbol( value_stack[ --top ] ); if (symbol != YES_SYMBOL && symbol != NO_SYMBOL) complain( "Boolean value expected." ); if (symbol == YES_SYMBOL) new_pc = info; break; case INS_JUMP_IF_NO: symbol = value_to_symbol( value_stack[ --top ] ); if (symbol != YES_SYMBOL && symbol != NO_SYMBOL) complain( "Boolean value expected." ); if (symbol == NO_SYMBOL) new_pc = info; break; case INS_JUMP_NOW: old_top = top; path = new_node( &path_list, sizeof( path_node_t ), LIST_START ); path->pc = new_pc; path->nested_subrules = nested_subrules; path->base = base; path->bottom = bottom; while (bottom < old_top) push_value( value_stack[ bottom++ ] ); base += (top - old_top); path_count++; new_pc = info; break; case INS_JUMP_LATER: old_top = top; path = new_node( &path_list, sizeof( path_node_t ), LIST_START ); path->pc = info; path->nested_subrules = nested_subrules; path->base = base; path->bottom = bottom; while (bottom < old_top) push_value( value_stack[ bottom++ ] ); base += (top - old_top); path_count++; break; case INS_JUMP_SUBRULE: push_number_value( base - bottom ); push_number_value( new_pc ); base = top; new_pc = rule_sys->rules[ info ].first_instr; nested_subrules++; break; case INS_RETURN: old_base = bottom + value_to_int( value_stack[ base - 2 ] ); new_pc = value_to_int( value_stack[ base - 1 ] ); value_stack[ base - info - 2 ] = value_stack[ top - 1 ]; /* Result. */ top = base - (info + 1); base = old_base; nested_subrules--; break; default: complain( "Internal error." ); break; } if (! terminate) pc = new_pc; else if (path_list.first != NULL) { /* Load a previously saved rule-internal path and continue. */ path_count--; path = (path_node_t *) path_list.first; top = bottom; base = path->base; bottom = path->bottom; pc = path->pc; nested_subrules = path->nested_subrules; free_first_node( &path_list ); terminate = FALSE; } } } IF_ERROR { source_of_instr( executed_rule_sys, pc, &line, &file, NULL ); print_text( error_text, " (\"%s\", line %d)", name_in_path( file ), line ); if (in_emacs_malaga_mode) printf( "SHOW \"%s\":%d:0\n", file, line ); } END_TRY; pc = -1; executed_rule_number = -1; executed_rule_sys = NULL; } /*---------------------------------------------------------------------------*/ rule_sys_t * read_rule_sys( string_t file_name ) /* Read rule system from file FILE_NAME. * A symbol file must have already been loaded. */ { FILE *stream; rule_header_t header; rule_sys_t *rule_sys; stream = open_stream( file_name, "rb" ); read_vector( &header, sizeof( header ), 1, stream, file_name ); check_header( &header.common_header, file_name, RULE_FILE, MIN_RULE_CODE_VERSION, RULE_CODE_VERSION ); rule_sys = new_mem( sizeof( rule_sys_t ) ); rule_sys->initial_rule_set = header.initial_rule_set; rule_sys->initial_feat = header.initial_feat; rule_sys->robust_rule = header.robust_rule; rule_sys->allo_rule = header.allo_rule; rule_sys->pruning_rule = header.pruning_rule; rule_sys->input_filter = header.input_filter; rule_sys->output_filter = header.output_filter; rule_sys->rule_count = header.rule_count; rule_sys->rules = read_new_vector( sizeof( rule_t ), header.rule_count, stream, file_name ); rule_sys->rule_sets_size = header.rule_sets_size; rule_sys->rule_sets = read_new_vector( sizeof( int_t ), header.rule_sets_size, stream, file_name ); rule_sys->instr_count = header.instr_count; rule_sys->instrs = read_new_vector( sizeof( instr_t ), header.instr_count, stream, file_name ); rule_sys->values_size = header.values_size; rule_sys->values = read_new_vector( sizeof( cell_t ), header.values_size, stream, file_name ); rule_sys->src_line_count = header.src_line_count; rule_sys->src_lines = read_new_vector( sizeof( src_line_t ), header.src_line_count, stream, file_name ); rule_sys->var_count = header.var_count; rule_sys->vars = read_new_vector( sizeof( var_t ), header.var_count, stream, file_name ); rule_sys->var_scope_count = header.var_scope_count; rule_sys->var_scopes = read_new_vector( sizeof( var_scope_t ), header.var_scope_count, stream, file_name ); rule_sys->constant_count = header.constant_count; rule_sys->constants = read_new_vector( sizeof( constant_t ), header.constant_count, stream, file_name ); rule_sys->strings_size = header.strings_size; rule_sys->strings = read_new_vector( sizeof( char_t ), header.strings_size, stream, file_name ); close_stream( &stream, file_name ); return rule_sys; } /*---------------------------------------------------------------------------*/ void free_rule_sys( rule_sys_t **rule_sys ) /* Free all memory used by *RULE_SYS. */ { if (*rule_sys != NULL) { free_mem( &(*rule_sys)->rules ); free_mem( &(*rule_sys)->rule_sets ); free_mem( &(*rule_sys)->instrs ); free_mem( &(*rule_sys)->values ); free_mem( &(*rule_sys)->src_lines ); free_mem( &(*rule_sys)->vars ); free_mem( &(*rule_sys)->var_scopes ); free_mem( &(*rule_sys)->constants ); free_mem( &(*rule_sys)->strings ); free_mem( rule_sys ); } } /* Debug support functions. =================================================*/ void source_of_instr( rule_sys_t *rule_sys, int_t instr_index, int_t *line, string_t *file_name, string_t *rule_name ) /* Set *LINE, *FILE_NAME and *RULE_NAME to appropriate values * for the statement that has generated the instruction at INSTR_INDEX. */ { int_t lower, upper, middle; src_line_t *src_line; int_t rule_number, i, first_instr; rule_t *rule; if (rule_sys->src_line_count == 0 || rule_sys->src_lines[0].instr > instr_index) { if (line != NULL) *line = -1; if (file_name != NULL) *file_name = NULL; if (rule_name != NULL) *rule_name = NULL; return; } /* Find the last SRC_LINE entry with INSTR <= INSTR_INDEX. */ lower = 0; upper = rule_sys->src_line_count - 1; while (lower < upper) { middle = (lower + upper + 1) / 2; src_line = rule_sys->src_lines + middle; if (src_line->instr <= instr_index) lower = middle; else upper = middle - 1; } src_line = rule_sys->src_lines + lower; if (line != NULL) *line = src_line->line; if (file_name != NULL) { if (src_line->file != -1) *file_name = rule_sys->strings + src_line->file; else *file_name = NULL; } /* Find the rule of the statement */ if (rule_name != NULL) { rule_number = 0; first_instr = -1; for (i = 0; i < rule_sys->rule_count; i++) { rule = rule_sys->rules + i; if (rule->first_instr <= instr_index && rule->first_instr > first_instr) { rule_number = i; first_instr = rule->first_instr; } } *rule_name = rule_sys->strings + rule_sys->rules[ rule_number ].name; } } /*---------------------------------------------------------------------------*/ string_t rule_set_readable( rule_sys_t *rule_sys, int_t rule_set ) /* Return RULE_SET in RULE_SYS as a readable string. * The string must be freed after use. */ { text_t *text; bool_t name_has_been_printed; int_t *rule; text = new_text(); if (rule_set == -1) add_to_text( text, "(end state)" ); else { add_to_text( text, "rules " ); rule = rule_sys->rule_sets + rule_set; while (TRUE) { name_has_been_printed = FALSE; while (*rule >= 0) { if (name_has_been_printed) add_to_text( text, ", " ); else name_has_been_printed = TRUE; add_to_text( text, rule_sys->strings + rule_sys->rules[ *rule++ ].name ); } if (*rule == -1) break; add_to_text( text, " else " ); rule++; } } return text_to_string( &text ); } /*---------------------------------------------------------------------------*/ static int_t first_variable_index( int_t instr_index ) /* Return the stack index of the first variable that is visible * when PC is at INSTR_INDEX in RULE_SYS. */ { rule_t *rule, *rule2; int_t i, first_instr; /* Find the rule/subrule we're in. */ rule = NULL; first_instr = -1; for (i = 0; i < executed_rule_sys->rule_count; i++) { rule2 = executed_rule_sys->rules + i; if (rule2->first_instr <= instr_index && rule2->first_instr > first_instr) { rule = rule2; first_instr = rule->first_instr; } } if (rule->type == SUBRULE) return - (2 + rule->param_count); else return 0; } /*---------------------------------------------------------------------------*/ int_t get_frame_count( void ) /* Get the number of frames in the current path. */ { int_t frame, count; /* Count the number of frames. */ count = 1; for (frame = base; frame > bottom; frame = bottom + value_to_int( value_stack[ frame - 2 ] )) { count++; } return count; } /*---------------------------------------------------------------------------*/ void get_frame_info( int_t frame, int_t *pc_index, int_t *base_index, int_t *first_var_index, int_t *last_var_index ) /* Return *PC_INDEX, *BASE_INDEX, *FIRST_VAR_INDEX and *LAST_VAR_INDEX * of the frame no. FRAME. Any result pointer may be NULL. * Frame no. 0 is the current frame, * frame no. "get_frame_count() - 1" is the outermost one. */ { int_t first_var_idx, last_var_idx, base_idx, pc_idx; last_var_idx = top; pc_idx = pc; base_idx = base; first_var_idx = base_idx + first_variable_index( pc_idx ); /* Find the right frame. */ for (; frame > 0; frame--) { last_var_idx = first_var_idx; pc_idx = value_to_int( value_stack[ base_idx - 1 ] ); base_idx = bottom + value_to_int( value_stack[ base_idx - 2 ] ); first_var_idx = base_idx + first_variable_index( pc_idx ); } if (pc_index != NULL) *pc_index = pc_idx; if (base_index != NULL) *base_index = base_idx; if (first_var_index != NULL) *first_var_index = first_var_idx; if (last_var_index != NULL) *last_var_index = last_var_idx; } /*---------------------------------------------------------------------------*/ static var_scope_t * get_var_scope( rule_sys_t *rule_sys, var_t *var, int_t instr_index ) /* Return the stack index of variable VAR at INSTR_INDEX. * Return -1 if it is not currently defined. */ { int_t lower, upper, middle; var_scope_t *var_scope; /* Find last scope whose FIRST_INSTR is not higher than INSTR_INDEX. */ lower = var->first_scope; upper = lower + var->scope_count - 1; while (lower < upper) { middle = (lower + upper + 1) / 2; var_scope = rule_sys->var_scopes + middle; if (var_scope->first_instr <= instr_index) lower = middle; else upper = middle - 1; } /* LOWER is the index of the highest line * with an instruction index not more than INSTR_INDEX. */ if (lower == upper) /* We found a scope. */ { var_scope = rule_sys->var_scopes + lower; if (instr_index >= var_scope->first_instr && instr_index <= var_scope->last_instr) { return var_scope; } } return NULL; } /*---------------------------------------------------------------------------*/ string_t variable_at_index( rule_sys_t *rule_sys, int_t stack_index, int_t instr_index ) /* Return the name of the variable that is defined at STACK_INDEX * when instruction INSTR_INDEX is executed or NULL if there is none. */ { int_t i; var_t *var; var_scope_t *var_scope; /* There is never a variable at stack index -2 or -1. */ if (stack_index == -2 || stack_index == -1) return NULL; /* For each variable name, test if it is the right one. */ for (i = 0; i < rule_sys->var_count; i++) { var = rule_sys->vars + i; var_scope = get_var_scope( rule_sys, var, instr_index ); if (var_scope != NULL && var_scope->stack_index == stack_index) return rule_sys->strings + var->name; } return NULL; } /*---------------------------------------------------------------------------*/ var_scope_t * get_var_scope_by_name( rule_sys_t *rule_sys, string_t var_name, int_t instr_index ) /* Return the scope of variable VAR_NAME at INSTR_INDEX. */ { int_t lower, upper, middle, result; var_t *var; /* Search for the right variable name (binary search). */ lower = 0; upper = rule_sys->var_count - 1; while (lower <= upper) { middle = (lower + upper) / 2; var = rule_sys->vars + middle; result = strcmp_no_case( var_name, rule_sys->strings + var->name ); if (result < 0) upper = middle - 1; else if (result > 0) lower = middle + 1; else return get_var_scope( rule_sys, var, instr_index ); } return NULL; } /*---------------------------------------------------------------------------*/ value_t get_constant( rule_sys_t *rule_sys, string_t name ) /* Return the value of constant NAME in RULE_SYS. * Return NULL if there is no such constant. */ { int_t lower, upper, middle, result; constant_t *constant; /* Search for the right variable name (binary search). */ lower = 0; upper = rule_sys->constant_count - 1; while (lower <= upper) { middle = (lower + upper) / 2; constant = rule_sys->constants + middle; result = strcmp_no_case( name, rule_sys->strings + constant->name ); if (result < 0) upper = middle - 1; else if (result > 0) lower = middle + 1; else return rule_sys->values + constant->value; } return NULL; } /* End of file. =============================================================*/ malaga-7.12/rules.h0000644000175000017500000001453310236624431013517 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module contains the Malaga rule interpreter. */ /* Types. ===================================================================*/ typedef struct /* Contains a rule system of a compiled rule file. * A "..._count" or "..._size" variable contains the number of elements * in the following table. */ { int_t initial_rule_set; /* Rules index of the initial rule set. */ int_t initial_feat; /* Values index of initial feature structure. */ int_t robust_rule; /* Number of robust_rule or -1. */ int_t pruning_rule; /* Number of pruning_rule or -1. */ int_t allo_rule; /* Number of allo_rule or -1. */ int_t input_filter; /* Number of input filter rule or -1. */ int_t output_filter; /* Number of output filter rule or -1. */ rule_t *rules; /* Name and code of every rule. */ int_t rule_count; int_t *rule_sets; /* A collection of lists. Each list is a series of rules, * followed by -1. A list may be subdivided into sublists, * which are separated by -2. The rules of a sublist are * executed if none of the rules of the preceding sublist * has been successful. */ int_t rule_sets_size; instr_t *instrs; /* The actual rule instructions. */ int_t instr_count; cell_t *values; /* All constant Malaga values. */ int_t values_size; char_t *strings; /* Names of files, variables, rules, patterns. */ int_t strings_size; src_line_t *src_lines; /* Correspondence between source lines * and rule instructions. */ int_t src_line_count; var_t *vars; /* Variable names. */ int_t var_count; var_scope_t *var_scopes; /* Variable scopes. */ int_t var_scope_count; constant_t *constants; /* Named constants. */ int_t constant_count; } rule_sys_t; /* Variables. ===============================================================*/ extern void (*add_end_state)( value_t feat ); /* Add a state, consisting of feature structure FEAT, as an end state. * This is a callback function called from "execute_rule". */ extern void (*add_running_state)( value_t feat, int_t rule_set ); /* Add a running state, consisting of feature structure FEAT and RULE_SET. * This is a callback function called from "execute_rule". */ extern void (*add_allo)( string_t surf, value_t feat ); /* Add an allomorph, consisting of SURF and feature structure FEAT, * to the lexicon. This is a callback function called from "execute_rule". */ extern void (*debug_rule)( bool_t interrupt ); /* Called from "execute_rule" before instruction at PC is executed. * This is a callback function called from "execute_rule". */ extern void (*transmit)( void ); /* Stack effects: VALUE -> NEW_VALUE. * Called when FUNC_TRANSMIT is executed. * This is a callback function called from "execute_rule". */ extern rule_sys_t *debug_rule_sys; /* The rule system to debug or NULL. */ extern bool_t rule_successful; /* Indicator for execution of result, accept, or allo statement. Read only! */ /* These values are used by "execute_rule", * but they are global to support debuggers and error messages. Read only! */ extern int_t pc; extern int_t base; extern int_t nested_subrules; extern int_t executed_rule_number; extern rule_sys_t *executed_rule_sys; extern int_t path_count; /* Functions. ===============================================================*/ extern void execute_rule( rule_sys_t *rule_sys, int_t rule_number ); /* Execute rule RULE_NUMBER in the rule system RULE_SYS. * Any parameters must be on the value stack. */ extern rule_sys_t *read_rule_sys( string_t file_name ); /* Read rule system from file FILE_NAME. * A symbol file must have already been loaded. */ extern void free_rule_sys( rule_sys_t **rule_sys ); /* Free all memory used by *RULE_SYS. */ /* Debug support functions. =================================================*/ extern void source_of_instr( rule_sys_t *rule_sys, int_t instr_index, int_t *line, string_t *file_name, string_t *rule_name ); /* Set *LINE, *FILE_NAME and *RULE_NAME to appropriate values * for the statement that has generated the instruction at INSTR_INDEX. */ extern string_t rule_set_readable( rule_sys_t *rule_sys, int_t rule_set ); /* Return RULE_SET in RULE_SYS as a readable string. * The string must be freed after use. */ extern int_t get_frame_count( void ); /* Get the number of frames in the current path. */ extern void get_frame_info( int_t frame, int_t *pc_index, int_t *base_index, int_t *first_var_index, int_t *last_var_index ); /* Return *PC_INDEX, *BASE_INDEX, *FIRST_VAR_INDEX and *LAST_VAR_INDEX * of the frame no. FRAME. Any result pointer may be NULL. * Frame no. 0 is the current frame, * frame no. "get_frame_count() - 1" is the outermost one. */ extern var_scope_t *get_var_scope_by_name( rule_sys_t *rule_sys, string_t var_name, int_t instr_index ); /* Return the scope of variable VAR_NAME at INSTR_INDEX. */ extern string_t variable_at_index( rule_sys_t *rule_sys, int_t stack_index, int_t instr_index ); /* Return the name of the variable that is defined at STACK_INDEX * when instruction INSTR_INDEX is executed or NULL if there is none. */ extern value_t get_constant( rule_sys_t *rule_sys, string_t name ); /* Return the value of constant NAME in RULE_SYS. * Return NULL if there is no such constant. */ /* Switches support =========================================================*/ extern void set_switch( symbol_t key, value_t value ); /* Set the switch KEY to VALUE. */ extern value_t get_switch( symbol_t key ); /* Return the value of the switch KEY. * Report an error if this switch doesn't exist. */ extern void get_first_switch( value_t *value, symbol_t *key ); /* Return the first switch in *VALUE and its key in *KEY. * If there is no switch, *VALUE is NULL. */ extern void get_next_switch( value_t *value, symbol_t *key ); /* Return the next switch in *VALUE and its key in *KEY. * If there is no more switch, *VALUE is NULL. */ extern void free_switches( void ); /* Free all settings. */ /* End of file. =============================================================*/ malaga-7.12/rule_symbols.c0000644000175000017500000003371410236624424015103 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module manages the symbol tree for constants, variables and rules. */ /* Includes. ================================================================*/ #include #include #include #include #include #include "basic.h" #include "pools.h" #include "files.h" #include "values.h" #include "rule_type.h" #include "rule_code.h" #include "avl_trees.h" #include "rule_symbols.h" /* Types. ===================================================================*/ typedef struct /* A definition of a variable and its scope. */ { list_node_t *next; int_t first_instr; /* First instruction where variable is accessible. */ int_t last_instr; /* Last instruction where variable is accessible. * -1 means "scope not closed yet". */ int_t stack_index; } comp_scope_t; typedef struct /* A symbol table node. */ { avln_node_t node; /* A symbol node is an AVLN node. */ int_t name_index; /* Index of NODE.NAME in CODE.STRING_POOL. */ /* The associated rule. */ int_t rule_number; /* Rule number in CODE.RULE_POOL or -1. */ rule_t *rule_p; /* Rule pointer or NULL. */ int_t rule_line; /* The source line of the rule definition. */ string_t rule_file; /* The source file of the rule definition. */ /* The associated constant. */ int_t const_index; /* Index in CODE.VALUE_POOL or -1. */ bool_t const_fixed; /* TRUE if constant is already fixed. */ /* The associated variable scopes. */ list_t scopes; } symbol_node_t; /* Variables. ===============================================================*/ static avln_node_t *symbol_tree; /* Root node of the symbol tree. * Actually points to symbol_node_t. */ /* Basic functions. =========================================================*/ static symbol_node_t * find_symbol_node( string_t name ) /* Find and return a symbol node with NAME. * If that symbol node does not exist, create a new one. */ { symbol_node_t *node; /* Look for existing node. */ node = (symbol_node_t *) find_avln_node( name, symbol_tree ); if (node == NULL) { /* Node not found - create a new one. */ node = new_mem( sizeof( symbol_node_t ) ); node->node.name = copy_string_to_pool( code.string_pool, name, &node->name_index ); node->rule_number = -1; node->rule_p = NULL; node->const_index = -1; clear_list( &node->scopes ); insert_avln_node( (avln_node_t *) node, &symbol_tree ); } return node; } /*---------------------------------------------------------------------------*/ static void free_symbol_tree( avln_node_t **node_p ) /* Free all memory used by *NODE_P (including the node itself). */ { comp_scope_t *scope; symbol_node_t *node = (symbol_node_t *) *node_p; if (*node_p == NULL) return; free_symbol_tree( &(*node_p)->left ); free_symbol_tree( &(*node_p)->right ); FOREACH_FREE( scope, node->scopes ) ; /* empty */ free_mem( node_p ); } /*---------------------------------------------------------------------------*/ void free_symbols( void ) /* Free all memory used by the symbol table. */ { free_symbol_tree( &symbol_tree ); } /* Functions that use the symbol table for rules. ===========================*/ static void create_rule_node( symbol_node_t *node ) /* Create an empty rule entry for NODE. */ { rule_t rule; rule.name = node->name_index; rule.first_instr = -1; rule.type = -1; rule.param_count = -1; node->rule_p = (rule_t *) copy_to_pool( code.rule_pool, &rule, 1, &node->rule_number ); } /*---------------------------------------------------------------------------*/ static string_t rule_type_name( rule_type_t type ) /* Return TYPE as a readable string. */ { switch (type) { case ALLO_RULE: return "allo-rule"; case COMBI_RULE: return "combi-rule"; case END_RULE: return "end-rule"; case FILTER_RULE: return "filter-rule"; case PRUNING_RULE: return "pruning-rule"; case ROBUST_RULE: return "robust-rule"; case SUBRULE: return "subrule"; default: complain( "Internal error." ); } } /*---------------------------------------------------------------------------*/ string_t get_rule_file( string_t name ) /* Return file where rule NAME is defined. */ { symbol_node_t *node; node = find_symbol_node( name ); return node->rule_file; } /*---------------------------------------------------------------------------*/ int_t get_rule_line( string_t name ) /* Return line where rule NAME is defined. */ { symbol_node_t *node; node = find_symbol_node( name ); return node->rule_line; } /*---------------------------------------------------------------------------*/ void enter_function( string_t name, int_t index ) /* Associate standard function NAME with INDEX. */ { symbol_node_t *node; node = find_symbol_node( name ); if (node->rule_p != NULL || node->rule_number != -1) complain( "Function \"%s\" already defined.", name ); node->rule_number = index; } /*---------------------------------------------------------------------------*/ int_t enter_rule( string_t name, int_t first_instr, rule_type_t type, int_t param_count, int rule_line, string_t rule_file ) /* Enter into the symbol table the rule NAME of TYPE that starts at FIRST_INSTR * and takes PARAM_COUNT parameters. The source is at RULE_LINE in RULE_FILE. * The rule number will be returned. */ { symbol_node_t *node; node = find_symbol_node( name ); if (node->rule_p != NULL) { if (node->rule_p->first_instr != -1) { complain( "Rule \"%s\" already defined in \"%s\", line %d.", name, name_in_path( node->rule_file ), node->rule_line ); } else if (type == SUBRULE) { if (node->rule_p->type == COMBI_RULE) { complain( "Rule \"%s\" already used as a combi rule or end rule " "in \"%s\", line %d.", name, name_in_path( node->rule_file ), node->rule_line ); } if (node->rule_p->param_count != param_count) { complain( "\"%s\" has been called with %d parameters " "in \"%s\", line %d.", name, node->rule_p->param_count, name_in_path( node->rule_file ), node->rule_line ); } } else if (node->rule_p->type == SUBRULE) { complain( "Rule \"%s\" already used as a subrule in \"%s\", line %d.", name, name_in_path( node->rule_file ), node->rule_line ); } } else { if (node->rule_number != -1) complain( "\"%s\" is a standard function." ); create_rule_node( node ); } node->rule_line = rule_line; node->rule_file = rule_file; node->rule_p->first_instr = first_instr; node->rule_p->type = type; node->rule_p->param_count = param_count; return node->rule_number; } /*---------------------------------------------------------------------------*/ rule_t * find_subrule( string_t name, int_t *rule_number, int line, string_t file ) /* Find subrule or standard function NAME and return its rule descriptor. * If the rule descriptor is NULL, NAME denotes a standard function. * If RULE_NUMBER != NULL, save the rule index in *RULE_NUMBER. */ { symbol_node_t *node; node = find_symbol_node( name ); if (node->rule_p == NULL) { if (node->rule_number == -1) { create_rule_node( node ); node->rule_p->type = SUBRULE; node->rule_line = line; node->rule_file = file; } } else if (node->rule_p->type != SUBRULE) { complain( "\"%s\" %s as a %s in \"%s\", line %d.", name, (node->rule_p->first_instr == -1 ? "used" : "defined"), rule_type_name( node->rule_p->type ), name_in_path( node->rule_file ), node->rule_line ); } if (rule_number != NULL) *rule_number = node->rule_number; return node->rule_p; } /*---------------------------------------------------------------------------*/ rule_t * find_combi_rule( string_t name, int_t *rule_number, int line, string_t file ) /* Find combi-rule or end-rule NAME and return its rule descriptor. * If the rule descriptor is NULL, NAME describes a standard function. * If RULE_NUMBER != NULL, save the rule index in *RULE_NUMBER. */ { symbol_node_t *node; node = find_symbol_node( name ); if (node->rule_p == NULL) { if (node->rule_number != -1) complain( "\"%s\" is a function.", name ); create_rule_node( node ); node->rule_p->type = COMBI_RULE; node->rule_line = line; node->rule_file = file; } else if (node->rule_p->type != COMBI_RULE && node->rule_p->type != END_RULE) { complain( "\"%s\" %s as a %s in \"%s\", line %d.", name, (node->rule_p->first_instr == -1 ? "used" : "defined"), rule_type_name( node->rule_p->type ), name_in_path( node->rule_file ), node->rule_line ); } if (rule_number != NULL) *rule_number = node->rule_number; return node->rule_p; } /*---------------------------------------------------------------------------*/ static void check_rules_defined_local( avln_node_t *node ) /* If NODE is associated with a rule, check if it is defined. */ { symbol_node_t *sym_node = (symbol_node_t *) node; if (node == NULL) return; check_rules_defined_local( node->left ); if (sym_node->rule_p != NULL && sym_node->rule_p->first_instr == -1) { if (in_emacs_malaga_mode) printf( "SHOW \"%s\":%d:0\n", sym_node->rule_file, sym_node->rule_line ); complain( "Undefined rule \"%s\". (\"%s\", line %d)", node->name, name_in_path( sym_node->rule_file ), sym_node->rule_line ); } check_rules_defined_local( node->right ); } /*---------------------------------------------------------------------------*/ void check_rules_defined( void ) /* Check if all rules in the symbol tree are defined. */ { check_rules_defined_local( symbol_tree ); } /* Functions that use the symbol table for variables. =======================*/ int_t find_variable( string_t name ) /* Find variable NAME in the symbol table and return its stack index. */ { comp_scope_t *scope; scope = (comp_scope_t *) find_symbol_node( name )->scopes.last; if (scope == NULL || scope->last_instr != -1) complain( "Variable \"$%s\" is not defined.", name ); return scope->stack_index; } /*---------------------------------------------------------------------------*/ string_t define_variable( string_t name, int_t stack_index ) /* Define the value on index STACK_INDEX to be a new variable NAME. * Copy its name to the string pool and return the index of this copy. */ { symbol_node_t *node; comp_scope_t *scope; node = find_symbol_node( name ); scope = (comp_scope_t *) node->scopes.last; if (scope != NULL && scope->last_instr == -1) complain( "Variable \"$%s\" is defined twice.", name ); /* Allocate a new scope and initialise it. */ scope = new_node( &node->scopes, sizeof( comp_scope_t ), LIST_END ); scope->first_instr = code.instr_count; scope->last_instr = -1; /* Scope is not yet closed. */ scope->stack_index = stack_index; return node->node.name; } /*---------------------------------------------------------------------------*/ void undefine_variable( string_t name ) /* Close the scope of variable NAME. */ { comp_scope_t *scope; scope = (comp_scope_t *) find_symbol_node( name )->scopes.last; scope->last_instr = code.instr_count; } /*---------------------------------------------------------------------------*/ static void dump_variables_and_constants_local( avln_node_t *node ) /* Dump all variables and constants in NODE and its descendants. */ { comp_scope_t *scope; /* A scope in the symbol table. */ var_t var; /* A new entry in CODE.VAR_POOL. */ var_scope_t var_scope; /* A new entry in CODE.VAR_SCOPE_POOL. */ constant_t constant; symbol_node_t *sym_node = (symbol_node_t *) node; if (node == NULL) return; dump_variables_and_constants_local( node->left ); /* Dump variables. */ if (sym_node->scopes.first != NULL) { var.name = sym_node->name_index; var.first_scope = pool_item_count( code.var_scope_pool ); var.scope_count = 0; /* Copy all scopes to the var-scope pool. */ FOREACH( scope, sym_node->scopes ) { var_scope.first_instr = scope->first_instr; var_scope.last_instr = scope->last_instr; var_scope.stack_index = scope->stack_index; copy_to_pool( code.var_scope_pool, (void *) &var_scope, 1, NULL ); var.scope_count++; } copy_to_pool( code.var_pool, (void *) &var, 1, NULL ); } /* Dump constant. */ if (sym_node->const_index != -1) { constant.name = sym_node->name_index; constant.value = sym_node->const_index; copy_to_pool( code.constant_pool, (void *) &constant, 1, NULL ); } dump_variables_and_constants_local( node->right ); } /*---------------------------------------------------------------------------*/ void dump_variables_and_constants( void ) /* Dump all variables and constants in the table. */ { /* Emit all variables and constants in alphabetical order. */ dump_variables_and_constants_local( symbol_tree ); } /* Functions that use the symbol table for constants. =======================*/ int_t find_constant( string_t name ) /* Find constant NAME in the symbol table and return its value pool index. */ { symbol_node_t *node; node = find_symbol_node( name ); if (node->const_index == -1) complain( "Constant \"@%s\" is not defined.", name ); node->const_fixed = TRUE; return node->const_index; } /*---------------------------------------------------------------------------*/ void define_constant( string_t name, int_t const_index, bool_t fixed ) /* Define constant NAME with value at CONST_INDEX in the value pool. * If FIXED is FALSE, the given value is only a default value. */ { symbol_node_t *node; node = find_symbol_node( name ); if (node->const_fixed) complain( "Constant \"@%s\" is already defined.", name ); if (! fixed && node->const_index != -1) complain( "Constant \"@%s\" already has a default value.", name ); node->const_index = const_index; node->const_fixed = fixed; } /* End of file. =============================================================*/ malaga-7.12/rule_symbols.h0000644000175000017500000000576010236624415015110 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module manages the symbol table for constants, variables and rules. */ /* Functions that use the symbol table for rules and functions. =============*/ extern int_t enter_rule( string_t name, int_t first_instr, rule_type_t type, int_t param_count, int_t rule_line, string_t rule_file ); /* Enter into the symbol table the rule NAME of TYPE that starts at FIRST_INSTR * and takes PARAM_COUNT parameters. The source is at RULE_LINE in RULE_FILE. * The rule number will be returned. */ extern void enter_function( string_t name, int_t index ); /* Associate standard function NAME with INDEX. */ extern rule_t *find_subrule( string_t name, int_t *rule_number, int line, string_t file ); /* Find subrule or standard function NAME and return its rule descriptor. * If the rule descriptor is NULL, NAME denotes a standard function. * If RULE_NUMBER != NULL, save the rule index in *RULE_NUMBER. */ extern rule_t *find_combi_rule( string_t name, int_t *rule_number, int line, string_t file ); /* Find combi-rule or end-rule NAME and return its rule descriptor. * If the rule descriptor is NULL, NAME describes a standard function. * If RULE_NUMBER != NULL, save the rule index in *RULE_NUMBER. */ extern void check_rules_defined( void ); /* Check if all rules in the symbol tree are defined. */ extern string_t get_rule_file( string_t name ); /* Return file where rule NAME is defined. */ extern int_t get_rule_line( string_t name ); /* Return line where rule NAME is defined. */ /* Functions that use the symbol table for variables. =======================*/ extern string_t define_variable( string_t name, int_t stack_index ); /* Define the value on index STACK_INDEX to be a new variable with NAME. * Return a copy of its name in the string pool. */ extern void undefine_variable( string_t name ); /* Close the scope of variable NAME. */ extern int_t find_variable( string_t name ); /* Find variable NAME in the symbol table and return its stack index. */ /* Functions that use the symbol table for constants. =======================*/ extern int_t find_constant( string_t name ); /* Find constant NAME in the symbol table and return its value pool index. * If the constant only has a default value, it becomes the real value. */ extern void define_constant( string_t name, int_t const_index, bool_t fixed ); /* Define constant NAME with value at CONST_INDEX in the value pool. * If FIXED is FALSE, the value given is only a default value. */ /*---------------------------------------------------------------------------*/ extern void dump_variables_and_constants( void ); /* Dump all variables and constants in the table. */ extern void free_symbols( void ); /* Free all memory used by the symbol table. */ /* End of file. =============================================================*/ malaga-7.12/rule_type.h0000644000175000017500000002000210236624414014362 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module defines the data types needed for Malaga rules. */ /* Constants ================================================================*/ /* The rule-internal state is described by the following variables: * S is the value stack. * SP (stack pointer) is the index of the first free element in S. * BP (base pointer) is the index of the first element in S local to the * current rule. * I is information that is stored in the instruction itself. * PC is the program counter, i.e., the index of the next code to be executed. * BT is the backtrace stack, a stack of triples: (PC, BP, S). * BTP is the top index of B. */ enum /* These are the opcodes of the rule instructions. */ { /* control instructions */ INS_SYSTEM_ERROR, /* report error(I); terminate all paths. */ INS_ERROR, /* report error( S[SP - 1] ); terminate all paths. */ INS_TERMINATE, /* terminate this path. */ INS_NOP, /* do nothing. */ INS_TERMINATE_IF_NULL, /* if (S[SP - 1] == NULL) {terminate;} else {SP--;} */ /* result instructions */ INS_ADD_END_STATE, /* result = S[SP - 1]; rule_successful = TRUE; SP--; */ INS_ADD_STATE, /* result = S[SP - 1]; rules = rules[I]; * rule_successful = TRUE; SP--; */ INS_ADD_ALLO, /* surf = S[SP-2]; allo = S[SP - 1]; * rule_successful = TRUE; SP-= 2 */ INS_ACCEPT, /* rule_successful = TRUE; */ /* stack management instructions */ INS_PUSH_NULL, /* for (i = 0; i < I; i++) { S[SP + i] = NULL; } SP += I; */ INS_PUSH_VAR, /* S[SP] = S[I]; SP++; */ INS_PUSH_CONST, /* S[SP] = Const(I); SP++; */ INS_PUSH_SYMBOL, /* S[SP] = Symbol(I); SP++; */ INS_PUSH_PATTERN_VAR, /* S[SP] = Pattern_Var(I); SP++; */ INS_POP, /* SP -= I; */ INS_POP_TO, /* SP = BP + I; */ /* value instructions */ INS_BUILD_LIST, /* S[SP - I] = "<"S[SP - I],.., S[SP - 1]">"; SP -= I - 1; */ INS_DECOMPOSE_LIST, /* = S[SP - 1]; * SP += I - 1; */ INS_BUILD_RECORD, /* S[SP - 2 * I] = "[" S[SP - 2 * I] : S[SP - 2 * I + 1] * ... * S[SP - 2] : S[SP - 1] "]"; * SP -= 2*I - 1; */ INS_BUILD_PATH, /* SP[SP - I] = S[SP - I] "." .. "." S[SP - 1]; SP -= I-1; */ INS_DOT_OPERATION, /* S[SP - 2] = S[SP - 2] "." S[SP - 1]; SP--; */ INS_PLUS_OPERATION, /* S[SP - 2] := S[SP - 2] "+" S[SP - 1]; SP--; */ INS_MINUS_OPERATION, /* S[SP - 2] = S[SP - 2] "-" S[SP - 1]; SP--; */ INS_ASTERISK_OPERATION, /* S[SP - 2] = S[SP - 2] "*" S[SP - 1]; SP--; */ INS_SLASH_OPERATION, /* S[SP - 2] = S[SP - 2] "/" S[SP - 1]; SP--; */ INS_UNARY_MINUS_OP, /* S[SP - 1] = "-" S[SP - 1]; */ INS_GET_ATTRIBUTE, /* S[SP - 1] = S[SP - 1] "." Symbol(I); */ INS_REMOVE_ATTRIBUTE, /* S[SP - 1] = S[SP - 1] "-" Symbol(I); */ INS_STD_FUNCTION, /* S[SP - 1] = function_I( S[SP - 1] ); */ INS_MATCH, /* S[SP - 1] = S[SP - 1] "match" String(I); (yes or no) */ /* instructions to modify variables */ INS_SET_VAR, /* S[I] = S[SP - 1]; SP--; */ INS_PLUS_VAR, /* S[I] = S[I] "+" S[SP - 1]; SP--; */ INS_MINUS_VAR, /* S[I] = S[I] "-" S[SP - 1]; SP--; */ INS_ASTERISK_VAR, /* S[I] = S[I] "*" S[SP - 1]; SP--; */ INS_SLASH_VAR, /* S[I] = S[I] "/" S[SP - 1]; SP--; */ INS_SET_VAR_PATH, /* (S[I] "." S[SP - 2]) = S[SP - 1]; SP -= 2; */ INS_PLUS_VAR_PATH, /* (S[I] "." S[SP-2]) = (S[I] "." S[SP-2]) "+" S[SP-1]; * SP -= 2; */ INS_MINUS_VAR_PATH, /* (S[I] "." S[SP-2]) = (S[I] "." S[SP-2]) "-" S[SP-1]; * SP -= 2; */ INS_ASTERISK_VAR_PATH, /* (S[I]"." S[SP-2]) = (S[I] "." S[SP-2]) "*" S[SP-1]; * SP -= 2; */ INS_SLASH_VAR_PATH, /* (S[I] "." S[SP-2]) = (S[I] "." S[SP-2]) "/" S[SP-1]; * SP -= 2; */ /* Instructions to support loops. */ INS_GET_1ST_ELEMENT, /* S[SP-1] = 1st element/attrib/ordinal of S[SP-1]; */ INS_ITERATE, /* S[I - 1] must be a list, a record, or a number * and S[I] the n-th element/attrib/ordinal of S[I - 1]. * S[I] = (n+1)-th element/attr/ordinal of S[I - 1]; */ /* Jump instructions. */ INS_JUMP, /* PC = I. */ INS_JUMP_IF_EQUAL, /* if (S[SP-2] "=" S[SP-1]) {PC = I;} SP -= 2; */ INS_JUMP_IF_NOT_EQUAL, /* if (! S[SP-2] "=" S[SP-1]) {PC = I;} SP -= 2; */ INS_JUMP_IF_CONGR, /* if (S[SP-2] "~" S[SP-1]) {PC = I;} SP -= 2; */ INS_JUMP_IF_NOT_CONGR, /* if (! S[SP-2] "~" S[SP-1]) {PC = I;} SP -= 2; */ INS_JUMP_IF_IN, /* if (S[SP-2] "in" S[SP-1]) {PC = I;} SP -= 2; */ INS_JUMP_IF_NOT_IN, /* if (! S[SP-2] "in" S[SP-1]) {PC = I;} SP -= 2; */ INS_JUMP_IF_LESS, /* if (S[SP-2] < S[SP-1]) {PC = I;} SP -= 2; */ INS_JUMP_IF_NOT_LESS, /* if (! S[SP-2] < S[SP-1]) {PC = I;} SP -= 2; */ INS_JUMP_IF_GREATER, /* if (S[SP-2] > S[SP-1]) {PC = I;} SP -= 2; */ INS_JUMP_IF_NOT_GREATER, /* if (! S[SP-2] > S[SP-1]) {PC = I;} SP -= 2; */ INS_JUMP_IF_NULL, /* if (S[SP-1] == NULL) {PC = I;} SP--; */ INS_JUMP_IF_NOT_NULL, /* if (! S[SP-1] == NULL) {PC = I;} SP--; */ INS_JUMP_IF_YES, /* if (S[SP-1] == yes) {PC = I;} SP--; */ INS_JUMP_IF_NO, /* if (S[SP-1] == no) {PC = I;} SP--; */ INS_JUMP_NOW, /* BT[BTP] = {PC, BP, S}; PC = I; BTP++; */ INS_JUMP_LATER, /* BT[BTP] = {I, BP, S}; BTP++; */ INS_JUMP_SUBRULE, /* Push BP; Push PC+1; BP = TOP; PC = first_instr(I); */ INS_RETURN /* SP = BP; Pop PC; Pop BP; Pop (I-1); */ }; /* Types of INS_SYSTEM_ERROR. */ enum {ASSERTION_ERROR, NO_RETURN_ERROR}; /* Standard functions for INS_STANDARD_FUNCTION. */ enum {FUNC_TO_ATOMS, FUNC_IS_CAPITAL, FUNC_GET_LENGTH, FUNC_TO_MULTI, FUNC_TO_SET, FUNC_GET_SWITCH, FUNC_GET_VALUE_TYPE, FUNC_GET_VALUE_STRING, FUNC_TRANSMIT, FUNC_FLOOR, FUNC_SUBSTRING}; #define INSTR_INFO_MIN (-1L << 23) #define INSTR_INFO_MAX ((1L << 23) - 1) /* Never use an instruction info smaller than INSTR_INFO_MIN or * greater than INSTR_INFO_MAX. */ enum {OPCODE_MAX = 255}; /* The largest opcode possible. */ /* Macros. ==================================================================*/ #define INSTR(opcode, instr_info) ((opcode) | (u_int_t) (instr_info) << 8) /* Use this macro to create an instruction. */ #define OPCODE(instr) ((int_t) (instr) & OPCODE_MAX) /* Use this macro to get the opcode of an instruction. */ #define INSTR_INFO(instr) ((int_t) (instr) >> 8) /* Use this macro to get the info of an instruction. */ /* Types. ===================================================================*/ typedef u_int_t instr_t; /* An instruction is an u_int_t whose lower 8 bits store the opcode. * The upper 24 bits store a signed value, the Info value. */ typedef enum /* Rule types */ {ALLO_RULE, COMBI_RULE, END_RULE, FILTER_RULE, PRUNING_RULE, ROBUST_RULE, SUBRULE} rule_type_t; typedef struct /* A rule definition.*/ { int_t name; /* String table index to rule name. */ int_t first_instr; /* Code index of rule start. */ rule_type_t type; /* Type of the rule. */ int_t param_count; /* Number of parameters the rule takes. */ } rule_t; typedef struct /* A correspondence between a source line and a rule code index. */ { int_t line; /* Source line or -1 if instruction can't be * associated with a specific source line */ int_t file; /* String table index to source file name or -1. */ int_t instr; /* Index of first instruction that belongs to LINE in FILE. */ } src_line_t; typedef struct /* A variable name and all its scopes. */ { int_t name; /* String table index of variable name. */ int_t first_scope; /* Index of first scope of this variable in VAR_SCOPES. */ int_t scope_count; /* Number of scopes of this variable. */ } var_t; typedef struct /* A single scope of a variable. */ { int_t first_instr; /* First instruction where variable is defined. */ int_t last_instr; /* Last instruction where variable is defined. */ int_t stack_index; /* Index of variable in value stack. */ } var_scope_t; typedef struct /* A named constant. */ { int_t name; /* String table index of constant name. */ int_t value; /* Value index. */ } constant_t; /* End of file. =============================================================*/ malaga-7.12/scanner.c0000644000175000017500000004306410425345261014013 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module supports scanning (lexical analysis) of malaga source files. */ /* Includes. ================================================================*/ #include #include #include #include #include #include "basic.h" #include "files.h" #include "scanner.h" /* Constants. ===============================================================*/ /* List of all keywords and their token codes. * (This list must be maintained in alphabetical order.) */ static struct { string_t name; int_t code; } keywords[ NUMBER_OF_KEYWORDS ] = { { "accept", TOK_ACCEPT }, { "allo_rule", TOK_ALLO_RULE }, { "and", TOK_AND }, { "assert", TOK_ASSERT }, { "break", TOK_BREAK }, { "choose", TOK_CHOOSE }, { "combi_rule", TOK_COMBI_RULE }, { "continue", TOK_CONTINUE }, { "default", TOK_DEFAULT }, { "define", TOK_DEFINE }, { "else", TOK_ELSE }, { "elseif", TOK_ELSEIF }, { "end", TOK_END }, { "end_rule", TOK_END_RULE }, { "error", TOK_ERROR }, { "foreach", TOK_FOREACH }, { "greater", TOK_GREATER }, { "greater_equal", TOK_GREATER_EQUAL }, { "if", TOK_IF }, { "in", TOK_IN }, { "include", TOK_INCLUDE }, { "initial", TOK_INITIAL }, { "input_filter", TOK_INPUT_FILTER }, { "less", TOK_LESS }, { "less_equal", TOK_LESS_EQUAL }, { "matches", TOK_MATCHES }, { "not", TOK_NOT }, { "or", TOK_OR }, { "output_filter", TOK_OUTPUT_FILTER }, { "parallel", TOK_PARALLEL }, { "pruning_rule", TOK_PRUNING_RULE }, { "repeat", TOK_REPEAT }, { "require", TOK_REQUIRE }, { "result", TOK_RESULT }, { "return", TOK_RETURN }, { "robust_rule", TOK_ROBUST_RULE }, { "rules", TOK_RULES }, { "select", TOK_SELECT }, { "stop", TOK_STOP }, { "subrule", TOK_SUBRULE }, { "then", TOK_THEN }, { "while", TOK_WHILE } }; /* Types. ===================================================================*/ typedef struct /* A source stream for lexical analysis. */ { list_node_t *next; /* The next (including) source stream. */ FILE *stream; /* The input stream for this include level. */ string_t file_name; /* The name of the input file. */ text_t *line; /* The current line. */ string_t next_char_p; /* Pointer to the next char in LINE to be read. */ int_t column; /* Column that has been read. */ int_t line_number; /* Number of the line that has been read. */ int_t next_char; /* Buffer NEXT_CHAR if this source is backed up. */ int_t next_token; /* Buffer NEXT_TOKEN if this source is backed up. */ } source_t; /* Global variables. ========================================================*/ int_t next_token; string_t token_name; char_t *token_string; double token_number; /* Variables. ===============================================================*/ static list_t sources; /* The list of sources, current source first. */ static string_t scanner_input; /* If no file is included, the scanner reads its input from SCANNER_INPUT. */ static int_t next_char; /* The next unicode char to be read. */ static text_t *token_text; /* The text of the next token. */ /* Functions. ===============================================================*/ static void read_next_char( void ) /* Read the next char from input into NEXT_CHAR. * If end of input stream is reached, return EOF. * If no input stream is selected, read input from INPUT_BUFFER. * If reading from stream, update column information. */ { source_t *source; int_t c; source = (source_t *) sources.first; if (scanner_input != NULL) /* Read from a string. */ { if (*scanner_input == EOS) next_char = EOF; else { next_char = g_utf8_get_char( scanner_input ); scanner_input = g_utf8_next_char( scanner_input ); } } else if (source != NULL) /* Read from a file. */ { /* Read a new line if current line is empty. */ if (*source->next_char_p == EOS) { clear_text( source->line ); do { c = getc( source->stream ); if (c == EOS) complain( "Null byte in \"%s\"", source->file_name ); else if (c == EOF) { if (ferror( source->stream )) { complain( "Can't read from \"%s\": %s.", source->file_name, strerror( errno ) ); } else break; } else ADD_CHAR_TO_TEXT( source->line, c ); } while (c != '\n'); if (! g_utf8_validate( source->line->buffer, -1, NULL )) complain( "Illegal UTF-8 character in \"%s\".", source->file_name ); source->next_char_p = source->line->buffer; } if (*source->next_char_p == EOS) next_char = EOF; else { /* Get next char from current line. */ next_char = g_utf8_get_char( source->next_char_p ); source->next_char_p = g_utf8_next_char( source->next_char_p ); /* Update line and column information. */ if (next_char == '\t') source->column = (source->column + 8) & ~7; else if (next_char == '\n') { source->column = 0; source->line_number++; } else if (next_char == '\r') source->column = 0; else if (next_char != EOF) source->column++; } } else next_char = EOF; } /*---------------------------------------------------------------------------*/ string_t current_file_name( void ) /* Return the name of the file reading from or NULL. */ { source_t *source; source = (source_t *) sources.first; if (source == NULL) return NULL; return source->file_name; } /*---------------------------------------------------------------------------*/ int_t current_line_number( void ) /* Return the line number where the last char has been read or -1. */ { source_t *source; source = (source_t *) sources.first; if (source == NULL) return -1; return source->line_number; } /*---------------------------------------------------------------------------*/ int_t current_column( void ) /* Return the column where the last char has been read or -1. */ { source_t *source; source = (source_t *) sources.first; if (source == NULL) return -1; if (source->column == 0) return 0; return source->column - 1; /* Let columns start with 0. */ } /*---------------------------------------------------------------------------*/ void set_scanner_input( string_t input ) /* Make the scanner use INPUT as scanner input * until "set_scanner_input( NULL )" is called. * INPUT must remain valid until then. */ { source_t *source; source = (source_t *) sources.first; scanner_input = input; if (input != NULL) { if (source != NULL) { source->next_char = next_char; source->next_token = next_token; } read_next_char(); read_next_token(); } else if (source != NULL) { next_char = source->next_char; next_token = source->next_token; } } /*---------------------------------------------------------------------------*/ void begin_include( string_t file_name ) /* Open a new level of inclusion and read tokens from file FILE_NAME. */ { FILE *stream; source_t *source; source = (source_t *) sources.first; stream = open_stream( file_name, "r" ); /* Next char of old source should be read later. */ if (source != NULL) { source->next_char = next_char; source->next_token = next_token; } /* Create new source description. */ source = new_node( &sources, sizeof( source_t ), LIST_START ); source->line = new_text(); source->next_char_p = source->line->buffer; source->file_name = file_name; source->line_number = 1; source->column = 0; source->stream = stream; read_next_char(); read_next_token(); } /*---------------------------------------------------------------------------*/ void end_include( void ) /* Stop reading from current source stream and read from former stream. */ { source_t *source; source = (source_t *) sources.first; close_stream( &source->stream, source->file_name ); free_text( &source->line ); free_first_node( &sources ); if (sources.first != NULL) { source = (source_t *) sources.first; next_char = source->next_char; next_token = source->next_token; } } /*---------------------------------------------------------------------------*/ void end_includes( void ) /* Stop reading from all nested source streams. */ { while (sources.first != NULL) end_include(); } /*---------------------------------------------------------------------------*/ void init_scanner( void ) /* Initialise the scanner. */ { token_text = new_text(); } /*---------------------------------------------------------------------------*/ void terminate_scanner( void ) /* Terminate the scanner, even when it's scanning. */ { source_t *source; scanner_input = NULL; FOREACH_FREE( source, sources ) { close_stream( &source->stream, NULL ); free_text( &source->line ); } token_name = NULL; free_text( &token_text ); free_mem( &token_string ); } /*---------------------------------------------------------------------------*/ static void read_name( void ) /* Read rule name, variable, or keyword into TOKEN_NAME. */ { token_name = NULL; clear_text( token_text ); while (next_char != EOF && (g_unichar_isalnum( next_char ) || next_char == '_' || next_char == '&' || next_char == '|')) { add_unichar_to_text( token_text, next_char ); read_next_char(); } token_name = token_text->buffer; if (*token_name == EOS) complain( "Illegal character in name." ); } /*---------------------------------------------------------------------------*/ static int_t keyword_code( string_t name ) /* Look up NAME in the keyword table and return its token value. * If NAME is no keyword, return TOK_IDENT. */ { int_t lower, upper, middle, result; /* We do a binary search on the keywords. * A keyword must be in the range of keywords[ lower..upper ]. */ lower = 0; upper = NUMBER_OF_KEYWORDS - 1; while (lower <= upper) { middle = (lower + upper) / 2; result = strcmp_no_case( name, keywords[ middle ].name ); if (result < 0) upper = middle - 1; else if (result > 0) lower = middle + 1; else return keywords[ middle ].code; } return TOK_IDENT; } /*---------------------------------------------------------------------------*/ static void read_number( void ) /* Read a floating point number. Save its value in TOKEN_NUMBER. */ { token_name = NULL; clear_text( token_text ); while (next_char >= '0' && next_char <= '9') { add_char_to_text( token_text, next_char ); read_next_char(); } if (next_char == 'l' || next_char == 'L') read_next_char(); else if (next_char == 'r' || next_char == 'R') { insert_char_in_text( token_text, '-', 0 ); read_next_char(); } else { if (next_char == '.') { add_char_to_text( token_text, next_char ); read_next_char(); if (next_char < '0' || next_char >'9') complain( "Missing digits after \".\"." ); while (next_char >= '0' && next_char <= '9') { add_char_to_text( token_text, next_char ); read_next_char(); } } if (next_char == 'E' || next_char == 'e') { /* Read an exponent. */ add_char_to_text( token_text, next_char ); read_next_char(); if (next_char == '-' || next_char == '+') { add_char_to_text( token_text, next_char ); read_next_char(); } if (next_char < '0' || next_char > '9') complain( "Missing exponent." ); while (next_char >= '0' && next_char <= '9') { add_char_to_text( token_text, next_char ); read_next_char(); } } } if (sscanf( token_text->buffer, "%lf", &token_number ) != 1) complain( "Illegal number." ); } /*---------------------------------------------------------------------------*/ static void read_string( void ) /* Read a string. Save its value in TOKEN_STRING. */ { int_t i; u_int_t code; token_name = NULL; clear_text( token_text ); read_next_char(); /* Overread beginning '"'. */ while (next_char != '\"') { if (next_char == EOF || next_char == '\n') complain( "Unterminated string at end of line." ); if (next_char != '\\') { add_unichar_to_text( token_text, next_char ); read_next_char(); } else { read_next_char(); if (next_char == '\\' || next_char == '\"') { add_char_to_text( token_text, next_char ); read_next_char(); } else if (next_char >= '0' && next_char <= '7') { code = 0; for (i = 0; i < 3; i++) { if (next_char >= '0' && next_char <= '7') code = 8 * code + (next_char - '0'); else complain( "Escape sequence must have 3 octal digits." ); read_next_char(); } if (! g_unichar_validate( code )) complain( "Escape sequence defines invalid character." ); add_unichar_to_text( token_text, code ); } else complain( "Illegal escape sequence in string." ); } } read_next_char(); /* Read over final '"'. */ free_mem( &token_string ); /* Free old token string. */ token_string = new_string( token_text->buffer, NULL ); } /*---------------------------------------------------------------------------*/ void read_next_token( void ) /* Read the next token from current source into NEXT_TOKEN. * If end of input stream is reached, return EOF. */ { /* Read chars until a token has been recognised. */ while (TRUE) { switch (next_char) { case EOF: next_token = EOF; return; case ' ': case '\t': case '\n': /* Read over whitespace. */ read_next_char(); break; case '\r': read_next_char(); if (next_char != '\n') complain( "Carriage return without line feed." ); read_next_char(); break; case '#': /* Read over a comment. */ do { read_next_char(); } while (next_char != '\n' && next_char != EOF); break; case '\"': /* Read a string. */ read_string(); next_token = TOK_STRING; return; case ':': /* Read a ":", ":=", ":=+", ":=-", ":=*", ":=/". */ read_next_char(); if (next_char == '=') { read_next_char(); if (next_char == '+') { next_token = TOK_ASSIGN_PLUS; read_next_char(); } else if (next_char == '-') { next_token = TOK_ASSIGN_MINUS; read_next_char(); } else if (next_char == '*') { next_token = TOK_ASSIGN_ASTERISK; read_next_char(); } else if (next_char == '/') { next_token = TOK_ASSIGN_SLASH; read_next_char(); } else next_token = TOK_ASSIGN; } else next_token = ':'; return; case '/': /* Read a "/", a "/=" or a "/~". */ read_next_char(); if (next_char == '=') { next_token = TOK_NOT_EQUAL; read_next_char(); } else if (next_char == '~') { next_token = TOK_NOT_CONGRUENT; read_next_char(); } else next_token = '/'; return; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* Read a number. */ read_number(); next_token = TOK_NUMBER; return; case '$': read_next_char(); read_name(); next_token = TOK_VARIABLE; return; case '@': read_next_char(); read_name(); next_token = TOK_CONSTANT; return; default: if (g_unichar_isalpha( next_char ) || next_char == '_' || next_char == '&' || next_char == '|') { read_name(); next_token = keyword_code( token_name ); return; } else { next_token = next_char; read_next_char(); return; } } } } /*---------------------------------------------------------------------------*/ string_t token_as_text( int_t token ) /* Return TOKEN as a string readable for humans. * The string must be freed after use. */ { int_t i; char token_buffer[2]; /* Look if TOKEN is a keyword. */ for (i = 0; i < NUMBER_OF_KEYWORDS; i++) { if (keywords[i].code == token) return concat_strings( "\"", keywords[i].name, "\"", NULL ); } switch (token) { case EOF: return new_string( "end of input", NULL ); case TOK_STRING: return new_string( "string", NULL ); case TOK_IDENT: return new_string( "identifier", NULL ); case TOK_VARIABLE: return new_string( "variable", NULL ); case TOK_CONSTANT: return new_string( "constant", NULL ); case TOK_NUMBER: return new_string( "number", NULL ); case TOK_ASSIGN: return new_string_readable( ":=", NULL ); case TOK_ASSIGN_PLUS: return new_string_readable( ":=+", NULL ); case TOK_ASSIGN_MINUS: return new_string_readable( ":=-", NULL ); case TOK_ASSIGN_ASTERISK: return new_string_readable( ":=*", NULL ); case TOK_ASSIGN_SLASH: return new_string_readable( ":=/", NULL ); case TOK_NOT_EQUAL: return new_string_readable( "/=", NULL ); case TOK_NOT_CONGRUENT: return new_string_readable( "/~", NULL ); default: token_buffer[0] = token; token_buffer[1] = EOS; return new_string_readable( token_buffer, NULL ); } } /*---------------------------------------------------------------------------*/ void test_token( int_t token ) /* Test if TOKEN is the next token. If it's not, report an error. */ { if (next_token != token) { complain( "Expected %s, not %s.", token_as_text( token ), token_as_text( next_token ) ); } } /*---------------------------------------------------------------------------*/ void parse_token( int_t token ) /* Test if TOKEN is the next token and read next token. */ { test_token( token ); read_next_token(); } /* End of file. =============================================================*/ malaga-7.12/scanner.h0000644000175000017500000000733210425344650014017 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module supports scanning (lexical analysis) of malaga source files. */ /* Constants. ===============================================================*/ /* The next token is read by "read_next_token". * Its value is stored in NEXT_TOKEN. * A token that consists of one character has the code of that character. * A token value of EOF stands for end-of-file. * All other tokens are as follows: */ enum { TOK_STRING = 256, /* A string. */ TOK_IDENT, /* An identifier. */ TOK_VARIABLE, /* A variable name. */ TOK_CONSTANT, /* A constant name. */ TOK_NUMBER, /* A floating number. */ TOK_ASSIGN, /* ":=". */ TOK_ASSIGN_PLUS, /* ":=+". */ TOK_ASSIGN_MINUS, /* ":=-". */ TOK_ASSIGN_ASTERISK, /* ":=*". */ TOK_ASSIGN_SLASH, /* ":=/". */ TOK_NOT_EQUAL, /* "/=". */ TOK_NOT_CONGRUENT, /* "/~". */ TOK_ACCEPT, TOK_ALLO_RULE, TOK_AND, TOK_ASSERT, TOK_BREAK, TOK_CHOOSE, TOK_COMBI_RULE, TOK_CONTINUE, TOK_DEFAULT, TOK_DEFINE, TOK_ELSE, TOK_ELSEIF, TOK_END, TOK_END_RULE, TOK_ERROR, TOK_FOREACH, TOK_GREATER, TOK_GREATER_EQUAL, TOK_IF, TOK_IN, TOK_INCLUDE, TOK_INITIAL, TOK_INPUT_FILTER, TOK_LESS, TOK_LESS_EQUAL, TOK_MATCHES, TOK_NOT, TOK_OR, TOK_OUTPUT_FILTER, TOK_PARALLEL, TOK_PRUNING_RULE, TOK_REPEAT, TOK_REQUIRE, TOK_RESULT, TOK_RETURN, TOK_ROBUST_RULE, TOK_RULES, TOK_SELECT, TOK_STOP, TOK_SUBRULE, TOK_THEN, TOK_WHILE }; enum {FIRST_KEYWORD = TOK_ACCEPT, LAST_KEYWORD = TOK_WHILE}; enum {NUMBER_OF_KEYWORDS = (LAST_KEYWORD - FIRST_KEYWORD + 1)}; /* Variables. ===============================================================*/ extern int_t next_token; /* Next token that is to be consumed by parser. */ extern string_t token_name; /* If NEXT_TOKEN == TOK_IDENT, the name is in TOKEN_NAME. */ extern char_t *token_string; /* If NEXT_TOKEN == TOK_STRING, the name is in TOKEN_STRING. */ extern double token_number; /* If NEXT_TOKEN == TOK_NUMBER, its content is in TOKEN_NUMBER. */ /* Functions. ===============================================================*/ extern void init_scanner( void ); /* Initialise the scanner. */ extern void terminate_scanner( void ); /* Terminate the scanner, even when it's scanning. */ extern void begin_include( string_t file_name ); /* Open a new level of inclusion and read tokens from file FILE_NAME. */ extern void end_include( void ); /* Stop reading from current source stream and read from former file. */ extern void end_includes( void ); /* Stop reading from all nested source streams. */ extern void set_scanner_input( string_t input ); /* Make the scanner use INPUT as scanner input * until "set_scanner_input( NULL )" is called. * INPUT must remain valid until then. */ extern string_t current_file_name( void ); /* Return the name of the file reading from or NULL. */ extern int_t current_line_number( void ); /* Return the line number where the last char has been read or -1. */ extern int_t current_column( void ); /* Return the column where the last char has been read or -1. */ extern void read_next_token( void ); /* Read the next token from current source into NEXT_TOKEN. * If end of input stream is reached, return EOF. */ extern void test_token( int_t token ); /* Test if TOKEN is the next token. If it's not, report an error. */ extern void parse_token( int_t token ); /* Test if TOKEN is the next token and read next token. */ extern string_t token_as_text( int_t token ); /* Return TOKEN as a string readable for humans. * Note that the string is only valid until this function is called again. */ /* End of file. =============================================================*/ malaga-7.12/symbols.c0000644000175000017500000001463010245130061014035 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module administrates the name and atoms for each symbol. */ /* Includes. ================================================================*/ #include #include #include #include #include #include "basic.h" #include "pools.h" #include "values.h" #include "files.h" #include "malaga_files.h" #include "symbols.h" /* Variables. ===============================================================*/ static struct /* This is the symbol table. */ { int_t symbol_count; /* Number of symbols in this table. */ symbol_entry_t *symbols; /* The names and atoms of all symbols. */ symbol_t *symbols_by_name; /* All symbols sorted by their names. */ symbol_t *symbols_by_atoms; /* All symbols sorted by their atom lists. */ int_t values_size; symbol_t *values; /* Contains the lists of atomic symbols. */ int_t strings_size; char_t *strings; /* Contains the symbol names. */ } symbol_table; /* Functions. ===============================================================*/ string_t get_symbol_name( symbol_t symbol ) /* Return the name of SYMBOL. */ { return symbol_table.strings + symbol_table.symbols[ symbol ].name; } /*---------------------------------------------------------------------------*/ value_t get_atoms( symbol_t symbol ) /* Return the atom list of SYMBOL. */ { return symbol_table.values + symbol_table.symbols[ symbol ].atoms; } /*---------------------------------------------------------------------------*/ symbol_t find_symbol( string_t name ) /* Find a symbol NAME in the symbol table and return its code. * If there is no symbol NAME, report an error. */ { int_t lower, upper, middle, result; symbol_t symbol; /* We do a binary search in SYMBOLS_BY_NAME. */ lower = 0; upper = symbol_table.symbol_count - 1; while (lower <= upper) { middle = (lower + upper) / 2; symbol = symbol_table.symbols_by_name[ middle ]; result = strcmp_no_case( name, get_symbol_name( symbol ) ); if (result < 0) upper = middle - 1; else if (result > 0) lower = middle + 1; else return symbol; } complain( "Unknown symbol \"%s\".", name ); } /*---------------------------------------------------------------------------*/ symbol_t find_multi_symbol( value_t atoms ) /* Find a symbol by its atoms in the symbol table and return its code. * If there is no multi-symbol for ATOMS, report an error. */ { int_t lower, upper, middle, result; symbol_t symbol; /* We do a binary search in SYMBOLS_BY_ATOMS. */ lower = 0; upper = symbol_table.symbol_count - 1; while (lower <= upper) { middle = (lower + upper) / 2; symbol = symbol_table.symbols_by_atoms[ middle ]; result = compare_atom_lists( atoms, get_atoms( symbol ) ); if (result < 0) upper = middle - 1; else if (result > 0) lower = middle + 1; else return symbol; } complain( "No multi symbol for this atom list." ); } /*---------------------------------------------------------------------------*/ int_t symbol_count( void ) /* Return the number of symbols defined. */ { return symbol_table.symbol_count; } /*---------------------------------------------------------------------------*/ static int compare_symbols_by_name( const void *symbol1, const void *symbol2 ) /* Return -1 if name( SYMBOL1 ) < name( SYMBOL2 ) * 0 if name( SYMBOL1 ) == name( SYMBOL2 ) * 1 if name( SYMBOL1 ) > name( SYMBOL2 ). */ { return strcmp_no_case( get_symbol_name( *(symbol_t *) symbol1 ), get_symbol_name( *(symbol_t *) symbol2 ) ); } /*---------------------------------------------------------------------------*/ static int compare_symbols_by_atoms( const void *symbol1, const void *symbol2 ) /* Return -1 if atoms( SYMBOL1 ) < atoms( SYMBOL2 ) * 0 if atoms( SYMBOL1 ) == atoms( SYMBOL2 ) * 1 if atoms( SYMBOL1 ) > atoms( SYMBOL2 ). */ { return compare_atom_lists( get_atoms( *(symbol_t *) symbol1 ), get_atoms( *(symbol_t *) symbol2 ) ); } /*---------------------------------------------------------------------------*/ void init_symbols( string_t file_name ) /* Initialise this module. Read SYMBOL_TABLE from file FILE_NAME. */ { FILE *stream; symbol_header_t header; int_t i; stream = open_stream( file_name, "rb" ); read_vector( &header, sizeof( header ), 1, stream, file_name ); check_header( &header.common_header, file_name, SYMBOL_FILE, MIN_SYMBOL_CODE_VERSION, SYMBOL_CODE_VERSION ); symbol_table.symbol_count = header.symbol_count; symbol_table.symbols = read_new_vector( sizeof( symbol_entry_t ), header.symbol_count, stream, file_name ); symbol_table.values_size = header.values_size; symbol_table.values = read_new_vector( sizeof( cell_t ), header.values_size, stream, file_name ); symbol_table.strings_size = header.strings_size; symbol_table.strings = read_new_vector( sizeof( char_t ), header.strings_size, stream, file_name ); close_stream( &stream, file_name ); /* Build a list of all symbols sorted by their names * and a list of all symbols sorted by their atom lists. */ symbol_table.symbols_by_name = new_vector( sizeof( symbol_t ), header.symbol_count ); symbol_table.symbols_by_atoms = new_vector( sizeof( symbol_t ), header.symbol_count ); for (i = 0; i < header.symbol_count; i++) { symbol_table.symbols_by_name[i] = i; symbol_table.symbols_by_atoms[i] = i; } qsort( symbol_table.symbols_by_name, header.symbol_count, sizeof( symbol_t ), compare_symbols_by_name ); qsort( symbol_table.symbols_by_atoms, header.symbol_count, sizeof( symbol_t ), compare_symbols_by_atoms ); values_get_symbol_name = get_symbol_name; values_get_atoms = get_atoms; } /*---------------------------------------------------------------------------*/ void terminate_symbols( void ) /* Terminate this module. */ { free_mem( &symbol_table.symbols ); free_mem( &symbol_table.symbols_by_name ); free_mem( &symbol_table.symbols_by_atoms ); free_mem( &symbol_table.values ); free_mem( &symbol_table.strings ); } /* End of file. =============================================================*/ malaga-7.12/symbols.h0000644000175000017500000000214510236624404014051 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module administrates the name and atoms for each symbol. */ /* Functions. ===============================================================*/ extern string_t get_symbol_name( symbol_t symbol ); /* Return the name of SYMBOL. */ extern value_t get_atoms( symbol_t symbol ); /* Return the atom list of SYMBOL. */ extern symbol_t find_symbol( string_t name ); /* Find a symbol by NAME in the symbol table and return its code. * If there is no symbol NAME, report an error. */ extern symbol_t find_multi_symbol( value_t atoms ); /* Find the multi-symbol for ATOMS and return its code. * If there is no multi-symbol for ATOMS, report an error. */ extern int_t symbol_count( void ); /* Return the number of symbols defined. */ extern void init_symbols( string_t file_name ); /* Initialise this module; Read symbol table from file FILE_NAME. */ extern void terminate_symbols( void ); /* Terminate this module. */ /* End of file. =============================================================*/ malaga-7.12/sym_compiler.c0000644000175000017500000002501410236624402015054 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module compiles malaga symbol files. */ /* Includes. ================================================================*/ #include #include #include #include #include #include "basic.h" #include "pools.h" #include "values.h" #include "scanner.h" #include "files.h" #include "malaga_files.h" #include "symbols.h" #include "avl_trees.h" #include "hangul.h" #include "sym_compiler.h" /* Types. ===================================================================*/ typedef struct /* A node of the symbol table. */ { avln_node_t node; /* The symbol tree is an AVLN tree. */ value_t atoms; /* List of atoms in VALUE_POOL. */ symbol_t symbol; /* Symbol which this node represents. */ } symbol_node_t; typedef struct /* A node of the atoms tree. */ { avl_node_t node; /* The atoms tree is an AVL tree, sorted by its atoms. */ value_t atoms; symbol_t symbol; string_t name; } atoms_node_t; /* Variables. ===============================================================*/ static avln_node_t *symbol_tree; /* The symbol table, sorted by names. * This is actually a symbol_node_t. */ static avl_node_t *atoms_tree; /* The symbol table, sorted by atoms. * This is actually a atoms_node_t. */ static pool_t symbol_pool; /* Symbol entries. */ static pool_t value_pool; /* Lists of atomic symbols. */ static pool_t string_pool; /* Symbol names. */ /* Functions. ===============================================================*/ static int_t compare_by_atoms( avl_node_t *node1, avl_node_t *node2 ) /* Callback function for AVL tree functions. */ { return compare_atom_lists( ((atoms_node_t *) node1)->atoms, ((atoms_node_t *) node2)->atoms ); } /*---------------------------------------------------------------------------*/ static symbol_node_t * find_symbol_node( string_t name ) /* Find and return a symbol node with given name. * If no symbol node exists, return NULL. */ { avln_node_t *node; int_t result; /* Look for existing node. */ node = symbol_tree; while (node != NULL) { result = strcmp_no_case( name, node->name ); if (result < 0) node = node->left; else if (result > 0) node = node->right; else return (symbol_node_t *) node; } return NULL; } /*---------------------------------------------------------------------------*/ static symbol_t find_atomic_symbol( string_t name ) /* Find symbol NAME and check if it is atomic. Return the symbol. */ { symbol_node_t *node; node = find_symbol_node( name ); if (node == NULL) complain( "Symbol \"%s\" is not defined.", name ); else if (get_list_length( node->atoms ) > 1) complain( "Symbol \"%s\" is not atomic.", name ); return node->symbol; } /*---------------------------------------------------------------------------*/ static void enter_symbol( string_t name, value_t atoms ) /* Enter NAME as a symbol name with atomic symbol list ATOMS * in the symbol tree. */ { symbol_node_t *node; atoms_node_t *atoms_node; symbol_entry_t symbol_entry; int_t result; node = find_symbol_node( name ); if (atoms == NULL) { /* Make atom list for atomic symbol. */ top = 0; if (node != NULL) push_symbol_value( node->symbol ); else push_symbol_value( pool_item_count( symbol_pool ) ); build_list(1); atoms = value_stack[0]; } if (node != NULL) { /* Compare with previous definition. */ if (compare_atom_lists( atoms, node->atoms ) != 0) { complain( "Atom list for \"%s\" differs in previous definition.", node->node.name ); } } else { /* Create new symbol node. */ node = new_mem( sizeof( symbol_node_t ) ); node->node.name = copy_string_to_pool( string_pool, name, &symbol_entry.name ); node->symbol = pool_item_count( symbol_pool ); if (node->symbol >= SYMBOL_MAX) complain( "Too many symbols." ); node->atoms = copy_value_to_pool( value_pool, atoms, &symbol_entry.atoms ); insert_avln_node( (avln_node_t *) node, &symbol_tree ); copy_to_pool( symbol_pool, &symbol_entry, 1, NULL ); if (get_list_length( atoms ) > 1) { /* Check that there is no identical atom list. */ atoms_node = (atoms_node_t *) atoms_tree; while (atoms_node != NULL) { result = compare_atom_lists( atoms, atoms_node->atoms ); if (result < 0) atoms_node = (atoms_node_t *) atoms_node->node.left; else if (result > 0) atoms_node = (atoms_node_t *) atoms_node->node.right; else { complain( "Atom list is the same as for \"%s\".", atoms_node->name ); } } /* Create new atoms node. */ atoms_node = new_mem( sizeof( atoms_node_t ) ); atoms_node->atoms = node->atoms; atoms_node->name = node->node.name; atoms_node->symbol = node->symbol; insert_avl_node( (avl_node_t *) atoms_node, &atoms_tree, compare_by_atoms ); } } } /*---------------------------------------------------------------------------*/ static void parse_atom_list( value_t *atom_list_p ) /* Stack effects: (nothing) -> LIST. * Parse a list of symbols. Return it as *ATOM_LIST_P. */ { int_t i; top = 0; test_token( '<' ); do { read_next_token(); test_token( TOK_IDENT ); push_symbol_value( find_atomic_symbol( token_name ) ); /* Test if SYMBOL already occurs in symbol list. */ for (i = 0; i < top-1; i++) { if (values_equal( value_stack[ top - 1 ], value_stack[i] )) complain( "Symbol \"%s\" twice in atom list.", token_name ); } /* Read after TOKEN_NAME. */ read_next_token(); } while (next_token == ','); parse_token( '>' ); if (top < 2) complain( "Atom list must contain at least two atoms." ); build_list( top ); *atom_list_p = value_stack[0]; } /*---------------------------------------------------------------------------*/ static void parse_symbols( void ) /* Parse a symbol file. */ { string_t file_name, symbol_name; value_t atom_list; while (next_token != EOF) { if (next_token == TOK_INCLUDE) { /* Include a new file. */ read_next_token(); test_token( TOK_STRING ); file_name = absolute_path( token_string, current_file_name() ); read_next_token(); begin_include( file_name ); parse_symbols(); end_include(); free_mem( &file_name ); parse_token( ';' ); } else { /* Read a symbol. */ test_token( TOK_IDENT ); symbol_name = new_string( token_name, NULL ); read_next_token(); if (next_token == TOK_ASSIGN) { read_next_token(); parse_atom_list( &atom_list ); } else atom_list = NULL; enter_symbol( symbol_name, atom_list ); free_mem( &symbol_name ); parse_token( ';' ); } } } /*---------------------------------------------------------------------------*/ static void write_symbols( string_t file_name ) /* Write symbol table to file FILE_NAME. */ { FILE *stream; symbol_header_t symbol_header; stream = open_stream( file_name, "wb" ); /* Set rule file header data. */ set_header( &symbol_header.common_header, SYMBOL_FILE, SYMBOL_CODE_VERSION ); symbol_header.symbol_count = pool_item_count( symbol_pool ); symbol_header.values_size = pool_item_count( value_pool ); symbol_header.strings_size = pool_item_count( string_pool ); /* Write header. */ write_vector( &symbol_header, sizeof( symbol_header ), 1, stream, file_name ); /* Write tables to stream. */ write_pool( symbol_pool, stream, file_name ); write_pool( value_pool, stream, file_name ); write_pool( string_pool, stream, file_name ); close_stream( &stream, file_name ); } /*---------------------------------------------------------------------------*/ static void init_sym_compiler( void ) /* Initialise this module. */ { symbol_pool = new_pool( sizeof( symbol_entry_t ) ); value_pool = new_pool( sizeof( symbol_t ) ); string_pool = new_pool( sizeof( char_t ) ); } /*---------------------------------------------------------------------------*/ static void free_tree( avl_node_t *node ) { if (node == NULL) return; free_tree( node->left ); free_tree( node->right ); free_mem( &node ); } /*---------------------------------------------------------------------------*/ static void terminate_sym_compiler( void ) /* Terminate this module. */ { free_tree( (avl_node_t *) symbol_tree ); symbol_tree = NULL; free_tree( (avl_node_t *) atoms_tree ); atoms_tree = NULL; free_pool( &symbol_pool ); free_pool( &value_pool ); free_pool( &string_pool ); } /*---------------------------------------------------------------------------*/ void compile_symbol_file( string_t source_file, string_t object_file, string_t old_symbol_file ) /* Read symbol file SOURCE_FILE and create translated file OBJECT_FILE. * If OLD_SYMBOL_FILE != NULL, all symbols from this file are included in * the new file. */ { value_t atoms; symbol_t symbol; init_sym_compiler(); if (old_symbol_file != NULL) { /* Enter the symbols from OLD_SYMBOL_FILE. */ init_symbols( old_symbol_file ); init_hangul(); for (symbol = 0; symbol < symbol_count(); symbol++) { atoms = get_atoms( symbol ); if (get_list_length( atoms ) <= 1) atoms = NULL; enter_symbol( get_symbol_name( symbol ), atoms ); } terminate_symbols(); set_esym_stamp(); } else { /* Enter the standard symbols in the same order as in "values.h". */ enter_symbol( "nil", NULL ); enter_symbol( "yes", NULL ); enter_symbol( "no", NULL ); enter_symbol( "symbol", NULL ); enter_symbol( "string", NULL ); enter_symbol( "number", NULL ); enter_symbol( "list", NULL ); enter_symbol( "record", NULL ); set_sym_stamp(); } begin_include( source_file ); TRY { parse_symbols(); if (next_token != EOF) complain( "Symbol definition expected." ); } IF_ERROR { print_text( error_text, " (\"%s\", line %d, column %d)", name_in_path( current_file_name() ), current_line_number(), current_column() ); if (in_emacs_malaga_mode) { printf( "SHOW \"%s\":%d:%d\n", current_file_name(), current_line_number(), current_column() ); } } FINALLY end_includes(); END_TRY; write_symbols( object_file ); terminate_sym_compiler(); terminate_hangul(); } /* End of file. =============================================================*/ malaga-7.12/sym_compiler.h0000644000175000017500000000122710236624377015074 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module compiles malaga symbol files. */ /* Functions. =============================================================*/ extern void compile_symbol_file( string_t source_file, string_t object_file, string_t old_symbol_file ); /* Read symbol file SOURCE_FILE_NAME and create translated file * with name OBJECT_FILE_NAME. * If OLD_SYMBOL_FILE != NULL, include symbols of that file. */ /* End of file. =============================================================*/ malaga-7.12/transmit.c0000644000175000017500000000751410506407317014224 0ustar bjoernbjoern/* Copyright (C) 1997 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module invokes and manages the transmit process from malaga. */ /* Includes. ================================================================*/ #include #include #include #include #include #include #include "basic.h" #include "pools.h" #include "values.h" #include "files.h" #include "input.h" #include "symbols.h" #include "commands.h" #include "value_parser.h" #include "scanner.h" #include "options.h" #include "rule_type.h" #include "rules.h" #include "processes.h" #include "transmit.h" /* Variables. ===============================================================*/ static process_t transmit_process; /* Functions. ===============================================================*/ static void transmit_local( void ) /* Stack effects: VALUE -> NEW_VALUE * Start the Malaga transmit process by executing TRANSMIT_COMMAND_LINE * if it is not already running. * Send VALUE, in text format, to the transmit process and receive an answer * value in text format, convert it into internal format as NEW_VALUE. */ { string_t input_line, value_string; /* Start transmit process. */ transmit_process.use_input = TRUE; transmit_process.use_output = TRUE; transmit_process.name = "transmit process"; start_process( &transmit_process ); /* Send top value to transmit process. */ value_string = value_to_readable( value_stack[ --top ], TRUE, -1 ); fprintf( transmit_process.output_stream, "%s\n", value_string ); fflush( transmit_process.output_stream ); free_mem( &value_string ); /* Read result and convert it to value format. */ input_line = read_line( transmit_process.input_stream ); if (input_line == NULL) complain( "Transmit process doesn't answer." ); set_scanner_input( input_line ); TRY { parse_a_value(); parse_token( EOF ); } FINALLY { free_mem( &input_line ); set_scanner_input( NULL ); } END_TRY; } /*---------------------------------------------------------------------------*/ void init_transmit( void ) /* Initialise this module. */ { transmit = transmit_local; } /*---------------------------------------------------------------------------*/ void terminate_transmit( void ) /* Terminate this module. */ { stop_process( &transmit_process ); transmit = NULL; } /*---------------------------------------------------------------------------*/ static void do_transmit_cmd_option( string_t arguments ) /* Set the command line to start the transmit process. */ { if (*arguments == EOS) { printf( "transmit-cmd: \"%s\"\n", (transmit_process.command_line == NULL ? "" : transmit_process.command_line) ); } else { stop_process( &transmit_process ); transmit_process.command_line = parse_word( &arguments ); } parse_end( &arguments ); } command_t transmit_cmd_option = { "transmit-cmd transmit-line transmit", do_transmit_cmd_option, "Usage: set transmit-cmd \"TRANSMIT_COMMAND_LINE\"\n" "Set the command that is used to start the transmit process.\n" }; /*---------------------------------------------------------------------------*/ static void do_transmit( string_t arguments ) /* Communicate with the transmit process. */ { string_t result; set_scanner_input( arguments ); TRY { parse_a_value(); test_token( EOF ); } FINALLY set_scanner_input( NULL ); END_TRY; transmit_local(); result = value_to_readable( value_stack[ --top ], FALSE, 0 ); printf( "%s\n", result ); free_mem( &result ); } command_t transmit_command = { "transmit", do_transmit, "Usage: transmit VALUE\n" "Send VALUE to the transmit process and display the result.\n" }; /* End of file. =============================================================*/ malaga-7.12/transmit.h0000644000175000017500000000132610506407465014230 0ustar bjoernbjoern/* Copyright (C) 1997 Bjoern Beutel. */ /* Description. =============================================================*/ /* Manages the transmit process from Malaga. */ /* Functions. ===============================================================*/ extern void init_transmit( void ); /* Initialise this module. */ extern void terminate_transmit( void ); /* Terminate this module. */ /* Commands. ================================================================*/ extern command_t transmit_cmd_option; /* Set the command line to start the display process. */ extern command_t transmit_command; /* Communicate with the transmit process. */ /* End of file. =============================================================*/ malaga-7.12/tree.c0000644000175000017500000007751610655264263013341 0ustar bjoernbjoern/* Copyright (C) 2002 Bjoern Beutel. */ /* Description. =============================================================*/ /* Read in and display Malaga Variables. */ /* Includes. ================================================================*/ #include #include #include #include #include #include #include "basic.h" #include "scanner.h" #include "input.h" #include "canvas.h" #include "tree.h" /* Constants. ===============================================================*/ enum {FIRST_STATE, NEXT_STATE, PREV_STATE, LAST_STATE}; enum {PATH_BEGIN, PATH_END, FROM_ROOT}; /* Items of the tree's pop-up menu. */ /* Types. ===================================================================*/ typedef enum {INTER_NODE, BREAK_NODE, FINAL_NODE, UNFINAL_NODE, PRUNED_NODE} tree_node_type_t; typedef enum {ELEMENT_NODE, ELEMENT_LINK, ELEMENT_RULE} element_t; /* Elements of a node that may be hit by the mouse pointer. */ typedef struct tree_node { struct tree_node *parent; /* Parent of this tree node. */ struct tree_node *sibling; /* Next sibling of this tree node. */ struct tree_node *child; /* First successor of this tree node. */ int_t state_index; /* State index of this tree node. */ tree_node_type_t type; /* Type of this node. */ string_t rule_name; /* Name of rule that created this node. */ string_t link_surf; string_t link_feat; string_t result_surf; string_t result_feat; string_t rule_set; bool_t result_path; /* The following items are used to display the tree node. */ bool_t in_path; /* TRUE iff this node is in displayed path. */ int_t x, y; /* Node position. */ pos_string_t *pos_rule_name; /* Positioned rule name. */ pos_string_t *pos_link_surf; /* Positioned link surface. */ pos_string_t *pos_state_index; /* Positioned state index. */ } tree_node_t; typedef struct { list_node_t *next; /* Next path node in this list. */ pos_string_t *state_index; pos_string_t *link_surf; pos_value_t *link_feat; pos_string_t *rule_name; pos_string_t *result_surf; pos_value_t *result_feat; pos_string_t *rule_set; } path_node_t; /* Global variables. ========================================================*/ rectangle_t tree_geometry, path_geometry; string_t tree_font_family, path_font_family; int_t tree_font_size, path_font_size; tree_mode_t tree_mode; bool_t show_state_indexes; bool_t inline_path; /* Variables. ===============================================================*/ /* Information in Tree window. */ static pos_string_t *result_surf; static tree_node_t *tree_nodes; static tree_node_t **states; /* Dynamic array of nodes representing states. */ static int_t state_count; /* Size of the array STATES. */ static int_t tree_width, tree_height; /* Width and height of tree canvas. */ static canvas_t *tree_canvas; static tree_node_t *popup_menu_node; static bool_t tree_show_state_indexes; /* Controls whether state indexes are shown in tree. */ /* Information in Path window. */ static list_t path_nodes; static canvas_t *path_canvas; static pos_string_t *plus; static pos_string_t *comma; static tree_node_t *path_begin, *path_end; static bool_t path_show_state_indexes; /* Controls whether state indexes are shown in path. */ /* Forward declarations. ====================================================*/ static void goto_state( canvas_t *canvas, guint action ); /* Functions. ===============================================================*/ static string_t parse_optional_value( string_t *input ) /* Parse "{}" or "{VALUE}" in *INPUT and return NULL or VALUE, resp. * Update *INPUT. The result must bee freed after use. */ { string_t s, value; if (**input != '{') complain( "Missing \"{\"." ); for (s = *input + 1; *s != '}'; s++) { if (*s == EOS) complain( "Missing \"}\"." ); if (*s == '\"') { for (s++; *s != '\"'; s++) { if (*s == EOS) complain( "Missing '\"'." ); if (s[0] == '\\' && s[1] == '\"') s++; } } } if (s > *input + 1) value = new_string( *input + 1, s ); else value = NULL; *input = s + 1; parse_whitespace( input ); return value; } /*---------------------------------------------------------------------------*/ static void configure_path( canvas_t *canvas, int_t *width_p, int_t *height_p ) /* Do the layout of the path CANVAS. * Return the canvas' total size in *WIDTH_P and *HEIGHT_P. */ { int_t path_width, path_height, x, x_dist; path_node_t *node; bool_t is_first; int_t space_width = get_space_width( canvas ); int_t font_height = get_font_height( canvas ); int_t font_ascent = get_font_ascent( canvas ); int_t border_width = get_border_width( canvas ); config_pos_string( plus, canvas ); config_pos_string( comma, canvas ); x_dist = space_width + comma->width; path_width = path_height = border_width; is_first = TRUE; FOREACH( node, path_nodes ) { if (node->link_feat != NULL) { if (is_first) is_first = FALSE; else path_height += font_height; config_pos_string( node->link_surf, canvas ); node->link_surf->x = border_width + plus->width + space_width; path_width = MAX( path_width, node->link_surf->x + node->link_surf->width ); config_pos_value( node->link_feat, canvas ); node->link_feat->x = node->link_surf->x; if (inline_path) { node->link_surf->y = (path_height + node->link_feat->ascent - font_ascent); node->link_feat->x += node->link_surf->width + x_dist; } else { node->link_surf->y = path_height; path_height += font_height; } node->link_feat->y = path_height; path_width = MAX( path_width, node->link_feat->x + node->link_feat->width ); path_height += node->link_feat->height; } if (node->result_feat != NULL) { if (is_first) is_first = FALSE; else path_height += font_height; x = border_width; /* Configure rule name. */ if (node != (path_node_t *) path_nodes.first) { config_pos_string( node->rule_name, canvas ); node->rule_name->x = x; x += node->rule_name->width + 2 * space_width; if (! inline_path) node->rule_name->y = path_height; } /* Configure state index. */ if (path_show_state_indexes) { config_pos_string( node->state_index, canvas ); node->state_index->x = x; if (inline_path) x += node->state_index->width + x_dist; else { node->state_index->y = path_height; path_width = MAX( path_width, x + node->state_index->width ); path_height += font_height; } } /* Configure result surface. */ config_pos_string( node->result_surf, canvas ); node->result_surf->x = x; if (inline_path) x += node->result_surf->width + x_dist; else { node->result_surf->y = path_height; path_width = MAX( path_width, x + node->result_surf->width ); path_height += font_height; } /* Configure result feature structure. */ config_pos_value( node->result_feat, canvas ); node->result_feat->x = x; node->result_feat->y = path_height; if (inline_path) x += node->result_feat->width + x_dist; else { path_width = MAX( path_width, x + node->result_feat->width ); path_height += node->result_feat->height; } /* Configure rule set. */ config_pos_string( node->rule_set, canvas ); node->rule_set->x = x; if (inline_path) { node->rule_name->y = node->state_index->y = node->result_surf->y = node->rule_set->y = path_height + node->result_feat->ascent - font_ascent; path_height += node->result_feat->height; } else { node->rule_set->y = path_height; path_height += font_height; } path_width = MAX( path_width, x + node->rule_set->width ); } } *width_p = path_width + border_width; *height_p = path_height + border_width; } /*---------------------------------------------------------------------------*/ static void expose_path( canvas_t *canvas, rectangle_t *area ) { path_node_t *node; int_t x1, x2, y; int_t space_width = get_space_width( canvas ); int_t font_height = get_font_height( canvas ); int_t border_width = get_border_width( canvas ); int_t line_width = get_line_width( canvas ); set_color( BLACK ); FOREACH( node, path_nodes ) { if (node->link_feat != NULL) { plus->x = border_width; plus->y = node->link_surf->y; draw_pos_string( plus, canvas ); draw_pos_string( node->link_surf, canvas ); draw_pos_value( node->link_feat, canvas ); if (inline_path) { comma->x = node->link_surf->x + node->link_surf->width; comma->y = node->link_surf->y; draw_pos_string( comma, canvas ); } } if (node->result_feat != NULL) { if (node != (path_node_t *) path_nodes.first) { x1 = node->rule_name->x; x2 = x1 + node->rule_name->width + space_width; y = node->rule_name->y + font_height + line_width; draw_pos_string( node->rule_name, canvas ); /* Draw arrow. */ draw_lines( 2, x1, y, x2, y ); draw_lines( 3, x2 - space_width, y - space_width / 2, x2, y, x2 - space_width, y + space_width / 2 ); } if (path_show_state_indexes) draw_pos_string( node->state_index, canvas ); draw_pos_string( node->result_surf, canvas ); draw_pos_value( node->result_feat, canvas ); draw_pos_string( node->rule_set, canvas ); if (inline_path) { comma->x = node->result_surf->x + node->result_surf->width; comma->y = node->result_surf->y; draw_pos_string( comma, canvas ); comma->x = node->result_feat->x + node->result_feat->width; draw_pos_string( comma, canvas ); } } } } /*---------------------------------------------------------------------------*/ static void unmark_tree_nodes( tree_node_t *node ) /* Mark NODE and all its children and siblings *not* to be part of the path. */ { for (; node != NULL; node = node->sibling) { node->in_path = FALSE; unmark_tree_nodes( node->child ); } } /*---------------------------------------------------------------------------*/ static void free_path( void ) { path_node_t *path_node; /* Clear old path nodes. */ FOREACH_FREE( path_node, path_nodes ) { free_pos_string( &path_node->state_index ); free_pos_value( &path_node->link_feat ); free_pos_value( &path_node->result_feat ); } unmark_tree_nodes( tree_nodes ); } /*---------------------------------------------------------------------------*/ static void close_path( canvas_t *canvas ) { free_path(); path_begin = path_end = NULL; redraw_canvas( tree_canvas ); } /*---------------------------------------------------------------------------*/ static void set_inline_path( canvas_t *canvas, guint action, GtkWidget *item ) { inline_path = GTK_CHECK_MENU_ITEM( item )->active; configure_canvas( canvas ); } /*---------------------------------------------------------------------------*/ static void path_index_option( canvas_t *canvas, guint action, GtkWidget *item ) { path_show_state_indexes = GTK_CHECK_MENU_ITEM( item )->active; configure_canvas( canvas ); } /*---------------------------------------------------------------------------*/ static GtkItemFactoryEntry path_items[] = { { "/Style/Inline", NULL, set_inline_path, 0, "" }, { "/Path", NULL, NULL, 0, "" }, { "/Path/Show State Indexes", NULL, path_index_option, 0, "" }, { "/End States", NULL, NULL, 0, "" }, { "/End States/Show First End State", "F", goto_state, FIRST_STATE, NULL }, { "/End States/Show Previous End State", "P", goto_state, PREV_STATE, NULL }, { "/End States/Show Next End State", "N", goto_state, NEXT_STATE, NULL }, { "/End States/Show Last End State", "L", goto_state, LAST_STATE, NULL } }; /*---------------------------------------------------------------------------*/ static void display_path( void ) { tree_node_t *tree_node; path_node_t *path_node; string_t state_index, string; free_path(); /* Create the path nodes. We go backwards from the path end to the path * beginning, since this direction is easier to traverse. */ for (tree_node = path_end; ; tree_node = tree_node->parent) { tree_node->in_path = TRUE; path_node = new_node( &path_nodes, sizeof( path_node_t ), LIST_START ); if (path_begin != NULL && tree_node->result_feat != NULL) { /* Create a new state in the path. */ state_index = int_to_string( tree_node->state_index ); string = concat_strings( "State ", state_index, ":", NULL ); path_node->state_index = new_pos_string( string ); free_mem( &string ); free_mem( &state_index ); path_node->rule_name = new_pos_string( tree_node->rule_name ); path_node->result_surf = new_pos_string( tree_node->result_surf ); set_scanner_input( tree_node->result_feat ); path_node->result_feat = parse_pos_value(); parse_token( EOF ); set_scanner_input( NULL ); path_node->rule_set = new_pos_string( tree_node->rule_set ); } if (tree_node == path_begin) break; if (tree_node->link_feat != NULL) { /* Create a new link in the path. */ path_node->link_surf = new_pos_string( tree_node->link_surf ); set_scanner_input( tree_node->link_feat ); path_node->link_feat = parse_pos_value(); parse_token( EOF ); set_scanner_input( NULL ); } if (path_begin == NULL) break; } if (path_canvas == NULL) { path_canvas = create_canvas( "Malaga Path", "path.eps", &path_geometry, configure_path, expose_path, close_path, NULL, TRUE, path_items, ARRAY_LENGTH( path_items ) ); path_show_state_indexes = show_state_indexes; if (path_show_state_indexes) activate_menu_item( path_canvas, "/Path/Show State Indexes" ); if (inline_path) activate_menu_item( path_canvas, "/Style/Inline" ); } else { configure_canvas( path_canvas ); show_canvas( path_canvas ); } redraw_canvas( tree_canvas ); } /*---------------------------------------------------------------------------*/ static void configure_node( canvas_t *canvas, tree_node_t *node, int_t x, int_t y ) { int_t w, node_width; tree_node_t *subnode; bool_t is_first; int_t font_height = get_font_height( canvas ); int_t space_width = get_space_width( canvas ); int_t line_width = get_line_width( canvas ); if (tree_show_state_indexes && node->state_index != -1) { config_pos_string( node->pos_state_index, canvas ); node_width = MAX( node->pos_state_index->width + space_width, font_height ); node->pos_state_index->x = x + (node_width - node->pos_state_index->width) / 2; node->pos_state_index->y = tree_height - font_height * 3 / 2 + 1; } else node_width = font_height; node->x = x + node_width / 2; node->y = y; x += node_width; tree_width = MAX( tree_width, x ); is_first = TRUE; for (subnode = node->child; subnode != NULL; subnode = subnode->sibling) { if (tree_mode == NO_DEAD_ENDS && subnode->type == BREAK_NODE) continue; if (tree_mode == RESULT_PATHS && ! subnode->result_path) continue; if (is_first) is_first = FALSE; else tree_height += (5 * font_height) / 2; config_pos_string( subnode->pos_link_surf, canvas ); config_pos_string( subnode->pos_rule_name, canvas ); w = MAX( subnode->pos_link_surf->width, subnode->pos_rule_name->width ); w = MAX( w, space_width ); subnode->pos_link_surf->x = x + (w - subnode->pos_link_surf->width) / 2; subnode->pos_link_surf->y = tree_height - font_height - line_width; subnode->pos_rule_name->x = x + (w - subnode->pos_rule_name->width) / 2; subnode->pos_rule_name->y = tree_height + line_width; configure_node( canvas, subnode, x + w, tree_height ); } } /*---------------------------------------------------------------------------*/ static void configure_tree( canvas_t *canvas, int_t *width_p, int_t *height_p ) { int_t font_height = get_font_height( canvas ); int_t border_width = get_border_width( canvas ); tree_width = tree_height = border_width; /* Configure result surface. */ config_pos_string( result_surf, canvas ); result_surf->x = border_width; result_surf->y = border_width; tree_width = MAX( tree_width, border_width + result_surf->width ); tree_height += font_height; if (tree_mode != RESULT_PATHS || tree_nodes->result_path) { /* Configure tree. */ tree_height += 2 * font_height; configure_node( canvas, tree_nodes, border_width, tree_height ); } /* Return width and height. */ *width_p = tree_width + border_width; *height_p = tree_height + font_height + border_width; } /*---------------------------------------------------------------------------*/ static void expose_node( canvas_t *canvas, tree_node_t *node, int_t font_height ) { tree_node_t *subnode; const int_t x = node->x; const int_t y = node->y; const int_t radius1 = font_height / 2; const int_t radius2 = (radius1 * 3) / 5; int_t middle = y; int_t bottom = y; /* Draw all subnodes. */ for (subnode = node->child; subnode != NULL; subnode = subnode->sibling) { if (tree_mode == NO_DEAD_ENDS && subnode->type == BREAK_NODE) continue; if (tree_mode == RESULT_PATHS && ! subnode->result_path) continue; /* Draw horizontal line. */ bottom = subnode->y; if (node->in_path && subnode->in_path) { middle = subnode->y; set_color( RED ); } else set_color( BLACK ); draw_lines( 2, x, subnode->y, subnode->x, subnode->y ); if (path_begin == NULL && subnode->in_path) set_color( RED ); draw_pos_string( subnode->pos_link_surf, canvas ); set_color( BLACK ); draw_pos_string( subnode->pos_rule_name, canvas ); expose_node( canvas, subnode, font_height ); } /* Draw vertical line. */ set_color( BLACK ); draw_lines( 2, x, middle, x, bottom ); if (middle != y) { set_color( RED ); draw_lines( 2, x, y, x, middle ); } /* Draw the node itself. */ if (node->type == BREAK_NODE) { set_color( (node->in_path && path_begin != NULL ? RED : BLACK) ); draw_rectangle( x - radius1 , y - radius1, 2 * radius1, 2 * radius1 ); } else { set_color( WHITE ); draw_circle( TRUE, x, y, radius1 ); set_color( (node->in_path && path_begin != NULL ? RED : BLACK) ); draw_circle( FALSE, x, y, radius1 ); if (node->type == FINAL_NODE || node->type == UNFINAL_NODE) draw_circle( FALSE, x, y, radius2 ); if (node->type == PRUNED_NODE || node->type == UNFINAL_NODE) { draw_lines( 2, x - radius1, y - radius1, x + radius1, y + radius1 ); draw_lines( 2, x + radius1, y - radius1, x - radius1, y + radius1 ); } } /* Draw the state index. */ if (tree_show_state_indexes && node->state_index != -1) { set_color( BLUE ); draw_pos_string( node->pos_state_index, canvas ); } } /*---------------------------------------------------------------------------*/ static void expose_tree( canvas_t *canvas, rectangle_t *area ) /* Expose AREA on tree CANVAS. */ { int_t font_height = get_font_height( canvas ); if (result_surf != NULL) { set_color( BLACK ); draw_pos_string( result_surf, canvas ); } if (tree_nodes == NULL) return; if (tree_mode != RESULT_PATHS || tree_nodes->result_path) expose_node( canvas, tree_nodes, font_height ); } /*---------------------------------------------------------------------------*/ static bool_t in_circle( int_t x, int_t y, int_t circle_x, int_t circle_y, int_t radius ) /* Return TRUE if position (X,Y) lies in disc with center (CIRCLE_X, CIRCLE_Y) * and RADIUS. */ { int_t diff_x = x - circle_x; int_t diff_y = y - circle_y; /* Taking DIFF_X or DIFF_Y to the 2nd power may result in an overflow, * so we will check first whether DIFF_X and DIFF_Y are small enough. */ return (ABS( diff_x ) < radius && ABS( diff_y ) < radius && diff_x * diff_x + diff_y * diff_y <= radius * radius); } /*---------------------------------------------------------------------------*/ static bool_t in_pos_string( int_t x, int_t y, pos_string_t *pos_string, int_t height ) /* Return TRUE if position (X,Y) lies in bounding box of POS_STRING, using font * height HEIGHT. */ { return (x >= pos_string->x && x < pos_string->x + pos_string->width && y >= pos_string->y && y < pos_string->y + height); } /*---------------------------------------------------------------------------*/ static bool_t in_rectangle( int_t x, int_t y, int_t rect_x, int_t rect_y, int_t width, int_t height ) /* Return TRUE if position (X,Y) lies in rectangle with upper left corner * (RECT_X, RECT_Y), width WIDTH and height HEIGHT. */ { return (x >= rect_x && x <= rect_x + width && y >= rect_y && y <= rect_y + height); } /*---------------------------------------------------------------------------*/ static void set_tree( canvas_t *canvas, guint mode ) /* Set the tree's display mode to MODE. */ { tree_mode = mode; if (path_end != NULL && ((tree_mode == NO_DEAD_ENDS && path_end->type == BREAK_NODE) || (tree_mode == RESULT_PATHS && ! path_end->result_path))) { hide_canvas( path_canvas ); } configure_canvas( tree_canvas ); } /*---------------------------------------------------------------------------*/ static void goto_state( canvas_t *canvas, guint action ) /* Display a certain state, according to ACTION, in the path window. */ { int_t i = 0; bool_t inverse = FALSE; /* TRUE if we search in inverse direction. */ if (action == FIRST_STATE || action == LAST_STATE || (path_begin != NULL && path_begin->type == FINAL_NODE)) { switch (action) { case FIRST_STATE: i = 0; break; case PREV_STATE: i = path_begin->state_index - 1; inverse = TRUE; break; case NEXT_STATE: i = path_begin->state_index + 1; break; case LAST_STATE: i = state_count - 1; inverse = TRUE; break; } while (i >= 0 && i < state_count) { if (states[i] != NULL && states[i]->type == FINAL_NODE) { path_begin = path_end = states[i]; make_visible( tree_canvas, path_begin->x, path_begin->y ); display_path(); break; } if (inverse) i--; else i++; } } } /*---------------------------------------------------------------------------*/ static tree_node_t * tree_node_at_position( tree_node_t *node, int_t x, int_t y, int_t font_height, element_t *element_p) { tree_node_t *subnode; if (node == NULL) return NULL; for (; node != NULL; node = node->sibling) { if (tree_mode == NO_DEAD_ENDS && node->type == BREAK_NODE) continue; if (tree_mode == RESULT_PATHS && ! node->result_path) continue; if ((node->type == BREAK_NODE && in_rectangle( x, y, node->x - font_height / 2, node->y - font_height / 2, font_height, font_height )) || (node->type != BREAK_NODE && in_circle( x, y, node->x, node->y, font_height / 2 ) )) { *element_p = ELEMENT_NODE; return node; } if (in_pos_string( x, y, node->pos_link_surf, font_height )) { *element_p = ELEMENT_LINK; return node; } if (in_pos_string( x, y, node->pos_rule_name, font_height )) { *element_p = ELEMENT_RULE; return node; } subnode = tree_node_at_position( node->child, x, y, font_height, element_p ); if (subnode != NULL) return subnode; } return NULL; } /*---------------------------------------------------------------------------*/ static void display_node( canvas_t *canvas, guint action ) { tree_node_t *node; if (action == PATH_BEGIN) path_begin = popup_menu_node; else if (action == FROM_ROOT) path_begin = tree_nodes; if (action == PATH_END || action == FROM_ROOT) path_end = popup_menu_node; /* Check whether there is a part from PATH_BEGIN to PATH_END. */ node = path_end; while (node != NULL && node != path_begin) node = node->parent; if (node == NULL) path_begin = path_end = popup_menu_node; display_path(); } /*---------------------------------------------------------------------------*/ static bool_t mouse_event( canvas_t *canvas, int_t x, int_t y, int_t button ) /* Called if mouse has moved to position (X,Y). */ { tree_node_t *node; element_t element; node = tree_node_at_position( tree_nodes, x, y, get_font_height( canvas ), &element ); if (node == NULL) { set_cursor( canvas, FALSE ); return FALSE; } /* No button pressed: we should just update the cursor. */ if (button == 0) { set_cursor( canvas, TRUE ); return TRUE; } switch (element) { case ELEMENT_NODE: if (button == 1) { path_begin = path_end = node; display_path(); } else if (button == 3) { popup_menu_node = node; popup_menu( canvas ); } break; case ELEMENT_LINK: path_begin = NULL; path_end = node; display_path(); break; case ELEMENT_RULE: path_begin = node->parent; path_end = node; display_path(); break; } return TRUE; } /*---------------------------------------------------------------------------*/ static void tree_index_option( canvas_t *canvas, guint action, GtkWidget *item ) { tree_show_state_indexes = GTK_CHECK_MENU_ITEM( item )->active; configure_canvas( canvas ); } /*---------------------------------------------------------------------------*/ static GtkItemFactoryEntry tree_items[] = { { "/Tree", NULL, NULL, 0, "" }, { "/Tree/Full Tree", NULL, set_tree, FULL_TREE, "" }, { "/Tree/No Dead Ends", NULL, set_tree, NO_DEAD_ENDS, "/Tree/Full Tree" }, { "/Tree/Complete Paths", NULL, set_tree, RESULT_PATHS, "/Tree/Full Tree" }, { "/Tree/sep1", NULL, NULL, 0, "" }, { "/Tree/Show State Indexes", NULL, tree_index_option, 0, "" }, { "/End States", NULL, NULL, 0, "" }, { "/End States/Show First End State", "F", goto_state, FIRST_STATE, NULL }, { "/End States/Show Previous End State", "P", goto_state, PREV_STATE, NULL }, { "/End States/Show Next End State", "N", goto_state, NEXT_STATE, NULL }, { "/End States/Show Last End State", "L", goto_state, LAST_STATE, NULL } }; /*---------------------------------------------------------------------------*/ static GtkItemFactoryEntry popup_items[] = { { "/Set Path Begin", NULL, display_node, PATH_BEGIN, "" }, { "/Set Path End", NULL, display_node, PATH_END, "" }, { "/Show Path From Root", NULL, display_node, FROM_ROOT, "" } }; /*---------------------------------------------------------------------------*/ static void free_tree_nodes( tree_node_t *node ) /* Free *NODE_P and all its siblings and children. Set *NODE_P to NULL. */ { tree_node_t *next; for (; node != NULL; node = next) { /* Remove node from state index. */ if (node->state_index != -1) states[ node->state_index ] = NULL; free_tree_nodes( node->child ); free_mem( &node->rule_name ); free_mem( &node->link_surf ); free_mem( &node->link_feat ); free_mem( &node->result_surf ); free_mem( &node->result_feat ); free_mem( &node->rule_set ); free_pos_string( &node->pos_link_surf ); free_pos_string( &node->pos_rule_name ); free_pos_string( &node->pos_state_index ); next = node->sibling; free( node ); } } /*---------------------------------------------------------------------------*/ static void free_tree( void ) { /* Clear old variables. */ free_pos_string( &result_surf ); free_pos_string( &plus ); free_pos_string( &comma ); free_tree_nodes( tree_nodes ); tree_nodes = NULL; } /*---------------------------------------------------------------------------*/ static void close_tree( canvas_t *canvas ) /* Called by "canvas.c" when CANVAS gets hidden. */ { if (path_canvas != NULL) hide_canvas( path_canvas ); free_tree(); } /*---------------------------------------------------------------------------*/ void read_tree( void ) /* Read new tree from STDIN. */ { string_t line; /* A line of input from STDIN. */ string_t line_p; /* Part of LINE which is yet to parse. */ string_t type; /* Node type. */ string_t state_index; tree_node_t *node; int_t parent_state_index, i; tree_node_t **node_p; if (path_canvas != NULL) hide_canvas( path_canvas ); free_tree(); /* Allocate new nodes array. */ if (state_count == 0) { state_count = 100; states = new_vector( sizeof( tree_node_t * ), state_count ); } /* Read new input surface. */ line = read_line( stdin ); result_surf = new_pos_string( line ); free_mem( &line ); /* Read new tree. */ while (TRUE) { line = read_line( stdin ); if (line == NULL) complain( "Premature EOF." ); if (strcmp_no_case( line, "end" ) == 0) break; node = new_mem( sizeof( tree_node_t ) ); line_p = line; node->state_index = parse_int( &line_p ); type = parse_word( &line_p ); if (strcmp_no_case( type, "inter" ) == 0) node->type = INTER_NODE; else if (strcmp_no_case( type, "break" ) == 0) node->type = BREAK_NODE; else if (strcmp_no_case( type, "final" ) == 0) node->type = FINAL_NODE; else if (strcmp_no_case( type, "unfinal" ) == 0) node->type = UNFINAL_NODE; else if (strcmp_no_case( type, "pruned" ) == 0) node->type = PRUNED_NODE; else complain( "Unknown node type \"%s\".", type ); free_mem( &type ); parent_state_index = parse_int( &line_p ); node->rule_name = parse_word( &line_p ); node->link_surf = parse_optional_value( &line_p ); node->link_feat = parse_optional_value( &line_p ); node->result_surf = parse_optional_value( &line_p ); node->result_feat = parse_optional_value( &line_p ); node->rule_set = parse_word( &line_p ); parse_end( &line_p ); free_mem( &line ); node->pos_link_surf = new_pos_string( node->link_surf ); node->pos_rule_name = new_pos_string( node->rule_name ); if (node->state_index != -1) { state_index = int_to_string( node->state_index ); node->pos_state_index = new_pos_string( state_index ); free_mem( &state_index ); } /* Find parent node. */ if (parent_state_index == -1) tree_nodes = node; /* This is the root node. */ else if (parent_state_index < 0 || parent_state_index >= state_count || states[ parent_state_index ] == NULL) { complain( "Display data corrupted." ); } else { node->parent = states[ parent_state_index ]; /* Add NODE to be a child of NODE->PARENT. */ node_p = &node->parent->child; while (*node_p != NULL) node_p = &(*node_p)->sibling; *node_p = node; } /* Add node to the STATES array. */ if (node->state_index >= state_count) { renew_vector( &states, sizeof( tree_node_t * ), 2 * node->state_index ); for (i = state_count; i < 2 * node->state_index; i++) states[i] = NULL; state_count = 2 * node->state_index; } if (node->state_index != -1) states[ node->state_index ] = node; /* If this is a final node, mark it and all its predecessors. */ if (node->type == FINAL_NODE) { for (; node != NULL; node = node->parent) node->result_path = TRUE; } } free_mem( &line ); if (tree_nodes == NULL) complain( "Missing root node in tree." ); plus = new_pos_string( "+" ); comma = new_pos_string( "," ); if (tree_canvas == NULL) { tree_canvas = create_canvas( "Malaga Tree", "tree.eps", &tree_geometry, configure_tree, expose_tree, close_tree, mouse_event, FALSE, tree_items, ARRAY_LENGTH( tree_items ) ); set_popup_menu( tree_canvas, popup_items, ARRAY_LENGTH( popup_items ) ); tree_show_state_indexes = show_state_indexes; if (tree_show_state_indexes ) activate_menu_item( tree_canvas, "/Tree/Show State Indexes" ); } else { configure_canvas( tree_canvas ); show_canvas( tree_canvas ); } } /* End of file. =============================================================*/ malaga-7.12/tree.h0000644000175000017500000000145410275341711013322 0ustar bjoernbjoern/* Copyright (C) 2002 Bjoern Beutel. */ /* Description. =============================================================*/ /* Read in and display a Malaga Tree. */ /* Types. ===================================================================*/ typedef enum {FULL_TREE, NO_DEAD_ENDS, RESULT_PATHS} tree_mode_t; /* Variables. ===============================================================*/ extern rectangle_t tree_geometry, path_geometry; extern tree_mode_t tree_mode; extern bool_t show_state_indexes; extern bool_t inline_path; /* If TRUE, feature structures are shown in line. */ /* Functions. ===============================================================*/ extern void read_tree( void ); /* Read new tree from STDIN. */ /* End of file. =============================================================*/ malaga-7.12/tries.c0000644000175000017500000002413310612056443013503 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module implements a static trie structure */ /* Includes. ================================================================*/ #include #include #include #include #include #include "basic.h" #include "pools.h" #include "tries.h" /* Macros. ==================================================================*/ #define ALIGN(addr, n) (((ptr_t) (addr) + (ptr_t) (n - 1)) & ~ (ptr_t) (n - 1)) /* Align ADDR to next multiple of N. */ #define INTS(n) (((n) + (ptr_t ) 3) >> 2) /* Number of ints needed to store N bytes. */ /* Types. ===================================================================*/ typedef struct /* A node in a list of keys. */ { list_node_t *next; u_short_t key; /* Key for this node. */ int_t subnode; /* Index of node for KEY in trie. */ int_t content; /* Content associated with KEY. */ } key_node_t; typedef struct /* A dynamic trie node. */ { string_t prefix; /* The prefix of this node. */ int_t prefix_len; /* The length of PREFIX in bytes. */ list_t key_list; /* List of keys. */ } trie_node_t; /* The trie is a vector of int_t that contains compact trie nodes. * A compact trie node is int_t-aligned and looks as follows: * u_byte_t prefix_len; * char_t prefix[ prefix_len ]; * 0 or 1 pad bytes of value 0; * u_short_t subnode_count; * u_short_t content_count; * u_short_t subnode_keys[ subnode_count ]; * u_short_t content_keys[ content_count ]; * 0 or 2 pad bytes of value 0; * int_t subnodes[ subnode_count ]; * int_t contents[ content_count ]; */ typedef struct /* Pointers to the items of a compact trie node. */ { u_byte_t *prefix_len; /* Number of chars that precede the keys. */ char_t *prefix; /* The chars that precede the keys. */ u_short_t *subnode_count; /* The number of subnodes in this node. */ u_short_t *content_count; /* The number of contents in this node. */ u_short_t *subnode_keys; /* The keys for the subnodes in this node. */ u_short_t *content_keys; /* The keys for the contents in this node. */ int_t *subnodes; /* Indexes of the subnodes. */ int_t *contents; /* Contents. */ } compact_node_t; /*---------------------------------------------------------------------------*/ static int_t store_trie_node( pool_t trie_pool, trie_node_t *node ) /* Store NODE in TRIE_POOL and return its index. */ { int_t node_size; /* Size of the trie node in TRIE_POOL. */ int_t node_index; /* Index of the trie node in TRIE_POOL. */ int_t i, j, subnode_count, content_count; key_node_t *key_node; int_t *compact_node; compact_node_t n; /* Pointers to the items of the compactified NODE. */ string_t s; char_t *d; /* Count the number of entries in NODE->KEY_LIST. */ subnode_count = content_count = 0; FOREACH( key_node, node->key_list ) { if (key_node->subnode != -1) subnode_count++; if (key_node->content != -1) content_count++; } /* Get pool space for the new node. */ node_size = (INTS( sizeof( u_byte_t ) + sizeof( char_t ) * node->prefix_len + sizeof( u_short_t ) + sizeof( u_short_t ) * subnode_count + sizeof( u_short_t ) + sizeof( u_short_t ) * content_count ) + subnode_count + content_count); compact_node = get_pool_space( trie_pool, node_size, &node_index ); /* Set up the pointers to the items of the node. */ n.prefix_len = (u_byte_t *) compact_node; n.prefix = (char_t *) (n.prefix_len + 1); n.subnode_count = (u_short_t *) ALIGN(n.prefix + node->prefix_len, 2 ); n.content_count = (u_short_t *) (n.subnode_count + 1); n.subnode_keys = (u_short_t *) (n.content_count + 1); n.content_keys = (u_short_t *) (n.subnode_keys + subnode_count); n.subnodes = (int_t *) ALIGN( n.content_keys + content_count, 4 ); n.contents = (int_t *) n.subnodes + subnode_count; /* Copy the items. */ *n.prefix_len = node->prefix_len; d = n.prefix; for (s = node->prefix; s < node->prefix + node->prefix_len; s = g_utf8_next_char( s )) { d += g_unichar_to_utf8( g_unichar_tolower( g_utf8_get_char( s ) ), d ); } *n.subnode_count = subnode_count; *n.content_count = content_count; i = j = 0; FOREACH( key_node, node->key_list ) { if (key_node->subnode != -1) { n.subnode_keys[i] = key_node->key; n.subnodes[i] = key_node->subnode; i++; } if (key_node->content != -1) { n.content_keys[j] = key_node->key; n.contents[j] = key_node->content; j++; } } return node_index; } /*---------------------------------------------------------------------------*/ static int_t new_subtrie( pool_t trie_pool, trie_entry_t entries[], int_t start, int_t end, int_t index ) /* Create a subtrie for ENTRIES[ START ]..ENTRIES[ END - 1 ], * store it in TRIE_POOL and return the index of its root node. * The first INDEX bytes in the keys will be ignored, so they * must match for the keys in ENTRIES[ START ]..ENTRIES[ END - 1 ]. */ { trie_node_t node; int_t key_idx; /* The key index. */ int_t node_index; int_t sub_start, sub_end; /* Start and end of a subtrie. */ string_t first_key, last_key; /* Used as abbreviations. */ string_t f, l, e; key_node_t *key_node; if (start >= end) return -1; /* Look how many chars from INDEX onward are equal in the first and * the last entry. This will be the prefix of the new node. * If the key of the first entry is as long as the prefix, shorten the prefix * by one character. */ first_key = entries[ start ].key; last_key = entries[ end - 1 ].key; for (f = first_key + index, l = last_key + index; *g_utf8_next_char( f ) != EOS; f = g_utf8_next_char( f ), l = g_utf8_next_char( l )) { if (g_unichar_tolower( g_utf8_get_char( f ) ) != g_unichar_tolower( g_utf8_get_char( l ) )) { break; } } key_idx = f - first_key; node.prefix = first_key + index; node.prefix_len = key_idx - index; /* Scan list of entries for the first char behind the prefix. For each key, * find the corresponding lower and upper index in the list of entries. */ clear_list( &node.key_list ); for (sub_start = start; sub_start < end; sub_start = sub_end) { /* Create a new node for the current key. */ key_node = new_node( &node.key_list, sizeof( key_node_t ), LIST_END ); f = entries[ sub_start ].key + key_idx; key_node->key = g_unichar_tolower( g_utf8_get_char(f) ); e = g_utf8_next_char(f); if (*e == EOS) { key_node->content = entries[ sub_start ].content; sub_start++; } else key_node->content = -1; /* Find last entry with same key. */ for (sub_end = sub_start; sub_end < end; sub_end++) { l = entries[ sub_end ].key + key_idx; if (g_unichar_tolower( g_utf8_get_char(l) ) != key_node->key) break; } key_node->subnode = new_subtrie( trie_pool, entries, sub_start, sub_end, key_idx + e - f ); } /* Store compact node and clear the key list. */ node_index = store_trie_node( trie_pool, &node ); while (node.key_list.first != NULL) free_first_node( &node.key_list ); return node_index; } /*---------------------------------------------------------------------------*/ void new_trie( int_t n, trie_entry_t *entries, pool_t *trie_pool, int_t *root_node_index ) /* Take N ENTRIES and build a trie of them. * Return the trie in *TRIE_POOL * and the index of its root node in *ROOT_NODE_INDEX. * The keys in *ENTRIES must be non-empty, unique, and sorted. */ { *trie_pool = new_pool( sizeof( int_t ) ); *root_node_index = new_subtrie( *trie_pool, entries, 0, n, 0 ); } /*---------------------------------------------------------------------------*/ bool_t lookup_trie( int_t *trie, int_t *node_index, string_t *input, int_t *content ) /* Test if a prefix of *INPUT matches the node at *NODE_INDEX in TRIE. * If it does, return TRUE (else return FALSE) and: * *CONTENT contains the associated content, * *NODE contains the subnode for the matched input, and * *INPUT points to the first char behind the prefix. */ { int_t lower, upper, middle; compact_node_t r; /* Pointers to the items of the root node; */ gunichar c; while (*node_index != -1) { /* Test if node's prefix matches the given key. */ r.prefix_len = (u_byte_t *) (trie + *node_index); r.prefix = (char_t *) (r.prefix_len + 1); if (strncmp_no_case( *input, r.prefix, *r.prefix_len ) != 0) return FALSE; (*input) += *r.prefix_len; /* Get the rest of the node. */ r.subnode_count = (u_short_t *) ALIGN(r.prefix + *r.prefix_len, 2); r.content_count = (u_short_t *) (r.subnode_count + 1); r.subnode_keys = (u_short_t *) (r.content_count + 1); r.content_keys = (u_short_t *) (r.subnode_keys + *r.subnode_count); r.subnodes = (int_t *) ALIGN( r.content_keys + *r.content_count, 4 ); r.contents = (int_t *) (r.subnodes + *r.subnode_count); /* Perform binary search for subnode with given key. */ c = g_unichar_tolower( g_utf8_get_char( *input ) ); *node_index = -1; lower = 0; upper = *r.subnode_count - 1; while (lower <= upper) { middle = (lower + upper) / 2; if (c < r.subnode_keys[ middle ]) upper = middle - 1; else if (c > r.subnode_keys[ middle ]) lower = middle + 1; else /* This entry matches. */ { *node_index = r.subnodes[ middle ]; break; } } /* Perform binary search for content with given key. */ *content = -1; lower = 0; upper = *r.content_count - 1; while (lower <= upper) { middle = (lower + upper) / 2; if (c < r.content_keys[ middle ]) upper = middle - 1; else if (c > r.content_keys[ middle ]) lower = middle + 1; else /* This entry matches. */ { *content = r.contents[ middle ]; break; } } *input = g_utf8_next_char( *input ); if (*content != -1) return TRUE; } return FALSE; } /* End of file. =============================================================*/ malaga-7.12/tries.h0000644000175000017500000000303010224725217013502 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module implements a static trie structure. */ /* Types. ===================================================================*/ typedef struct /* A "trie_entry_t" associates KEY with CONTENT. */ { string_t key; /* The key of a trie entry is considered case insensitive. */ int_t content; } trie_entry_t; /* Functions. ===============================================================*/ /* A trie is a vector of ints. When constructed, it is returned as a pool * together with the index of the root node. */ extern void new_trie( int_t n, trie_entry_t *entries, pool_t *trie_pool, int_t *root_node_index ); /* Take N ENTRIES and build a trie of them. * Return the trie in *TRIE_POOL * and the index of its root node in *ROOT_NODE_INDEX. * The keys in *ENTRIES must be non-empty, unique, and sorted. */ extern bool_t lookup_trie( int_t *trie, int_t *node_index, string_t *input, int_t *content ); /* Test if a prefix of *INPUT matches the node at *NODE_INDEX in TRIE. * If it does, return TRUE (else return FALSE) and: * *CONTENT contains the associated content, * *NODE contains the subnode for the matched input, and * *INPUT points to the first char behind the prefix. */ /* End of file. =============================================================*/ malaga-7.12/value_parser.c0000644000175000017500000000454610236624011015045 0ustar bjoernbjoern/* Copyright (C) 2002 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module parses Malaga values. */ /* Includes. ================================================================*/ #include #include #include #include "basic.h" #include "pools.h" #include "values.h" #include "symbols.h" #include "scanner.h" #include "hangul.h" #include "value_parser.h" /* Functions. ===============================================================*/ static void parse_symbol( void ) /* Parse a symbol and push it on the VALUE_STACK. */ { test_token( TOK_IDENT ); push_symbol_value( find_symbol( token_name ) ); read_next_token(); } /*---------------------------------------------------------------------------*/ void parse_a_value( void ) /* Parse a value (use scanner input) and leave it on the VALUE_STACK. */ { int_t n; /* Number of values in list or record. */ switch (next_token) { case '<': /* Parse a list. */ read_next_token(); n = 0; if (next_token != '>') { parse_a_value(); n++; while (next_token == ',') { read_next_token(); parse_a_value(); n++; } } parse_token( '>' ); build_list(n); break; case '[': /* Parse a record. */ read_next_token(); n = 0; if (next_token != ']') { parse_symbol(); parse_token( ':' ); parse_a_value(); n++; while (next_token == ',') { read_next_token(); parse_symbol(); parse_token( ':' ); parse_a_value(); n++; } } parse_token( ']' ); build_record(n); break; case TOK_IDENT: /* Parse a symbol. */ parse_symbol(); break; case TOK_STRING: /* Parse a string. */ encode_hangul( &token_string ); push_string_value( token_string, NULL ); read_next_token(); break; case TOK_NUMBER: /* Parse a number. */ push_number_value( token_number ); read_next_token(); break; case '-': /* Parse a negative number. */ read_next_token(); test_token( TOK_NUMBER ); push_number_value( -token_number ); read_next_token(); break; default: complain( "Value expected, not %s.", token_as_text( next_token ) ); } } /* End of file. =============================================================*/ malaga-7.12/value_parser.h0000644000175000017500000000072510236624016015052 0ustar bjoernbjoern/* Copyright (C) 2002 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module parses Malaga values. */ /* Functions. ===============================================================*/ extern void parse_a_value( void ); /* Stack effects: (nothing) -> NEW_VALUE. * Parse a value (use scanner input) and leave it on the stack. */ /* End of file. =============================================================*/ malaga-7.12/values.c0000644000175000017500000022672610435516371013674 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module defines the data type "value_t", and many * operations to build, modify, and print such values. * The first cell of a value, its type cell, is used to store the value's type * together with some type dependent information, which is an unsigned number * less than INFO_MAX. * Use the macro TYPE to get the type of a value, and INFO to get the type * dependent information. Use TYPE_CELL to create a type-cell. * There are five different types of values: * symbol, string, list, record and number. */ /* Includes. ================================================================*/ #include #include #include #include #include #include "basic.h" #include "pools.h" #include "hangul.h" #include "values.h" /* Constants. ===============================================================*/ #define CELL_BITS BITS_PER_BYTE * sizeof( cell_t ) #define TYPE_BITS 3 #define INFO_BITS (CELL_BITS - TYPE_BITS) #define TYPE_MAX ((cell_t) 1 << TYPE_BITS) #define INFO_MAX ((cell_t) 1 << INFO_BITS) #define TYPE_MASK ((TYPE_MAX - 1) << INFO_BITS) #define INFO_MASK (INFO_MAX - 1) #define SYMBOL_TYPE ((cell_t) 0 << INFO_BITS) /* A value of type SYMBOL_TYPE consists only of a type cell. * Its INFO-value is the code for the symbol. */ #define STRING_TYPE ((cell_t) 1 << INFO_BITS) /* A value of type STRING_TYPE consists of its type cell, * followed by the actual string. Its INFO-value is the * number of characters in the string. The actual string * is stored in the subsequent cells, two characters * paired in a cell, and terminated by one or two * NUL-characters, so that the total number of chars is * even. The NUL-chars are NOT part of the string. */ #define LIST_TYPE ((cell_t) 2 << INFO_BITS) /* A value of type LIST_TYPE consists of its type cell and a subsequent cell, * which hold the type and the length of the value, followed by 0 or more * values of any type, namely the values that form the list. * The length of a list VALUE, that is the number of cells needed to store * all the list's values, is (INFO( value[0] ) << CELL_BITS) + value[1]. */ #define RECORD_TYPE ((cell_t) 3 << INFO_BITS) /* A value of type RECORD_TYPE consists of its type cell and a subsequent cell, * which hold the type and the length of the value, followed by 0 or more * pairs of values. * In a pair of values, the first value must be a symbol and is considered as * an attribute of that record. The second value is the value of that * attribute, and it can be of any type. * The length of a record VALUE, that is the number of cells * needed to store all the record's value pairs, is computed as * (INFO( value ) << CELL_BITS) + value[1]. */ #define NUMBER_TYPE ((cell_t) 4 << INFO_BITS) /* A value of type NUMBER_TYPE consists of its type cell, * followed by a implementation-dependent number of cells * that contain a C "double" value. * Its INFO-value is 0. */ /* Macros. ==================================================================*/ #define TYPE(value) ((*(value)) & TYPE_MASK) #define INFO(value) ((*(value)) & INFO_MASK) #define TYPE_CELL(type,info) ((type) | (info)) /* Use one of the following predicates to test a value * against a specific type. */ #define IS_SYMBOL(value) (TYPE( value ) == SYMBOL_TYPE) #define IS_STRING(value) (TYPE( value ) == STRING_TYPE) #define IS_RECORD(value) (TYPE( value ) == RECORD_TYPE) #define IS_LIST(value) (TYPE( value ) == LIST_TYPE) #define IS_NUMBER(value) (TYPE( value ) == NUMBER_TYPE) #define NEXT_VALUE(value) ((value) + length_of_value( value )) /* Return end of VALUE. * This may also be the beginning of the next value in a list. */ #define NEXT_ATTRIB(attrib) ((attrib) + 1 + length_of_value( (attrib) + 1 )) /* Return the next attribute in a record. */ #define CELLS_PER_NUMBER ((int_t) (sizeof( double ) / sizeof( cell_t ))) /* The number of cells needed to contain a number value. * sizeof( double ) *must* be a multiple of sizeof( cell_t ). */ /* Types. ===================================================================*/ typedef struct /* An element in a list of hidden attributes. */ { list_node_t *next; symbol_t symbol; } attribute_t; /* Global variables. ========================================================*/ string_t (*values_get_symbol_name)( symbol_t symbol ); value_t (*values_get_atoms)( symbol_t symbol ); value_t *value_stack; int_t top; attribute_order_t attribute_order; /* Variables. ===============================================================*/ /* Two constant values. */ static cell_t empty_list[] = {TYPE_CELL( LIST_TYPE, 0 ), 0}; static cell_t empty_record[] = {TYPE_CELL( RECORD_TYPE, 0 ), 0}; static cell_t *value_heap; /* The actual heap. */ static cell_t *value_heap_end; /* Pointer to first free cell in heap. */ static int_t value_heap_size; /* Size of the value heap in cells. */ static int_t value_stack_size; /* Size of the value stack. */ static list_t hidden_attributes; /* The list of hidden attributes. */ static text_t *value_text; /* Buffer for conversion of values to text. */ /* Forward declarations. ====================================================*/ static void value_to_text( text_t *text, value_t value, bool_t full_value, int_t indent ); /* Support functions. =======================================================*/ static void copy_cells( value_t destination, value_t source, int_t n ) /* Copy N cells of value SOURCE to DESTINATION. */ { memcpy( destination, source, n * sizeof( cell_t ) ); } /*---------------------------------------------------------------------------*/ static void copy_value( value_t destination, value_t source ) /* Copy all cells of value SOURCE to DESTINATION. */ { memcpy( destination, source, length_of_value( source ) * sizeof( cell_t ) ); } /*---------------------------------------------------------------------------*/ static int compare_value_pointers( const void *key1, const void *key2 ) /* Return -1/0/1 when the value VALUE1_P points to is stored on a * lower/same/higher address than the value VALUE2_P points to. */ { value_t *value1_p; value_t *value2_p; value1_p = * (value_t **) key1; value2_p = * (value_t **) key2; if (*value1_p < *value2_p) return -1; else if (*value1_p > *value2_p) return 1; else return 0; } /*---------------------------------------------------------------------------*/ static void collect_garbage( void ) /* Make sure the value heap only contains values that are on the value stack. * Compactify the heap, i.e. move all values on the heap to the beginning. */ { int_t i, value_len; value_t old_value, new_value; value_t **value_pointer; new_value = value_heap; /* Copy values if there is at least one value to save. */ if (top > 0) { /* Create a table of pointers to the values. */ value_pointer = new_vector( sizeof( value_t * ), top ); for (i = 0; i < top; i++) value_pointer[i] = value_stack + i; /* Sort pointers according to the address of the value they point to. */ qsort( value_pointer, top, sizeof( value_t * ), compare_value_pointers ); /* Find the first index I whose value is on the heap. */ for (i = 0; i < top; i++) { if (*value_pointer[i] >= value_heap) break; } /* Work on all values on the heap. */ while (i < top && *value_pointer[i] < value_heap_end) { /* Copy the value. */ old_value = *value_pointer[i]; value_len = length_of_value( old_value ); memmove( new_value, old_value, value_len * sizeof( cell_t ) ); /* Adjust the value address and the addresses of all values * that are part of that value. */ while (i < top && *value_pointer[i] < old_value + value_len) { *value_pointer[i] -= (old_value - new_value); i++; } new_value += value_len; } free_mem( &value_pointer ); } value_heap_end = new_value; } /*---------------------------------------------------------------------------*/ static value_t space_for_value( int_t size ) /* Get SIZE adjacent free cells on the value heap. */ { value_t pointer, old_heap, old_heap_end; int_t i; if ((value_heap_end - value_heap) + size > value_heap_size) { collect_garbage(); if ((value_heap_end - value_heap) + size > value_heap_size) { old_heap = value_heap; old_heap_end = value_heap_end; /* Enlarge the value heap. */ value_heap_size = renew_vector( &value_heap, sizeof( cell_t ), 2 * (size + (old_heap_end - old_heap)) ); value_heap_end = value_heap + (old_heap_end - old_heap); /* Adapt the value stack pointers. */ for (i = 0; i < top; i++) { if (value_stack[i] >= old_heap && value_stack[i] < old_heap_end) value_stack[i] = value_heap + (value_stack[i] - old_heap); } } } pointer = value_heap_end; value_heap_end += size; return pointer; } /*---------------------------------------------------------------------------*/ static value_t space_for_composed_value( int_t type, int_t length ) /* Allocate LENGTH cells for a composed value of TYPE, set its type cell * and return the value. */ { value_t value; int_t content_size; value = space_for_value( length ); content_size = length - 2; if (content_size >= 1L << (INFO_BITS + CELL_BITS)) complain( "Value too big." ); value[0] = TYPE_CELL( type, content_size >> CELL_BITS ); value[1] = content_size & ((1L << CELL_BITS) - 1); return value; } /* Module initialisation. ===================================================*/ void init_values( void ) /* Initialise this module. */ { value_text = new_text(); value_heap_size = 1000; value_heap = new_vector( sizeof( cell_t ), value_heap_size ); value_heap_end = value_heap; value_stack_size = 100; value_stack = new_vector( sizeof( value_t ), value_stack_size ); top = 0; clear_list( &hidden_attributes ); } /*---------------------------------------------------------------------------*/ void terminate_values( void ) /* Terminate this module. */ { free_mem( &value_heap ); free_mem( &value_stack ); free_text( &value_text ); clear_hidden_attributes(); } /* Value operations. ========================================================*/ value_t new_value( value_t value ) /* Allocate space for VALUE and copy it. * Free the value space after use. */ { value_t value2; value2 = new_vector( sizeof( cell_t ), length_of_value( value ) ); copy_value( value2, value ); return value2; } /*---------------------------------------------------------------------------*/ value_t copy_value_to_pool( pool_t value_pool, value_t value, int_t *index ) /* Copy VALUE to the pool VALUE_POOL and store its index in *INDEX. */ { value_t value2; value2 = get_pool_space( value_pool, length_of_value( value ), index ); copy_value( value2, value ); return value2; } /*---------------------------------------------------------------------------*/ int_t length_of_value( value_t value ) /* Return the length of VALUE in cells. */ { switch (TYPE( value )) { case LIST_TYPE: case RECORD_TYPE: return 2 + ((int_t) INFO( value ) << CELL_BITS) + value[1]; case SYMBOL_TYPE: return 1; case STRING_TYPE: return 2 + INFO( value ) / sizeof( cell_t ); case NUMBER_TYPE: return 1 + CELLS_PER_NUMBER; default: complain( "Internal error." ); } } /*---------------------------------------------------------------------------*/ symbol_t get_value_type( value_t value ) /* Return the type of VALUE. Depending of the type, the result value may be * SYMBOL_SYMBOL, STRING_SYMBOL, NUMBER_SYMBOL, LIST_SYMBOL, RECORD_SYMBOL. */ { switch (TYPE( value )) { case SYMBOL_TYPE: return SYMBOL_SYMBOL; case STRING_TYPE: return STRING_SYMBOL; case NUMBER_TYPE: return NUMBER_SYMBOL; case LIST_TYPE: return LIST_SYMBOL; case RECORD_TYPE: return RECORD_SYMBOL; default: complain( "Internal error." ); } } /*---------------------------------------------------------------------------*/ void push_value( value_t value ) /* Stack effects: (nothing) -> VALUE. */ { if (top + 1 > value_stack_size) { value_stack_size = renew_vector( &value_stack, sizeof( value_t ), 2 * (top + 1) ); } value_stack[ top++ ] = value; } /*---------------------------------------------------------------------------*/ void insert_value( int_t n, value_t value ) /* Stack effects: VALUE1...VALUE_N -> VALUE VALUE1...VALUE_N. */ { int_t i; push_value( NULL ); for (i = 0; i < n; i++) value_stack[ top - i - 1 ] = value_stack[ top - i - 2 ]; value_stack[ top - n - 1 ] = value; } /* Symbol operations. =======================================================*/ symbol_t value_to_symbol( value_t value ) /* Return VALUE as a symbol. It is an error if VALUE is no symbol. */ { if (! IS_SYMBOL( value )) complain( "Value is no symbol." ); return *value; } /*---------------------------------------------------------------------------*/ void push_symbol_value( symbol_t symbol ) /* Stack effects: (nothing) -> NEW_SYMBOL. * NEW_SYMBOL is SYMBOL converted to a Malaga value. */ { value_t value; value = space_for_value(1); *value = TYPE_CELL( SYMBOL_TYPE, symbol ); push_value( value ); } /* String operations. =======================================================*/ string_t value_to_string( value_t value ) /* Return the value of STRING as a C style string. */ { if (! IS_STRING( value )) complain( "Value is no string." ); return (string_t) (value + 1); } /*---------------------------------------------------------------------------*/ void push_string_value( string_t string_start, string_t string_end ) /* Stack effects: (nothing) -> NEW_STRING. * NEW_STRING is the string starting at STRING_START as a Malaga value. * If STRING_END != NULL, it marks the end of the string. */ { value_t value, value_end; int_t length; string_t source_p; char_t *target_p; if (string_end == NULL) string_end = string_start + strlen( string_start ); length = string_end - string_start; if (length > INFO_MAX - 1) complain( "String too long to be a value." ); value = space_for_value( 2 + length / sizeof( cell_t ) ); *value = TYPE_CELL( STRING_TYPE, length ); /* Copy the string content. */ source_p = string_start; target_p = (char_t *) (value + 1); value_end = NEXT_VALUE( value ); while (source_p < string_end) *target_p++ = *source_p++; /* Pad with EOS. */ while (target_p < (string_t) value_end) *target_p++ = EOS; push_value( value ); } /*---------------------------------------------------------------------------*/ void concat_string_values( void ) /* Stack effects: STRING1 STRING2 -> NEW_STRING. * NEW_STRING is the concatenation of STRING1 and STRING2. */ { int_t new_length; string_t old_string, string_end; char_t *string; value_t string_value; if (! IS_STRING( value_stack[ top - 2 ] ) || ! IS_STRING( value_stack[ top - 1 ] )) { complain( "Concatenation operands must be strings." ); } new_length = ((int_t) INFO( value_stack[ top - 2 ] ) + (int_t) INFO( value_stack[ top - 1 ] )); if (new_length > INFO_MAX - 1) complain( "Strings too long for concatenation." ); string_value = space_for_value( 2 + new_length / sizeof( cell_t ) ); *string_value = TYPE_CELL( STRING_TYPE, new_length ); /* Join the strings. We do it by hand so it's easier to align. */ string = (char_t *) (string_value + 1); old_string = (string_t) (value_stack[ top - 2 ] + 1); while (*old_string != '\0') *string++ = *old_string++; old_string = (string_t) (value_stack[ top - 1 ] + 1); while (*old_string != '\0') *string++ = *old_string++; string_end = (string_t) NEXT_VALUE( string_value ); while (string < string_end) *string++ = '\0'; top--; value_stack[ top - 1 ] = string_value; } /* Record operations. =======================================================*/ value_t get_attribute( value_t record, symbol_t attribute ) /* Return the value of ATTRIBUTE in the record RECORD * or NULL if it doesn't exist. */ { value_t record_end, v; /* No error when getting an attribute from "nil". */ if (*record == NIL_SYMBOL) return NULL; if (! IS_RECORD( record )) complain( "Can get an attribute value of a record only." ); record_end = NEXT_VALUE( record ); for (v = record + 2; v < record_end; v = NEXT_ATTRIB(v)) { if (*v == attribute) return v + 1; } return NULL; } /*---------------------------------------------------------------------------*/ void build_record( int_t n ) /* Stack effects: ATTR1 VALUE1 ... ATTR_N VALUE_N -> NEW_RECORD. * NEW_RECORD looks like [ATTR1: VALUE1, ..., ATTR_N: VALUE_N]. */ { value_t new_record, v; int_t i, j, new_record_length; value_t *values; values = value_stack + top - 2 * n; /* Check that all attributes are different. */ for (i = 0; i < n; i++) { if (! IS_SYMBOL( values[ 2 * i ] )) complain( "Attribute must be symbol." ); for (j = 0; j < i; j++) { if (*values[ 2 * i ] == *values[ 2 * j ]) complain( "Attribute twice in record." ); } } /* Compute record length. */ new_record_length = 2; for (i = 0; i < n; i++) new_record_length += 1 + length_of_value( values[ 2 * i + 1 ] ); /* Allocate new record and copy content. */ new_record = space_for_composed_value( RECORD_TYPE, new_record_length ); v = new_record + 2; for (i = 0; i < n; i++) { *v++ = *values[ 2 * i ]; copy_value( v, values[ 2 * i + 1 ] ); v = NEXT_VALUE(v); } top -= 2 * n; push_value( new_record ); } /*---------------------------------------------------------------------------*/ void join_records( void ) /* Stack effects: RECORD1 RECORD2 -> NEW_RECORD. * NEW_RECORD contains all attributes of RECORD1 and RECORD2, and * their associated values. If an attribute has different values in RECORD1 * and RECORD2, the value in RECORD2 will be taken. */ { value_t record1, record2, record1_end, record2_end, new_record, v, v1, v2; int_t new_record_length; record1 = value_stack[ top - 2 ]; record2 = value_stack[ top - 1 ]; record1_end = NEXT_VALUE( record1 ); record2_end = NEXT_VALUE( record2 ); if (! IS_RECORD( record1 ) || ! IS_RECORD( record2 )) complain( "Join operands must be records." ); /* Calculate the space needed. This is the length of the * first record plus the length of the second record minus the * sum of the length of all attribute-value-pairs in RECORD1 whose * attributes are also in RECORD2. */ new_record_length = length_of_value( record1 ) + length_of_value( record2 ) - 2; for (v1 = record1 + 2; v1 < record1_end; v1 = NEXT_ATTRIB( v1 )) { for (v2 = record2 + 2; v2 < record2_end; v2 = NEXT_ATTRIB( v2 )) { if (*v1 == *v2) /* We've discovered two identical attributes */ { new_record_length -= (1 + length_of_value( v1 + 1 )); break; } } } /* Allocate a new record value. */ new_record = space_for_composed_value( RECORD_TYPE, new_record_length ); /* The values on stack may have moved if garbage collection was called. */ record1 = value_stack[ top - 2 ]; record2 = value_stack[ top - 1 ]; record1_end = NEXT_VALUE( record1 ); record2_end = NEXT_VALUE( record2 ); /* Copy the attributes of the first record. If an attribut * belongs to both VALUE1 and VALUE2, don't copy its value. */ v = new_record + 2; for (v1 = record1 + 2; v1 < record1_end; v1 = NEXT_ATTRIB( v1 )) { /* Go through RECORD2 until we reach end or find same attribute. */ for (v2 = record2 + 2; v2 < record2_end; v2 = NEXT_ATTRIB( v2 )) { if (*v1 == *v2) break; } if (v2 >= record2_end) { /* If attrib not in RECORD2, copy the value of RECORD1. */ *v = *v1; copy_value( v + 1, v1 + 1 ); v = NEXT_ATTRIB(v); } } /* Append the attributes of the second record. */ copy_cells( v, record2 + 2, length_of_value( record2 ) - 2 ); /* Push new record on stack. */ top--; value_stack[ top - 1 ] = new_record; } /*---------------------------------------------------------------------------*/ void select_attribute( symbol_t attribute ) /* Stack effects: RECORD -> NEW_RECORD. * NEW_RECORD contains ATTRIBUTE and its value in RECORD. */ { value_t record, record_end, v, new_record; int_t new_record_length; record = value_stack[ top - 1 ]; record_end = NEXT_VALUE( record ); if (! IS_RECORD( record )) complain( "Can select attributes from record only." ); for (v = record + 2; v < record_end; v = NEXT_ATTRIB(v)) { if (*v == attribute) break; } if (v == record_end) new_record = empty_record; else { new_record_length = 3 + length_of_value( v + 1 ); new_record = space_for_composed_value( RECORD_TYPE, new_record_length ); record = value_stack[ top - 1 ]; record_end = NEXT_VALUE( record ); /* Find ATTRIBUTE in record. */ for (v = record + 2; *v != attribute; v = NEXT_ATTRIB(v)) /* empty */; new_record[2] = attribute; copy_value( new_record + 3, v + 1 ); } value_stack[ top - 1 ] = new_record; } /*---------------------------------------------------------------------------*/ void select_attributes( void ) /* Stack effects: RECORD LIST -> NEW_RECORD. * NEW_RECORD contains all attribute-value pairs of RECORD whose attributes * are in LIST. */ { value_t record, list, record_end, list_end, v, v1, v2, new_record; int_t new_record_length; record = value_stack[ top - 2 ]; list = value_stack[ top - 1 ]; record_end = NEXT_VALUE( record ); list_end = NEXT_VALUE( list ); if (! IS_RECORD( record )) complain( "Can select attributes from record only." ); if (! IS_LIST( list )) complain( "Attribute selection list must be a list." ); /* Check that VALUE2 is a list with symbols only. */ for (v2 = list + 2; v2 < list_end; v2 = NEXT_VALUE( v2 )) { if (! IS_SYMBOL( v2 )) complain( "Attribute selection list must contain symbols only." ); } /* Calculate size of new value */ new_record_length = 2; for (v1 = record + 2; v1 < record_end; v1 = NEXT_ATTRIB( v1 )) { for (v2 = list + 2; v2 < list_end; v2++) { if (*v1 == *v2) { new_record_length += 1 + length_of_value( v1 + 1 ); break; } } } /* We don't create a new record if no attributes are deleted. */ if (new_record_length == length_of_value( record )) new_record = record; else { /* Allocate and copy new value. */ new_record = space_for_composed_value( RECORD_TYPE, new_record_length ); record = value_stack[ top - 2 ]; list = value_stack[ top - 1 ]; record_end = NEXT_VALUE( record ); list_end = NEXT_VALUE( list ); v = new_record + 2; for (v1 = record + 2; v1 < record_end; v1 = NEXT_ATTRIB( v1 )) { for (v2 = list + 2; v2 < list_end; v2++) { if (*v1 == *v2) { *v++ = *v1; copy_value( v, v1 + 1 ); v = NEXT_VALUE(v); break; } } } } top--; value_stack[ top - 1 ] = new_record; } /*---------------------------------------------------------------------------*/ void remove_attribute( symbol_t attribute ) /* Stack effects: RECORD -> NEW_RECORD. * NEW_RECORD contains all attribute-value pairs of RECORD but the one with * attribute ATTRIBUTE. */ { value_t record, new_record, record_end, v, v1; int_t new_record_length; record = value_stack[ top - 1 ]; record_end = NEXT_VALUE( record ); if (! IS_RECORD( record )) complain( "Can remove attributes from record only." ); /* Find the attribute that is to be deleted. */ for (v1 = record + 2; v1 < record_end; v1 = NEXT_ATTRIB( v1 )) { if (*v1 == attribute) break; } /* Check if we have an attribute to delete. */ if (v1 == record_end) new_record = record; else { /* Compute its length and get space for the new record. */ new_record_length = length_of_value( record ) - (length_of_value( v1 + 1 ) + 1); new_record = space_for_composed_value( RECORD_TYPE, new_record_length ); /* Get the original record. */ record = value_stack[ top - 1 ]; record_end = NEXT_VALUE( record ); /* Copy the record. */ v = new_record + 2; for (v1 = record + 2; v1 < record_end; v1 = NEXT_ATTRIB( v1 )) { if (*v1 != attribute) { *v = *v1; copy_value( v + 1, v1 + 1 ); v = NEXT_ATTRIB(v); } } } value_stack[ top - 1 ] = new_record; } /*---------------------------------------------------------------------------*/ void remove_attributes( void ) /* Stack effects: RECORD LIST -> NEW_RECORD. * NEW_RECORD contains all attribute-value pairs of RECORD but the ones * whose attributes are in LIST. */ { value_t v, v1, v2, record, list, record_end, list_end, new_record; int_t new_record_length; record = value_stack[ top - 2 ]; list = value_stack[ top - 1 ]; record_end = NEXT_VALUE( record ); list_end = NEXT_VALUE( list ); if (! IS_RECORD( record )) complain( "Can remove attributes from record only." ); if (! IS_LIST( list )) complain( "Attribute list must be a list." ); /* Check if the list consists of symbols only. */ for (v2 = list + 2; v2 < list_end; v2++) { if (! IS_SYMBOL( v2 )) complain( "Attribute list must contain symbols only." ); } /* Compute the length of the new record. */ new_record_length = 2; for (v1 = record + 2; v1 < record_end; v1 = NEXT_ATTRIB( v1 )) { for (v2 = list + 2; v2 < list_end; v2++) { if (*v1 == *v2) break; } if (v2 == list_end) new_record_length += 1 + length_of_value( v1 + 1 ); } /* We don't create a new record if no attributes will be deleted. */ if (new_record_length == length_of_value( record )) new_record = record; else { new_record = space_for_composed_value( RECORD_TYPE, new_record_length ); /* Get the values, since they may have moved by garbage collection. */ record = value_stack[ top - 2 ]; list = value_stack[ top - 1 ]; record_end = NEXT_VALUE( record ); list_end = NEXT_VALUE( list ); /* Copy the other attributes. */ v = new_record + 2; for (v1 = record + 2; v1 < record_end; v1 = NEXT_ATTRIB( v1 )) { for (v2 = list + 2; v2 < list_end; v2++) { if (*v1 == *v2) break; } if (v2 == list_end) { *v = *v1; copy_value( v + 1, v1 + 1 ); v = NEXT_ATTRIB(v); } } } top--; value_stack[top - 1] = new_record; } /*---------------------------------------------------------------------------*/ void replace_attribute( symbol_t attribute ) /* Stack effects: RECORD VALUE -> NEW_RECORD. * NEW_RECORD is equal to RECORD, only the value of ATTRIBUTE is replaced * by VALUE. RECORD must contain ATTRIBUTE. */ { value_t record, value, record_end, new_record, v, nv; int_t new_record_length; record = value_stack[ top - 2 ]; value = value_stack[ top - 1 ]; record_end = NEXT_VALUE( record ); if (! IS_RECORD( record )) complain( "Value must be a record." ); /* Find the attribute to replace. */ for (v = record + 2; v < record_end; v = NEXT_ATTRIB(v)) { if (*v == attribute) break; } if (v == record_end) complain( "Missing attribute to replace." ); new_record_length = (length_of_value( record ) + length_of_value( value ) - length_of_value( v + 1 )); new_record = space_for_composed_value( RECORD_TYPE, new_record_length ); record = value_stack[ top - 2 ]; value = value_stack[ top - 1 ]; record_end = NEXT_VALUE( record ); nv = new_record + 2; for (v = record + 2; v < record_end; v = NEXT_ATTRIB(v)) { *nv = *v; if (*v == attribute) copy_value( nv + 1, value ); else copy_value( nv + 1, v + 1 ); nv = NEXT_ATTRIB( nv ); } top--; value_stack[ top - 1 ] = new_record; } /* List operations. =========================================================*/ int_t get_list_length( value_t list ) /* Return the number of elements in LIST. * LIST must be a list. */ { int_t elements; value_t list_end, v; if (! IS_LIST( list )) complain( "Can get length of a list only." ); list_end = NEXT_VALUE( list ); elements = 0; for (v = list + 2; v < list_end; v = NEXT_VALUE(v)) elements++; return elements; } /*---------------------------------------------------------------------------*/ value_t get_element( value_t list, int_t n ) /* Return the N-th element of the list LIST, * or NULL, if that element doesn't exist. * If N is positive, elements will be counted from the left border. * If it's negative, elements will be counted from the right border. */ { value_t list_end, v; /* No error when getting an element from "nil". */ if (*list == NIL_SYMBOL) return NULL; if (! IS_LIST( list )) complain( "Can get an element of a list only." ); if (n < 0) n = get_list_length( list ) + n + 1; if (n <= 0) return NULL; list_end = NEXT_VALUE( list ); for (v = list + 2; v < list_end; v = NEXT_VALUE(v)) { n--; if (n == 0) return v; } return NULL; } /*---------------------------------------------------------------------------*/ void build_list( int_t n ) /* Stack effects: VALUE1 ... VALUE_N -> NEW_LIST. * NEW_LIST looks like . */ { value_t new_list, v; int_t i, new_list_length; value_t *elements; elements = value_stack + top - n; new_list_length = 2; for (i = 0; i < n; i++) new_list_length += length_of_value( elements[i] ); new_list = space_for_composed_value( LIST_TYPE, new_list_length ); v = new_list + 2; for (i = 0; i < n; i++) { copy_value( v, elements[i] ); v = NEXT_VALUE( v ); } top -= n; push_value( new_list ); } /*---------------------------------------------------------------------------*/ int_t decompose_list( void ) /* Stack effects: LIST -> VALUE1 ... VALUE_N. * VALUE1 ... VALUE_N are the elements of LIST. * Return N. */ { int_t n; value_t list, list_end, element; list = value_stack[ top - 1 ]; top--; list_end = NEXT_VALUE( list ); if (! IS_LIST( list )) complain( "Only lists can be decomposed." ); n = 0; for (element = list + 2; element < list_end; element = NEXT_VALUE( element )) { push_value( element ); n++; } return n; } /*---------------------------------------------------------------------------*/ void concat_lists( void ) /* Stack effects: LIST1 LIST2 -> NEW_LIST. * NEW_LIST is the concatenation of LIST1 and LIST2. */ { int_t list1_length, list2_length, new_list_length; value_t list1, list2, new_list; list1 = value_stack[ top - 2 ]; list2 = value_stack[ top - 1 ]; if (! IS_LIST( list1 ) || ! IS_LIST( list2 )) complain( "Concatenation operands must be lists." ); list1_length = length_of_value( list1 ); list2_length = length_of_value( list2 ); new_list_length = list1_length + list2_length - 2; new_list = space_for_composed_value( LIST_TYPE, new_list_length ); list1 = value_stack[ top - 2 ]; list2 = value_stack[ top - 1 ]; /* Copy all elements of the first and the second list. */ copy_cells( new_list + 2, list1 + 2, list1_length - 2 ); copy_cells( new_list + list1_length, list2 + 2, list2_length - 2 ); top--; value_stack[ top - 1 ] = new_list; } /*---------------------------------------------------------------------------*/ void get_list_difference( void ) /* Stack effects: LIST1 LIST2 -> NEW_LIST. * NEW_LIST contains the list difference of LIST1 and LIST2: * An element that appears M times in LIST1 and N times in LIST2 * appears M - N times in NEW_LIST. */ { value_t list1, list2, list1_end, list2_end, new_list, v, v1, v2; int_t new_list_length, appearances; list1 = value_stack[ top - 2 ]; list2 = value_stack[ top - 1 ]; list1_end = NEXT_VALUE( list1 ); list2_end = NEXT_VALUE( list2 ); if (! IS_LIST( list1 ) || ! IS_LIST( list2 )) complain( "List difference operands must be lists." ); /* Calculate the size of the new value. */ new_list_length = 2; for (v1 = list1 + 2; v1 < list1_end; v1 = NEXT_VALUE( v1 )) { /* Check whether V1 will be included in the list. * It will be included if the ordinal number of its appearance is * higher than the number of appearances in LIST2. */ /* Count appearences in LIST1 up to (including) V1. */ appearances = 1; for (v2 = list1 + 2; v2 < v1; v2 = NEXT_VALUE( v2 )) { if (values_equal( v1, v2 )) appearances++; } /* Subtract appearences in VALUE2. */ for (v2 = list2 + 2; v2 < list2_end; v2 = NEXT_VALUE( v2 )) { if (values_equal( v1, v2 )) appearances--; } if (appearances > 0) new_list_length += length_of_value( v1 ); } /* We don't create a new list if no elements will be deleted. */ if (new_list_length == length_of_value( list1 )) new_list = list1; else { new_list = space_for_composed_value( LIST_TYPE, new_list_length ); list1 = value_stack[ top - 2 ]; list2 = value_stack[ top - 1 ]; list1_end = NEXT_VALUE( list1 ); list2_end = NEXT_VALUE( list2 ); v = new_list + 2; for (v1 = list1 + 2; v1 < list1_end; v1 = NEXT_VALUE( v1 )) { /* Check whether V1 will be included in the list. * It will be included if the ordinal number of its appearance is * higher than the number of appearances in VALUE2. */ /* Count appearences in VALUE1 up to (including) V1. */ appearances = 1; for (v2 = list1 + 2; v2 < v1; v2 = NEXT_VALUE( v2 )) { if (values_equal( v1, v2 )) appearances++; } /* Subtract appearences in VALUE2. */ for (v2 = list2 + 2; v2 < list2_end; v2 = NEXT_VALUE( v2 )) { if (values_equal( v1, v2 )) appearances--; } if (appearances > 0) { copy_value( v, v1 ); v = NEXT_VALUE(v); } } } top--; value_stack[ top - 1 ] = new_list; } /*---------------------------------------------------------------------------*/ void get_set_difference( void ) /* Stack effects: LIST1 LIST2 -> NEW_LIST. * NEW_LIST contains the set difference of LIST1 and LIST2. * Each element of LIST1 is in NEW_LIST if it is not in LIST2. */ { value_t list1, list2, list1_end, list2_end, new_list, v, v1, v2; int_t new_list_length; list1 = value_stack[ top - 2 ]; list2 = value_stack[ top - 1 ]; list1_end = NEXT_VALUE( list1 ); list2_end = NEXT_VALUE( list2 ); if (! IS_LIST( list1 ) || ! IS_LIST( list2 )) complain( "Set difference operands must be lists." ); /* Compute the length of the new list. */ new_list_length = 2; for (v1 = list1 + 2; v1 < list1_end; v1 = NEXT_VALUE( v1 )) { for (v2 = list2 + 2; v2 < list2_end; v2 = NEXT_VALUE( v2 )) { if (values_equal( v1, v2 )) break; } if (v2 == list2_end) new_list_length += length_of_value( v1 ); } /* No need to create a new list if no elements will be deleted. */ if (new_list_length == length_of_value( list1 )) new_list = list1; else { new_list = space_for_composed_value( LIST_TYPE, new_list_length ); list1 = value_stack[ top - 2 ]; list2 = value_stack[ top - 1 ]; list1_end = NEXT_VALUE( list1 ); list2_end = NEXT_VALUE( list2 ); v = new_list + 2; for (v1 = list1 + 2; v1 < list1_end; v1 = NEXT_VALUE( v1 )) { for (v2 = list2 + 2; v2 < list2_end; v2 = NEXT_VALUE( v2 )) { if (values_equal( v1, v2 )) break; } if (v2 == list2_end) { copy_value( v, v1 ); v = NEXT_VALUE(v); } } } top--; value_stack[ top - 1 ] = new_list; } /*---------------------------------------------------------------------------*/ void intersect_lists( void ) /* Stack effects: LIST1 LIST2 -> NEW_LIST. * NEW_LIST contains the list intersection of LIST1 and LIST2. * Each element that appears M times in LIST1 and N times in LIST2 * appears min(M, N) times in NEW_LIST. */ { value_t new_list, list1, list2, list1_end, list2_end, v1, v2, v; int_t new_list_length, appearances; list1 = value_stack[ top - 2 ]; list2 = value_stack[ top - 1 ]; list1_end = NEXT_VALUE( list1 ); list2_end = NEXT_VALUE( list2 ); /* Check arguments. */ if (! IS_LIST( list1 ) || ! IS_LIST( list2 )) complain( "Operands for intersection must be lists." ); /* Calculate the size of the new list. */ new_list_length = 2; for (v1 = list1 + 2; v1 < list1_end; v1 = NEXT_VALUE( v1 )) { /* Count appearences in LIST1 up to (including) V1. */ appearances = 1; for (v2 = list1 + 2; v2 < v1; v2 = NEXT_VALUE( v2 )) { if (values_equal( v1, v2 )) appearances++; } /* Subtract appearences in LIST2. */ for (v2 = list2 + 2; v2 < list2_end; v2 = NEXT_VALUE( v2 )) { if (values_equal( v1, v2 )) appearances--; } /* Add element size if included. */ if (appearances <= 0) new_list_length += length_of_value( v1 ); } /* We don't create a new list if no elements will be deleted. */ if (new_list_length == length_of_value( list1 )) new_list = list1; else { new_list = space_for_composed_value( LIST_TYPE, new_list_length ); /* Get arguments again: they may have been moved by garbage collection. */ list1 = value_stack[ top - 2 ]; list2 = value_stack[ top - 1 ]; list1_end = NEXT_VALUE( list1 ); list2_end = NEXT_VALUE( list2 ); /* Copy the elements. */ v = new_list + 2; for (v1 = list1 + 2; v1 < list1_end; v1 = NEXT_VALUE( v1 )) { /* Count appearences in VALUE1 up to (including) V1. */ appearances = 1; for (v2 = list1 + 2; v2 < v1; v2 = NEXT_VALUE( v2 )) { if (values_equal( v1, v2 )) appearances++; } /* Subtract appearences in VALUE2. */ for (v2 = list2 + 2; v2 < list2_end; v2 = NEXT_VALUE( v2 )) { if (values_equal( v1, v2 )) appearances--; } /* Copy value if included. */ if (appearances <= 0) { copy_value( v, v1 ); v = NEXT_VALUE(v); } } } /* Pop arguments and push result on stack. */ top--; value_stack[ top - 1 ] = new_list; } /*---------------------------------------------------------------------------*/ void remove_element( int_t n ) /* Stack effects: LIST -> NEW_LIST. * NEW_LIST is LIST without element at index N. * If N is positive, the elements will be counted from the left border; * if N is negative, they will be counted from the right border. * If LIST contains less than abs(N) elements, then NEW_LIST = LIST. */ { value_t list, list_end, new_list, element, v; int_t new_list_length; list = value_stack[ top - 1 ]; if (! IS_LIST( list )) complain( "Can remove an element in a list only." ); /* Find the first/last value in the list that will/won't be copied. */ element = get_element( list, n ); if (element == NULL) new_list = list; else { new_list_length = length_of_value( list ) - length_of_value( element ); new_list = space_for_composed_value( LIST_TYPE, new_list_length ); /* Get the values again, since they may have moved. */ list = value_stack[ top - 1 ]; list_end = NEXT_VALUE( list ); element = get_element( list, n ); /* Copy the list. */ v = new_list + 2; copy_cells( v, list + 2, element - (list + 2) ); v += element - (list + 2); copy_cells( v, NEXT_VALUE( element ), list_end - NEXT_VALUE( element ) ); } value_stack[ top - 1 ] = new_list; } /*---------------------------------------------------------------------------*/ void remove_elements( int_t n ) /* Stack effects: LIST -> NEW_LIST. * NEW_LIST is LIST without abs(N) elements. * If N is positive, the elements will be cut from the left border, * if N is negative, they will be cut from the list's right border. * If LIST contains less than abs(N) elements, then NEW_LIST = <>. */ { value_t new_list, list, list_end, border_value; int_t new_list_length; list = value_stack[ top - 1 ]; if (! IS_LIST( list )) complain( "Can delete an element in a list only." ); /* Find the first/last value in the list that will/won't be copied. */ if (n == 0) return; border_value = get_element( list, n ); if (border_value == NULL) new_list = empty_list; else if (n > 0) { /* Copy all elements behind BORDER_VALUE to a new list. */ new_list_length = 2 + NEXT_VALUE( list ) - NEXT_VALUE( border_value ); new_list = space_for_composed_value( LIST_TYPE, new_list_length ); list = value_stack[ top - 1 ]; list_end = NEXT_VALUE( list ); copy_cells( new_list + 2, list_end - (new_list_length - 2), new_list_length - 2 ); } else { /* Copy all elements in front of BORDER_VALUE to a new list. */ new_list_length = border_value - list; new_list = space_for_composed_value( LIST_TYPE, new_list_length ); list = value_stack[ top - 1 ]; copy_cells( new_list + 2, list + 2, new_list_length - 2 ); } value_stack[ top - 1 ] = new_list; } /*---------------------------------------------------------------------------*/ void extract_elements( int_t n ) /* Stack effects: LIST -> NEW_LIST. * NEW_LIST is LIST with only abs(N) elements. * If N is positive, the elements will be taken from the left border, * if N is negative, they will be taken from the list's right border. * If LIST contains less than abs(N) elements, then NEW_LIST = LIST. */ { value_t new_list, list, list_end, border_value; int_t new_list_length; list = value_stack[ top - 1 ]; if (! IS_LIST( list )) complain( "Can extract elements from a list only." ); /* Find the first/last value in the list that will/won't be copied. */ if (n == 0) new_list = empty_list; else { border_value = get_element( list, n ); if (border_value == NULL) return; if (n > 0) { /* Copy all elements in front of BORDER_VALUE to a new list. */ new_list_length = NEXT_VALUE( border_value ) - list; new_list = space_for_composed_value( LIST_TYPE, new_list_length ); list = value_stack[ top - 1 ]; copy_cells( new_list + 2, list + 2, new_list_length - 2 ); } else { /* Copy all elements behind BORDER_VALUE to a new list. */ new_list_length = 2 + NEXT_VALUE( list ) - border_value; new_list = space_for_composed_value( LIST_TYPE, new_list_length ); list = value_stack[ top - 1 ]; list_end = NEXT_VALUE( list ); copy_cells( new_list + 2, list_end - (new_list_length - 2), new_list_length - 2 ); } } value_stack[ top - 1 ] = new_list; } /*---------------------------------------------------------------------------*/ void replace_element( int_t n ) /* Stack effects: LIST VALUE -> NEW_LIST. * NEW_LIST is LIST, but its N-th element is replaced by VALUE. * If N is negative, count from the right end. * LIST must contain at least N elements. */ { value_t list, value, new_list, element, nv; int_t new_list_length; /* Get arguments. */ list = value_stack[ top - 2 ]; value = value_stack[ top - 1 ]; /* Check arguments. */ if (! IS_LIST( list )) complain( "Can only replace an element in a list." ); element = get_element( list, n ); if (element == NULL) complain( "Missing element to replace." ); new_list_length = (length_of_value( list ) + length_of_value( value ) - length_of_value( element )); new_list = space_for_composed_value( LIST_TYPE, new_list_length ); /* Get arguments again: they may have been moved by garbage collection. */ list = value_stack[ top - 2 ]; value = value_stack[ top - 1 ]; element = get_element( list, n ); /* Copy left part */ nv = new_list + 2; copy_cells( nv, list + 2, element - (list + 2) ); /* Copy changed element. */ nv += element - (list + 2); copy_value( nv, value ); /* Copy right part. */ nv = NEXT_VALUE( nv ); copy_cells( nv, NEXT_VALUE( element ), NEXT_VALUE( list ) - NEXT_VALUE( element ) ); /* Push result on stack. */ top--; value_stack[ top - 1 ] = new_list; } /*---------------------------------------------------------------------------*/ void convert_list_to_set( void ) /* Stack effects: LIST -> NEW_LIST. * NEW_LIST contains all elements of LIST, but multiple appearances * of one value are reduced to a single appearance. * That means, NEW_LIST is LIST converted to a set. */ { value_t v1, v2, v, new_list, list, list_end; int_t new_list_length; list = value_stack[ top - 1 ]; list_end = NEXT_VALUE( list ); if (! IS_LIST( list )) complain( "Can only convert a list to a set." ); /* Compute the length of the new list. */ new_list_length = 2; for (v1 = list + 2; v1 < list_end; v1 = NEXT_VALUE( v1 )) { /* Check if V1 already occurred in the list. */ for (v2 = list + 2; v2 < v1; v2 = NEXT_VALUE( v2 )) { if (values_equal( v1, v2 )) break; } if (v2 == v1) new_list_length += length_of_value( v1 ); } /* No need to create a new list if no elements will be deleted. */ if (new_list_length == length_of_value( list )) new_list = list; else { new_list = space_for_composed_value( LIST_TYPE, new_list_length ); list = value_stack[ top - 1 ]; list_end = NEXT_VALUE( list ); v = new_list + 2; for (v1 = list + 2; v1 < list_end; v1 = NEXT_VALUE( v1 )) { /* Check if V1 already occurred in the list. */ for (v2 = list + 2; v2 < v1; v2 = NEXT_VALUE( v2 )) { if (values_equal( v1, v2 )) break; } if (v2 == v1) { copy_value( v, v1 ); v = NEXT_VALUE( v ); } } } value_stack[ top - 1 ] = new_list; } /* Number operations. =======================================================*/ double value_to_double( value_t value ) /* Return the value of VALUE which must be a number value. */ { int_t i; union { double number; cell_t cells[CELLS_PER_NUMBER]; } v; if (! IS_NUMBER( value )) complain( "Value is no number." ); for (i = 0; i < CELLS_PER_NUMBER; i++) v.cells[i] = value[ i + 1 ]; return v.number; } /*---------------------------------------------------------------------------*/ int_t value_to_int( value_t value ) /* Return the value of VALUE which must be an integral number value. */ { double number; int_t result; number = value_to_double( value ); result = (int_t) number; if (result != number) complain( "Number too big or not integral." ); return result; } /*---------------------------------------------------------------------------*/ void push_number_value( double number ) /* Stack effects: (nothing) -> NEW_NUMBER. * NEW_NUMBER is NUMBER as a Malaga value. */ { int_t i; value_t value; union { double number; cell_t cells[CELLS_PER_NUMBER]; } v; v.number = number; value = space_for_value( 1 + CELLS_PER_NUMBER ); *value = TYPE_CELL( NUMBER_TYPE, 0 ); for (i = 0; i < CELLS_PER_NUMBER; i++) value[ i + 1 ] = v.cells[i]; push_value( value ); } /* Type dependent Malaga operations. ========================================*/ void dot_operation( void ) /* Stack effects: VALUE1 VALUE2 -> NEW_VALUE. * NEW_VALUE is VALUE1 "." VALUE2 or NULL, if that value doesn't exist. * The actual operation depends on the type of the values. */ { value_t value1, value2; value1 = value_stack[ top - 2 ]; value2 = value_stack[ top - 1 ]; switch (TYPE( value2 )) { case SYMBOL_TYPE: top--; value_stack[ top - 1 ] = get_attribute( value1, value_to_symbol( value2 ) ); break; case NUMBER_TYPE: top--; value_stack[ top - 1 ] = get_element( value1, value_to_int( value2 ) ); break; case LIST_TYPE: top--; value_stack[ top - 1 ] = get_value_part( value1, value2 ); break; default: complain( "In \"V1 . V2\", V2 must be symbol, number or list." ); } } /*---------------------------------------------------------------------------*/ void plus_operation( void ) /* Stack effects: VALUE1 VALUE2 -> NEW_VALUE. * NEW_VALUE is VALUE1 "+" VALUE2. * The actual operation depends on the type of the values. */ { value_t value1, value2; value1 = value_stack[ top - 2 ]; value2 = value_stack[ top - 1 ]; switch (TYPE( value1 )) { case STRING_TYPE: concat_string_values(); break; case LIST_TYPE: concat_lists(); break; case RECORD_TYPE: join_records(); break; case NUMBER_TYPE: top -= 2; push_number_value( value_to_double( value1 ) + value_to_double( value2 ) ); break; default: complain( "\"+\"-operands must be strings, lists, records, or numbers." ); } } /*---------------------------------------------------------------------------*/ void minus_operation( void ) /* Stack effects: VALUE1 VALUE2 -> NEW_VALUE. * NEW_VALUE is VALUE1 "-" VALUE2. * The actual operation depends on the type of the values. */ { value_t value1, value2; value1 = value_stack[ top - 2 ]; value2 = value_stack[ top - 1 ]; switch (TYPE( value1 )) { case LIST_TYPE: switch (TYPE( value2 )) { case NUMBER_TYPE: top--; remove_element( value_to_int( value2 ) ); break; case LIST_TYPE: get_list_difference(); break; default: complain( "In \"LIST - VALUE\", VALUE must be number or list." ); } break; case RECORD_TYPE: switch (TYPE( value2 )) { case SYMBOL_TYPE: top--; remove_attribute( value_to_symbol( value2 ) ); break; case LIST_TYPE: remove_attributes(); break; default: complain( "In \"RECORD - VALUE\", VALUE must be symbol or list." ); } break; case NUMBER_TYPE: top -= 2; push_number_value( value_to_double( value1 ) - value_to_double( value2 ) ); break; default: complain( "In \"V1 - V2\", V1 must be list, record, or number." ); } } /*---------------------------------------------------------------------------*/ void asterisk_operation( void ) /* Stack effects: VALUE1 VALUE2 -> NEW_VALUE. * NEW_VALUE is VALUE1 "*" VALUE2. * The actual operation depends on the type of the values. */ { value_t value1, value2; value1 = value_stack[ top - 2 ]; value2 = value_stack[ top - 1 ]; switch (TYPE( value1 )) { case LIST_TYPE: switch (TYPE( value2 )) { case LIST_TYPE: intersect_lists(); break; case NUMBER_TYPE: top--; extract_elements( value_to_int( value2 ) ); break; default: complain( "In \"LIST * VALUE\", VALUE must be list, or number." ); } break; case RECORD_TYPE: switch (TYPE( value2 )) { case SYMBOL_TYPE: top--; select_attribute( value_to_symbol( value2 ) ); break; case LIST_TYPE: select_attributes(); break; case RECORD_TYPE: /* Join records, but exchange arguments. */ top--; insert_value( 1, value_stack[ top ] ); join_records(); break; default: complain( "In \"RECORD * VALUE\", " "VALUE must be symbol, list, or record." ); } break; case NUMBER_TYPE: top -= 2; push_number_value( value_to_double( value1 ) * value_to_double( value2 ) ); break; default: complain( "In \"V1 * V2\", V1 must be list, record, or number." ); } } /*---------------------------------------------------------------------------*/ void slash_operation( void ) /* Stack effects: VALUE1 VALUE2 -> NEW_VALUE. * NEW_VALUE is VALUE1 "/" VALUE2. * The actual operation depends on the type of the values. */ { value_t value1, value2; double divisor; value1 = value_stack[ top - 2 ]; value2 = value_stack[ top - 1 ]; switch (TYPE( value1 )) { case LIST_TYPE: switch (TYPE( value2 )) { case NUMBER_TYPE: top--; remove_elements( value_to_int( value2 ) ); break; case LIST_TYPE: get_set_difference(); break; default: complain( "In \"LIST / VALUE\", VALUE must be number or list." ); } break; case NUMBER_TYPE: divisor = value_to_double( value2 ); if (divisor == 0.0) complain( "Division by zero." ); top -= 2; push_number_value( value_to_double( value1 ) / divisor ); break; default: complain( "\"/\"-operands must be lists or numbers." ); } } /*---------------------------------------------------------------------------*/ void unary_minus_operation( void ) /* Stack effects: VALUE -> NEW_VALUE. * NEW_VALUE is "-" VALUE. * The actual operation depends on the type of the value. */ { push_number_value( -value_to_double( value_stack[ --top ] ) ); } /* Attribute path functions. ================================================*/ value_t get_value_part( value_t value, value_t path ) /* Return the value part of VALUE that is specified by the path PATH. * If that value part does not exist, return NULL. */ { value_t part, path_end; if (! IS_LIST( path )) complain( "Path must be a list." ); path_end = NEXT_VALUE( path ); for (part = path + 2; part < path_end; part = NEXT_VALUE( part )) { if (IS_SYMBOL( part )) value = get_attribute( value, *part ); else if (IS_NUMBER( part )) value = get_element( value, value_to_int( part ) ); else complain( "Path must contain symbols and numbers only." ); if (value == NULL) return NULL; } return value; } /*---------------------------------------------------------------------------*/ void build_path( int_t n ) /* Stack effects: VALUE1 ... VALUE_N -> NEW_LIST. * NEW_LIST is a path which contains VALUE1, ..., VALUE_N. * VALUE1, ..., VALUE_N must be numbers, symbols or lists of numbers and * symbols. If a value is a list, the elements of this list are inserted into * NEW_LIST instead of the value itself. */ { value_t new_list, v, element_end; int_t i, new_list_length; value_t *elements; elements = value_stack + top - n; new_list_length = 2; for (i = 0; i < n; i++) { switch (TYPE( elements[i] )) { case LIST_TYPE: element_end = NEXT_VALUE( elements[i] ); for (v = elements[i] + 2; v < element_end; v = NEXT_VALUE(v)) { if (! IS_SYMBOL(v) && ! IS_NUMBER(v)) complain( "Sublist in path may contain symbols and numbers only." ); } new_list_length += length_of_value( elements[i] ) - 2; break; case SYMBOL_TYPE: case NUMBER_TYPE: new_list_length += length_of_value( elements[i] ); break; default: complain( "Value path may contain symbols, numbers and lists only." ); } } new_list = space_for_composed_value( LIST_TYPE, new_list_length ); v = new_list + 2; for (i = 0; i < n; i++) { if (IS_LIST( elements[i] )) { copy_cells( v, elements[i] + 2, length_of_value( elements[i] ) - 2 ); v += length_of_value( elements[i] ) - 2; } else { copy_value( v, elements[i] ); v = NEXT_VALUE(v); } } top -= n; push_value( new_list ); } /*---------------------------------------------------------------------------*/ static void modify_value_part_local( void (*modifier)( void ), int_t value_index, int_t path_index ) /* Stack effects: VALUE PATH MOD_VALUE -> VALUE PATH NEW_VALUE. * NEW_VALUE is VALUE, but the part that is described by PATH is * modified. PATH must be a list of symbols and numbers . * They will be used as nested attributes and indexes, so the part of VALUE * that is actually modified is OLD_VALUE := VALUE.E1.E2..E_N. * If this part does not exist, an error will be reported. Else the function * MODIFIER will be called on OLD_VALUE and MOD_VALUE. * The value returned by MODIFIER will be entered in VALUE in place of * OLD_VALUE. */ { value_t value, subvalue, selector; int_t subvalue_index, index; symbol_t symbol; value = value_stack[ top - 3 ] + value_index; selector = get_element( value_stack[ top - 2 ], path_index ); if (selector == NULL) /* No more selectors. */ { insert_value( 1, value ); modifier(); } else /* Find attribute in VALUE. */ { if (IS_SYMBOL( selector ) ) { symbol = value_to_symbol( selector ); subvalue = get_attribute( value, symbol ); if (subvalue == NULL) { complain( "No attribute \"%s\" in value.", values_get_symbol_name( symbol ) ); } } else if (IS_NUMBER( selector )) { index = value_to_int( selector ); subvalue = get_element( value, index ); if (subvalue == NULL) complain( "No element at index %d in value.", index ); } else complain( "Path must consist of symbols and numbers." ); subvalue_index = subvalue - value_stack[ top - 3 ]; /* Go down recursively */ modify_value_part_local( modifier, subvalue_index, path_index + 1 ); subvalue = value_stack[ top - 3 ] + subvalue_index; value = value_stack[ top - 3 ] + value_index; selector = get_element( value_stack[ top - 2 ], path_index ); if (value_stack[ top - 1 ] == subvalue) value_stack[ top - 1 ] = value; else if (IS_SYMBOL( selector )) { insert_value( 1, value ); replace_attribute( value_to_symbol( selector ) ); } else { insert_value( 1, value ); replace_element( value_to_int( selector ) ); } } } /*---------------------------------------------------------------------------*/ void modify_value_part( void (*modifier)( void ) ) /* Stack effects: VALUE PATH MOD_VALUE -> NEW_VALUE. * NEW_VALUE is VALUE, but the part that is described by PATH is * modified. PATH must be a list of symbols and numbers . * They will be used as nested attributes and indexes, so the part of VALUE * that is actually modified is OLD_VALUE := VALUE.E1.E2..E_N. * If this part does not exist, an error will be reported. Else the function * MODIFIER will be called on OLD_VALUE and MOD_VALUE. * The value returned by MODIFIER will be entered in VALUE in place of * OLD_VALUE. */ { modify_value_part_local( modifier, 0, 1 ); value_stack[ top - 3 ] = value_stack[ top - 1 ]; top -= 2; } /*---------------------------------------------------------------------------*/ void right_value( void ) /* Stack effects: LEFT_VALUE RIGHT_VALUE -> RIGHT_VALUE. * A modifier for "modify_value_part". */ { top--; value_stack[ top - 1 ] = value_stack[ top ]; } /* Functions for list/record iteration. =====================================*/ value_t get_first_item( value_t value ) /* If VALUE is a list, then return its first element (or NULL). * If VALUE is a record, then return its first attribute (or NULL). */ { if (! IS_LIST( value ) && ! IS_RECORD( value )) complain( "Can only get first item in a record or a list." ); if (length_of_value( value ) == 2) return NULL; return value + 2; } /*---------------------------------------------------------------------------*/ value_t get_next_item( value_t value, value_t item ) /* If VALUE is a list, and ELEMENT one of its elements, * then NEW_ELEMENT is the successor of ELEMENT (or NULL). * If VALUE is a record, and ELEMENT one of its attributes, * then NEW_ELEMENT is the next attribute in VALUE (or NULL). */ { value_t next_item; switch (TYPE( value )) { case LIST_TYPE: next_item = NEXT_VALUE( item ); break; case RECORD_TYPE: next_item = NEXT_ATTRIB( item ); break; default: complain( "Can only get next item in a list or record." ); } if (next_item == NEXT_VALUE( value )) return NULL; else return next_item; } /*---------------------------------------------------------------------------*/ void get_first_element( void ) /* Stack effects: VALUE -> NEW_VALUE. * If VALUE is a list, then NEW_VALUE is its first element (or NULL). * If VALUE is a record, then NEW_VALUE is its first attribute (or NULL). * If VALUE is a number, then NEW_VALUE is NULL (if VALUE == 0), * 1 (if VALUE > 0) or -1 (if VALUE < 0). */ { value_t value; int_t limit; value = value_stack[ top - 1 ]; top--; if (*value == NIL_SYMBOL) push_value( NULL ); else { switch (TYPE( value )) { case RECORD_TYPE: case LIST_TYPE: /* Return NULL if list or record is empty. */ if (length_of_value( value ) == 2) push_value( NULL ); else push_value( value + 2 ); break; case NUMBER_TYPE: limit = value_to_int( value ); if (limit > 0) push_number_value( 1.0 ); else if (limit < 0) push_number_value( -1.0 ); else push_value( NULL ); break; default: complain( "Can iterate on lists, records and numbers only." ); } } } /*---------------------------------------------------------------------------*/ void get_next_element( int_t index ) /* Stack effects: (nothing) -> (nothing). * VALUE is VALUE_STACK[ INDEX - 1 ], ELEMENT is VALUE_STACK[ INDEX ]. * VALUE_STACK[ INDEX ] will be set to NEW_ELEMENT. * ELEMENT must be the result of an application of "get_first_element()" or * "get_next_element()" on VALUE. * If VALUE is a list, and ELEMENT one of its elements, * then NEW_ELEMENT is the successor of ELEMENT (or NULL). * If VALUE is a record, and ELEMENT one of its attributes, * then NEW_ELEMENT is the next attribute in VALUE (or NULL). * If VALUE is a positive number, and ELEMENT a number smaller than * VALUE, then NEW_ELEMENT is ELEMENT + 1. * If VALUE is a negative number, and ELEMENT a number greater than * VALUE, then NEW_ELEMENT is ELEMENT - 1. */ { value_t value, element; int_t number, limit; value = value_stack[ index - 1 ]; element = value_stack[ index ]; if (element == NULL) return; switch (TYPE( value )) { case RECORD_TYPE: element = NEXT_ATTRIB( element ); if (element >= NEXT_VALUE( value )) element = NULL; break; case LIST_TYPE: element = NEXT_VALUE( element ); if (element >= NEXT_VALUE( value )) element = NULL; break; case NUMBER_TYPE: limit = value_to_int( value ); number = value_to_int( element ); if (limit > 0 && number < limit) { push_number_value( number + 1 ); element = value_stack[ --top ]; } else if (limit < 0 && number > limit) { push_number_value( number - 1 ); element = value_stack[ --top ]; } else element = NULL; break; default: complain( "Can iterate on lists, records and numbers only." ); } value_stack[ index ] = element; } /* Functions to compare values. =============================================*/ static void check_atom_list( value_t atoms ) /* Check if ATOMS is a list that contains of atoms only. */ { value_t v; value_t atoms_end; if (! IS_LIST( atoms )) complain( "Atom list must be a list." ); atoms_end = NEXT_VALUE( atoms ); for (v = atoms + 2; v < atoms_end; v++) { if (! IS_SYMBOL(v)) complain( "Atom list must consist of symbols." ); } } /*---------------------------------------------------------------------------*/ static symbol_t next_symbol( value_t atoms, int_t lower_limit ) /* Return the smallest symbol in ATOMS that is greater than LOWER_LIMIT. * Return SYMBOL_MAX if no such symbol exists. */ { symbol_t symbol; value_t v; value_t atoms_end; atoms_end = NEXT_VALUE( atoms ); symbol = SYMBOL_MAX; for (v = atoms + 2; v < atoms_end; v++) { if (*v > lower_limit && *v < symbol) symbol = *v; } return symbol; } /*---------------------------------------------------------------------------*/ int_t compare_atom_lists( value_t atoms1, value_t atoms2 ) /* Compare atom lists ATOMS1 and ATOMS2. * Return -1 if ATOMS1 < ATOMS2. * Return 0 if ATOMS1 == ATOMS2. * Return 1 if ATOMS1 > ATOMS2. */ { int_t limit1, limit2; check_atom_list( atoms1 ); check_atom_list( atoms2 ); limit1 = limit2 = -1; while (TRUE) { limit1 = next_symbol( atoms1, limit1 ); limit2 = next_symbol( atoms2, limit2 ); if (limit1 < limit2) return -1; if (limit1 > limit2) return 1; if (limit1 == SYMBOL_MAX) return 0; } } /*---------------------------------------------------------------------------*/ bool_t values_equal( value_t value1, value_t value2 ) /* Return a truth value indicating whether VALUE1 and VALUE2 are equal. * VALUE1 an VALUE2 must be of same type or one of them must be nil. * Refer to documentation to see what "equal" in Malaga really means. */ { value_t value1_end, value2_end, v1, v2; if (TYPE( value1 ) != TYPE( value2 )) { if (*value1 != NIL_SYMBOL && *value2 != NIL_SYMBOL) complain( "Can compare values of same type only." ); return FALSE; } switch (TYPE( value1 )) { case SYMBOL_TYPE: return (*value1 == *value2); case STRING_TYPE: return (strcmp_no_case( (string_t) (value1 + 1), (string_t) (value2 + 1) ) == 0); case LIST_TYPE: /* Look for each value pair if they are equal. */ value1_end = NEXT_VALUE( value1 ); value2_end = NEXT_VALUE( value2 ); for (v1 = value1 + 2, v2 = value2 + 2; v1 < value1_end && v2 < value2_end; v1 = NEXT_VALUE( v1 ), v2 = NEXT_VALUE( v2 )) { if (! values_equal( v1, v2 )) return FALSE; } return (v1 == value1_end && v2 == value2_end); case RECORD_TYPE: value1_end = NEXT_VALUE( value1 ); value2_end = NEXT_VALUE( value2 ); /* Do the records have the same length? */ if (value1_end - value1 != value2_end - value2) return FALSE; /* Check whether for every attribute in VALUE1, there is one * in VALUE2 and that their values are equal. */ for (v1 = value1 + 2; v1 < value1_end; v1 = NEXT_ATTRIB( v1 )) { /* Look for the same attribute in VALUE2. */ for (v2 = value2 + 2; v2 < value2_end; v2 = NEXT_ATTRIB( v2 )) { if (*v1 == *v2) break; } /* Return if we looked 'till end of value2 and didn't the find attribute, * or if they don't have the same values. */ if (v2 == value2_end || ! values_equal( v1 + 1, v2 + 1 )) return FALSE; } return TRUE; case NUMBER_TYPE: return (value_to_double( value1 ) == value_to_double( value2 )); default: complain( "Internal error." ); } } /*---------------------------------------------------------------------------*/ bool_t values_congruent( value_t value1, value_t value2 ) /* Return a truth value indicating whether VALUE1 and VALUE2 have * at least one element in common. * VALUE1 and VALUE2 must both be symbols or lists. */ { value_t value1_end, value2_end, v1, v2; if (TYPE( value1 ) != TYPE( value2 )) complain( "For congruency test, values must be of same type." ); if (IS_SYMBOL( value1 )) { value1 = values_get_atoms( value_to_symbol( value1 ) ); value2 = values_get_atoms( value_to_symbol( value2 ) ); } else if (! IS_LIST( value1 )) complain( "For congruency test, values must be lists or symbols." ); /* Look for a common element. */ value1_end = NEXT_VALUE( value1 ); value2_end = NEXT_VALUE( value2 ); for (v1 = value1 + 2; v1 < value1_end; v1 = NEXT_VALUE( v1 )) { for (v2 = value2 + 2; v2 < value2_end; v2 = NEXT_VALUE( v2 )) { if (values_equal( v1, v2 )) return TRUE; } } /* No common symbol found. */ return FALSE; } /*---------------------------------------------------------------------------*/ bool_t value_in_value( value_t value1, value_t value2 ) /* Return bool value saying if VALUE1 is element or attribute of VALUE2. * VALUE2 must be a list or a record. * If VALUE2 is a record, then VALUE1 must be a symbol. */ { value_t value2_end; value2_end = NEXT_VALUE( value2 ); if (IS_LIST( value2 )) { for (value2 += 2; value2 < value2_end; value2 = NEXT_VALUE( value2 )) { if (values_equal( value1, value2 )) return TRUE; } } else if (IS_RECORD( value2 )) { if (! IS_SYMBOL( value1 )) complain( "Only attributes can be found in a record using \"in\"." ); for (value2 += 2; value2 < value2_end; value2 = NEXT_ATTRIB( value2 )) { if (*value1 == *value2) return TRUE; } } else complain( "Can use \"in\" with records and lists only." ); return FALSE; } /* Functions to print values. ===============================================*/ static attribute_t * find_hidden_attribute( symbol_t symbol ) /* Find a hidden attribute in the attribute list and return it. * Return NULL if there is none. */ { attribute_t *attr; FOREACH( attr, hidden_attributes ) { if (attr->symbol == symbol) return attr; } return NULL; } /*---------------------------------------------------------------------------*/ symbol_t * get_hidden_attributes( void ) /* Get a SYMBOL_MAX-terminated vector of the currently hidden attributes. * The vector must be freed after use. */ { int_t i; attribute_t *attr; symbol_t *vector; /* Count the attributes. */ i = 0; FOREACH( attr, hidden_attributes ) i++; /* Create the new vector. */ vector = new_vector( sizeof( symbol_t ), i + 1 ); i = 0; FOREACH( attr, hidden_attributes ) vector[ i++ ] = attr->symbol; vector[ i++ ] = SYMBOL_MAX; return vector; } /*---------------------------------------------------------------------------*/ void add_hidden_attribute( symbol_t attribute ) /* Add ATTRIBUTE to the list of currently hidden attributes. */ { attribute_t *attr; attr = find_hidden_attribute( attribute ); if (attr == NULL) { attr = new_node( &hidden_attributes, sizeof( attribute_t ), LIST_END ); attr->symbol = attribute; } } /*---------------------------------------------------------------------------*/ void remove_hidden_attribute( symbol_t attribute ) /* Remove ATTRIBUTE from the list of currently hidden attributes. */ { attribute_t *attr; attr = find_hidden_attribute( attribute ); if (attr != NULL) free_node( &hidden_attributes, (list_node_t *) attr ); } /*---------------------------------------------------------------------------*/ void clear_hidden_attributes( void ) /* Clear the list of currently hidden attributes. */ { attribute_t *attr; FOREACH_FREE( attr, hidden_attributes ) /*empty*/; } /*---------------------------------------------------------------------------*/ static void attribute_to_text( text_t *text, value_t attr, bool_t full_value, int_t indent ) /* Print the attribute and value of the attribute-value pair ATTR. * If ! FULL_VALUE and *ATTR is hidden, don't print its value. */ { string_t attr_name; attr_name = values_get_symbol_name( *attr ); if (full_value || find_hidden_attribute( *attr ) == NULL) { add_to_text( text, attr_name ); add_to_text( text, ": " ); if (indent >= 0) indent += g_utf8_strlen( attr_name, -1 ) + 2; value_to_text( text, attr + 1, full_value, indent ); } else { add_char_to_text( text, '(') ; add_to_text( text, attr_name ); add_char_to_text( text, ')' ); } } /*---------------------------------------------------------------------------*/ static void print_comma( text_t *text, int_t indent ) /* Print a comma separator. * If INDENT >= 0, break the line and indent to column INDENT. */ { int_t i; if (indent >= 0) { add_to_text( text, ",\n" ); for (i = 0; i < indent; i++) ADD_CHAR_TO_TEXT( text, ' ' ); } else add_to_text( text, ", " ); } /*---------------------------------------------------------------------------*/ static string_t simple_value_to_string( value_t value ) /* Return VALUE, which must be a simple value, as a string */ { char_t *string; switch (TYPE( value )) { case SYMBOL_TYPE: string = new_string( values_get_symbol_name( *value ), NULL ); break; case STRING_TYPE: string = new_string_readable( (string_t) (value + 1), NULL ); decode_hangul( &string ); break; case NUMBER_TYPE: string = double_to_string( value_to_double( value ) ); break; } return string; } /*---------------------------------------------------------------------------*/ static void value_to_text( text_t *text, value_t value, bool_t full_value, int_t indent ) /* Convert VALUE to a format readable for humans and add it to TEXT. * which extends to OUTPUT_END (this is a pointer to the first byte after * OUTPUT. The pointer returned points to the EOS of the built string. * If FULL_VALUE == TRUE, show all attributes, even those that are hidden. */ { value_t value_end; string_t string; value_t item; bool_t list_is_simple; int_t column; string_t item_string; value_t attr, last_attr, next_attr; string_t name, last_name = NULL, next_name = NULL; if (value == NULL) return; value_end = NEXT_VALUE( value ); switch (TYPE( value )) { case SYMBOL_TYPE: case STRING_TYPE: case NUMBER_TYPE: string = simple_value_to_string( value ); add_to_text( text, string ); free_mem( &string ); break; case LIST_TYPE: add_char_to_text( text, '<' ); if (indent >= 0) indent++; /* Check if all elements are simple. */ list_is_simple = TRUE; for (item = value + 2; item < value_end; item = NEXT_VALUE( item )) { if (IS_LIST( item ) || IS_RECORD( item )) { list_is_simple = FALSE; break; } } if (indent >= 0 && list_is_simple) { /* Print multiple items on a line, break at column 80. */ column = indent; for (item = value + 2; item < value_end; item = NEXT_VALUE( item )) { item_string = simple_value_to_string( item ); if (item > value + 2) { if (column + 2 + g_utf8_strlen( item_string, -1 ) >= 80) { print_comma( text, indent ); column = indent; } else { print_comma( text, -1 ); column += 2; } } add_to_text( text, item_string ); column += g_utf8_strlen( item_string, -1 ); free_mem( &item_string ); } } else { /* Print each item on its own line or all items on one line. */ for (item = value + 2; item < value_end; item = NEXT_VALUE( item )) { if (item > value + 2) print_comma( text, indent ); value_to_text( text, item, full_value, indent ); } } add_char_to_text( text, '>' ); break; case RECORD_TYPE: add_char_to_text( text, '[' ); if (indent >= 0) indent++; last_attr = NULL; while (TRUE) { /* Find the next attribute to be printed. */ next_attr = NULL; for (attr = value + 2; attr < value_end; attr = NEXT_ATTRIB( attr )) { /* If ATTR comes after LAST_ATTR and before NEXT_ATTR, * then it's the new candidate to be printed this time. */ switch (attribute_order) { case ALPHABETIC_ORDER: name = values_get_symbol_name( *attr ); if ((last_attr == NULL || strcmp_no_case( name, last_name ) > 0) && (next_attr == NULL || strcmp_no_case( name, next_name ) < 0)) { next_attr = attr; next_name = name; } break; case DEFINITION_ORDER: if ((last_attr == NULL || *attr > *last_attr) && (next_attr == NULL || *attr < *next_attr)) { next_attr = attr; } break; case INTERNAL_ORDER: if ((last_attr == NULL || attr > last_attr) && (next_attr == NULL || attr < next_attr)) { next_attr = attr; } break; } } if (next_attr == NULL) break; if (last_attr != NULL) print_comma( text, indent ); attribute_to_text( text, next_attr, full_value, indent ); last_attr = next_attr; last_name = next_name; } add_char_to_text( text, ']' ); break; default: complain( "Internal error." ); } } /*---------------------------------------------------------------------------*/ char_t * value_to_readable( value_t value, bool_t full_value, int_t indent ) /* Return VALUE in a format readable for humans. * If FULL_VALUE == TRUE, show all attributes, even those that are hidden. * If INDENT >= 0, format value, i.e. print each element of a list or record * on a line of its own. Assume the value is indented by INDENT columns. * The result must be freed after use. */ { clear_text( value_text ); value_to_text( value_text, value, full_value, indent ); return new_string( value_text->buffer, NULL ); } /* End of file. =============================================================*/ malaga-7.12/values.h0000644000175000017500000003675110425347436013701 0ustar bjoernbjoern/* Copyright (C) 1995 Bjoern Beutel. */ /* Description. =============================================================*/ /* This module defines the data type "value_t", and many * operations to build, modify, and print such values. * There are six different types of values: * symbol, string, list, record, number and index. */ /* Constants. ===============================================================*/ /* Some standard symbols. */ enum {NIL_SYMBOL, YES_SYMBOL, NO_SYMBOL, SYMBOL_SYMBOL, STRING_SYMBOL, NUMBER_SYMBOL, LIST_SYMBOL, RECORD_SYMBOL}; enum {SYMBOL_MAX = 8192}; /* Symbols are in the range of 0..SYMBOL_MAX - 1. */ /* Types. ===================================================================*/ typedef u_short_t cell_t; /* A value is stored in one or more cells. * Use this type if you want to allocate memory (pools etc.) for values. */ typedef cell_t *value_t; /* Reference to a Malaga values by this type. */ typedef cell_t symbol_t; typedef enum {INTERNAL_ORDER, ALPHABETIC_ORDER, DEFINITION_ORDER} attribute_order_t; /* INTERNAL_ORDER is the order in which attributes are stored internally. * ALPHABETIC_ORDER means the alphabetic order of the attribute names. * DEFINITION_ORDER is the order in which the attributes are defined in the * symbol file. */ /* Variables. ===============================================================*/ extern string_t (*values_get_symbol_name)( symbol_t symbol ); /* Return the name of "symbol". * This is a callback function that must be set externally. */ extern value_t (*values_get_atoms)( symbol_t symbol ); /* Return the list of atoms of SYMBOL. * This is a callback function that must be set externally. */ extern value_t *value_stack; /* The value stack contains static values and local values. * The location of the VALUE_STACK-vector may change when the stack size * must increase. */ extern int_t top; /* The index of the first unused item on VALUE_STACK. * You may only read or decrease this variable! */ extern attribute_order_t attribute_order; /* The order in which attributes in a record are printed. * Used by "value_readable". */ /* Module initialisation. ===================================================*/ extern void init_values( void ); /* Initialise this module. */ extern void terminate_values( void ); /* Terminate this module. */ /* Value operations. ========================================================*/ extern value_t new_value( value_t value ); /* Allocate space for VALUE and copy it. * Use "free" to free the space occupied by this value. */ extern value_t copy_value_to_pool( pool_t value_pool, value_t value, int_t *index ); /* Copy VALUE to the pool VALUE_POOL and store its index in *INDEX. */ extern int_t length_of_value( value_t value ); /* Return the length of VALUE in cells. */ extern symbol_t get_value_type( value_t value ); /* Return the type of VALUE. Depending of the type, the result value may be * SYMBOL_SYMBOL, STRING_SYMBOL, NUMBER_SYMBOL, LIST_SYMBOL, RECORD_SYMBOL. */ extern void push_value( value_t value ); /* Stack effects: (nothing) -> VALUE. */ extern void insert_value( int_t n, value_t value ); /* Stack effects: VALUE1...VALUE_N -> VALUE VALUE1...VALUE_N. */ /* Symbol operations. =======================================================*/ extern symbol_t value_to_symbol( value_t value ); /* VALUE must be a symbol. * Return VALUE as a symbol. */ extern void push_symbol_value( symbol_t symbol ); /* Stack effects: (nothing) -> NEW_SYMBOL. * NEW_SYMBOL is SYMBOL converted to a Malaga value. */ /* String operations. =======================================================*/ extern string_t value_to_string( value_t value ); /* VALUE must be a string value. * Return the value of VALUE as a C style string. */ extern void push_string_value( string_t string_start, string_t string_end ); /* Stack effects: (nothing) -> NEW_STRING. * NEW_STRING is the string starting at STRING_START as a Malaga value. * If STRING_END != NULL, it marks the end of the string. */ extern void concat_string_values( void ); /* Stack effects: STRING1 STRING2 -> NEW_STRING. * NEW_STRING is the concatenation of STRING1 and STRING2. */ /* Record operations. =======================================================*/ extern value_t get_attribute( value_t record, symbol_t attribute ); /* Return the value of ATTRIBUTE in the record RECORD * or NULL if it doesn't exist. */ extern void build_record( int_t n ); /* Stack effects: ATTR1 VALUE1 ... ATTR_N VALUE_N -> NEW_RECORD. * NEW_RECORD looks like [ATTR1: VALUE1, ..., ATTR_N: VALUE_N]. */ extern void join_records( void ); /* Stack effects: RECORD1 RECORD2 -> NEW_RECORD. * NEW_RECORD contains all attributes of RECORD1 and RECORD2, and * their associated values. If an attribute has different values in RECORD1 * and RECORD2, the value in RECORD2 will be taken. */ extern void select_attribute( symbol_t attribute ); /* Stack effects: RECORD -> NEW_RECORD. * NEW_RECORD contains ATTRIBUTE and its value in RECORD. */ extern void select_attributes( void ); /* Stack effects: RECORD LIST -> NEW_RECORD. * NEW_RECORD contains all attribute-value pairs of RECORD whose attributes * are in LIST. */ extern void remove_attribute( symbol_t attribute ); /* Stack effects: RECORD -> NEW_RECORD. * NEW_RECORD contains all attribute-value pairs of RECORD but the one with * attribute ATTRIBUTE. */ extern void remove_attributes( void ); /* Stack effects: RECORD LIST -> NEW_RECORD. * NEW_RECORD contains all attribute-value pairs of RECORD but the ones * whose attributes are in LIST. */ extern void replace_attribute( symbol_t attribute ); /* Stack effects: RECORD VALUE -> NEW_RECORD. * NEW_RECORD is equal to RECORD, only the value of ATTRIBUTE is replaced * by VALUE. RECORD must contain ATTRIBUTE. */ /* List operations. =========================================================*/ extern int_t get_list_length( value_t list ); /* Return the number of elements in the list LIST. */ extern value_t get_element( value_t list, int_t n ); /* Return the N-th element of the list LIST, * or NULL, if that element doesn't exist. * If N is positive, elements will be counted from the left border. * If it's negative, elements will be counted from the right border. */ extern void build_list( int_t n ); /* Stack effects: VALUE1 ... VALUE_N -> NEW_LIST. * NEW_LIST looks like . */ extern int_t decompose_list( void ); /* Stack effects: LIST -> VALUE1 ... VALUE_N. * VALUE1 ... VALUE_N are the elements of LIST. * Return N. */ extern void concat_lists( void ); /* Stack effects: LIST1 LIST2 -> NEW_LIST. * NEW_LIST is the concatenation of LIST1 and LIST2. */ extern void get_list_difference( void ); /* Stack effects: LIST1 LIST2 -> NEW_LIST. * NEW_LIST contains the list difference of LIST1 and LIST2: * An element that appears M times in LIST1 and N times in LIST2 * appears M - N times in NEW_LIST. */ extern void get_set_difference( void ); /* Stack effects: LIST1 LIST2 -> NEW_LIST. * NEW_LIST contains the set difference of LIST1 and LIST2. * Each element of LIST1 is in NEW_LIST if it is not in LIST2. */ extern void intersect_lists( void ); /* Stack effects: LIST1 LIST2 -> NEW_LIST. * NEW_LIST contains the list intersection of LIST1 and LIST2. * Each element that appears M times in LIST1 and N times in LIST2 * appears min(M, N) times in NEW_LIST. */ extern void remove_element( int_t n ); /* Stack effects: LIST -> NEW_LIST. * NEW_LIST is LIST without element at index N. * If N is positive, the elements will be counted from the left border; * if N is negative, they will be counted from the right border. * If LIST contains less than abs(N) elements, then NEW_LIST = LIST. */ extern void remove_elements( int_t n ); /* Stack effects: LIST -> NEW_LIST. * NEW_LIST is LIST without abs(N) elements. * If N is positive, the elements will be cut from the left border, * if N is negative, they will be cut from the list's right border. * If LIST contains less than abs(N) elements, then NEW_LIST = <>. */ extern void extract_elements( int_t n ); /* Stack effects: LIST -> NEW_LIST. * NEW_LIST is LIST with only abs(N) elements. * If N is positive, the elements will be taken from the left border, * if N is negative, they will be taken from the list's right border. * If LIST contains less than abs(N) elements, then NEW_LIST = LIST. */ extern void replace_element( int_t n ); /* Stack effects: LIST VALUE -> NEW_LIST. * NEW_LIST is LIST, but its N-th element is replaced by VALUE. * If N is negative, count from the right end. * LIST must contain at least N elements. */ extern void convert_list_to_set( void ); /* Stack effects: LIST -> NEW_LIST. * NEW_LIST contains all elements of LIST, but multiple appearances * of one value are reduced to a single appearance. * That means, NEW_LIST is LIST converted to a set. */ /* Number operations. =======================================================*/ extern double value_to_double( value_t value ); /* Return the value of VALUE which must be a number value. */ extern int_t value_to_int( value_t value ); /* Return the value of VALUE which must be an integral number value. */ extern void push_number_value( double number ); /* Stack effects: (nothing) -> NEW_NUMBER. * NEW_NUMBER is NUMBER as a Malaga value. */ /* Type dependent Malaga operations. ========================================*/ extern void dot_operation( void ); /* Stack effects: VALUE1 VALUE2 -> NEW_VALUE. * NEW_VALUE is VALUE1 "." VALUE2 or NULL, if that value doesn't exist. * The actual operation depends on the type of the values. */ extern void plus_operation( void ); /* Stack effects: VALUE1 VALUE2 -> NEW_VALUE. * NEW_VALUE is VALUE1 "+" VALUE2. * The actual operation depends on the type of the values. */ extern void minus_operation( void ); /* Stack effects: VALUE1 VALUE2 -> NEW_VALUE. * NEW_VALUE is VALUE1 "-" VALUE2. * The actual operation depends on the type of the values. */ extern void asterisk_operation( void ); /* Stack effects: VALUE1 VALUE2 -> NEW_VALUE. * NEW_VALUE is VALUE1 "*" VALUE2. * The actual operation depends on the type of the values. */ extern void slash_operation( void ); /* Stack effects: VALUE1 VALUE2 -> NEW_VALUE. * NEW_VALUE is VALUE1 "/" VALUE2. * The actual operation depends on the type of the values. */ extern void unary_minus_operation( void ); /* Stack effects: VALUE -> NEW_VALUE. * NEW_VALUE is "-" VALUE. * The actual operation depends on the type of the value. */ /* Functions for value paths. ===============================================*/ extern value_t get_value_part( value_t value, value_t path ); /* Return the value part of VALUE that is specified by the path PATH. * If that value part does not exist, return NULL. */ extern void build_path( int_t n ); /* Stack effects: VALUE1 ... VALUE_N -> NEW_LIST. * NEW_LIST is a path which contains VALUE1, ..., VALUE_N. * VALUE1, ..., VALUE_N must be numbers, symbols or lists of numbers and * symbols. If a value is a list, the elements of this list are inserted into * NEW_LIST instead of the value itself. */ extern void modify_value_part( void (*modifier)( void ) ); /* Stack effects: VALUE PATH MOD_VALUE -> NEW_VALUE. * NEW_VALUE is VALUE, but the part that is described by PATH is * modified. PATH must be a list of symbols and numbers . * They will be used as nested attributes and indexes, so the part of VALUE * that is actually modified is OLD_VALUE := VALUE.E1.E2..E_N. * If this part does not exist, an error will be reported. Else the function * MODIFIER will be called on OLD_VALUE and MOD_VALUE. * The value returned by MODIFIER will be entered in VALUE in place of * OLD_VALUE. */ extern void right_value( void ); /* Stack effects: LEFT_VALUE RIGHT_VALUE -> RIGHT_VALUE. * A modifier for "modify_value_part". */ /* Functions for list/record iteration. =====================================*/ extern value_t get_first_item( value_t value ); /* If VALUE is a list, then return its first element (or NULL). * If VALUE is a record, then return its first attribute (or NULL). */ extern value_t get_next_item( value_t value, value_t item ); /* If VALUE is a list, and ELEMENT one of its elements, * then NEW_ELEMENT is the successor of ELEMENT (or NULL). * If VALUE is a record, and ELEMENT one of its attributes, * then NEW_ELEMENT is the next attribute in VALUE (or NULL). */ extern void get_first_element( void ); /* Stack effects: VALUE -> NEW_VALUE. * If VALUE is a list, then NEW_VALUE is its first element (or NULL). * If VALUE is a record, then NEW_VALUE is its first attribute (or NULL). * If VALUE is a number, then NEW_VALUE is NULL (if VALUE == 0), * 1 (if VALUE > 0) or -1 (if VALUE < 0). */ extern void get_next_element( int_t stack_index ); /* Stack effects: (nothing) -> (nothing). * VALUE1 is VALUE_STACK[ INDEX - 1 ], VALUE2 is VALUE_STACK[ INDEX ]. * VALUE_STACK[ INDEX ] will be set to NEW_VALUE. * VALUE2 must be the result of an application of "get_first_element" or * "get_next_element" on VALUE1. * If VALUE1 is a list, and VALUE2 one of its elements, * then NEW_VALUE is the successor of VALUE2 (or NULL). * If VALUE1 is a record, and VALUE2 one of its attributes, * then NEW_VALUE is the next attribute in VALUE1 (or NULL). * If VALUE1 is a positive number, and VALUE2 a number smaller than * VALUE1, then NEW_VALUE is VALUE2 + 1. * If VALUE1 is a negative number, and VALUE2 a number greater than * VALUE1, then NEW_VALUE is VALUE2 - 1. */ /* Functions to compare values. =============================================*/ extern int_t compare_atom_lists( value_t atoms1, value_t atoms2 ); /* Compare atom lists ATOMS1 and ATOMS2. * Return -1 if ATOMS1 < ATOMS2. * Return 0 if ATOMS1 == ATOMS2. * Return 1 if ATOMS1 > ATOMS2. */ extern bool_t values_equal( value_t value1, value_t value2 ); /* Return a truth value indicating whether VALUE1 and VALUE2 are equal. * VALUE1 an VALUE2 must be of same type or one of them must be nil. * Refer to documentation to see what "equal" in Malaga really means. */ extern bool_t values_congruent( value_t value1, value_t value2 ); /* Return a truth value indicating whether VALUE1 and VALUE2 have * at least one element in common. * VALUE1 and VALUE2 must both be symbols or lists. */ extern bool_t value_in_value( value_t value1, value_t value2 ); /* Return bool value saying if VALUE1 is element or attribute of VALUE2. * VALUE2 must be a list or a record. * If VALUE2 is a record, then VALUE1 must be a symbol. */ /* Functions to convert values to text. =====================================*/ extern symbol_t *get_hidden_attributes( void ); /* Get a SYMBOL_MAX-terminated vector of the currently hidden attributes. * The vector must be freed after use. */ extern void add_hidden_attribute( symbol_t attribute ); /* Add ATTRIBUTE to the list of currently hidden attributes. */ extern void remove_hidden_attribute( symbol_t attribute ); /* Remove ATTRIBUTE from the list of currently hidden attributes. */ extern void clear_hidden_attributes( void ); /* Clear the list of currently hidden attributes. */ extern char_t *value_to_readable( value_t value, bool_t full_value, int_t indent ); /* Return VALUE in a format readable for humans. * If FULL_VALUE == TRUE, show all attributes, even those that are hidden. * If INDENT >= 0, format value, i.e. print each element of a list or record * on a line of its own. Assume the value is indented by INDENT columns. * The result must be freed after use. */ /* End of file. =============================================================*/ malaga-7.12/variables.c0000644000175000017500000001660710236624026014334 0ustar bjoernbjoern/* Copyright (C) 2002 Bjoern Beutel. */ /* Description. =============================================================*/ /* Read in and display Malaga Variables. */ /* Includes. ================================================================*/ #include #include #include #include #include #include #include #include "basic.h" #include "scanner.h" #include "input.h" #include "canvas.h" #include "variables.h" /* Types. ===================================================================*/ typedef struct { list_node_t *next; string_t string; pos_string_t *name; pos_value_t *value; bool_t is_shown; } variable_t; typedef struct { list_node_t *next; string_t name; } hidden_var_t; /* Global variables. ========================================================*/ rectangle_t variables_geometry; string_t variables_font_family; int_t variables_font_size; /* Variables. ===============================================================*/ static list_t variables; static list_t hidden_vars; static canvas_t *variables_canvas; static pos_string_t *equal, *dots; /* Functions. ===============================================================*/ static void configure_variables( canvas_t *canvas, int_t *width_p, int_t *height_p ) { int_t width, height; variable_t *variable; int_t font_height = get_font_height( canvas ); int_t space_width = get_space_width( canvas ); int_t border_width = get_border_width( canvas ); config_pos_string( equal, canvas ); config_pos_string( dots, canvas ); width = height = border_width; FOREACH( variable, variables ) { if (variable != (variable_t *) variables.first) height += font_height; config_pos_string( variable->name, canvas ); variable->name->x = border_width; variable->name->y = height; equal->x = variable->name->x + variable->name->width + space_width; if (variable->is_shown) { config_pos_value( variable->value, canvas ); variable->value->x = equal->x + equal->width + space_width; variable->value->y = height; variable->name->y += (variable->value->height - font_height) / 2; width = MAX( width, variable->value->x + variable->value->width ); height += variable->value->height; } else { dots->x = equal->x + equal->width + space_width; width = MAX( width, dots->x + dots->width ); height += font_height; } } *width_p = width + border_width; *height_p = height + border_width; } /*---------------------------------------------------------------------------*/ static void expose_variables( canvas_t *canvas, rectangle_t *area ) { int_t space_width = get_space_width( canvas ); variable_t *variable; set_color( BLACK ); FOREACH( variable, variables ) { draw_pos_string( variable->name, canvas ); equal->x = variable->name->x + variable->name->width + space_width; equal->y = variable->name->y; draw_pos_string( equal, canvas ); if (variable->is_shown) draw_pos_value( variable->value, canvas ); else { dots->x = equal->x + equal->width + space_width; dots->y = equal->y; draw_pos_string( dots, canvas ); } } } /*---------------------------------------------------------------------------*/ static void show_variable( variable_t *variable, bool_t do_show ) { hidden_var_t *hidden_var; if (variable->is_shown == do_show) return; if (do_show) { /* Remove the variable in the list of hidden variables. */ FOREACH( hidden_var, hidden_vars ) { if (strcmp_no_case( hidden_var->name, variable->string ) == 0) break; } free_mem( &hidden_var->name ); free_node( &hidden_vars, (list_node_t *) hidden_var ); } else { /* Add the variable to the list of hidden variables. */ hidden_var = new_node( &hidden_vars, sizeof( hidden_var_t ), LIST_END ); hidden_var->name = new_string( variable->string, NULL ); } variable->is_shown = do_show; } /*---------------------------------------------------------------------------*/ static bool_t mouse_event( canvas_t *canvas, int_t x, int_t y, int_t button ) /* Called if pointer has entered CANVAS at position (X,Y), * if mouse has been moved to position (X,Y), * or if BUTTON has been pressed at position (X,Y). */ { variable_t *variable; int_t font_height = get_font_height( canvas ); FOREACH( variable, variables ) { if (x >= variable->name->x && x < variable->name->x + variable->name->width && y >= variable->name->y && y < variable->name->y + font_height) { if (button != 0) { show_variable( variable, ! variable->is_shown ); configure_canvas( canvas ); } else set_cursor( canvas, TRUE ); return TRUE; } } set_cursor( canvas, FALSE ); return FALSE; } /*---------------------------------------------------------------------------*/ static void show_all_variables( canvas_t *canvas, guint do_show ) { variable_t *variable; FOREACH( variable, variables ) show_variable( variable, do_show ); configure_canvas( canvas ); } /*---------------------------------------------------------------------------*/ static GtkItemFactoryEntry menu_items[] = { { "/Variables", NULL, NULL, 0, "" }, { "/Variables/Show All", NULL, show_all_variables, TRUE, NULL }, { "/Variables/Hide All", NULL, show_all_variables, FALSE, NULL }, }; /*---------------------------------------------------------------------------*/ static void free_variables( canvas_t *canvas ) { variable_t *variable; free_pos_string( &equal ); free_pos_string( &dots ); FOREACH_FREE( variable, variables ) { free_mem( &variable->string ); free_pos_string( &variable->name ); free_pos_value( &variable->value ); } } /*---------------------------------------------------------------------------*/ void read_variables( void ) /* Read new variables from STDIN. */ { string_t line; variable_t *variable; hidden_var_t *hidden_var; free_variables( NULL ); while (TRUE) { line = read_line( stdin ); if (line == NULL) complain( "Premature EOF." ); if (strcmp_no_case( line, "end" ) == 0) break; /* Read a new variable. */ variable = new_node( &variables, sizeof( variable_t ), LIST_END ); set_scanner_input( line ); /* Read variable name. */ test_token( TOK_STRING ); variable->name = new_pos_string( token_string ); variable->string = new_string( token_string, NULL ); read_next_token(); /* Read variable value. */ parse_token( '{' ); variable->value = parse_pos_value(); parse_token( '}' ); parse_token( EOF ); set_scanner_input( NULL ); free_mem( &line ); /* Check if variable is to be shown. */ FOREACH( hidden_var, hidden_vars ) { if (strcmp_no_case( hidden_var->name, variable->string ) == 0) break; } variable->is_shown = (hidden_var == NULL); } free_mem( &line ); equal = new_pos_string( "=" ); dots = new_pos_string( "..." ); if (variables_canvas == NULL) { variables_canvas = create_canvas( "Malaga Variables", "variables.eps", &variables_geometry, configure_variables, expose_variables, free_variables, mouse_event, TRUE, menu_items, ARRAY_LENGTH( menu_items ) ); } else { configure_canvas( variables_canvas ); show_canvas( variables_canvas ); } } /* End of file. =============================================================*/ malaga-7.12/variables.h0000644000175000017500000000101310236624032014317 0ustar bjoernbjoern/* Copyright (C) 2002 Bjoern Beutel. */ /* Description. =============================================================*/ /* Read in and display Malaga Variables. */ /* Variables. ===============================================================*/ extern rectangle_t variables_geometry; /* Functions ================================================================*/ extern void read_variables( void ); /* Read new variables from STDIN. */ /* End of file. =============================================================*/ malaga-7.12/CHANGES.txt0000644000175000017500000012515110761576605014040 0ustar bjoernbjoern MALAGA VERSION CHANGES Copyright (C) 1996 Bjoern Beutel = Version 7.12, released 2008-02-28 =========================================== malshow now uses cairo for drawing; line thickness grows with font size. The Malaga executables now link the dynamic malaga library, thanks to Ville-Pekka Vainio. When using the command "help", the commands are now sorted columns-first, instead of lines-first. The documentation has changed to reflect the fact that Win32 is no longer "officially" supported. = Version 7.11, released 2007-07-09 =========================================== Malaga may now be licensed by GPL version 2 or any later version. Repaired project file name dialog in Malaga's Emacs mode. The Makefile now uses LDFLAGS for linking, thanks to Michael Piotrowski. = Version 7.10, released 2007-05-27 =========================================== Entering Ctrl-D to exit no longer causes a segmentation violation error. = Version 7.9, released 2006-10-28 ============================================ Added missing UTF-8 validity checks for "libreadline" input and "-input" command line option. Added manpages written by Antti-Juhani Kaijanaho (from Malaga 4.3) and updated them. Changed options "display-line" and "transmit-line" to "display-cmd" and "transmit-cmd", respectively. The old option names can still be used for compatibility. = Version 7.8, released 2006-09-22 ============================================ The options "mor-pruning" and "syn-pruning" are now integer values. A value of 0 means that pruning rules are not called. A value > 0 indicates the minimum number of states needed to call the pruning rule. = Version 7.7, released 2006-09-20 ============================================ Compiling and linking creates more readable and compacter logs. "commands_interactive.c" now includes "stdio.h" and "input.h". A "pruning_rule" can now also be defined for a morphology grammar. The switch for using the pruning rule is called "mor-pruning" for morphology and "syn-pruning" for syntax. = Version 7.6, released 2006-08-31 ============================================ When using "libmalaga", the readline library is no longer needed, thanks to Harri Pitkänen. Update to autoconf 2.60 and libtool 1.5.22, thanks to Harri Pitkänen. Support for specifying DESTDIR during "make install" and "make uninstall", thanks to Flammie Pirinen. = Version 7.5, released 2006-06-18 ============================================ The function "get_value_string()" now returns a "char_t *", so the result can be modified and freed. When the windows of a malshow process have different font sizes, commas could be displayed in the wrong size. This has been corrected. Option "use-display" will be set to "no" if the "DISPLAY" environment is undefined. The configure option "--with-readline" enables fancy command line editing, provided that the GNU readline library is installed. = Version 7.4 ================================================================= Some errors in the Win32 code part have been corrected, thanks to Kai Solehmainen. The "string_t" type has been changed to "const char_t *", which improves source code documentation, optimisation and interaction via the "malaga.h" API. = Version 7.3 ================================================================= An error in the function "strncmp_no_case" has been fixed, thanks to Harri Pitkänen. The error led to incorrect results in the allomorph lexicon search. = Version 7.2 ================================================================= Path selection in malshow's Tree window has been changed. The left mouse button is now used to select a single state. The right mouse button activates a pop-up menu. The Malaga profile may now contain lines "show_indexes: {yes,no}", "hanging_style: {yes,no}", "inline_path: {yes,no}", and "show_tree: {full,no_dead_ends,result_paths}" which set the respective defaults for the malshow windows. Malaga now contains an if-expression, which is equivalent to an if-statement, but part of an expression. The "parallel" statement has been replaced by the "select" statement, which replaces the keyword "parallel" by "select" and the keyword "and" by "or". The new keyword fits better to Malaga's semantics and nicely complements the "choose" statement. For compatibility reasons, the "parallel" statement still exists. In malaga, the commands "ma-line", "sa-line", and their debug counterparts now take the line number as their first argument. If the file name is omitted, the file name of the previous "{ma,sa}-line" or "{ma,sa}-file" command will be used. In mallex, the commands "ga-line" and "debug-ga-line" now expect the line number as their first argument. For these commands, and the commands "ga-file" and "read-constants", the lexicon file name is now optional. If it is omitted, the previous lexicon file name will be used. = Version 7.1 ================================================================= When exporting in Postscript format, the program "malshow" will now only include the Hangul font if there are actually Hangul characters to be exported. The dynamic library "libmalaga.so" now contains a reference to libglib-2.0, so glib-2.0.so is automatically loaded. Pressing Ctrl-D in interactive mode makes malaga and mallex quit now. Previously, the programs sometimes stuck in an endless loop. = Version 7.0 ================================================================= Malaga now supports Unicode via the UTF-8 format. Support for 8-bit character sets (like ISO8859-x) and for KSC5601 has been abandoned. The project option "charset: xxx" has been removed, since the character set is now always UTF-8. Hangul support can now be switched on with the project option "split-hangul-syllables: yes". In malshow, you can now use the mouse wheel to scroll a canvas up and down. In Malaga Emacs mode, a brace that spans multiple lines is now indented correctly even if whitespace is following the opening brace. The program "mallex" doesn't crash anymore when a lexicon file contains named constants. = Version 6.14 ================================================================ From now, the state numbers in the tree display won't count break nodes, since they are no states. You can use the tree display's menu option "Tree/Show State Indexes" to toggle state indexes in the tree window. You can use the path display's menu option "Path/Show State Indexes" to toggle state indexes in the path window. When compiling with GTK+ 2.0 (or later), we do not use our own flicker-free drawing mechanism any more, since GTK+ 2.0 has a general one. The configure script now prefers to compile "malshow" with GTK+ 2.0 (or later). The GTK+ scrollbars are automatic now: they only appear if the window is not wide and/or tall enough. The new "continue" statement is similar to the break statement, but it terminates the current pass of a foreach loop and starts the next pass. = Version 6.13 ================================================================ The alternative syntax for rule definitions and rule calls with braces has been abandoned again. The options "mor-incomplete" and "syn-incomplete" may be used to get results for incompletely parsed input. The command line option "-quoted" makes malaga require quotes around each input line. The quotes are removed prior to analysis. The option "result-list" may be used to print all analysis results as a single list when malaga is used in filter mode or a file is analysed. Even results of different lengths are combined, which is useful in combination with "mor-incomplete" and "syn-incomplete". = Version 6.12 ================================================================ "Categories" have been renamed to "feature structures", since that's what they are. In combi rules, "start" has been renamed to "state" and "next" has been renamed to "link". = Version 6.11 ================================================================ Malaga's internal function error() has been renamed to complain() because the GNU C library "glibc" defines the function error(). Let's hope "complain" will never be used by "glibc". = Version 6.10 ================================================================ When configured, Malaga now prefers to be compiled for GTK+ 1.2, since it has been written for this version. Postscript output will now use Helvetica instead of Times-Roman. = Version 6.9 ================================================================= The debugger commands "step" and "next" will now also stop when a path has terminated and another path is going to be executed. The formal example grammars have been renamed. Their new names reflect the languages which they recognize. = Version 6.8 ================================================================= The expression LIST * NUMBER now returns the first NUMBER elements of LIST, if NUMBER > 0, or the last NUMBER elements of LIST, if NUMBER < 0. Libmalaga now uses the standard versioning scheme supported by libtool. The interface file "malaga.h" also contains versioning information. A new, precompiled lexicon format has been introduced, "prelex", to support distribution of binary lexicons that may be extended by the recipient. = Version 6.7 ================================================================= PostScript may now also exported for Hangul. Furthermore, the PostScript code now uses the metrics from the PostScript fonts, not the screen fonts. = Version 6.6 ================================================================= An alternate pattern for rule definitions and rule calls has been introduced: Instead of "NAME( $ARG1, $ARG2, ... )" you may write "{NAME $ARG1, $ARG2}". = Version 6.5 ================================================================= When reporting an error, malrul now prints where a rule or subrule has been defined or used for the first time. The "print" command may now print not only variables, but also named constants. If "use-display = yes", the output will be displayed in a window of its own. The "finish" debug-command resumes rule execution until a "return" is met or the current rule path is terminated. = Version 6.4 ================================================================= The command "get switches" will print the switches in alphabetical order. The "fail" statement has been renamed to "stop". "fail" is still valid, but it will generate a warning. Rule execution may be interrupted. = Version 6.3 ================================================================= malshow now uses the character set that is selected in the project file line that begins with "char-set:" or "char_set:". malshow's font may now be changed by "font:" in the configuration file. The default font size may be changed by "font_size:" in the configuration file. = Version 6.2 ================================================================= The "debug-state" command now behaves more intuitively. It doesn't switch back to "walk mode" if debugging a new successor rule of a state; instead, it uses the current debug mode. Emacs should now always understand when Malaga wants it to jump to a certain point in a source file. = Version 6.1 ================================================================= Malaga is now also compilable under the Microsoft Win32 API, using the MinGW GCC compiler. The malmake option "-new" causes the whole project to be recompiled. = Version 6.0 ================================================================= In regular expressions, a "?" behind one of the postfix operators "?", "+", "*" makes the operator behave in a "non-greedy" fashion: It will try to match as few characters as possible. Without the "?", the operators will try to match as many characters as possible. The escape char in regular expressions has changed from "!" to "\". Since this is also the escape char in strings, it has to be inserted twice in a regular expression. And if you want to use a "\" in a pattern as a simple character, you have to insert it even four times. = Version 5.10 ================================================================ Depending on the processor endianness, the binary files get the suffix "_l" (for little endian), "_b" (for big endian) or "_c" (for complex schemes). The calling syntax for "malrul", "mallex", "malsym" and "maldump" has changed because the binary file names are no longer allowed as arguments. = Version 5.9 ================================================================= The function length() now also works on string values. The function "substring(STRING, FIRST_INDEX, LAST_INDEX)" returns the substring in STRING that begins at FIRST_INDEX and ends at LAST_INDEX (both inclusive). = Version 5.8 ================================================================= Libtool is now included in the Malaga Package. = Version 5.7 ================================================================= Malaga now uses GNU Libtool to create its libraries. = Version 5.6 ================================================================= "configure.in" now checks for "gtk-config". A 64-bit pointer incompatibility in "tries.c" has been removed. = Version 5.5 ================================================================= The documentation format has been changed from LaTeX to Texinfo. = Version 5.4 ================================================================= In rule files and the lexicon file, default values for constants can be defined via "default @constant := VALUE;" After such a definition, the constant may be redefined via "define @constant := VALUE;", but only if the constant has not used until then. The commands "frame", "up" and "down" have been introduced to select the current frame when debugging. In the project file, any line may end with a comment "#...". All Malaga programs now have a "-help" command line option. The TCL/TK Display program has been removed. Instead, the GTK+ Display program "malshow" has been included. The display-command-line "malshow" is set by default. The configuration option for debug versions has been removed. The system-wide startup file "malagarc" has been removed. = Version 5.3 ================================================================= The "continue" command with a comparison expression has been reworked. It now must be applied at a point in the source where the tested variable is currently defined. Only this variable will be tested, all other variables with the same name will be ignored. This speeds up execution. malaga and mallex read a system wide startup file "${MALAGA}/malagarc" as well as the personal one "${HOME}/.malagarc". The parsing of the lexicon file won't get irritated by execution of the commands "print" or "continue $VAR = VALUE" in debug mode any longer. = Version 5.2 ================================================================= The types "int_t" and "u_int_t" are now set to "int" and "unsigned int", resp. This makes Malaga work with 64-bit architectures where "int" is still 32 bits long. The Hangul KSC encoding has been slightly modified. To generate debug versions of the executables, use the configure option "--enable-debug". = Version 5.1 ================================================================= The type "char_t" is now equal to "char" instead of "unsigned char", to be compliant with Standard C. The option "auto-result" can be used to switch automatic results after analyses on or off. Errors while setting options from the project file or ".malagarc" will be reported. Malaga will now use the cache also in "ma-file" and in morphology analysis from libmalaga. A relative path name as argument for "init_libmalaga" doesn't crash any longer. = Version 5.0 ================================================================= The Tree display now contains "unfinal" nodes: these are nodes of end states that have been removed since they didn't consume all the input. The first parameter of the robust rule now contains the remaining input up to, but not including, the next space. The robust rule now has an optional second parameter that contains all the remaining input. The result statement in a robust_rule may now have two arguments: if it has two arguments, the first must be a prefix of the remaining input, and the second must be the feature structure for this prefix. This enables you to set word-boundaries in a more flexible way. If your end-rule only has one parameter, it is only called at a word boundary, that means, if there is a leading space in the remaining input or all input is consumed. If your end-rule has two parameters, then the second is the input that has not been consumed yet. In this case, your end-rule will be called regardless what the remaining input looks like. You can use the input to decide if you really want to have an analysis result here. This enables you to set word-boundaries in a more flexible way. The error statement may now take any value that evaluates to a string as argument, not just a constant string literal. A new Emacs major mode has been introduced, namely "malaga-project-mode", which is intended to edit Malaga project files. It is an extension of "text-mode"; the commands "malaga", "mallex" and "malmake" are bound to the keys "C-c C-p", "C-c C-l" and "C-c C-r", respectively. The debug command "continue" now allows local breakpoints and local watchpoints: - "c [FILE_NAME] LINE_NUMBER" or "c RULE_NAME" continues until the specified source text position (which is called "local breakpoint") or a global breakpoint is reached. - "c VAR_PATH = VALUE" continues until VAR_PATH (a variable name which may be followed by a path of attribute names and indexes) equals VALUE. The Tcl/Tk variables display now has an easier way to make a variable value (dis)appear: click on the variable name. If a variable should be defined in a pattern match, the new preferred way to do it is to write the variable name BEHIND the pattern segment instead in front of it: ? $x matches ".*": $var1, "en"; The old way is still allowed for backwards compatibility. Malaga now supports the Hangul character set. If the symbol file has been compiled with the option "-hangul", e.g. "malsym xxx.sym -hangul", the symbol file and all files that use it will be encoded with the Hangul character set. If the project file contains a line "char-set: hangul", then "malmake" will execute "malsym" with that option. In malaga and mallex, the option "use-ksc" can be used to use either KSC-5601 encoding or romanized Hangul for output. "mallex" has been reworked and now needs much less process space, which is important because it creates the whole lexicon in main memory before it is dumped to the lexicon file. Malaga values are now pretty-printed if printed in interactive mode. Results and variables may now be printed by the external "display" program or by malaga itself, using the "result" resp. "variable" command. This can be chosen using the "display-output" switch. The "output" command and the "output" option have been deleted, because their work is now done by "result" if "display-output = no". The "print" command does not print all variables of a rule any longer, this will be done by "variables" if "display-output = no". The "print" command can still be used to print the values of single variables or paths. The "result" option has been deleted, so the result output will be printed always after an analysis. In mallex, the command "read-constants" may be used to initialize lexicon constants by reading them from a file. The commands ma-line/sa-line and their "debug" counterparts, "debug-ma-line" and "debug-sa-line" have been introduced. They allow analysing a single word or a single sentence from a file by giving its line number. The ga/sa/ma commands have been renamed (once again), so they form a more regular pattern: ga ga-line ga-file debug-ga debug-ga-line ma ma-line ma-file debug-ma debug-ma-line sa sa-line sa-file debug-sa debug-sa-line The function "transmit" is now available in allomorph rules as well as in combination rules. Positive numbers may be written alternatively like "5L" (= "5"), negative numbers may be written alternatively like "12R" (= "-12"). Output files for morphology/syntax analysis and lexicon generation get default suffix ".out" instead of ".cat". Assignment of list elements to multiple variables introduced: "<$a, $b, $c> := ", or, if you want do define $a, $b, $c: "define <$a, $b, $c> := ". = Version 4.3 ================================================================= The escape char in patterns has changed from "\" to "!". The foreach statement may now be preceded by a label, and the break statement may leave a foreach loop. In a rule set, there may be more than one rule after an "else" keyword, like "rules (A1, A2, A3 else B1, B2, B3 else C1, C2, C3)". The "matches" condition has been reworked. Now it looks like: MatchCond ::= Expr "matches" "(" Segment "," ... "," Segment ")" ";" . Segment ::= [Variable ":" ] Pattern-String . A Pattern string may be any constant String (consisting of literals, constant values and the operator "+"). The value of the String must be a pattern, which may now contain parentheses for grouping. The "input_rule" and "filter_rule" have been renamed to "input_filter" and "output_filter", respectively. The pruning rule now works differently; It has only one parameter, namely a list of feature structures, and must execute a "return" statement with a list of "yes"/"no"-symbols, one for each feature structure in the parameter. The value heap now grows automatically if needed; it can grow indefinitely, so the option "heap-size" is no longer needed and abolished. In the emacs Malaga support file, Malaga mode will also be invoked for files with suffix ".mal", but no longer for files with suffix ".nav" or ".sub". In the emacs Malaga support file, The commands "C-c m", "C-c r", "C-c l" and "C-c d" have changed to "C-c C-p", "C-c C-r", "C-c C-l" and "C-c C-d" resp. In an assert statement, you can now use "!" as a shorthand for "assert". The function "floor(N)", which returns the greatest integer number not greater than N, has been introduced. The repeat statement has been introduced. The expression "LIST / NUMBER" yields LIST without its leftmost NUMBER elements, if NUMBER > 0, or LIST without its rightmost abs(NUMBER) elements, if NUMBER < 0. The function "symbol_name" has been changed to the function "value_string" which can convert every value to a string. The rule set in the initial state or in a result statement may be enclosed in parentheses. Subrules may now have zero parameters. The environment variables "MALAGA_TRANSMIT" and "MALAGA_DISPLAY" have been abandoned. The command lines are now defined by setting the options "transmit" and "display", respectively. The user can now set preferred options for malaga and mallex in the startup file "~/.malagarc". The Operator "RECORD1 * RECORD2" works like "RECORD2 + RECORD1". So ":=*" is useful to add a default attribute to a record if that attribute doesn't exist in the original record. Malaga switches can now have any values, even records and lists. = Version 4.2 ================================================================= The function "transmit" has been introduced, which allows communication with an external process via pipe. Indexes and floats are merged into the Malaga value type "number", which has the same properties as "float". If you want to access the sixth element of $list, write "$list.6" instead of "$list.6L". Negative numbers count from the right end of a list, e.g. "$list.-2". Attention: a dot that is immediately following a number is part of the number, so "$list.2.4" is different from "$list.(2).(4)". The "match" condition, now called "matches" condition, is now written as "VALUE matches PATTERN" instead of "match VALUE = PATTERN". In mallex, the command "debug" has been renamed to "debug-entry". The command "debug-file" has been introduced which generates allomorphs for a file in debug mode. In mallex, the commands "ga-file" and "debug-file" leave their results permanent, so the results can be displayed with "output" or "result". The commands "ma-file" and "sa-file" don't interrupt if an error occurs during file analysis. Instead, the error message is written into the output file and the next item is analysed. The new function "symbol_name" returns the name of a symbol as a string. A condition can be used everywhere a (non-constant) value can be used. The value of a condition used in such a place is "yes" or "no". Conditions are now grouped by ordinary parentheses "()" instead of "{}". A match condition can now be used in every place where an ordinary condition can be used. Exception: If a match condition defines variables, it may not be part of a disjunction or a negation. The pattern in a match condition may contain constants and literal strings; it may contain parentheses and the operators & (for concatenation of subpatterns) and | (for alternatives). They may be only mixed if precedence is indicated by parentheses. A variable definition which subsumes only part of a pattern must be in parentheses: '$x: "A" & "B"' will assign "AB" to $s if it does match, whereas '($x: "A") & "B"' will assign "A" to $x. A variable definition may not be part of an alternative. A lexicon file may now contain constant definitions "define @Name := Value;". The lexicon entries in a lexicon file may now be arbitrary Malaga expressions, i.e. they may contain constants and the operators ".", "+", "-", "*" and "/". The command "ga-line" has been introduced in mallex, which generates allomorphs for a single entry in a lexicon file. Allomorphs can be displayed graphically in mallex using "result". The commands "output" and "result" have been incorporated into mallex as well as the options with the very names. There may now be only one allo_rule in the allo rule file, which may only call subrules and create allomorphs. The allomorphs are now created by the command "result", not "allo". An allo rule file may also contain a filter_rule which is called once for each set of generated allomorph lexicon entries that share the same surface. This rule can be used to join entries with a common surface. In a morphology file, aside the combination rules, there may be a filter_rule (formerly located in the mfil-file) and a robust_rule (formerly called "unknown_rule"). In a syntax file, aside the combination rules, there may be a input_rule (formerly known as "filter_rule" in the ifil-file), a pruning_rule, and a filter_rule (formerly located in the sfil-file). In Emacs Malaga mode, comments that start at the first column will not be indented. The command line options of malaga, mallex etc. now have one-letter-abbreviations, for example "-v" for "-version". The option "alias" has been introduced. It is used to define command line abbreviations. The "paradigm" command has been deleted, so the "generate" statement has been deleted, too. Identifiers may also include the character "|". "include" is now forbidden within rules. The operators "+=" and "-=" have changed to ":=+" and ":=-", resp. They are complemented by the new operators ":=*" and ":=/". The unary prefix operator "-" has been introduced which inverts numbers. Constant values can now also contain parentheses "()", and the operators "+", "-", "*", "/" and ".". The end of a rule may now include the rule name: "end RULE_NAME;" The command "value" has been renamed to "print". It now also accepts indexes in a variable path. The option "sort-records" now has three possible settings: "internal", "alphabetic", and "definition" (as in the symbol-table). Float values may now be preceded by a "-" sign. The operator "value_type()" returns the type of a Malaga value coded as one of the symbols "symbol", "string", "float", "index", "list", and "record". Indexes like 1L or 4R may now be part of Malaga values. They can also be part of a path in an assignment. The "." operator may now be followed by a list of symbols and/or indexes. This will be interpreted as ".e1.e2.e3". The operator "length()" returns the number of elements in a list as an index, e.g. length() = 3L. The statement "choose" may now choose indexes: "choose $index in 6L;" generates paths where $index has values 1L, 2L, ..., 6L. "choose $index in 6R;" generates paths where $index has values 1R, 2R, ..., 6R. The statement "foreach" may now iterate over indexes: "foreach $index in 6L: STATEMENTS end;" executes STATEMENTS where $index is assigned the values 1L, 2L, ..., 6L sequentially. The operator "LIST - INDEX" now removes ONLY the element at position INDEX in LIST. The "remain" part of a "choose" statement has been removed. Where it has been needed, it can be replaced by index iterating and removing elements by position: "choose $Element in $List remain $List" would be replaced by "choose $Index in length($List); define $Element := $List.$Index; $List :=- $Index;" The argument to the function "switch" must now be a symbol instead of a string. The commands "ma" and "sa" without arguments don't enter ma-mode or sa-mode any longer; they re-analyse the last input. Use "ma-mode" and "sa-mode" to enter ma-mode or sa-mode, respectively. = Version 4.1 ================================================================= The functions in libmalaga now return also when an error occurred. In this case, the error message is in "malaga_error". Else, "malaga_error" is NULL. The command "clear-cache", which deletes all wordforms in the cache, has been introduced. You can set switches in malaga and mallex with the option "set switch", and you can query them in rules using the operator "switch". The option "variables" has been introduced, to show Variables automatically in debug mode. Output is now sent to a single graphical display program via pipes. The program command line must be in the environment variable MALAGA_DISPLAY. A subrule can now be called before it is defined. A command "trace" has been added, to show the current call stack. The option "graphics" has been deleted. For textual result output, use the command "output". For graphical results, use the command "result". The commands can be automatically executed after "sa" or "ma". Use the options "result" and "output" for this purpose. The option "cache" has been deleted. Use "set cache-size 0" to deactivate the cache. "result-format" and "unknown-format" are also used for textual output with "ma", "sa" and "result". In "result-format" and "unknown-format", "%n" means the number of states for this analysis. In "result-format", "%r" is the ambiguity-index. "get cache-size" now also shows how many cache entries are used. sa-file, ma-file and ga-file take an additional optional parameter, namely the output file name. malaga and mallex print statistic information when they work in batch mode. analyse_item() in libmalaga now takes an additional argument, which says whether malaga should create an analysis tree. mallex now also reads the project file if it is called via malmake. Renamed option "heapsize" to "heap-size". Implemented a word form cache and option "cache" to switch it on or off. The cache size can be set using the option "cache-size" Replaced option "format" by "allo-format", "result-format" and "unknown-format". libmalaga now reads the "malaga:" option lines from the project file, not the "libmalaga:" lines. It ignores the options that only make sense for malaga. The option "heapsize" has been introduced to set the heapsize to a new value. Lines in the project file that start with "morinfo:" or "syninfo:" will be stored as mor-info or syn-info. In malaga, use the command "info mor" or "info syn" to get this information. In libmalaga, use the function "get_info(grammar_t grammar)". Option lines in included project files ("include:" lines) are now also executed. In the left hand of an assignment, paths can now also include any expressions, like "$var.$var1.($var2.attr) := value;" "sa" now supports sa-mode. "ma" now supports ma-mode. The "output" option has been replaced by the "graphics" option and the "tree" option. The "set" keyword must now be used when setting options that appear in the project file. The "define" keyword must now also be used for constant definitions. The "hidden" option syntax now needs a "+" in front of each symbol to hide, a "-" in front of each symbol to hide no more and a "none" to hide no symbols. TAB in Malaga mode only jumps to first non-blank if the cursor previously was in front of the first non-blank. = Version 4.0 ================================================================= The symbols "yes" and "no" are now defined by the system. A condition that consists only of a value (without condition operator) is tested whether it contains the value "yes" or "no". The former condition "capital" is now a standard function that returns a "yes" or "no" value. A definition of a new variable (formerly an assignment) now needs the keyword "define" in front. It is now called the define-statement. An assignment (formerly a "set"-statement) doesn't need a "set" in front any longer. A test-statement may be introduced by the "?" as well as the new keyword "require". The "next" command has been introduced. It works like "step", but it executes subrules without interruption. The "set" command is now introduced to set options; there are no individual commands for the individual options left. The "get" command is used to get the current settings. The initial state is now described in the format "initial FEAT, rules RULES;" (for combi rules), or "initial rules RULES;" (for other rules). The result statement now displays the result in a TCL/Tk window. This can be changed by the "output" option. The "set()" function has been implemented. It takes one parameter and it converts a list (multi-set) to a set where every element is contained at most one time. The debug commands have been renamed to form a more regular pattern: "debug" (for allomorph rules), "debug-line" (for lexicon lines), "debug-mor" (for morphology combination rules), "debug-mfil" (for morphology output filter rules), "debug-ifil" (for syntax input filter rules), "debug-syn" (for syntax combination rules), "debug-sfil" (for syntax output filter rules), "debug-node" (for analysis states). The keywords "base" and "cat" have been deleted. The "generate" statement now takes an "allo" keyword instead of "base" if the rule can generate a base allomorph. The "allo" statement now looks like: "allo ALLO, FEAT, BASE;". Syntax input filter rules have been introduced. A syntax input filter rule file has the ending ".ifil" and is executed after morphology output filter rules have been executed and before syntax combination rules will do their work. As a consequence, the morphology output filter rules may only use symbols of the symbol file, not of the extended symbol file (since the morphology output filter rules now belong totally to the morphology system). The "filter" command now takes the keywords "mfil", "sfil" and "ifil" instead of "mor" and "syn". The "error" statement now needs a string, namely the error message that it should print. The keyword "final_state_check" has been changed to "end_rule" again, since it IS a rule (although not a combi-rule). The "foreach" statement can now only include one list over which to iterate. This reduces complexity of Malaga statements. The "choose" statement can now assign the remainder to an existing variable: use the form "choose $var1 in $list remain set $rem_var", which will assign the remainder to "$rem_var". The "start" statement has been deleted. Instead, the rule parameters have to be specified behind the rule name, in parentheses, like: "rule ABC( $state, $link, $link_surf ):". Combi rules have 2-4 parameters, namely: state feature structure, link feature structure, link surface (optional) and link index (optional). Pruning rules have 3 parameters: the list of feature structures of the states that have already been tested, the feature structure of the state currently tested, and the list of feature structures of states to be tested later. Filter rules, allo rules and end rules have one parameter. There is no difference between test statements and result statements any longer. Therefore, the "case" statement was superfluous and could be erased. The "parallel" statement has been changed in syntax: instead of the "subrule" keyword IN FRONT of each parallel part, and "and" keyword BETWEEN two parallel parts is now used. Subrules (i.e. Malaga functions) have been introduced. They start with the keyword "subrule" and their parameter list can have any number of parameters. A subrule must return a value via the "result" statement: "result $xyz;". It is called in an expression like "$new := subrule_name( $Param1, $Param2 );". Subrules may nest, but they must not be called recursively. Every subrule must be defined before it is called (no forward declarations are possible). Values can be much bigger now (up to 1 Gigabyte, which is perhaps academic). = Version 3.0 ================================================================= The command "hide" has been renamed to "hidden", it takes an additional first argument: "add", "delete" or "clear". For "add", all subsequent arguments are added to the list of hidden arguments. For "delete", all subsequent arguments are removed from the list of hidden arguments. For "clear", all symbols are removed from the list of hidden arguments. The command "attributes" has been renamed to "sort_records". The command "hangul" now gets a parameter "on" or "off", so command "roman" could be deleted. The command "show" has been renamed to "output". The command "unknown" has been removed, it functionality has been included into command "format". The command "debug-node" takes a state number which you get from the title of a TCL/Tk state window, and executes all rules in debug mode that process this state. The "Disam" package has been removed: the commands "disam" and "prune" are no longer available. The command "value" now supports paths: You can write a series of attributes behind a variable name, e.g. "malaga> value $state.Form.Syn" Filter rules have been introduced. You can have a filter rule system for your morphology and one for your syntax. The morphology filter rule file has to end in ".mfil", the syntax filter rule file has to end in ".sfil". The filter rules are called after the combination rules have been executed. They are similar to the allomorph rules, only that they begin with "filter_rule" instead of "allo_rule", and they get the list of results of the combination rules as their "start" parameter. In the filter rules, you can compare the results, change them and create the new actual analysis results by using the "result ... accept;" statement. Filter rules can use the symbols in the symbol file and the symbols in the extended symbol file. If you include filter rules in your project file or in your command line arguments when calling malaga, the execution of filter rules is switched on by default. You can switch it on or off using the "filter" command. The filter command needs two arguments: the filter rule system type ("mor" or "syn") and one of "on" or "off". The file ending ".sys" (for syntax symbol file) has been changed to ".esym" (for extended symbol file) because the symbols in this file can now also be used by the filter rules. Pruning rules have been introduced. You can have a single pruning rule in your syntax rule file. Before a set of states (which have consumed the same amount of analysis input) is combined with a new link, the pruning rule is called for each state of this set. The rule decides whether the state should be deleted or not. The pruning rule starts with "pruning_rule", and in the "start" statement, it gets a list of three elements as a parameter: the first element is the list of feature structures of the states that have already been examined by the pruning rule, the second argument is the feature structure of the state that is to be examined currently, and the third argument is the list of feature structures of the states that haven't been examined yet. When the pruning rule executes an "accept" statement, the state will be preserved; else it will be killed. In morphology rule files, after the initial state, you can now include a "unknown_cat FEAT;". When robust analysis is activated, an unknown wordform is assigned the feature structure FEAT. Robust analysis is switched on and off with the command "robust". Commands that are included in the project file after "malaga:" or "mallex:" are now also executed in batch mode, so only commands that change settings are allowed here. Command line options for malaga and mallex have been reduced to "-version", "-readable" and "-interactive" for mallex and "-version", "-syntax", "-morphology" for malaga. The "-" operator for lists is the MULTI-SET difference now, whilst the "/" operator for lists is the SET difference. = Version 2.1 ================================================================= The keyword "end-rule" has been renamed to "final_state_check". The character "-" may not be part of symbol names, keywords, variable names... any longer. The new operator "-" can subtract floats and create the difference of multi-sets. The symbol "nil" can be compared to any value, even records, lists and strings. A rule set may contain multiple default rules (rules aa, bb, cc else dd else ee else...) The "set" statement can now set the value of a specified attribute, like "set $state.Form.Mor := $New_Value;". The new assignment operators "+=" and "-=" have been introduced (in set statements only). The statement "set a += b;" is an abbreviation for "set a := a + b"; the analogon holds for "-=". The atomizing operator "* a" now has to be written as "atoms(a)". The inverse operator has been introduced: "multi(a)" returns the multi-symbol whose atomic symbols are equal to a, which must be a list of atomic symbols. An error is reported if that multi symbol doesn't exist. In the symbol table, the "*" is not needed to mark multi-symbols; it is now forbidden. Furthermore, every multi-symbol's symbol list must contain two symbols at least and all multi-symbols need to have different definitions. The output format of the commands "ma-file", "sa-file" and "ga..." can be configured. The commands "format" and "unknown" have been introduced for this purpose. The condition "capital(string)" now tests whether "string" starts with a capital letter. In rule files, global constants can be defined by definitions of the form "@const := CONSTANT". Constants can only be defined outside of rules; they are valid throughout the rule file. The comparison operators "greater", "less_equal" and "greater_equal" compare floating point numbers (like "less"). In Malaga Emacs mode, the mode-line now also includes the name of the project file that is being used. mallex now can also generate readable lexicon files in batch mode, use the command line option "-readable". The lexicon file will then be printed on the standard output stream. Analysis statistics are now printed on the standard output stream. = End of file. ================================================================ malaga-7.12/GPL.txt0000644000175000017500000004312710224725217013401 0ustar bjoernbjoern GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. malaga-7.12/INSTALL.txt0000644000175000017500000000560610761577212014073 0ustar bjoernbjoern INSTALLATION GUIDE TO MALAGA 7.12 (C) 1996 Bjoern Beutel Malaga should be easily portable to nearly every POSIX system on which an ISO-C90-Compiler is running. Malaga is available as a ".tgz" (GNU tar + GNU zip) archive. For extraction in POSIX systems, you need to have GNU tar, version 1.11.2 or later, installed. It is freely available from . Malaga uses Unicode support routines from GLib, so you need to have GLib, version 2.0 or later, installed on your computer system. You can get GLib for free from . For the GUI-based display of analysis data, you need to have GTK+, version 2.8 or later, installed on your computer system. You can get GTK+ for free from . In the source distribution, the documentation is included as a Texinfo file. You'll need GNU Texinfo, version 4.0 or later, to translate it to DVI or HTML. If you want to translate it to DVI, you'll also need TeX on your computer. The Info files are already included. You can get GNU Texinfo for free from . There is a Malaga interface to the editor Emacs, "malaga.el", written in Emacs Lisp. It provides "malaga-mode" that supports editing Malaga grammar files, "malaga-project-mode" that supports editing Malaga project files, and "malaga-process-mode", a mode for interactive work with "malaga" and "mallex" that also supports debugging. You can get GNU Emacs for free from and XEmacs from . = Installing the Malaga Source Distribution on POSIX systems =================== 1. All the files you need to install Malaga are stored in a file called "malaga-7.12.tgz". Move to the directory where you want tho create the Malaga directory, copy the file "malaga-7.12.tgz" to this directory and enter the following commands to unpack the original files: tar zxf malaga-7.12.tgz You will now discover a new directory "malaga-7.12" which contains all directories and files you need. 2. Change to the directory "malaga-7.12" and enter "./configure". Malaga will be configured for your system. 3. Enter "make". The source files will be compiled and the executables will be linked. 4. Enter "make install". The executables, the Malaga library, the Malaga header file and the Malaga Info files will be installed. You'll probably need to be in supervisor mode to have write access to the directories concerned. 5. If you are using Emacs, add the line (require 'malaga ".../malaga-7.12/malaga.el") to the file ".emacs" in your home directory, so the Malaga extensions will be loaded automatically if you are starting Emacs. (Use the absolute path for ".../malaga-7.12".) 6. Make sure that your terminal program (or Emacs) is using the UTF-8 character set. = End of file ================================================================= malaga-7.12/README.txt0000644000175000017500000001551610761577124013725 0ustar bjoernbjoern MALAGA VERSION 7 Copyright (C) 1996 Bjoern Beutel This is Malaga, a software package for the development and application of grammars that are used for the analysis of words and sentences of natural languages. It is a language-independent system that offers a programming language for the modelling of the language-dependent grammatical information. This language is also called Malaga. Malaga is based on the grammatical theory of the "Left Associative Grammar" (LAG), developed by Roland Hausser, professor for Computational Linguistics at University of Erlangen, Germany. You can get the latest infos about Malaga on the Malaga homepage, at . = Legal Status of Malaga ====================================================== Malaga is free software; you may 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, as published by the Free Software Foundation. Malaga 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. A copy of the GNU General Public License, version 2, should be in "GPL.txt"; if not, you may download it from http://www.fsf.org. = Requirements ================================================================ Malaga should be easily portable to nearly every POSIX system on which an ANSI/ISO-C-Compiler is running, and which supports the Unicode UTF-8 format. Older versions also ran on Win32 systems; this is no longer supported by the author, but may still work. Malaga is available as a ".tgz" (GNU tar + GNU zip) archive. For extraction in POSIX systems, you need to have GNU tar, version 1.11.2 or later, installed. It is freely available from . Malaga uses Unicode support routines from GLib, so you need to have GLib, version 2.0 or later, installed on your computer system. You can get GLib for free from . For the GUI-based display of analysis data, you need to have GTK+, version 2.8 or later, installed on your computer system. You can get GTK+ for free from . In the source distribution, the documentation is included as a Texinfo file. You'll need GNU Texinfo, version 4.0 or later, to translate it to DVI or HTML. The Info files are already included. You can get GNU Texinfo for free from . There is a Malaga interface to the editor Emacs, "malaga.el", written in Emacs Lisp. It provides "malaga-mode" that supports editing Malaga grammar files, "malaga-project-mode" that supports editing Malaga project files, and "malaga-process-mode", a mode for interactive work with "malaga" and "mallex" that also supports debugging. You can get GNU Emacs for free from and XEmacs from . = Directories and Files of the Malaga Package ================================= The Malaga distributions currently contain then following files and directories: "README.txt": This document. "GPL.txt": The GNU General Public License, version 2. "CHANGES.txt": Information about changes in the past and recent versions of the Malaga package. "INSTALL.txt": The installation guide. "*.c" / "*.h": The source text for the library "libmalaga" and for the programs "malaga", "mallex", "malrul", "malmake", "malshow", and "malsym". "configure", "config.guess", "config.sub", "install-sh", "ltmain.sh": Files needed for automatic configuration. "configure.in": The source file to create "configure" by means of GNU's "autoconf". You may need this if you modify the malaga source code. "Makefile.in": A file for the command "make" to create the executable files of Malaga automatically. This is converted to "Makefile" by "configure". "malaga.texi": The Texinfo documentation file for Malaga. "malaga.info*": The Info files for Malaga (online documentation) "malaga.el": An Emacs Lisp file which supports working with Malaga from Emacs. "grammars/": Some Malaga sample grammars. Each grammar has a project file (ending in ".pro"). If you want to test a grammar, change to the corresponding directory, enter the command "malmake PROJECT_FILE" to translate the grammar's source files into executables and finally start malaga by entering "malaga PROJECT_FILE". Do not forget to add the ending ".pro" to the project file name. If you are working with Emacs, and you have executed the Emacs Lisp file "malaga.el", you can translate a grammar by typing "M-x malmake" (then you'll be asked for the project file name), and you can test it by entering "M-x malaga" (enter the project file name again). There are several subdirectories for the sample grammars: "grammars/formal/": Some formal grammars that only differ in their morphology rule files (the files ending in ".mor"). They are: "same_count_with_noise.pro": A grammar for all words that consist of n "a"s and n "b"s behind and any number of "c"s spread in anywhere in the word. "choose_count.pro": A grammar for all words that consists of m "a"s, followed by n "b"s, followed by k "c"s, where k = m or k = n. "same_count_mixed.pro": A grammar for all non-empty words that consist of as many "a"s as "b"s. "max_count.pro": A grammar for all words that consists of k "a"s, followed by l "b"s, followed by m "c"s, where m = max{k, l}. "palindrome.pro": A grammar for all non-empty palindromes built of the letters "a", "b", "c", "d", and "e". "growing_blocks.pro": A grammar for all words that consist of alternating blocks of "a"s and "b"s, where each block must be as least as long as the one before. "quadratic.pro": A grammar for all words that consists of n^2 "a"s, where n may be any cardinal number. "repeat_word.pro": A grammar for all words that consist of a letter sequence built of "a", "b", "c", "d" and "e", and which is written twice. "grammars/german/": A syntax grammar named "german.pro" that recognises a small subset of German sentences. It uses a small full form lexicon. The directory also contains a file "sentences", which is a list of German sentences that are recognised by the grammar. The grammar also returns information about the sentence structure. The grammar can handle alternative valency frames, separate verb prefixes, perfekt forms, adverbial subclauses and some other features. "grammars/numeral/": The grammar "numeral.pro" recognises English numerals. It returns the numbers they stand for. = End of file ================================================================= malaga-7.12/malaga.texi0000644000175000017500000051330010761600762014331 0ustar bjoernbjoern\input texinfo @c %**start of header @setfilename malaga.info @settitle Malaga 7.12 @c %**end of header @paragraphindent 0 @tex \parindent 0cm @end tex @c Makeinfo 4.7 does not create umlauts properly when translating to @c HTML, so we have to do it by hand. @c In TeX, macros containing a command which must be on a line by @c itself, such as a conditional, cannot be invoked in the middle of a line, @c so we must handle umlauts for TeX separately. @macro uuml @html ü @end html @ifinfo ue@c @end ifinfo @end macro @macro ouml @html ö @end html @ifinfo oe@c @end ifinfo @end macro @c Copyright (C) 1995 Bjoern Beutel. @dircategory Malaga - a Natural Language Analysis System @direntry * Malaga: (malaga). A Grammar Development Environment for Natural Languages. * malaga: (malaga)malaga. Analyse words/sentences using a Malaga grammar. * mallex: (malaga)mallex. Run allomorph rules on lexicon entries. * malmake: (malaga)malmake. Compile all files of a Malaga grammar. * malrul: (malaga)malrul. Compile a rule file of a Malaga grammar. * malsym: (malaga)malsym. Compile a symbol file of a Malaga grammar. @end direntry @c ---------------------------------------------------------------------------- @titlepage @title Malaga 7.12 @subtitle User's and Programmer's Manual @author Bj@"orn Beutel @page @vskip 0pt plus 1 filll Copyright @copyright{} 1995 Bj@"orn Beutel. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation. @end titlepage @c ---------------------------------------------------------------------------- @ifhtml @node Top, Contents, (dir), (dir) @end ifhtml @ifinfo @node Top, Introduction, (dir), (dir) @majorheading Malaga 7.12 @end ifinfo @ifnottex This is the documentation for Malaga, a software package for the development and application of grammars that are used for the analysis of words and sentences of natural languages. Copyright @copyright{} 1995 Bj@ouml{}rn Beutel. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation. @end ifnottex @menu @ifhtml * Contents:: Table of Contents. @end ifhtml * Introduction:: What is Malaga? * Formalism:: The grammar formalism used by Malaga. * The Programs:: Invoking @code{malaga} and its friends. * Commands:: Interactive commands for @code{malaga} and @code{mallex}. * Options:: Interactive options for @code{malaga} and @code{mallex}. * The Language:: Definition of the Programming Language Malaga. * Index:: The Index. @end menu @c ---------------------------------------------------------------------------- @ifnotinfo @node Contents, Introduction, Top, Top @contents @end ifnotinfo @c ---------------------------------------------------------------------------- @ifnotinfo @node Introduction, Formalism, Contents, Top @end ifnotinfo @ifinfo @node Introduction, Formalism, Top, Top @end ifinfo @chapter Introduction The Name ``Malaga'' is used with two different meanings: on the one hand, it is the name of a special purpose programming language, namely a language to implement grammars for natural languages. On the other hand, it is the name of a program package for development of Malaga Grammars and testing them by analysing words and sentences. ``Malaga'' is an acronym for ``@b{M}erely @b{a} @b{L}eft-@b{A}ssociative @b{G}rammar @b{A}pplication''. @ifnottex The program package ``Malaga'' has been developed by Bj@ouml{}rn Beutel. @cindex Beutel, Bj@ouml{}rn Gerald Sch@uuml{}ller @cindex Sch@uuml{}ller, Gerald @end ifnottex @iftex The program package ``Malaga'' has been developed by Bj@"orn Beutel. @cindex Beutel, Bj@"orn Gerald Sch@"uller @cindex Sch@"uller, Gerald @end iftex has implemented parts of the debugger, parts of the Emacs Malaga mode, and the original Tree and Variable output via TCL/Tk. So far, morphology grammars for several natural languages have been developed with Malaga, including the Albanian, Bulgarian, English, Finnish, German, Italian, Korean and Spanish language. @c ---------------------------------------------------------------------------- @node Formalism, The Programs, Introduction, Top @chapter Malaga's Grammar Formalism @cindex Formalism @cindex LAG A formal grammar for a natural language can be used to check whether a sentence or a word form is grammatically well-formed (a word form is a special inflectional form of a word, so ``book'' and ``books'' are two different word forms of the word ``book''). Furthermore, a grammar can describe the structure and meaning of a sentence or a word form by a data structure that has been constructed during the analysis process. Malaga is using a formalism that is derived of the Left-Associative Grammar (LAG), which has been developed by Roland Hausser. An LAG analyses a sentence (or a word form) step by step: its parts are concatenated from the left to the right, hence the name ``Left-Associative Grammar''. A single LAG rule can only join two parts to a bigger one: it concatenates the state part (which is the beginning of the sentence or word form that has already been analysed) and the link part (which is the next word form or the next allomorph). In contrast to LAG, Malaga's formalism already reads in the first part of a word form or of a sentence by applying a rule. Take a look at the following sentence: @quotation Shakespeare liked writing comedies. @end quotation The sentence is being analysed by five rule applications: @quotation ``'' + ``Shakespeare'' @* ``Shakespeare'' + ``liked'' @* ``Shakespeare liked'' + ``writing'' @* ``Shakespeare liked writing'' + ``comedies'' @* ``Shakespeare liked writing comedies'' + ``.'' @* @end quotation To apply a rule it's not sufficient to know the spelling of a word or an allomorph. A rule also requires morphological and syntactic information, such as word class, gender, meaning of a suffix etc. This information, which is associated with an element of an utterance, like a sentence, a word form or an allomorph, is called its @dfn{feature structure}. The analysis of a sentence or a word form returns such a feature structure as result. Now let us take a closer look at how a sentence is analysed. @enumerate @item Before we can start to analyse a sentence, the analysis automaton must be in an @dfn{initial state}. The initial state includes: @itemize @bullet @item a feature structure for that state, and @item the @dfn{combination rule} checking whether it is allowed to start with a specific word form. This rule also builds the feature structure of the successor state (whose surface consists of the first word form). @end itemize @item The next word form that is going to be added is read and analysed morphologically. If there is no valid word form, the analysis process aborts. @item The feature structure that morphology assigns to this word form is called the link's feature structure. The feature structure of the input that has been analysed syntactically so far is called the state's feature structure. @item The active combination rule checks whether it is allowed to combine the state's surface (which may be empty if the rule is operating on the initial state) with the link, i.e., the next word form. The combination rule takes the feature structures of the state and of the link as parameters. They can be compared by logical tests, and finally the feature structure of the successor state (whose surface includes the word form that has been read), is constructed by the rule. The rule also specifies which @dfn{successor rule} is active in the successor state. Execution then continues at step 2. Instead of specifying a successor rule, a rule can also @emph{accept} the analysed sentence. In that case, the feature structure of the successor state will be used as the feature structure of the complete analysed sentence. @end enumerate Morphological analysis operates analogously, except that a word form, composed from allomorphs, is being analysed. The link (step 2) is found in the allomorph lexicon. This sketch is of course simplified. There can be ambiguities in an analysis, induced by several causes: @itemize @bullet @item The initial state may contain several rules to analyse the first word form or allomorph. @item A rule may have multiple successor rules. @item In morphology, the continuation of the input may match several trie entries. @item In syntax analysis, the link may be assigned several feature structures by morphology. @end itemize These ambiguities are coped with by dividing the analysis into several subanalyses: if there are two lexicon entries for a word form, for example, the analysis continues using the first entry (and its feature structure) as well as the second one. You can compare this with a branching path. The analyses will be continued independently of each other. So, one analysis path can accept the input while the other fails. Each analysis path can divide repeatedly when other ambiguities are met. If several analysis paths are continued until they accept, the analysis process returns more than one result. @c ---------------------------------------------------------------------------- @node The Programs, Commands, Formalism, Top @chapter The Malaga Programs The Malaga programs are all started in a similar manner: either you give the name of a @dfn{project file} as argument (this is not possible if you start @code{malrul} or @code{malsym}), or you give the name of the files that are needed by the program (for @code{malmake} and @code{malaga}, you have to give the project file as argument). The file type is recognised by the file name ending. Assume you've written a grammar that consists of a symbol file @file{english.sym}, an allomorph rule file @file{english.all}, a lexicon file @file{english.lex} and a morphology rule file @file{english.mor}, and you have also written a project file @file{english.pro}. You first have to create binary files from these files: @example malmake english.pro @end example The source files must be in the Unicode UTF-8 format, which is also used for input and output by the Malaga programs. The binary files have the same name as their source counterparts, but have a @file{_l} (for little endian processors like x86), a @file{_b} (for big endian processors like HPPA) or a @file{_c} (for other architectures) appended. Now you can start the program @code{malaga} by entering the following command line: @code{malaga english.pro}. The names of the grammar files will be read from the project file. If you want to know about the command line arguments of a Malaga program, you can get help by using the option @samp{-help} or @samp{-h}, like @code{mallex -help} @cindex @code{help} (command line option) If you just want to know which version of a Malaga program you are using, you can get the version number by using the option @samp{-version} or @samp{-v}, like @code{malrul -version} @cindex @code{version} (command line option) The program just emits a few lines with information about its version number and about using and copying it. @menu * Projects:: Describing the parts of a Malaga grammar. * Profiles:: Settings for @code{malaga}, @code{mallex} and @code{malshow}. * malaga:: Analysing words and sentences. * mallex:: Generating and debugging the allomorph lexicon. * malmake:: Controlling the compilation of a Malaga grammar. * malrul:: Compiling a Malaga rule file. * malsym:: Compiling a Malaga symbol file. @end menu @c ---------------------------------------------------------------------------- @node Projects, Profiles, The Programs, The Programs @section Projects @cindex projects A couple of files, taken together, form a Malaga grammar: @table @asis @item The @dfn{lexicon file} (@file{.lex}) A lexicon of base forms. @item The @dfn{prelex file} (@file{.prelex}, optional) A precompiled lexicon in binary format. @item The @dfn{allomorph rule file} (@file{.all}) A file with rules which generate the allomorphs of the base forms. @item The @dfn{morphology rule file} (@file{.mor}) A file with rules which combine allomorphs to word forms. @item The @dfn{symbol file} (@file{.sym}) A file with the symbols that may be used in rules and feature structures. @item The @dfn{syntax rule file} (@file{.syn}, optional) A file with rules that combine word forms to sentences. @item The @dfn{extended symbol file} (@file{.esym}, optional) A file with additional symbols that may only be used in a syntax rule file. @end table You can group these files together to a @dfn{project}. To do this, you have to write a project file, with a name ending in @file{.pro}, in which you list the names of the several files, each one behind a keyword (each file type in a line on its own). Imagine you have written a grammar that consists of the files @file{standard.sym}, @file{webster.lex}, @file{english.all}, @file{english.mor}, and @file{english.syn}. The project file for this grammar will look like this: @example sym: standard.sym lex: webster.lex all: english.all mor: english.mor syn: english.syn @end example In your source files, you can include further source files by using the @code{include} statement; so a binary file of your grammar may be dependent on several source files. The program @code{malmake} uses the information in the project file to check for dependencies between source files and binaries, so the project file must contain the name of all source files for a specific binary. Relative path names are always relative to the directory of the project file. Assume, you've got a lexicon file @file{webster.lex} that looks like this: @example include "suffixes.lex"; include "verbs.lex"; include "adjectives.lex"; include "nouns.lex"; include "particles.lex"; include "abbreviations.lex"; include "names.lex"; include "numbers.lex"; @end example In this case, you must write the names of all these files in the @samp{lex:} line of your project file behind the name of the real lexicon file: @example lex: webster.lex suffixes.lex verbs.lex adjectives.lex lex: nouns.lex particles.lex abbreviations.lex names.lex numbers.lex @end example Since there is a number of files in this example, the @samp{lex:} line has been divided into two lines, each line starting with @samp{lex:}. If you want to extend an existing project (for example, you might want to add a syntax rule file to a morphology grammar), you can include the project file of the morphology grammar in the project file of your syntax grammar by using a line starting with @samp{include:}: @example include: /projects/grammars/english/english.pro syn: english-syntax.syn @end example The file entries in the project file of the morphology are treated as if they would replace the @samp{include:} line. Relative paths in the included file are relative to the @emph{included} directory, not the @emph{including} directory. The programs @code{malaga} and @code{mallex} can set options like @code{hidden} or @code{robust} from the project file, so you do not need to set these options each time you start @code{malaga}. Each line in the project file that starts with @samp{malaga:} and @samp{mallex:}, respectively, will be executed when @code{malaga} and @code{mallex}, respectively, has been started, but you may only use the @code{set} command, so you can only set options in the project file. Here is an example: @example ... malaga: set hidden +semantics malaga: set robust-rule on mallex: set hidden +semantics +syntax ... @end example When you start @code{malaga}, the commands @code{set hidden +semantics} and @code{set robust-rule on} will be executed; when you start @code{mallex}, the command @code{set hidden +semantics +syntax} will be executed. Options in project files that are read in by @samp{include:} lines in other project files will be executed as if they were in place of the @samp{include:} line. Lines in project files that start with @samp{info:} contain information about the grammar. In @code{malaga}, you get this information if you use the command @code{info}. Example: @example info: ===================================== info: Deutsche Malaga Morphologie 3.0 info: written by Oliver Lorenz, 11.04.1997 info: ===================================== @end example @cindex Hangul The Korean writing system, Hangul, needs special treatment, because the characters it uses are syllables that must be split up into individual letters for morphological analysis. Such a conversion is built-in into malaga. To activate this Hangul support, insert the following line into your project file: @example split-hangul-syllables: yes @end example @cindex @code{split-hangul-syllables} If Hangul support has been switch on, you may also enter Hangul text in a Latin transcription that is based on the Yale transcription. Transcribed text must be contained in curly brackets, and each syllable must start with a dot, for example @samp{@{.cwess.ta@}}. Malaga can also display Hangul text in Latin transcription if Hangul support has been activated. This can be controlled by the option @code{roman-hangul}. When Malaga splits Hangul syllables, you must be aware that string operations work with Hangul letters, even if you have entered syllables in you grammar source code: @itemize @bullet @item In a pattern, a character class that contains a syllable will match each single Hangul letter that is part of that syllable. Only use single letters in character classes. If you want to select between different syllables, use alternatives, separated by vertical bars. @item In a pattern, when a postfix operator (@samp{*}, @samp{?}, or @samp{+}) follows a Hangul syllable, it will only operate on the last letter of that syllable. If you want the operator to work on the whole syllable, put the syllable in parentheses. @item The functions @code{substring} and @code{length} will count single characters, not syllables. @end itemize @c ---------------------------------------------------------------------------- @node Profiles, malaga, Projects, The Programs @section The Malaga Profiles @file{.malagarc} or @file{malaga.ini} @cindex @code{.malagarc} (file) @cindex @code{malaga.ini} (file) @cindex profile If you prefer some options that you want to use with every Malaga project, you may create a personal profile. On POSIX systems, it is located in your home directory and is called @file{.malagarc}. In Microsoft Windows (NT based) systems, it is located in your user profile directory and is called @file{malaga.ini}. In Microsoft Windows (DOS based) systems, it is located in the root directory of your system drive and is also called @file{malaga.ini}. You can enter @code{malaga} and @code{mallex} options in the same manner as you do in the project file: @example malaga: set display-cmd "malshow" malaga: set use-display yes mallex: set display-cmd "malshow" mallex: set use-display yes @end example The settings in your personal profile override the settings in the project file. You can set some attributes of the graphical user interface @code{malshow}, like the position, the size, and the font size of each window that is opened by @code{malshow}. The following attributes are available: @table @code @item *_geometry: @cindex geometry @cindex window geometry Defines the size and/or position of a window. The ``*'' must be replaced by the name of the window, which may be @code{allomorphs}, @code{path}, @code{result}, @code{tree}, @code{variables}, or @code{expressions}. The attribute must be followed by an expression like @samp{628x480+640+512}. The first two numbers (@samp{628x480}) define the width and the height of the window in pixels, the last two numbers (@samp{+640+512}) define the position of its upper left corner. @item font: @cindex font family The attribute must be followed by the name of the font family to use. @item font_size: @cindex font size The attribute must be followed by an integer font size, given in points. The available font sizes are 8, 10, 12, 14, 18, and 24 points. @item show_indexes: @cindex indexes, state @cindex state indexes The attribute must be followed by @code{yes} or @code{no}, which determines whether state indexes are shown in the Tree and Path windows. @item hanging_style: The attribute must be followed by @code{yes} or @code{no}, which determines whether horizontally adjacent complex values are aligned at their top lines (@dfn{hanging style}) or at their bottom lines (@dfn{non-hanging style}). @item inline_path: The attribute must be followed by @code{yes} or @code{no}, which determines whether the components of a state or a link in a path will be arranged horizontally or vertically. For small feature-structures, e.g. in formal grammars, horizontal arrangement is better readable, while full-blown natural language grammar paths look better in vertical arrangement. @item show_tree: A three-valued attribute that determines which states of a tree are shown. Possible values are: @code{full}, @code{no_dead_ends} and @code{result_paths}. @end table Here is an example which sets every option available: @example allomorphs_geometry: 628x480+640+0 path_geometry: 628x480+640+0 result_geometry: 628x480+640+0 tree_geometry: 628x480+640+512 variables_geometry: 628x480+640+512 expressions_geometry: 628x480+640+0 font: helvetica font_size: 12 show_indexes: yes hanging_style: yes inline_path: yes show_tree: no_dead_ends @end example @c ---------------------------------------------------------------------------- @node malaga, mallex, Profiles, The Programs @section The Program @code{malaga} @cindex @code{malaga} (program) The program @code{malaga} is the user interface for analysing word forms and sentences, displaying the results and finding bugs in a grammar. Start @code{malaga} with the name of a project file as argument: @example malaga english.pro @end example When @code{malaga} has been started, it loads the symbol file, the lexicon file and the morphology rule file, and the syntax rule file, if there is one. After loading, the @dfn{prompt} appears. Then @code{malaga} is ready to execute your commands: @cartouche @example $ malaga english.pro This is malaga, version 7.12. Copyright (C) 1995 Bjoern Beutel. This program is part of Malaga, a system for Natural Language Analysis. You can distribute it under the terms of the GNU General Public License. malaga> @end example @end cartouche You can now enter any @code{malaga} command. If you are not sure about the name of a command, use the command @code{help} to get an overview of all @code{malaga} commands. If you want to quit @code{malaga}, enter the command @code{quit}. You can use the following command line options when you start @code{malaga}: @table @asis @item @samp{-morphology} or @samp{-m} @cindex @code{morphology} (command line option) Starts @code{malaga} in @dfn{morphology mode}. That is, word forms are being read in from the standard input stream and analysed (one word form per line). The analysis result is being written to the standard output stream. @item @samp{-syntax} or @samp{-s} @cindex @code{syntax} (command line option) Starts @code{malaga} in @dfn{syntax mode}. That is, sentences are being read in from the standard input stream and analysed (one sentence per line). The analysis result is being written to the standard output stream. @item @samp{-quoted} or @samp{-q} @cindex @code{quoted} (command line option) When @code{malaga} has been started in syntax or morphology mode, and the option @samp{-quoted} has been used, then each input line must be enclosed in double quotes which are removed prior to analysis. Within the double quotes there may be any combination of printable characters except the backslash @samp{\} and the double quotes. These characters must be preceded by a @samp{\} (escape character). @item @samp{-input} or @samp{-i} @cindex @code{input} (command line option) Starts @code{malaga} in @dfn{argument analysis mode}. That is, the argument following the @samp{-input} is being analysed. Either the @samp{-morphology} or the @samp{-syntax} option must also be given. The analysis result is being sent to the standard output stream in a structured format. @end table @c ---------------------------------------------------------------------------- @node mallex, malmake, malaga, The Programs @section The Program @code{mallex} @cindex @code{mallex} (program) By using @code{mallex}, you can make the allomorph rules process the entries of a base form lexicon. You can start @code{mallex} either with the name of a project file or with the names of the needed grammar files: @example mallex english.pro @end example or @example mallex english.sym english.all english.lex @end example If you are not using a project file, you must give @itemize @bullet @item the name of the symbol file (@file{.sym}), @item the name of the allomorph rule file (@file{.all}), @item the name of the lexicon file (@file{.lex}, in batch mode), and @item the name of the prelex file (@file{.prelex}, in batch mode, optional). @end itemize Normally, @code{mallex} runs interactively: it loads the symbol file and the allomorph rule file. Then the @dfn{prompt} appears: @cartouche @example $ mallex english.pro This is mallex, version 7.12. Copyright (C) 1995 Bjoern Beutel. This program is part of Malaga, a system for Natural Language Analysis. You can distribute it under the terms of the GNU General Public License. mallex> @end example @end cartouche You can now enter any @code{mallex} command. If you do not remember the command names, you can use the command @code{help} to see an overview of the @code{mallex} commands. If you want to quit @code{mallex}, enter the command @code{quit}. If you have started @code{mallex} by using the option @samp{-binary} or @samp{-b}, it creates the run time lexicon file from the base form lexicon file and the optional prelex file. If the lexicons are very big or the allomorph rules are very complex, this can take some time. After creation, @code{mallex} exits. If you have started @code{mallex} by using the option @samp{-prelex} or @samp{-p}, it creates a precompiled lexicon file from the source lexicon file and the optional prelex file and exits. You can use the following command line options when you start @code{mallex}: @table @asis @item @samp{-binary} or @samp{-b} @cindex @code{binary} (command line option) Runs @code{mallex} in batch mode and creates the run-time lexicon. @item @samp{-readable} or @samp{-r} @cindex @code{readable} (command line option) Runs @code{mallex} in batch mode and outputs the allomorph lexicon in readable form on the standard output stream. @item @samp{-prelex} or @samp{-p} @cindex @code{prelex} (command line option) Runs @code{mallex} in batch mode, but doesn't apply the allomorph filter yet. Outputs the allomorph lexicon as a @file{.prelex} binary file. @end table @c ---------------------------------------------------------------------------- @node malmake, malrul, mallex, The Programs @section The Program @code{malmake} @cindex @code{malmake} (program) The program @code{malmake} reads a project file, checks if all grammar files needed do exist, and translates all grammar files that have not yet been translated or whose source files have changed since they have been translated. @code{malmake} itself calls the programs @code{malsym}, @code{mallex} and @code{malrul} if needed. An example: assume you have written a morphology grammar whose grammar files are bundled in a project file @file{english.pro}: @example sym: rules/english.sym all: rules/english.all lex: rules/english.lex lex/adjectives.lex lex: lex/particles.lex lex/suffixes.lex lex/verbs.lex lex: lex/nouns.lex lex/abbreviations.lex lex/numbers.lex mor: rules/english.mor mallex: set hidden +semantics +syntax malaga: set hidden +semantics @end example When executing @code{malmake dmm.pro} for the first time, the symbol file, the rule files and the lexicon file will be translated: @cartouche @example $ malmake dmm.pro compiling "dmm.sym" compiling "dmm.all" compiling "dmm.mor" compiling "dmm.lex" project is up to date $ @end example @end cartouche If you want all files to be recompiled on all accounts, use the option @file{-new} or @file{-n}. The translation of a big lexicon can take some minutes, since the allomorph rules have to be executed for each lexicon entry. @c ---------------------------------------------------------------------------- @node malrul, malsym, malmake, The Programs @section The Program @code{malrul} The program @code{malrul} translates Malaga rule files, i.e.@ files that have the endings @file{.all}, @file{.mor} or @file{.syn}. The compiled file gets the suffix @file{_l}, @file{_b}, or @file{_c}, depending on the endianness of your processor. Give the following arguments if you are starting @code{malrul}: @itemize @bullet @item the name of the rule file that is to be translated, and @item the name of the associated symbol file (@file{.sym} or @file{.esym}). @end itemize The order of the arguments is arbitrary. Here is an example: @example malrul english.mor english.sym @end example @c ---------------------------------------------------------------------------- @node malsym, , malrul, The Programs @section The Program @code{malsym} @code{malsym} can translate Malaga symbol files, i.e.@ files having the ending @file{.sym} or @file{.esym}. The translated file gets the suffix @file{_l}, @file{_b}, or @file{_c}, depending on the endianness of your processor. For example: @example malsym english.sym @end example If you are translating an extended symbol file with the ending @file{.esym}, enter the name of the compiled symbol file after the command line option @file{-use} or @file{-u}: @example malsym english.esym -use english.sym @end example This argument is needed since extended symbol files are extensions of ordinary symbol files. If you use the command line option @samp{-split-hangul-syllables} when starting @code{malsym}, the symbol file and all the Malaga files that use it will split up Hangul syllables in individual letters internally. This option is invoked by @code{malmake} if the project file contains the line @samp{split-hangul-syllables: yes}. @c ---------------------------------------------------------------------------- @node Commands, Options, The Programs, Top @chapter The Commands of @code{malaga} and @code{mallex} @cindex commands Since the user interfaces of @code{malaga} and @code{mallex} are very similar and since they have a bunch of commands in common, I will describe them in a common chapter. Commands that can be used in @code{malaga} or in @code{mallex} only, are marked by the name of the program in which they can be used. @menu * backtrace:: Show where rule execution has stopped. * break:: Add a new breakpoint. * clear-cache:: Clear the word cache. * continue:: Continue execution up to next breakpoint. * debug-ga:: Debug Generating Allomorphs. * debug-ga-file:: Debug Generating Allomorphs from a file. * debug-ga-line:: Debug Generating Allomorphs from a single line in a file. * debug-ma:: Debug Morphology Analysis. * debug-ma-line:: Debug Morphology Analysis of a line in a file. * debug-sa:: Debug Syntax Analysis. * debug-sa-line:: Debug Syntax Analysis of a line in a file. * debug-state:: Debug rule execution at an analysis state. * delete:: Delete breakpoints. * down:: Show code position and variables in calling rule. * finish:: Continue execution up to return or path termination. * frame:: Show code position and variables of a frame. * ga:: Generate Allomorphs. * ga-file:: Generate Allomorphs from a file. * ga-line:: Generate Allomorphs from a single line in a file. * get:: Get current values of options. * help:: Get help about commands and options. * info:: Get info about current grammar. * list:: List current breakpoints. * ma:: Analyse a word. * ma-file:: Analyse words in a file. * ma-line:: Analyse a word at line in a file. * mg:: Generate words from allomorphs. * next:: Continue execution up to next line, skip subrules. * print:: Display a variable or constant or a part of it. * quit:: Quit @code{malaga} or @code{mallex}. * read-constants:: Read constant definitions in lexicon file. * result:: Show results. * run:: Continue execution up to the end. * sa:: Analyse a sentence. * sa-file:: Analyse sentences in a file. * sa-line:: Analyse a sentence at a line in a file. * set:: Set values of options. * sg:: Generate sentences from words. * step:: Continue execution up to next line, enter subrules. * transmit:: Send value to transmit process and display answer. * tree:: Display analysis tree. * up:: Show code position and variables in called rule. * variables:: Display current variables. * walk:: Execute until next rule. * where:: Show current analysis state. @end menu @c ---------------------------------------------------------------------------- @node backtrace, break, Commands, Commands @section The Command @code{backtrace} @cindex @code{backtrace} (command) If you are executing your rules in debug mode or the rules were interrupted by an error, this command shows where rule execution currently stopped. If it stopped in a subrule, all calling rules are also shown. The currently examined rule is marked with a @samp{*}: @cartouche @example debug> backtrace *2: "dmm.mor", line 1218, rule "deletePOS" 1: "dmm.mor", line 31, rule "Start" debug> @end example @end cartouche This means, rule execution stopped in frame 2, line 1218 of @file{dmm.mor}, in rule @code{deletePOS}. This subrule was called from frame 1, line 31 in @file{dmm.mor}, in rule @code{Start}. @c ---------------------------------------------------------------------------- @node break, clear-cache, backtrace, Commands @section The Command @code{break} @cindex @code{break} (command) @cindex breakpoints If you want to stop the rules at a specific point, for example to take a look at the variables, you can use the command @code{break} to set @dfn{breakpoints}. A breakpoint is a point in the rule source text where rule execution is interrupted, so you can enter commands in debug mode. Breakpoints are only active in debug mode, this means you have started rule execution by a debug command or you have continued rule execution by one of the commands @code{step}, @code{next}, @code{walk}, or @code{continue}. Behind the command name, @code{break}, you can give one of the following arguments: @table @asis @item A line number. A breakpoint is set at this line in the current source file. If there is no statement starting at this line, the breakpoint will be set at the nearest line where a statement starts. You can, for example, set a breakpoint at line 245 in the current source file by entering the command @example break 245 @end example @item A file name and a line number. A breakpoint is set at this line in this file. If there is no statement starting at this line, the breakpoint will be set at the nearest line where a statement starts. An example: @example break english.syn 59 @end example @item A rule name. A breakpoint is set at the first statement in this rule. An example: @example break final_rule @end example @end table If the rule name or the file name is ambiguous, you can insert an abbreviation for the rule system you refer to. Put it in front of the rule name or the file name. The following abbreviations are used: @itemize @bullet @item @samp{all} for allomorph rules, @item @samp{mor} for morphology rules, @item @samp{syn} for syntax rules, @end itemize If you omit any argument, the breakpoint is set on the current line in the current file (this is helpful in debug mode). Every breakpoint gets a unique number once it has been set, so you can delete it later, when you do not need it any longer. You can list the breakpoints using the command @code{list} and delete them using @code{delete}. @c ---------------------------------------------------------------------------- @node clear-cache, continue, break, Commands @section The Command @code{clear-cache} (@code{malaga}) @cindex @code{clear-cache} (@code{malaga} command) If you have changed your settings so that the wordform cache is no longer valid, you can clear the cache using @code{clear-cache}. This can be necessary if you have turned on/off input or output filters or modified switches. @c ---------------------------------------------------------------------------- @node continue, debug-ga, clear-cache, Commands @section The Command @code{continue} @cindex @code{continue} (command) This command can only be executed in debug mode. It resumes rule execution and may be followed by: @table @emph @item Nothing. Rule execution is continued until a breakpoint is met or the rules have been executed completely. @item A line number. Rule execution is continued until a breakpoint is met, the rules have been executed completely or the given line in the current source file is met. If there is no statement starting at this line, execution will be stopped at the nearest line where a statement starts. You can, for example, continue execution until line 245 in the current source file is met by entering the command @example continue 245 @end example @item A file name and a line number. Rule execution is continued until a breakpoint is met, the rules have been executed completely or the given line in the given file is met. If there is no statement starting at this line, execution will be stopped at the nearest line where a statement starts. An example: @example continue english.syn 59 @end example @item A rule name. Rule execution is continued until a breakpoint is met, the rules have been executed completely or the first statement of the given rule is met. An example: @example continue final_rule @end example @item A comparison. The comparison must be of the form @code{@var{variable} = @var{value}}, where @var{variable} may be any variable name, maybe followed by a path, and @var{value} may be any Malaga value. Rule execution is continued until a breakpoint is met, the rules have been executed completely or until @var{variable} is defined and its value is @var{value}. @end table @c ---------------------------------------------------------------------------- @node debug-ga, debug-ga-file, continue, Commands @section The Command @code{debug-ga} (@code{mallex}) @cindex @code{debug-ga} (@code{mallex} command) Use @code{debug-ga} to find errors in your allomorph rules. This command works like @code{ga}, but the allomorph generation will be stopped before the first statement of the first rule is executed: @cartouche @example mallex> debug-ga [surface: "john", class: name] at rule "irregular_verb" debug> @end example @end cartouche The prompt @samp{debug>} that appears instead of @samp{mallex>} indicates that @code{mallex} is currently executing the allomorph rules but has been interrupted. Since this ability has been developed to support the @emph{debugging} of Malaga rules, this mode is called @dfn{debug mode}. When @code{mallex} arrives at the start of a new rule in debug mode (as in the example above), the name of this rule is displayed. When in debug mode, you can always get the name of the current rule using the command @code{rule}. If you're running @code{mallex} from Emacs, another Emacs window will display the source file. An arrow is used to show to the statement that will be executed next. @cartouche @example ... allo_rule irregular_verb ($entry): =>? $entry.class = verb; ... @end example @end cartouche In debug mode, you can, for example, get the variables that are currently defined (using @code{variable} or @code{print}), and you can execute statements (using @code{step}, @code{next}, @code{walk}, @code{continue}, or @code{run}). If you want to quit the debug mode, just enter @code{run}. The remaining statements for generation will then be executed without interruption. @c ---------------------------------------------------------------------------- @node debug-ga-file, debug-ga-line, debug-ga, Commands @section The Command @code{debug-ga-file} (@code{mallex}) @cindex @code{debug-ga-file} (@code{mallex} command) Use the command @code{debug-ga-file} to make the allomorph rules work on a lexicon file in debug mode. Assume you have written a lexicon file @file{mini.lex}: @example [surface: "m@{a@}n", class: noun]; [surface: "table", class: noun]; [surface: "wise", class: adjective]; @end example To let the rules process this lexicon in debug mode, enter: @example debug-ga-file mini.lex @end example @c ---------------------------------------------------------------------------- @node debug-ga-line, debug-ma, debug-ga-file, Commands @section The Command @code{debug-ga-line} (@code{mallex}) @cindex @code{debug-ga-line} (@code{mallex} command) Use the command @code{debug-ga-line} to make the allomorph rules generate allomorphs for a single lexicon entry in debug mode. Assume you want to test the second line in the lexicon file @file{mini.lex}: @example [surface: "m@{a@}n", class: noun]; [surface: "table", class: noun]; [surface: "wise", class: adjective]; @end example Enter the following line: @example debug-ga-line mini.lex 2 @end example Then @code{mallex} stops in debug mode at the entry of the first allomorph rule that is being executed for the lexicon entry @example [surface: "table", class:noun]; @end example If there is no lexicon entry at this line, the subsequent lexicon entry will be taken. @c ---------------------------------------------------------------------------- @node debug-ma, debug-ma-line, debug-ga-line, Commands @section The Command @code{debug-ma} (@code{malaga}) @cindex @code{debug-ma} (@code{malaga} command) Use the command @code{debug-ma} to find errors in your morphology combination rules. This command analyses the rest of the command line morphologically and executes the morphology combination rules in debug mode. Debug mode is explained for the command @code{debug-ga}. @c ---------------------------------------------------------------------------- @node debug-ma-line, debug-sa, debug-ma, Commands @section The Command @code{debug-ma-line} (@code{malaga}) @cindex @code{debug-ma-line} (@code{malaga} command) Use the command @code{debug-ma-line} to find errors in your morphology combination rules. This command analyses the rest of the command line morphologically and executes the morphology combination rules in debug mode. Debug mode is explained for the command @code{debug-ga}. @c ---------------------------------------------------------------------------- @node debug-sa, debug-sa-line, debug-ma-line, Commands @section The Command @code{debug-sa} (@code{malaga}) @cindex @code{debug-sa} (@code{malaga} command) Use the command @code{debug-sa} to find errors in your syntax combination rules. This command analyses the rest of the command line syntactically and executes the syntax combination rules in debug mode. Debug mode is explained for the command @code{debug-ga}. @c ---------------------------------------------------------------------------- @node debug-sa-line, debug-state, debug-sa, Commands @section The Command @code{debug-sa-line} (@code{malaga}) @cindex @code{debug-sa-line} (@code{malaga} command) Use the command @code{debug-sa-line} to find errors in your syntax combination rules. This command analyses the rest of the command line morphologically and executes the morphology combination rules in debug mode. Debug mode is explained for the command @code{debug-ga}. @c ---------------------------------------------------------------------------- @node debug-state, delete, debug-sa-line, Commands @section The Command @code{debug-state} (@code{malaga}) @cindex @code{debug-state} (@code{malaga} command) Use the command @code{debug-state} to execute the successor rules of a specific LAG state in debug mode. Previously, you must have already analysed a word or a sentence, respectively. Let malaga display the analysis tree by entering @code{tree}, move the mouse pointer over the state you want to debug, and press the left mouse button. A window opens in which this state's feature structure is shown. The window's title line contains the index of the state. Use this number as argument for @code{debug-state}. The last analysis input will be analysed again, and analysis stops when reaching the first successor rule of the specified state and malaga switches to debug mode. Debug mode is explained for the command @code{debug-ga}. @c ---------------------------------------------------------------------------- @node delete, down, debug-state, Commands @section The Command @code{delete} @cindex @code{delete} (command) If you want to delete a breakpoint, use the command @code{delete} with the number of the breakpoints as argument. Enter @samp{delete all} to delete all breakpoints. @c ---------------------------------------------------------------------------- @node down, finish, delete, Commands @section The Command @code{down} @cindex @code{down} (command) If you want to look at the source and the variables of the (sub)rule that is currently being called by the current subrule, you can do this by entering @code{down}. You can list the frames via @code{backtrace}. @c ---------------------------------------------------------------------------- @node finish, frame, down, Commands @section The Command @code{finish} @cindex @code{finish} (command) This command can only be executed in debug mode. The rule execution will be resumed and continues until a @code{return} statement is met or until the current rule path will be terminated. @c ---------------------------------------------------------------------------- @node frame, ga, finish, Commands @section The Command @code{frame} @cindex @code{frame} (command) If you want to look at the source and the variables of a (sub)rule that has called the current subrule, directly or indirectly, you can do this by typing @code{frame} and the number of the frame you want to examine. You can list the frames via @code{backtrace}. @c ---------------------------------------------------------------------------- @node ga, ga-file, frame, Commands @section The Command @code{ga} (@code{mallex}) @cindex @code{ga} (@code{mallex} command) Use the command @code{ga} (short for @emph{generate allomorphs}) to generate allomorphs. This is useful for testing allomorph generation from within @code{mallex}. When you enter the command, give a lexicon entry as argument. All allomorphs that are generated from this entry by the allomorph rules, are displayed on screen. For example: @cartouche @example mallex> ga [Lemma: "!", POS: Punctuation, Type: ExclamationMark] "!": [POS: , Punctuation: <[Allomorph: "!", BaseForm: "!", concatStem: no, concatSx: no, POS: Punctuation, Type: ExclamationMark, terminal: yes]>, Surface: "!"] mallex> @end example @end cartouche If the rules create multiple allomorphs from an entry, they are displayed one after another. @c ---------------------------------------------------------------------------- @node ga-file, ga-line, ga, Commands @section The Command @code{ga-file} (@code{mallex}) @cindex @code{ga-file} (@code{mallex} command) Use the command @code{ga-file} to make the allomorph rules generate allomorphs for a lexicon file. Assume you have written a lexicon file @file{mini.lex}: @example [surface: "m@{a@}n", class: noun]; [surface: "table", class: noun]; [surface: "wise", class: adjective]; @end example To generate the allomorphs for this lexicon, enter @samp{ga-file mini.lex}. This will produce a readable allomorph file whose name ends in @file{.out}; for @file{mini.lex} its name will be @file{mini.lex.out}: @example "man": [class: noun, syn: singular] "men": [class: noun, syn: plural] "table": [class: noun] "wise": [class: adjective, restr: complete] "wis": [class: adjective, restr: inflect] @end example @c ---------------------------------------------------------------------------- @node ga-line, get, ga-file, Commands @section The Command @code{ga-line} (@code{mallex}) @cindex @code{ga-line} (@code{mallex} command) Use the command @code{ga-line} to make the allomorph rules generate allomorphs for a single lexicon entry. Assume you want to test the second line in the lexicon file @file{mini.lex}: @example [surface: "m@{a@}n", class: noun]; [surface: "table", class: noun]; [surface: "wise", class: adjective]; @end example Enter the following line: @example ga-line mini.lex 2 @end example Then @code{mallex} generates allomorphs for @code{[surface: "table", class:noun];}. If there is no lexicon entry at this line, the subsequent lexicon entry will be taken. @c ---------------------------------------------------------------------------- @node get, help, ga-line, Commands @section The Command @code{get} @cindex @code{get} (command) This command is used to query settings of @code{malaga} or @code{mallex}. Enter it together with the name of the option whose setting you want to know. The possible options are described in the next chapter. If you just enter @samp{get}, all settings will be shown. @c ---------------------------------------------------------------------------- @node help, info, get, Commands @section The Command @code{help} @cindex @code{help} (command) Use this command to get a list of the commands you can use. If you give the name of a command or an option as argument, a short explanation of this item will be displayed. If a name represents a command as well as an option, prepend @samp{command} or @samp{option} to it. @c ---------------------------------------------------------------------------- @node info, list, help, Commands @section The Command @code{info} (@code{malaga}) @cindex @code{info} (@code{malaga} command) This command gives you information about the grammar you are using. It takes no argument. @c ---------------------------------------------------------------------------- @node list, ma, info, Commands @section The Command @code{list} @cindex @code{list} (command) If you enter the command @code{list}, all breakpoints are listed. For each breakpoint, its number, the name of the source file and the source line is shown. @c ---------------------------------------------------------------------------- @node ma, ma-file, list, Commands @section The Command @code{ma} (@code{malaga}) @cindex @code{ma} (@code{malaga} command) The command @code{ma} (for @emph{morphological analysis}) starts a word form analysis. Give the word form that you want to be analysed as argument: @example ma house @end example Malaga will show the results automatically, and it will also show the analysis tree automatically if you specified it using the @code{auto-tree} option. You can look at the results using @code{result} or at the entire analysis tree using @code{tree}. If you do not enter a word form behind the command @code{ma}, @code{malaga} re-analyses the last input. @c ---------------------------------------------------------------------------- @node ma-file, ma-line, ma, Commands @section The Command @code{ma-file} (@code{malaga}) @cindex @code{ma-file} (@code{malaga} command) The command @code{ma-file} can be used to analyse files that contain word lists. A word list consists of a number of word forms, each word form on a line on its own. There may be empty lines in a word list. The following example is a word list called @file{word-list}: @example table men's blue handicap @end example To analyse this word list, enter: @example ma-file word-list result @end example This will produce a file @file{result} that contains the analysis results. If the second argument is missing, the result will be written to a file whose name ends in @file{.out}; for @file{word-list}, its name will be @file{word-list.out}: @example 1: "table": [class: noun, ...] 2: "men's": [class: noun, ...] 3: "blue": [class: noun, ...] 3: "blue": [class: adjective, ...] 3: "blue": [class: name, ...] 4: "handicap: unknown @end example The number at the line start represents the line number of the analysed original word form. The output format can be changed by using the options @code{result-format} and @code{unknown-format}. If a runtime error occurs during the analysis of a word, the line will be output in the format given by the option @code{error-format}. After the analysis, some statistics will be displayed: @itemize @bullet @item The number of analysed word forms. @item The number of recognised word forms. @item The number of word forms recognised by combi-rules and end-rules. @item The number of word forms recognised by robust-rules. @item The number of word forms whose analyses produced errors. @item The average number of results per word form. @item The analysis run time. @item The average number of word forms that have been analysed per second. @item The number of cache accesses. @item The number of cache hits. @end itemize @c ---------------------------------------------------------------------------- @node ma-line, mg, ma-file, Commands @section The Command @code{ma-line} (@code{malaga}) @cindex @code{ma-line} (@code{malaga} command) You can use this command to analyse a single line in a text file morphologically. Assume you want to analyse the word in the third line in the file @file{words}. Then enter the following command: @example ma-line words 3 @end example Malaga will show the results automatically, and it will also show the analysis tree automatically if you specified it using the @code{auto-tree} option. You can look at the results using @code{result} or at the entire analysis tree using @code{tree}. @c ---------------------------------------------------------------------------- @node mg, next, ma-line, Commands @section The Command @code{mg} (@code{malaga}) @cindex @code{mg} (@code{malaga} command) Use the command @code{mg} to generate all word forms that consist of a specified set of allomorphs. For example, the command @example mg 3 un able believe @end example This generates all word forms that consist of up to three allomorphs, where only the specified allomorphs (@samp{un}, @samp{able}, and @samp{believe}) are used. The word forms are numbered from 1 onward, but different analyses of the same word form get the same index. The output will look like this: @cartouche @example malaga> mg 3 un able believe 1: "able" 2: "believe" 3: "unable" 4: "unbelieveable" malaga> @end example @end cartouche Please note that generation does not know of filters, pruning rules and default rules. @c ---------------------------------------------------------------------------- @node next, print, mg, Commands @section The Command @code{next} @cindex @code{next} (command) This command can only be executed in debug mode. The rule execution will be resumed and continues until a different source line is met, a different path is going to be executed since the old one has terminated, or until the rules have been executed completely. It is like @code{step}, but subrules will be executed without interruption. If you specify a number as argument, the command will be repeated as often as specified. @c ---------------------------------------------------------------------------- @node print, quit, next, Commands @section The Command @code{print} @cindex @code{print} (command) The command @code{print} is used to display the current values of Malaga variables or named constants, or parts of them. You can specify any variable or constant names (including the @samp{$} or @samp{@@}) as arguments to this command; you can also specify a path of attributes and/or indexes (with suffix @samp{L} or @samp{R}) behind each of the variable or constant names. In that case, only the values of the specified paths are displayed: @cartouche @example debug> print $word $word = [class: pronoun, result: S2] debug> print $word.class $word.class = pronoun debug> print @@plan.1L.name $plan.1L = declarative debug> @end example @end cartouche If the option @code{use-display} is on and @code{malshow} is used as @code{display-cmd}, the expressions will be displayed in window on their own. If the @code{Expressions} window is not open yet, it will open now. If there is an open @code{Expressions} window, the new expressions and their values will be displayed in this window. You can left-click on an expression to make its value disappear or appear again. You can middle-click or right-click on an expression to erase it. The @code{Expressions} window has a menu with some commands: @table @code @item Window @table @code @item Export Postscript... Export the displayed expressions as an Embedded Postscript file. Currently, only ASCII, Latin-1 Supplement, Hangul Compatibility Jamo and Hangul Syllables can be converted to Postscript. @item Close Close the @code{Expressions} window. @end table @item Style @table @code @item Font Size ... Select an item to adjust the font size. @item Hanging Normally, all values and subvalues are aligned at their bottom. If this option is active, records are ``hanging down'': they are aligned at their top. @end table @item Expressions @table @code @item Clear All Clear all expressions. @item Show All Display the values of all expressions currently displayed. @item Hide All Suppress the values of all expressions currently displayed. @end table @end table @c ---------------------------------------------------------------------------- @node quit, read-constants, print, Commands @section The Command @code{quit} @cindex @code{quit} (command) Use this command to leave @code{malaga} or @code{mallex}. @c ---------------------------------------------------------------------------- @node read-constants, result, quit, Commands @section The Command @code{read-constants} (@code{mallex}) @cindex @code{read-constants} (@code{mallex} command) If you want to parse lexicon entries that use Malaga constants (prefixed by @samp{@@}), these constants can be read in using the command @samp{read-constants @var{lexicon-file}}. It parses @var{lexicon-file} and memorizes all constant definitions in it. @c ---------------------------------------------------------------------------- @node result, run, read-constants, Commands @section The Command @code{result} @cindex @code{result} (command) If you have previously analysed a word form or a sentence using @code{ma}, @code{ma-line}, @code{sa}, or @code{sa-line} (in @code{malaga}), or you have generated allomorphs using @code{ga} or @code{ga-line} (in @code{mallex}), you can display the results with @code{result}. @itemize @asis @item @code{use-display} is off: The results will be sent to standard output. @item @code{use-display} is on and @code{malshow} is used as @code{display-cmd}: The results will show in a window on their own which is called @code{Results} for @code{malaga} and @code{Allomorphs} for @code{mallex}. They are numbered from 1 onward. If you are executing the command @code{result} for the first time, or if you have closed a @code{Results/Allomorphs} window that you'd opened before, a window will open, displaying the values of all results/allomorphs of the last analysis/generation. If there is a @code{Results/Allomorphs} window currently opened, the new results/allomorphs will be displayed in this window. @end itemize The @code{Result/Allomorphs} window has a menu with some commands: @table @code @item Window @table @code @item Export Postscript... Export the displayed results as an Embedded Postscript file. Currently, only ASCII, Latin-1 Supplement, Hangul Compatibility Jamo and Hangul Syllables can be converted to Postscript. @item Close Close the @code{Result/Allomorphs} window. @end table @item Style @table @code @item Font Size ... Select an item to adjust the font size. @item Hanging Normally, all values and subvalues are aligned at their bottom. If this option is active, records are ``hanging down'': they are aligned at their top. @end table @end table @c ---------------------------------------------------------------------------- @node run, sa, result, Commands @section The Command @code{run} @cindex @code{run} (command) This command can only be used in debug mode. The rule execution will be resumed, and the rules will be executed completely without any interruption. If you have invoked debug mode by the command @code{debug-node}, rule execution will be stopped again when another link is going to be analysed. @c ---------------------------------------------------------------------------- @node sa, sa-file, run, Commands @section The Command @code{sa} (@code{malaga}) @cindex @code{sa} (@code{malaga} command) If you have started @code{malaga} with a syntax file in your command line or in the project file, you can start syntactic analyses using the command @code{sa} (short for @emph{syntactic analysis}). Put the sentence you want to be analysed as argument behind the command name: @example sa The man is in town. @end example Malaga will show the results automatically, and it will also show the analysis tree automatically if you specified it using the @code{tree} option. You can look at the results using @code{result} or at the entire analysis tree using @code{tree}. If you do not enter a sentence behind the command @code{sa}, @code{malaga} re-analyses the last input. @c ---------------------------------------------------------------------------- @node sa-file, sa-line, sa, Commands @section The Command @code{sa-file} (@code{malaga}) @cindex @code{sa-file} (@code{malaga} command) Using the command @code{sa-file}, you can analyse files that contain sentence lists. In a sentence list, each sentence stands in a line on its own; empty lines are permitted. Here is an example, a sentence list named @file{sentence-list}: @example He sleeps. He slept. He has slept. He had slept. @end example To analyse this sentence list, enter: @example sa-file sentence-list result @end example This will produce a file @file{result} that contains the analysis results. If the second argument is missing, the result will be written to a file whose name ends in @file{.out}; for @file{sentence-list}, its name will be @file{sentence-list.out}. @example 1: "He sleeps.": [functor: [syn: , sem: <"sleep">]] 2: "He slept.": [functor: [syn: , sem: <"sleep">]] 3: "He has slept.": [functor: [syn: , sem: <"have", "sleep">]] 4: "He had slept.": [functor: [syn: , sem: <"have", "sleep">]] @end example The number at the line start represents the line number of the analysed original sentence. The output format can be changed by using the options @code{result-format} and @code{unknown-format}. If a runtime error occurs during the analysis of a sentence, the line's output will be in the format given by the option @code{error-format}. After the analysis, some statistics will be displayed: @itemize @bullet @item The number of analysed sentences. @item The number of recognised sentences. @item The number of sentences recognised by combi-rules and end-rules. @item The number of sentences recognised by robust-rules. @item The number of sentences whose analyses produced errors. @item The average number of results per sentence. @item The analysis run time. @item The average number of sentences that have been analysed per second. @item The number of cache accesses. @item The number of cache hits. @end itemize @c ---------------------------------------------------------------------------- @node sa-line, set, sa-file, Commands @section The Command @code{sa-line} (@code{malaga}) @cindex @code{sa-line} (@code{malaga} command) If you have started @code{malaga} with a syntax file in your command line or in the project file, you can start syntactic analyses using the command @code{sa-line} (short for @emph{syntactic analysis}). Assume you want to analyse the sentence in the third line in the file @file{sentences}. Then enter the following command: @example sa-line sentences 3 @end example Malaga will show the results automatically, and it will also show the analysis tree automatically if you specified it using the @code{auto-tree} option. You can look at the results using @code{result} or at the entire analysis tree using @code{tree}. @c ---------------------------------------------------------------------------- @node set, sg, sa-line, Commands @section The Command @code{set} @cindex @code{set} (command) This command is used to change the settings of @code{malaga} or @code{mallex}. The command line @samp{set @var{option argument}} changes @var{option} to @var{argument}. If you want to get the current state of an option, use the command @code{get}. Options can also be set in the project file. The possible options are described in the next chapter. @c ---------------------------------------------------------------------------- @node sg, step, set, Commands @section The Command @code{sg} (@code{malaga}) @cindex @code{sg} (@code{malaga} command) Use @code{sg} to generate sentences that are composed of a specified set of word forms. For example, enter: @example sg 3 . ? he she sleeps @end example All sentences that consist of up to three word forms, where only the specified word forms (``.'', ``?'', ``he'', ``she'', and ``sleeps'') are used. The sentences are numbered from 1 onward, but different analyses of the same sentence get the same index. The output looks like this: @cartouche @example malaga> sg 3 . ? he she sleeps 1: "he sleeps ." 2: "he sleeps ?" 3: "she sleeps ." 4: "she sleeps ?" malaga> @end example @end cartouche Please note that generation does not know of filters, pruning rules and default rules. @c ---------------------------------------------------------------------------- @node step, transmit, sg, Commands @section The Command @code{step} @cindex @code{step} (command) This command can only be executed in debug mode. The rule execution will be resumed and continues until a different source line is met, a different path is going to be executed since the old one has terminated, or until the rules have been executed completely. @c ---------------------------------------------------------------------------- @node transmit, tree, step, Commands @section The Command @code{transmit} @cindex @code{transmit} (command) If you have specified a transmit command line (to do this, use the option @code{transmit-cmd}), you can send a command to it: @cartouche @example malaga> set transmit-cmd cat malaga> transmit [surf: "go", POS: verb]; [POS: verb, surf: "go"] malaga> @end example @end cartouche @c ---------------------------------------------------------------------------- @node tree, up, transmit, Commands @section The Command @code{tree} (@code{malaga}) @cindex @code{tree} (@code{malaga} command) If you've started a grammatical analysis using one of the commands @code{ma} or @code{sa} (or their debug variants), you can make @code{malaga} display the result by entering @example tree @end example If the analysis has not yet finished (in debug mode or in case of an error), a partial tree will be shown. If you're executing the command @code{tree} for the first time, or if you've closed the @code{Tree} window before, a new tree window will open in which the current analysis tree will be displayed. If there is already a @code{Tree} window open, the new analysis tree will be displayed in this window. In the upper left corner of the @code{Tree} window, you will see the sentence or the word form that has been analysed. Below, the analysis tree is displayed. An analysis path always follows the edges from the left to the right. A circle node stands for a LAG state, a two-circle node stands for an end state. A crossed circle stands for a LAG state that has been removed by a pruning-rule, and a crossed two-circle node stands for an end state that is invalid because it has some remaining input still remaining. A box node is not a state, but a @dfn{dead end}, which means that no rule has created a state at this position. Above each edge, the link's surface of the corresponding rule application is displayed. Below the edge, you'll see the name of the applied rule. You can click on a node using the left mouse button. Then another window will open, namely the @code{Path} window. The @code{Path} window displays the surface, the feature structure and the successor rules of the state you've clicked on. The node will be highlighted by a red border. If you press the right mouse button while the mouse is on a node, a pop-up menu will appear. You can then either select that this node is the first node of the path to be displayed, or you can select it to be the last one. All rule applications, from the first node up to the last node in the path, will be displayed in the @code{Path} window. The corresponding path will be highlighted in the @code{Tree} window. If you're clicking on a link surface using any mouse button, the surface and its feature structure will be displayed in the @code{Path} window. You can also click on rule names using any mouse button. Then the corresponding rule application will be displayed in the @code{Path} window, i.e.@ the surfaces and feature structures of the original state, the link, and the successor state, and the successor rules. There are some commands that can be initiated from the @code{Tree} menu bar: @table @code @item Window @table @code @item Export Postscript... Export the displayed analysis tree as an Embedded Postscript file. Currently, only ASCII, Latin-1 Supplement, Hangul Compatibility Jamo and Hangul Syllables can be converted to Postscript. @item Close Close the @code{Tree} window. @end table @item Style Select an item in this menu to adjust the font size. @item Tree Specify which nodes of the analysis tree are actually displayed and whether state indexes are shown. @table @code @item Full Tree All analysis states are displayed, and also boxes for rule applications that did not succeed (dead ends). @item No Dead Ends All analysis states are displayed. @item Complete paths Only the nodes that are part of a complete analysis are displayed. @item Show State Indexes Toggles the display of the state's indexes. @end table @item End States Select an end state to display in the @code{Path} window. @table @code @item Show First Display the first end state. @item Show Previous If there is an end state displayed in the @code{Path} window, jump to the previous one. @item Show Next If there is an end state displayed in the @code{Path} window, jump to the next one. @item Show Last Display the last end state. @end table @end table The @code{Path} window has got its own menu bar which contains the menus @code{Window}, @code{Style}, and @code{End States} with the same menu items as the corresponding menus in the @code{Tree} window, and two additional options in @code{Style}: @table @code @item Hanging Normally, all values and subvalues are aligned at their bottom. If this option is active, records are ``hanging down'': they are aligned at their top. @item Inline Normally, a state is displayed with surface, feature structure and rule set stacked. If this option is active, they are displayed aligned on on line. @end table The @code{Path} window also has a menu @code{Path}, in which you can specify whether state indexes are shown: @table @code @item Show State Indexes Toggles the display of the state's indexes. @end table @c ---------------------------------------------------------------------------- @node up, variables, tree, Commands @section The Command @code{up} @cindex @code{up} (command) If you want to look at the source and the variables of the (sub)rule that has called the current subrule, you can do this by entering @code{up}. You can list the frames via @code{backtrace}. @c ---------------------------------------------------------------------------- @node variables, walk, up, Commands @section The Command @code{variables} @cindex @code{variables} (command) If you invoke @code{variables}, you get the values of all Malaga variables that are currently defined. The variables will be shown in the order of their definitions. You can only use the command @code{variables} in debug mode or if the previous analysis has stopped with an error in the combination rules. If the option @code{use-display} is off, the variables will be sent to standard output: @cartouche @example malaga> sa-debug You are so beautiful. entering rule "Noun", surf: "", link: "You", state: 1 debug> variables $sentence = [class: main_clause, parts: <>] $word = [class: pronoun, result: S2] debug> @end example @end cartouche If the option @code{use-display} is on and @code{malshow} is used as @code{display-cmd}, the variables will be displayed in window on their own. If the @code{Variables} window is not open yet, it will open now. If there is an open @code{Variables} window, the new variable contents will be displayed in this window. You can left-click on a variable name to make its value disappear or appear again. The @code{Variables} window has a menu with some commands: @table @code @item Window @table @code @item Export Postscript... Export the displayed variables as an Embedded Postscript file. Currently, only ASCII, Latin-1 Supplement, Hangul Compatibility Jamo and Hangul Syllables can be converted to Postscript. @item Close Close the @code{Variables} window. @end table @item Style @table @code @item Font Size ... Select an item to adjust the font size. @item Hanging Normally, all values and subvalues are aligned at their bottom. If this option is active, records are ``hanging down'': they are aligned at their top. @end table @item Variables @table @code @item Show All Display the values of all variables currently defined. @item Hide All Suppress the values of all variables currently defined. @end table @end table @c ---------------------------------------------------------------------------- @node walk, where, variables, Commands @section The Command @code{walk} @cindex @code{walk} (command) This command works in debug mode only. The rule execution will be continued and stopped again as soon as a new rule is executed, a breakpoint is met or there are no more rules to execute. @c ---------------------------------------------------------------------------- @node where, , walk, Commands @section The Command @code{where} @cindex @code{where} (command) This command can only be used in debugger mode or after rule execution has been stopped by an error. It displays the name of the rule that has been executed; additionally, the surfaces of state and link are displayed in @code{malaga}. For example: @cartouche @example debug> where at rule "flexion", surf: "hous", link: "es", state: 2 debug> @end example @end cartouche @c ---------------------------------------------------------------------------- @node Options, The Language, Commands, Top @chapter The Options of @code{malaga} and @code{mallex} @cindex options The programs @code{malaga} and @code{mallex} share some of their options, so I will describe them in a common chapter. Options can be set using the command @code{set}, and you can get the current value of an option using @code{get}. Options that can be used in @code{malaga} or in @code{mallex} only, are marked by the name of the program in which they can be used. @menu * alias:: Shortcuts for other commands. * allo-format:: The output format for allomorphs in readable form. * auto-tree:: Is the analysis tree displayed automatically after analysis? * auto-variables:: Are variables displayed automatically in debug mode? * cache-size:: The size of the word form cache. * display-cmd:: The command line for the display GUI. * error-format:: The output-format for analyses that reported an error. * hidden:: The attributes whose values are hidden in output. * mor-incomplete:: Will we accept words that have been incompletely parsed? * mor-out-filter:: Will the morphology output filter be executed? * mor-pruning:: Number of states needed to call the morphology pruning rule. * result-format:: The output format for successful analyses. * result-list:: Pack all analysis results in a single list. * robust-rule:: Will the robust rule be executed? * roman-hangul:: Will Hangul be transcribed? (for Hangul grammars only) * sort-records:: The order of the attributes in a record when displayed. * switch:: User options that can be read by the grammar. * syn-incomplete:: Will we accept sentences that have been incompletely parsed? * syn-in-filter:: Will the syntax input filter be executed? * syn-out-filter:: Will the syntax output filter be executed? * syn-pruning:: Number of states needed to call the syntax pruning rule. * transmit-cmd:: The command line for the transmit process. * unknown-format:: The output format for analyses that got no results. * use-display:: Will the program in @code{display-cmd} be used for output? @end menu @c ---------------------------------------------------------------------------- @node alias, allo-format, Options, Options @section The Option @code{alias} @cindex @code{alias} (option) With @code{alias}, you can define abbreviations for longer command lines. As arguments, give an alias name and an expansion (a command line which the name will stand for). If the expansion contains spaces, enclose it in double quotes. Use @code{set alias @var{name}} to delete alias @var{name}. If you type the name of an alias at your command line, its expansion will be executed. The character sequence @samp{%a} in your alias definition will be replaced by what follows the alias name in the command line. Aliases cannot be nested. @c ---------------------------------------------------------------------------- @node allo-format, auto-tree, alias, Options @section The Option @code{allo-format} (@code{mallex}) @cindex @code{allo-format} (@code{mallex} option) With @code{allo-format}, you can change the output format for the generated allomorphs. Enter a format string as argument. If the format string contains spaces, enclose it in double quotes. If the argument is an empty string (@code{""}), no allomorphs will be shown. In the format string, the following sequences have a special meaning: @table @samp @item %c Will be replaced by the allomorph's feature structure. @item %n Will be replaced by the allomorph's number. @item %s Will be replaced by the allomorph's surface. @end table @c ---------------------------------------------------------------------------- @node auto-tree, auto-variables, allo-format, Options @section The Option @code{auto-tree} (@code{malaga}) @cindex @code{auto-tree} (@code{malaga} option) You can use @code{auto-tree} to make @code{malaga} execute the @code{tree} command each time when you invoked an analysis by @code{ma} or @code{sa}. Set it in one of the following ways: @table @code @item set auto-tree yes The @code{tree} command will be executed after each analysis. @item set auto-tree no The @code{tree} command will not be executed automatically. @end table @c ---------------------------------------------------------------------------- @node auto-variables, cache-size, auto-tree, Options @section The Option @code{auto-variables} @cindex @code{auto-variables} (option) When @code{malaga} or @code{mallex} stops in debug mode while executing a malaga rule, they can automatically show the defined variables at this point. Use the option @code{auto-variables} to set this behaviour. @table @code @item set auto-variables yes The @code{variables} command will be executed each time when @code{malaga} or @code{mallex} stops in debug mode. @item set auto-variables no The @code{variables} command will not be executed automatically. @end table @c ---------------------------------------------------------------------------- @node cache-size, display-cmd, auto-variables, Options @section The Option @code{cache-size} (@code{malaga}) @cindex @code{cache-size} (@code{malaga} option) Malaga has a cache for word forms. You can set the cache size, i.e. the maximum number of words in the cache, to @var{n} with @code{set cache-size @var{n}}. If you set the cache size to 0, the cache will be deactivated. When malaga analyses a word form or sentence, it tries to get a word form from the cache before it uses the morphology combination rules. Therefore, malaga separates the first word form from the remaining input. It uses spacing characters as separators; so if a word-form contains a space or does not end with a space, caching will not work. @c ---------------------------------------------------------------------------- @node display-cmd, error-format, cache-size, Options @section The Option @code{display-cmd} @cindex @code{display-cmd} (option) The programs @code{malaga} and @code{mallex} normally use the program @code{malshow} for GUI-based display of Malaga trees, results or variables. If you want to use a different display program, set the command line that starts this program with the @code{display} option, like this: @example set display-cmd "java -classpath /opt/malaga/amalgam Amalgam" @end example @c ---------------------------------------------------------------------------- @node error-format, hidden, display-cmd, Options @section The Option @code{error-format} (@code{malaga}) @cindex @code{error-format} (@code{malaga} option) With @code{error-format}, you can change the output format for items that produced an analysis error. Enter a format string as argument. If the format string contains spaces, enclose it in double quotes. If the argument is an empty string (@code{""}), no forms that produced an error will be shown. In the format string, the following sequences have a special meaning: @table @samp @item %e Will be replaced by the error message for the analysed form. @item %l Will be replaced by the line number of the analysed form. @item %n Will be replaced by the number of analysis states for this form. @item %s Will be replaced by the surface. @end table @c ---------------------------------------------------------------------------- @node hidden, mor-incomplete, error-format, Options @section The Option @code{hidden} @cindex @code{hidden} (option) Some grammars can produce very large feature structures, so it can be useful not to show the values of some specified attributes. To achieve this, use the option @code{hidden}. You can give any number of arguments to this option. The following arguments are available: @table @samp @item +@var{attribute-name} The specified attribute name will be put in parentheses if it occurs in a value; the attribute value will not be shown. @item -@var{attribute-name} The specified attribute will be shown completely again in the future. @item none All attributes will be shown completely again in the future. @end table @c ---------------------------------------------------------------------------- @node mor-incomplete, mor-out-filter, hidden, Options @section The Option @code{mor-incomplete} (@code{malaga}) @cindex @code{mor-incomplete} (@code{malaga} option) If you want to get morphological analysis results not only for the whole input line, but for any grammatically well-formed prefix of the input line, you can use the option @code{mor-incomplete}: @table @code @item set mor-incomplete yes Accept words that have been incompletely parsed. @item set mor-incomplete no Only accept words that have been completely parsed. @end table Note that this option has no effect in subordinate morphological analyses that are needed by syntactic analysis. @c ---------------------------------------------------------------------------- @node mor-out-filter, mor-pruning, mor-incomplete, Options @section The Option @code{mor-out-filter} (@code{malaga}) @cindex @code{mor-out-filter} (@code{malaga} option) Use the option @code{mor-out-filter} to switch the morphology output-filter on or off: @table @code @item set mor-out-filter yes Activate the filter. @item set mor-out-filter no Deactivate the filter. @end table @c ---------------------------------------------------------------------------- @node mor-pruning, result-format, mor-out-filter, Options @section The Option @code{mor-pruning} (@code{malaga}) @cindex @code{mor-pruning} (@code{malaga} option) @cindex Pruning In your morphology rules, you may have specified a pruning rule that can prune the morphology analysis tree, i.e.@ it can reduce the number of parallel paths. If you want this pruning rule to be executed, use the option @code{mor-pruning}. Use one of the following arguments: @table @code @item set mor-pruning @var{n} Call the morphology pruning rule whenever at least @var{n} states have consumed the same amount of input, for @var{n} > 0. @item set mor-pruning 0 Deactivate the morphology pruning rule. @end table @c ---------------------------------------------------------------------------- @node result-format, result-list, mor-pruning, Options @section The Option @code{result-format} (@code{malaga}) @cindex @code{result-format} (@code{malaga} option) With @code{result-format}, you can change the output format for analysed items that have been recognised. Enter a format string as argument. If the format string contains spaces, enclose it in double quotes. If the argument is an empty string (@code{""}), no recognised forms will be shown. In the format string, the following sequences have a special meaning: @table @samp @item %c Will be replaced by the result feature structure of the analysis. @item %l Will be replaced by the line number of the analysed form. @item %n Will be replaced by the number of analysis states for this form. @item %r Will be replaced by the reading index (the results for a form are indexed from 1 to the number of results). @item %s Will be replaced by the surface. @end table @c ---------------------------------------------------------------------------- @node result-list, robust-rule, result-format, Options @section The Option @code{result-list} (@code{malaga}) @cindex @code{result-list} (@code{malaga} option) With this command, you can specify whether you want malaga to pack all analysis results into a single list. This option only has an impact in filter mode or when a file is being analysed. Even results of different lengths are combined; this could not be achieved by an output-filter. Results of different lenghts can occur when the option @code{mor-incomplete} or @code{syn-incomplete} is active. @table @code @item set result-list yes Combine results into a single list. @item set result-list no Leave results unchanged. @end table @c ---------------------------------------------------------------------------- @node robust-rule, roman-hangul, result-list, Options @section The Option @code{robust-rule} (@code{malaga}) @cindex @code{robust-rule} (@code{malaga} option) With this command, you can specify if you want to run a robust-rule for the word forms that could not be recognised by LAG rules. The robust-rule gets the surface of an unknown word form as parameter and it can create one or more results by executing the @code{result} statement. @table @code @item set robust-rule yes Enable the robust rule. @item set robust-rule no Disable the robust rule. @end table @c ---------------------------------------------------------------------------- @node roman-hangul, sort-records , robust-rule, Options @section The Option @code{roman-hangul} @cindex @code{roman-hangul} (option) @cindex Hangul, transcribed @cindex transcribed Hangul If you are using the option @samp{split-hangul-syllables: yes} in your project file, Malaga can transcribe Hangul using Latin letters, basing on the Yale system. The transcribed text is enclosed in curly braces, and each syllable starts with a dot. @table @code @item set roman-hangul yes Display Hangul using Latin transcription. @item set roman-hangul no Display Hangul directly. @end table @c ---------------------------------------------------------------------------- @node sort-records, switch, roman-hangul, Options @section The Option @code{sort-records} @cindex @code{sort-records} (option) @cindex order, attribute @cindex attribute order There are different ways to determine the order in which the attributes of a record are displayed. With @code{sort-records}, you can choose between three order schemes: @table @code @item set sort-records internal The attributes will be displayed in the order they have internally. @item set sort-records alphabetic The attributes will be ordered alphabetically by their names. @item set sort-records definition The attributes will be ordered by their names; the order is the same as in the symbol table. @end table @c ---------------------------------------------------------------------------- @node switch, syn-incomplete, sort-records, Options @section The Option @code{switch} @cindex @code{switch} (option) Malaga rules can query simple Malaga values (@dfn{switches}) that you can change during run time. Use the option @code{switch} to change the values: @table @code @item set switch @var{name} @var{value} Set the switch @var{name}, which must be a symbol, to @var{value}, which can be any Malaga value. @end table @c ---------------------------------------------------------------------------- @node syn-incomplete, syn-in-filter, switch, Options @section The Option @code{syn-incomplete} (@code{malaga}) @cindex @code{syn-incomplete} (@code{malaga} option) If you want to get syntactic analysis results not only for the whole input line, but for any grammatically well-formed prefix of the sentence, you can use the option @code{syn-incomplete}: @table @code @item set syn-incomplete yes Accept sentences that have been incompletely parsed. @item set syn-incomplete no Only accept sentences that have been completely parsed. @end table @c ---------------------------------------------------------------------------- @node syn-in-filter, syn-out-filter, syn-incomplete, Options @section The Option @code{syn-in-filter} (@code{malaga}) @cindex @code{syn-in-filter} (@code{malaga} option) Use the option @code{syn-in-filter} to switch the syntax input-filter on or off: @table @code @item set syn-in-filter yes Activate the filter. @item set syn-in-filter no Deactivate the filter. @end table @c ---------------------------------------------------------------------------- @node syn-out-filter, syn-pruning, syn-in-filter, Options @section The Option @code{syn-out-filter} (@code{malaga}) @cindex @code{syn-out-filter} (@code{malaga} option) Use the option @code{syn-out-filter} to switch the syntax output-filter on or off: @table @code @item set syn-out-filter yes Activate the filter. @item set syn-out-filter no Deactivate the filter. @end table @c ---------------------------------------------------------------------------- @node syn-pruning, transmit-cmd, syn-out-filter, Options @section The Option @code{syn-pruning} (@code{malaga}) @cindex @code{syn-pruning} (@code{malaga} option) @cindex Pruning In your syntax rules, you may have specified a pruning rule that can prune the syntax analysis tree, i.e.@ it can reduce the number of parallel paths. If you want this pruning rule to be executed, use the option @code{syn-pruning}. Use one of the following arguments: @table @code @item set syn-pruning @var{n} Call the syntax pruning rule whenever at least @var{n} states have consumed the same amount of input, for @var{n} > 0. @item set syn-pruning 0 Deactivate the syntax pruning rule. @end table @c ---------------------------------------------------------------------------- @node transmit-cmd, unknown-format, syn-pruning, Options @section The Option @code{transmit-cmd} @cindex @code{transmit-cmd} (option) If you want to use the @code{transmit} function in @code{malaga} or @code{mallex}, you have to set a command line that starts the transmit process using the @code{transmit-cmd} option. Here is an example: @example set transmit-cmd "perl my-transmit-program.pl" @end example @c ---------------------------------------------------------------------------- @node unknown-format, use-display, transmit-cmd, Options @section The Option @code{unknown-format} (@code{malaga}) @cindex @code{unknown-format} (@code{malaga} option) With @code{unknown-format}, you can change the output format for analysed items that have not been recognised. Enter a format string as argument. If the format string contains spaces, enclose it in double quotes. If the argument is an empty string (@code{""}), no unrecognised forms will be shown. In the format string, the following sequences have a special meaning: @table @samp @item %l Will be replaced by the line number of the analysed form. @item %n Will be replaced by the number of analysis states for this form. @item %s Will be replaced by the surface. @end table @c ---------------------------------------------------------------------------- @node use-display, , unknown-format, Options @section The Option @code{use-display} @cindex @code{use-display} (option) If you want the output of the commands @code{result} and @code{variables} to be shown by the @code{Display} process, use the option @code{use-display}: @table @code @item set use-display yes Use the @code{Display} process to show the output of @code{result} and @code{variables}. @item set use-display no Send the output of @code{result} and @code{variables} to your terminal. @end table @c ---------------------------------------------------------------------------- @node The Language, Index, Options, Top @chapter The Programming Language Malaga @cindex Malaga, programming language @menu * Characterisation:: The abstract characteristics of the language. * Source Texts:: General rules for Malaga source files. * Values:: The types that make any Malaga data. * Expressions:: How operators can combine values. * Conditions:: Expressions yielding a boolean value. * Boolean Operators:: The Operators @code{and}, @code{or} and @code{not}. * Symbol Table:: All symbols have to be defined here. * Initial State:: The initial LAG state. * Constant Definition:: Constants can be used in lexicon and rule files. * Rules:: Rules are comparable to functions in C. * Statements:: The atoms of which a rule is constructed. * Files:: The Files that make a Malaga grammar. * Syntax Summary:: Formal Description of the Malaga syntax. @end menu @c ---------------------------------------------------------------------------- @node Characterisation, Source Texts, The Language, The Language @section Characterisation of Malaga A malaga rule file resembles much in programming languages like Pascal or C (of course, those languages do not have a Left-Associative Grammar formalism built in). A malaga source file must be translated before execution, this is the same as for compiler languages. But the generated Malaga code is not a machine code, but an @emph{intermediate code} and has to be executed (@dfn{interpreted}) by an analysis program. Malaga may be characterised as follows, as far as programming structures and data structures are concerned: @table @emph @item structured values: The basic values in Malaga are symbols (names that can be used e.g. for categories or subcategories), numbers (floating point numbers), and strings. Values can be combined to ordered lists or records (also known as attribute-value matrixes). A value in a list or a record can be a list or a record itself. An ``ambiguous'' symbol like @code{singular_plural} can be assigned a list of symbols like @code{}; such a symbol is called a @dfn{multi-symbol}. @item structured statements: In Malaga, the concept of statement blocks is implemented in a similar way as it is in the programming language Pascal. There are structured control statements to select or repeat a statement sequence. A variable is always defined @dfn{locally}, i.e.@ it only exists from the point where it has been defined up to the end of the statement sequence in which it has been defined. @item no type restrictions: Any value can be assigned to a variable and the programmer can freely define the structure of values. @item no side effects: Malaga is, unlike programming languages like Pascal or C, free of side effects. If a variable gets a value, no other variable will be changed. Analysis paths are independent of each other. @item termination: A Malaga grammar that contains no recursive subrules and no @code{repeat} statements is guaranteed to terminate, i.e.@ it can never hang in a loop. @item variables: In a @code{define} statement, a variable is defined and gets an initial value. Use an assignment to set a variable that has already been defined to a new value. @item operators: Many generative grammar theories or linguistical programming languages use the concept of unification of feature structures. Malaga does not use unification, but it offers some operators to build feature structures explicitly. Since Malaga does without unification, analyses are much faster. @end table @c ---------------------------------------------------------------------------- @node Source Texts, Values, Characterisation, The Language @section Malaga Source Texts Source texts in Malaga must be in the Unicode UTF-8 format. They are format-free; this means that between lexical symbols (strings, identifiers, keywords, numerals and symbols such as @samp{+}, @samp{~} or @samp{:=}) there may be blanks or newlines (whitespaces) or comments. Between two identifiers or two keywords there @emph{must} be at least one whitespace to separate them syntactically. @menu * Comments:: How to insert comments in your source file. * Include:: How to read other files from your source file. * Identifiers:: Names in Malaga source files. @end menu @c ---------------------------------------------------------------------------- @node Comments, Include, Source Texts, Source Texts @subsection Comments @cindex comments A comment may be inserted everywhere where a whitespace may be inserted. A comment begins with the symbol @samp{#} and extends to the end of the line. Comments are being ignored. @c ---------------------------------------------------------------------------- @node Include, Identifiers, Comments, Source Texts @subsection The @code{include} Statement @cindex @code{include} (statement) A Malaga file may contain the statement @example include "@var{filename}"; @end example In a rule file, it can stand everywhere a rule can stand. In lexicon files, it can stand in place of a value; in symbol files, it can replace a symbol definition. The text of the included file is inserted verbatim at the very location where the @code{include} statement occurs. The file name has to be stated relatively to the directory of the file which contains the @code{include} statement. @c ---------------------------------------------------------------------------- @node Identifiers, , Include, Source Texts @subsection Identifiers @cindex identifiers In Malaga, names for variables, constants, symbols, and rules, and (see below for explanation) are called @dfn{identifiers}. An identifier may consist of uppercase and lowercase characters, the underscore @samp{_}, the ampersand @samp{&}, the vertical bar @samp{|}, and, from the second character on, also of digits. Uppercase and lowercase characters are not distinguished, i.e., Malaga is @emph{not} case-sensitive. Malaga keywords must not be used as identifiers. A variable name must start with a @samp{$}, a constant name must start with a @samp{@@}. The same identifier may be used as variable name, constant name, symbol name, or rule name independently. Malaga can distinguish them by the context in which they occur. Valid identifiers would be @samp{Noun}, @samp{noun} (the same as the first), @samp{R2D2}, @samp{Vb_aux}, @samp{A|G|D}, @samp{_INF}. Identifiers like @samp{2Noun}, @samp{Verb.Frame}, @samp{OK?}, @samp{_~INF} are @emph{not} valid. @c ---------------------------------------------------------------------------- @node Values, Expressions, Source Texts, The Language @section Values @cindex values Malaga expressions can have values with very complex structures. To describe how those values can be composed from simple values a few rules suffice. Simple values in Malaga are @dfn{symbols}, @dfn{numbers}, and @dfn{strings}, which can be composed to form @dfn{records} and @dfn{lists}. @menu * Symbols:: The atomic datatype that is basic to Malaga. * Numbers:: Floating point numbers, also used for indexes. * Strings:: A sequence of characters, used to store text. * Lists:: An ordered sequence of subvalues. * Records:: A set of attribute-value pairs. @end menu @c ---------------------------------------------------------------------------- @node Symbols, Numbers, Values, Values @subsection Symbols @cindex symbols The central data type in Malaga is the symbol. It is used for describing syntactic or semantic properties of an allomorph, a word, or a sentence. A symbol is an identifier like @samp{Verb}, @samp{reflexive}, @samp{Sing_1}. The symbols @samp{nil}, @samp{yes}, @samp{no}, @samp{symbol}, @samp{string}, @samp{number}, @samp{list}, and @samp{record} are predefined and have special meanings. @c ---------------------------------------------------------------------------- @node Numbers, Strings, Symbols, Values @subsection Numbers @cindex numbers A number in Malaga consists of an integer part, an optional fractional part and an optional exponent of the form @samp{E[+|-]n}. There must be a dot between the integer part and the fractional part. Examples: @samp{0}, @samp{1}, @samp{1.0}, @samp{13.75}, @samp{1.2E-5}. Alternatively, a number may consist of an integer number followed by @samp{L}, indicating that the number is intended as a list index counting from the @emph{left} border), or by @samp{R}, indicating that the number is intended as a list index counting from the @emph{right} border. Examples: @code{5L} = @code{5}, @code{12R} = @code{-12}. @c ---------------------------------------------------------------------------- @node Strings, Lists, Numbers, Values @subsection Strings @cindex strings A string may consist of any number of characters (it may also be empty). It must be enclosed in double quotes and must not extend over more than one line. Within the double quotes there may be any combination of printable characters except the backslash @samp{\} and the double quotes. When part of a string, these characters must be preceded by a @samp{\} (escape character). @cindex escape character (@samp{\}) Examples: @code{"Hello"}, @code{"He says: \"Great\""}. @c ---------------------------------------------------------------------------- @node Lists, Records, Strings, Values @subsection Lists @cindex lists A list is an ordered sequence of values. The values are separated by commas and enclosed in angle brackets: @example <@var{element1}, @var{element2}, ...> @end example A list may as well be empty. The elements in a list may be arbitrarily complex; they may also be lists or records. @c ---------------------------------------------------------------------------- @node Records, , Lists, Values @subsection Records @cindex records @cindex attributes A record is a collection of attributes. An @emph{attribute} consists of a symbol, the @emph{attribute name}, and an associated @emph{attribute value}, which can be an arbitrary Malaga value. The attribute name serves as an access key for the attribute value, so all attributes in a record must have distinct names. Records are noted down as follows: @example [@var{name1}: @var{value1}, @var{name2}: @var{value2}, ...] @end example where @var{name i} denotes an attribute name and @var{value i} the associated attribute value. Example: @code{[Class: Verb, Reg: Reg, Val: dirObj]}. A record with no attributes, @code{[]}, is called @dfn{empty record}. @cindex record, empty @cindex empty record @c ---------------------------------------------------------------------------- @node Expressions, Conditions, Values, The Language @section Expressions @cindex expressions An expression is the form in which a value is used in Malaga. Values can be written as follows: @example [Surf: "he", Class: Pron, Case&Number: S3] @end example Variables (these are placeholders for values within a rule) can as well be used as expressions: @example $Pron @end example Furthermore, constants (placeholders for values in a rule file) can be used as expressions: @example @@combination_table @end example All three forms can be mixed: @example [Surf: "he", Class: Pron, Case&Number: $result] @end example Furthermore, there are operators which modify values or combine two values to form a new value. Complex values can be composed using those operators. All operators have a priority assigned. An operator with higher priority is applied before an operator with lower priority. If two operators have the same priority, they are applied from the left to the right. The order in which the operators are to be applied can be changed by bracketing with round parentheses @samp{()}. @cindex priority, operator @cindex operator priority @table @asis @item unary @samp{-} very high priority @item @samp{.} high priority @item @samp{*}, @samp{/} middle priority @item @samp{+}, @samp{-} low priority @end table @menu * Malaga Variables:: Containers for Malaga Values in a Rule. * Constants:: Global containers for Malaga Values. * Subrule Calls:: Call a subrule from another rule. * Atoms:: The atoms of a multisymbol. * Capital:: Does a string begin with a capital letter? * Floor:: Round down to the next integer. * Length:: The length of a list or a string. * Multi:: The multisymbol of the given atoms list. * Set:: Make a list contain unique elements only. * Substring:: Get a substring of a string. * Switch:: Get a user-defined value. * Transmit:: Call the transmit process. * Value_String:: Convert a value to a string. * Value_Type:: Get the type of a value. * If Expression:: Evaluate one of several expressions. * Unary Minus:: Negate a value. * Operator Dot:: Select an attribute or a list element. * Operator Plus:: Concat strings, lists or records, or add. * Operator Minus:: Delete an attribute or an element, or subtract. * Operator Times:: Intersect lists, concat records, or multiply. * Operator Divide:: Delete elements from a list, or divide. @end menu @c ---------------------------------------------------------------------------- @node Malaga Variables, Constants, Expressions, Expressions @subsection Variables A variable is marked by a @samp{$} preceding its name. The name may be any valid identifier. A variable is defined by the @code{define} statement; it receives a value and may from this point on be used in all expressions within the statement sequence. In such a statement sequence (and all subordinated statement sequences) a variable with the same name must not be defined again. @c ---------------------------------------------------------------------------- @node Constants, Subrule Calls, Malaga Variables, Expressions @subsection Constants @cindex constants A constant is marked by a @samp{@@} preceding its name. The name may be any valid identifier. A constant is defined by a constant definition in a rule file, outside a rule. It is assigned a value and can be used in subsequent rules and constant definitions in that rule file. @c ---------------------------------------------------------------------------- @node Subrule Calls, Atoms, Constants, Expressions @subsection Subrule Invokations @cindex subrules, calling A subrule is invoked when an expression @code{@var{subrule}(@var{value1}, @var{value2}, ...)} is evaluated. The expression yields the value that is returned by the @code{return} statement in the subrule. @cindex @code{return} (statement) The number of parameters in a subrule invokation must match the number of parameters in the subrule definition. There is a number of default subrules which are predefined. They are called @dfn{functions}. @cindex functions @c ---------------------------------------------------------------------------- @node Atoms, Capital, Subrule Calls, Expressions @subsection The Function @code{atoms} @cindex @code{atoms} (function) The expression @code{atoms(@var{symbol})} yields the list of atomic symbols for @var{symbol}. If @var{symbol} is not a multi-symbol, it yields the list @code{<@var{symbol}>}. @c ---------------------------------------------------------------------------- @node Capital, Floor, Atoms, Expressions @subsection The Function @code{capital} @cindex @code{capital} (function) The expression @code{capital(@var{string})} yields @code{yes} if the first character of @var{string} is a capital letter, else it yields @code{no}. @c ---------------------------------------------------------------------------- @node Floor, Length, Capital, Expressions @subsection The Function @code{floor} @cindex @code{floor} (function) The expression @code{floor(@var{number})} yields the largest integer number that is not greater than @var{number}. @c ---------------------------------------------------------------------------- @node Length, Multi, Floor, Expressions @subsection The Function @code{length} @cindex @code{length} (function) The expression @code{length(@var{list})} yields the number of elements in @var{list}. The expression @code{length(@var{string})} yields the number of characters in @var{string}. @c ---------------------------------------------------------------------------- @node Multi, Set, Length, Expressions @subsection The Function @code{multi} @cindex @code{multi} (function) The expression @code{multi(@var{list})} where @var{list} is a list of symbols, yields the multi-symbol whose atomic list corresponds to @var{list}. If @var{list} contains a single atomic symbol, this symbol will be yield by the expression. @c ---------------------------------------------------------------------------- @node Set, Substring, Multi, Expressions @subsection The Function @code{set} @cindex @code{set} (function) The expression @code{set(@var{list})} yields a list which contains each element of @var{list}, but only once. That means, the list is converted to a set. @c ---------------------------------------------------------------------------- @node Substring, Switch, Set, Expressions @subsection The Function @code{substring} @cindex @code{substring} (function) The expression @code{substring(@var{string}, @var{start_index}, @var{end_index})} yields the substring of @var{string} that starts at @var{start_index} and ends at @var{end_index}, both inclusive. A positive index counts from the string start: @code{1L} is the index of the first character; a negative index counts from the string end: @code{1R} is the index of the last character. If @var{end_index} is omitted, it is assumed to be the same as @var{start_index}, so @code{substring(@var{string}, @var{index})} yields the character at @var{index} in @var{string}. If @var{end_index} is less than @var{start_index}, the function yields an empty string. @c ---------------------------------------------------------------------------- @node Switch, Transmit, Substring, Expressions @subsection The Function @code{switch} @cindex @code{switch} (function) The expression @code{switch(@var{symbol})} yields the current value of the switch associated to @var{symbol}. Use the option @code{switch} to change this value. @c ---------------------------------------------------------------------------- @node Transmit, Value_String, Switch, Expressions @subsection The Function @code{transmit} @cindex @code{transmit} (function) The expression @code{transmit(@var{value})} writes @var{value}, converted to text format, to the transmit process via pipe and reads a value in text format from the transmit process via pipe. The answer is converted to the internal Malaga value format and returned as the result of the expression. When this function is evaluated, the transmit process is started if it is not running. The command line of the transmit process is specified by the option @code{transmit}. @c ---------------------------------------------------------------------------- @node Value_String, Value_Type, Transmit, Expressions @subsection The Function @code{value_string} @cindex @code{value_string} (function) The expression @code{value_string(@var{value})} returns @var{value} converted to text format as a string. @c ---------------------------------------------------------------------------- @node Value_Type, If Expression, Value_String, Expressions @subsection The Function @code{value_type} @cindex @code{value_type} (function) The expression @code{value_type(@var{value})} yields the type of @var{value}. The type information is coded as one of the symbols @code{symbol}, @code{string}, @code{number}, @code{list}, or @code{record}. @c ---------------------------------------------------------------------------- @node If Expression, Unary Minus, Value_Type, Expressions @subsection The @code{if} Expression @cindex @code{if} (expression) @cindex @code{else} (keyword) @cindex @code{elseif} (keyword) An @code{if} expression has the following form: @example if @var{condition1} then @var{expression1} elseif @var{condition2} then @var{expression2} else @var{expression3} end if @end example The @code{elseif} part may be repeated unrestrictedly (including zero times). First, @var{condition1} is evaluated. If it is satisfied, the expression @var{expression1} is evaluated and yields the value of the @code{if} expression. If @var{condition1} is not satisfied, each condition following an @code{elseif} keyword is evaluated in turn, until a condition is found that is satisfied. The expression that follows this condition will be evaluated and yields the value of the @code{if} expression. If the @code{if} condition and @code{elseif} conditions all fail, the expression @var{expression3} will be evaluated and yields the value of the @code{if} expression. The @code{if} after the @code{end} may be omitted. @c ---------------------------------------------------------------------------- @node Unary Minus, Operator Dot, If Expression, Expressions @subsection Unary @samp{-} A @samp{-} in front of a value of type @code{number} negates that value. @c ---------------------------------------------------------------------------- @node Operator Dot, Operator Plus, Unary Minus, Expressions @subsection The Operator @samp{.} This operator may only be used in the following ways: @table @code @item @var{record}.@var{symbol} This yields the attribute value of the attribute of @var{record} whose name is @var{symbol}. If there is no attribute in @var{record} whose name is @var{symbol}, the expression yields the special symbol @code{nil}. @item @var{list}.@var{number} This yields the element of @var{list} at position @var{number}. If there is no element at position @var{number} in @var{list}, the expression yields the special symbol @code{nil}. @item @var{value}.@var{list} Here, @var{list} must be a list @code{<@var{e1}, @var{e2}, ...>} of symbols and/or numbers. This expression serves as an abbreviation for @code{@var{value}.@var{e1}.@var{e2}...}. @end table @c ---------------------------------------------------------------------------- @node Operator Plus, Operator Minus, Operator Dot, Expressions @subsection The Operator @samp{+} @cindex @code{+} (operator) This operator may only be used in the following ways: @table @code @item @var{string1} + @var{string2} This yields the concatenation of @var{string1} and @var{string2}. @item @var{list1} + @var{list2} This yields the concatenation of @var{list1} and @var{list2}. @item @var{number1} + @var{number2} This yields the sum of @var{number1} and @var{number2}. @item @var{record1} + @var{record2} This yields a record wich consists of all attributes of @var{record1} and @var{record2}. If @var{record1} and @var{record2} have a common attribute names, the corresponding attributes in the result record will have the attribute values from @var{record2}, in contrast to the operator @samp{*}. @end table @c ---------------------------------------------------------------------------- @node Operator Minus, Operator Times, Operator Plus, Expressions @subsection The Operator @samp{-} @cindex @code{-} (operator) This operator may only be used in the following ways: @table @code @item @var{record} - @var{symbol} This yields @var{record} without the attribute named @var{symbol}, if @var{symbol} is an attribute name in @var{record}. If not, the expression yields @var{record}. @item @var{record} - @var{list} Here, @var{list} must be a list of symbols. This yields @var{record} without the attributes in @var{list}. @item @var{list} - @var{number} This yields @var{list} without the element at index @var{number}. If this element does not exist, the expression yields @var{list}. @item @var{list1} - @var{list2} This yields the multi-set difference of the two lists @var{list1} and @var{list2}. This means, it yields the list @var{list1}, but the first @var{n} appearances of each element will be deleted, if that element appears @var{n} times in @var{list2}. @item @var{number1} - @var{number2} This yields the difference of @var{number1} and @var{number2}. @end table @c ---------------------------------------------------------------------------- @node Operator Times, Operator Divide, Operator Minus, Expressions @subsection The Operator @samp{*} @cindex @code{*} (operator) This operator may only be used in the following ways: @table @code @item @var{record} * @var{symbol} This yields the record which only contains the attribute of @var{record} whose name is @var{symbol}. @item @var{record1} * @var{record2} This yields a record wich consists of all attributes of @var{record1} and @var{record2}. If @var{record1} and @var{record2} have a common attribute names, the corresponding attributes in the result record will have the attribute values from @var{record1}, in contrast to the operator @samp{+}. @item @var{record} * @var{list} Her, @var{list} must be a list of symbols. This yields the record which only contains the attributes of @var{record} whose names are in @var{list}. @item @var{list1} * @var{list2} This yields the @dfn{intersection} of the lists interpreted as multi-sets; if an element is @var{m} times contained in @var{list1} and @var{n} times contained in @var{list2}, it will be @code{min(@var{m}, @var{n})} times contained in the result. @item @var{number1} * @var{number2} This yields the product of @var{number1} and @var{number2}. @end table @c ---------------------------------------------------------------------------- @node Operator Divide, , Operator Times, Expressions @subsection The Operator @samp{/} @cindex @code{/} (operator) This operator may only be used in the following ways: @table @code @item @var{list1} / @var{list2} This yields the list which contains all elements of @var{list1} which are not elements of @var{list2}. @item @var{list} / @var{number} This yields the list which contains all elements of @var{list} without the leftmost @var{number} elements, if @var{number} is positive, or without the rightmost -@var{number} elements, if @var{number} is negative. @item @var{number1} / @var{number2} Here, @var{number2} must not be 0. This yields the quotient of @var{number1} and @var{number2}. @end table @c ---------------------------------------------------------------------------- @node Conditions, Boolean Operators, Expressions, The Language @section Conditions @cindex conditions @cindex @code{yes} (symbol) @cindex @code{no} (symbol) A condition can either be true or false, as in @code{Verb = Verb} or @code{Verb = Noun}, respectively. An expression that is evaluated to any of the symbols @code{yes} or @code{no} is a valid condition. A condition can be used in all places where a non-constant value is needed. It will evaluate to @code{yes} or @code{no}. In this case, the condition must be surrounded by parentheses. @menu * Equality Tests:: Compare any values for equality. * Number Comparisons:: Test which number is greater. * Congruency Tests:: Check lists or multi-symbols for common elements. * Operator In:: Test an element or attribute for inclusion. * Regular Expressions:: String patterns. @end menu @c ---------------------------------------------------------------------------- @node Equality Tests, Number Comparisons, Conditions, Conditions @subsection The Operators @samp{=} and @samp{/=} @cindex @code{=} (operator) @cindex @code{/=} (operator) The condition @code{@var{expr1} = @var{expr2}} tests whether the expressions @var{expr1} and @var{expr2} are equal. Depending on the types of @var{expr1} and @var{expr2}, equality is defined as follows: @table @asis @item @var{expr1} and @var{expr2} are both symbols or both numbers. In this case @var{expr1} and @var{expr2} must be identical. @item @var{expr1} and @var{expr2} are strings. In this case @var{expr1} and @var{expr2} must be the same, but the test is case-insensitive. @item @var{expr1} and @var{expr2} are lists. In this case @var{expr1} and @var{expr2} must have the same length, and, for each @var{i}, the @var{i}-th element of @var{expr1} must be equal to the @var{i}-th element of @var{expr2}. @item @var{expr1} and @var{expr2} are records. In this case @var{expr1} and @var{expr2} must contain the same attribute names, though not necessarily in the same order. For each attribute name, the attribute value of @var{expr1} and the attribute value of @var{expr2} must be equal. @end table If @var{expr1} and @var{expr2} do not have the same type and are both different from the symbol @code{nil}, the test results in an error; the symbol @code{nil} can be compared to any value without error message. The test @code{@var{expr1} /= @var{expr2}} holds if and only if the test @code{@var{expr1} = @var{expr2}} does not hold. @c ---------------------------------------------------------------------------- @node Number Comparisons, Congruency Tests, Equality Tests, Conditions @subsection The Operators @code{less}, @code{less_equal}, @code{greater}, @code{greater_equal} @cindex @code{less} (operator) @cindex @code{less_equal} (operator) @cindex @code{greater} (operator) @cindex @code{greater_equal} (operator) A condition of type @code{@var{expr1} @var{operator} @var{expr2}} compares two numbers. Here, @var{operator} can have the following values: @table @code @item less The condition holds if @var{expr1} has a smaller value than @var{expr2}. @item less_equal The condition holds if @var{expr1} has a smaller value than @var{expr2} or both numbers are equal. @item greater The condition holds if @var{expr1} has a bigger value than @var{expr2} @item greater_equal The condition holds if @var{expr1} has a bigger value than @var{expr2} or both numbers are equal. @end table If either @var{expr1} or @var{expr2} is no number, an error will be reported. @c ---------------------------------------------------------------------------- @node Congruency Tests, Operator In, Number Comparisons, Conditions @subsection The Operators @samp{~} and @samp{/~} @cindex @code{~} (operator) @cindex @code{/~} (operator) The operator @samp{~} can be used in the following ways: @table @code @item @var{list1} ~ @var{list2} This tests whether @var{list1} and @var{list2} do @dfn{congruate}, this means, whether they have at least one element in common. @item @var{symbol1} ~ @var{symbol2} This tests if @code{atoms(@var{symbol1})} and @code{atoms(@var{symbol2})}, the lists of their atomic symbols, do congruate. @end table The comparison @code{@var{expr1} /~ @var{expr2}} holds if and only if the comparison @code{@var{expr1} ~ @var{expr2}} does not hold. @c ---------------------------------------------------------------------------- @node Operator In, Regular Expressions, Congruency Tests, Conditions @subsection The Operator @code{in} @cindex @code{in} (operator) The operator @code{in} can be only used in the following ways: @table @code @item @var{symbol} in @var{record} This condition holds if and only if @var{record} contains an attribute named @var{symbol}. @item @var{value} in @var{list} This condition holds if and only if @var{value} is an element of @var{list}. @end table @c ---------------------------------------------------------------------------- @node Regular Expressions, , Operator In, Conditions @subsection The @code{matches} Condition (Regular Expressions) @cindex @code{matches} (operator) @cindex expressions, regular @cindex regular expressions @cindex patterns, string @cindex string patterns The condition @code{@var{expr} matches @var{pattern}} or @code{@var{expr} matches (@var{pattern})} interprets @var{pattern} as a pattern (a regular expression) and tests whether @var{expr} matches @var{pattern}. Patterns are defined as follows: @table @asis @item @var{pattern} ::= @var{alternative} @{@samp{|} @var{alternative}@} The string must be identical with one of the alternatives. @item @var{alternative} ::= @{@var{atom} [@samp{*} | @samp{?} | @samp{+}]@} An alternative is a (possibly empty) sequence of atoms. An atom in a pattern corresponds to a character in a string. By using an optional postfix operator it is possible to specify for any atom how often it may be repeated within the string at that location: zero times or once (@samp{?}), at least once (@samp{+}), or arbitrarily often, including zero times (@samp{*}). Normally, these operators are @emph{greedy}, i.e. they try to match as much as possible. If you put a @samp{?} behind a postfix operator, it will try to match as few characters as possible. This can make a difference if you're assigning variables in your pattern. @item @var{atom} ::= @samp{(} @var{pattern} @samp{)} A pattern may be grouped by parentheses. @item @var{atom} ::= @samp{[} [@samp{^}] @var{range} @{@var{range}@} @samp{]} A character class. It represents exactly one character from one of the ranges. If the symbol @samp{^} is the first one in the class, the expression represents exactly one character that is @emph{not} contained in one of the ranges. @item @var{atom} ::= @samp{.} Represents any character. @item @var{atom} ::= @var{character} Represents the character itself. @item @var{range} ::= @var{character1} [@samp{-} @var{character2}] The range contains any character with a code at least as big as the code of @var{character1} and not bigger than the code of @var{character2}. The code of @var{character2} must be at least as big as the code of @var{character1}. If @var{character2} is omitted, the range only contains @var{character1}. @item @var{character} ::= Any character except @samp{*?+[]^-.\|()} To use one of the characters @samp{*?+[]^-.|()}, it must be preceded by a @samp{\\} (pattern escape). To insert the pattern escape itself, you have to double it: @samp{\\\\}. @end table You can divide the pattern into segments: @example $surf matches ("un|in|im|ir|il", ".*", "(en)?") @end example is is the same as @example $surf matches ("(un|in|im|ir|il).*(en)?") @end example A section of the string can be stored in a variable by suffixing the respective pattern with @samp{: @var{variable_name}}, as in @example $surf matches ("un|in|im|ir|il": $a, ".*") @end example For backwards compatibility, you may also prefix the pattern with the variable name, as in @example $surf matches $a: "un|in|im|ir|il", ".*" @end example The variables defined by pattern matching are only defined in the statement sequence which is being executed if the pattern matching is successful. A @code{matches} condition may not have variable definitions in it if it is @itemize @bullet @item contained in a disjunction (an @code{or} condition), @item contained in a negation (a @code{not} condition), or @item used as a truth value (e.g. in an assignment). @end itemize @c ---------------------------------------------------------------------------- @node Boolean Operators, Symbol Table, Conditions, The Language @section The Operators @code{not}, @code{and}, and @code{or} @cindex @code{not} (operator) @cindex @code{and} (operator) @cindex @code{or} (operator) @cindex boolean operators Conditions can be combined logically: @table @code @item not @var{cond} This is true if condition @var{cond} is false. @item @var{cond1} and @var{cond2} and @var{cond3} and ... This is true if all conditions @var{cond1}, @var{cond2}, @var{cond3}, ... are true. The conditions are tested one by one from left to right until one of them is false. This is called @dfn{short-cut evaluation}. @item @var{cond1} or @var{cond2} or @var{cond3} or ... This is true if at least one of the conditions @var{cond1}, @var{cond2}, @var{cond3}, ... is true. The conditions are tested one by one from left to right until one of them is true. This is also a form of short-cut evaluation. @end table The operator @code{not} takes exactly one argument. If its argument contains another logical operator, put it in parentheses @samp{()}, as in @code{not (@var{cond1} or @var{cond2})}. The operators @code{and} and @code{or} may not be mixed as in @code{@var{cond1} and @var{cond2} or @var{cond3}}; here the order of evaluation would be ambiguous. Use parentheses @samp{()} to indicate in wich order the condition is to be evaluated, as in @code{(@var{cond1} and @var{cond2}) or @var{cond3}}. @c ---------------------------------------------------------------------------- @node Symbol Table, Initial State, Boolean Operators, The Language @section The Symbol Table @cindex symbol table @cindex symbol definition Every symbol used in a grammar has to be defined at least once in the @dfn{symbol table}. Every symbol must be followed by a semicolon: @code{verb; noun; adjective;} Symbols that are being defined that way are called @dfn{atoms}. A symbol can also be defined as a @dfn{molecule}. Then the entry for this symbol has the following format: @cindex atoms @cindex molecules @example @var{symbol} := @var{list}; @end example The @var{list} for this symbol must consist of at least two atoms; no atom may occur more than once in the list. This list will be used by the operators @samp{~} and @samp{/~}, @code{atoms}, and @code{multi}. The lists in the symbol table must be different from each other; it does not suffice that they only differ in the order of their elements. If a symbol is defined more than once in the symbol table, the definitions must all match: Either the symbol must always be defined atomic or it must always be molecular with the same atom-list. @c ---------------------------------------------------------------------------- @node Initial State, Constant Definition, Symbol Table, The Language @section The Initial State @cindex state, initial @cindex initial state The initial state in a combination rule file is defined as follows: @example initial @var{value}, rules @var{rule1}, @var{rule2}, ...; @end example The initial state of a combi rule file specifies a feature structure and a list of rules (behind the keyword @code{rules}). Each of the rules will be applied to read in the first allomorph (in morphology) or word form (in syntax). The list may be enclosed in parentheses. @cindex failing rule @cindex rule, failing @cindex successful rule @cindex rule, successful A combi rule or an end rule is successful if it creates at least one new state, otherwise it fails. If you want rules to be executed only if all other rules failed, you can put their names behind the other rules' names and write an @code{else} in front of them: @example initial @var{value}, rules @var{rule1}, @var{rule2} else @var{rule3}, @var{rule4} else ...; @end example If both rules @var{rule1} and @var{rule2} fail, @var{rule3} and @var{rule4} are executed. If these rules also fail, the next rules are executed, and so on. @c ---------------------------------------------------------------------------- @node Constant Definition, Rules, Initial State, The Language @section The Constant Definition @cindex constant definition @cindex definition, constant A constant definition is of the form @example define @@@var{constant} := @var{expr}; @end example The constant expression @var{expr} will be evalued and the constant @@@var{constant} will be defined to have this value. The constant must not have been defined previously. The constant is valid from this definition up to the end of the rule file. If you use the keyword @code{default} instead of @code{define}, you provide a default value for @@@var{constant}. This means, the value is only preliminary and may be changed by a normal constant definition. After a constant has been used in an expression, its value may not be changed any more. @c ---------------------------------------------------------------------------- @node Rules, Statements, Constant Definition, The Language @section Rules @cindex rules @cindex @code{allo_rule} (rule) @cindex @code{combi_rule} (rule) @cindex @code{end_rule} (rule) @cindex @code{pruning_rule} (rule) @cindex @code{robust_rule} (rule) @cindex @code{input_filter} (rule) @cindex @code{output_filter} (rule) @cindex @code{subrule} (rule) A rule is a sequence of statements that is executed as a unit: @example combi_rule @var{name}(@var{$param1}, @var{$param2}, ...): @var{statement1} @var{statement2} ... end @var{name}; @end example A rule has to begin with one of the keywords @code{allo_rule}, @code{combi_rule}, @code{end_rule}, @code{pruning_rule}, @code{robust_rule}, @code{input_filter}, @code{output_filter} or @code{subrule}. It is followed by its @emph{parameter list}, a list of variable names. The variables will be assigned the parameter values when the rule is executed. The number of parameters depends on the rule type. The rule names have the following meanings: @table @code @item allo_rule(@var{$lex_entry}) An allo-rule must occur exactly once in an allomorph rule file. It analyses a lexical entry and must generate one or more allomorph entries via @code{result}. An allomorph rule has one parameter, namely the lexicon entry. @item combi_rule(@var{$state}, @var{$link}, @var{$surf}, @var{$index}) Any number of combi-rules may occur in a combi-rule file. Before processing such a rule, the @dfn{link} is read in, which is either the word form or the allomorph that follows the state's surface. The first parameter of the rule is the state's feature structure, the second is the link's feature structure, the third is the link's surface, and the fourth is the link's index. The third and the fourth parameter are optional. A combi-rule may state a successor rule set or accept the analysed input (both via @code{result}). @item end_rule(@var{$state}, @var{$remain_input}) Any number of end-rules may occur in a combi-rule file. The first parameter is the state's feature structure, the second, which is optional, is the remaining input. If the rule takes only one parameter, it is only called if the remaining input is empty or begins with a space. An end rule may accept the analysed input via @code{result}. @item pruning_rule(@var{$list}) A pruning-rule may occur at most once in a combi-rule file. During analysis, it can decide which states are still valid and which are to be deleted. The parameter is a list of feature structures of the states that have consumed the same input so far. The pruning-rule must execute a @code{return} statement with a list of the symbols @code{yes} and/or @code{no}. Each state in @var{$list} corresponds to a symbol in the result list. If the symbol is @code{yes}, the corresponding state is preserved. If the symbol is @code{no}, the state is abandoned. @item robust_rule(@var{$surface}, @var{$remain_input}) A robust-rule can only appear at most once a morphology rule file. If robust analysis has been switched on by the @code{robust} command, and a word form could not be recognised by the combi-rules, the robust-rule is executed with the surface of the next word form as its first parameter. The next word form is defined as the remaining input up to (but excluding) the next space. The optional second parameter contains the whole remaining input. A robust-rule can accept any prefix of the remaining input via @code{result}. @item input_filter(@var{$feature_structure_list}) An input-filter may occur at most once in a syntax rule file. The input-filter is called after a word form has been analysed. It gets one parameter, namely the list of the analysis results, and it transforms it to one or more filtered results (via @code{result}). @item output_filter(@var{$feature_structure_list}) An output-filter may occur at most once in any rule file. @table @emph @item In allo-rule files: The output-filter is called after all lexicon entry have been processed by the allo-rules. The filter is called for every allomorph surface. It gets one parameter, namely the list of the generated feature structures with that surface, and it transforms it to one or more filtered allomorph feature structures (via @code{result}). @item In combi-rule files: The output-filter is called after an item has been analysed. It gets one parameter, namely the list of the analysis results, and it transforms it to one or more filtered results (via @code{result}). @end table @item subrule(@var{$param1}, @var{$param2}, ...) Any number of subrules may occur in any rule file. A subrule can be invoked from other rules and it must return a value to this rule via @code{return}. It can have any number of parameters (at least one). @end table If a rule is executed, all statements in the rule are processed sequentially. After that, the rule execution is terminated. Thereby, the @code{if} statement, the @code{foreach} statement, and the @code{select} statement may change the processing order. Special conditions apply if: @enumerate @item A condition in a @code{require} statement does not hold. In this case the processing of the current rule path is terminated. This is not an error. @item The @code{stop} statement was executed. In this case the processing of the current rule path is terminated. This is not an error. @item An @code{assert} condition does not hold. In this case the processing of the whole grammar is terminated and an error message is displayed. This rule termination can be used to find bugs in the rule system or in the lexicon. @item The @code{error} statement was executed. In this case the processing of the whole grammar is terminated and an error message is displayed. @item The @code{return} statement was executed in a subrule or in a pruning rule. In a subrule, this terminates the subrule int the current rule path and immediately returns to the calling rule. In a pruning rule, this terminates the pruning rule. @end enumerate @c ---------------------------------------------------------------------------- @node Statements, Files, Rules, The Language @section Statements @cindex statements A rule body contains a sequence of statements. The statements are the assignment and the statements beginning with @code{assert}, @code{choose}, @code{define}, @code{error}, @code{foreach}, @code{if}, @code{repeat}, @code{require}, @code{result}, @code{return}, @code{select}, and @code{stop}. @menu * Assert:: Report an error if condition is not met. * The Assignment:: Assign a new value to a variable. * Break:: Break a @code{foreach} loop. * Choose:: Branch the current path for different values. * Continue:: Go to the next pass of a @code{foreach} loop. * Define:: Define a new variable. * Error:: Report an error. * Foreach:: Repeat statements for a given number of iterations. * If:: Conditionally execute statements. * Repeat:: Repeat statements for an unknown number of iterations. * Require:: Terminate the current path if condition is not met. * Result:: Emit a result in a rule. * Return:: Terminate the current subrule and return a value. * Select:: Branch the current path for different statement sequences. * Stop:: Terminate a path. @end menu @c ---------------------------------------------------------------------------- @node Assert, The Assignment, Statements, Statements @subsection The @code{assert} Statement The statement @code{assert @var{condition};} or @code{! @var{condition};} tests whether @var{condition} holds. If this is not the case, an error message with the line number in the source code is displayed and the processing of @emph{all} paths is terminated. The @code{assert} statement should be used to check whether there are structural flaws in the lexicon or the rule system. @c ---------------------------------------------------------------------------- @node The Assignment, Break, Assert, Statements @subsection The Assignment @cindex assignment To set the value of an already defined variable to a different value, use a statement of the following form: @example @var{$var} := @var{expr}; @end example The expression @var{expr} is evaluated and the result is assigned to the variable @var{$var}. The variable must have already been defined. You can assign the elements of a list value to multiple variables at once: @cindex list assignment @example <@var{$var1}, @var{$var2}, ... > := @var{expr}; @end example The first, second, ... element of @var{expr}, which must be a list, is assigned to variable @var{$var1}, @var{$var2}, ... respectively. Any of these variables may be followed by a path. The number of variables must match the length of the list value. You can optionally specify a path behind the variable that is to be set by an assignment: @example @var{$var}.@var{part1}.@var{part2} := @var{value}; @end example In this case, only the value of @code{@var{$var}.@var{part1}.@var{part2}} will be set to @var{value}; the remainder of the variable @var{$var} will be unchanged. Each @var{part} must be an expression that evaluates to a symbol, a number or a list of symbols and numbers. You can also use one of four other assignment operators instead of the operator @samp{:=}: The statement @code{@var{$var} :=+ @var{value};} is a shorthand for @code{@var{$var} := @var{$var} + @var{value};}. The same holds for the assignment operators @samp{:=-}, @samp{:=*}, and @samp{:=/}. Here, @var{$var} may be followed by a path again. @c ---------------------------------------------------------------------------- @node Break, Choose, The Assignment, Statements @subsection The @code{break} Statement @cindex @code{break} (statement) The @code{break} statement leaves the @code{foreach} loop with @var{Label}. @example break @var{Label}; @end example If the label is omitted, the break statement leaves the innermost @code{foreach} loop it is contained in. The statement must be situated in the body of the @code{foreach} loop it wants to leave. @c ---------------------------------------------------------------------------- @node Choose, Continue, Break, Statements @subsection The @code{choose} Statement @cindex @code{choose} (statement) The @code{choose} statement chooses an element of a list. Its format is: @example choose @var{$var} in @var{expr}; @end example For every element in the list @var{expr} a rule path is created; in this rule path the element is stored in the variable @var{$var}. Thus the number of rule paths can multiply. If, for example, @var{expr} has the value @code{}, the currently processed rule path has three continuations: In the first one @var{$var} has the value @code{A}, in the second one it has the value @code{B} and in the third one it has the value @code{C}. The three paths behave independently from now on. The @code{choose} statement can also be used for records. In that case, the variable @var{$var} gets a different attribute name of the record @var{expr} in each path. The @code{choose} statement also works for numbers: @itemize @bullet @item If @var{expr} is a positive number @var{n}, the variable @var{$var} is assigned the numbers 1, 2, ..., @var{n}, respectively, in each path. @item If @var{expr} is a negative number @var{-n}, the variable @var{$var} is assigned the numbers -1, -2, ..., @var{-n}, respectively, in each path. @end itemize @c ---------------------------------------------------------------------------- @node Continue, Define, Choose, Statements @subsection The @code{continue} Statement @cindex @code{continue} (statement) The @code{continue} statement terminates the current pass of the @code{foreach} loop with @var{Label} and starts the next pass. If the current pass is the last one, the loop will be left. @example continue @var{Label}; @end example If the label is omitted, the statement affects the innermost @code{foreach} loop it is contained in. The statement must be situated in the body of the @code{foreach} loop it wants to affect. @c ---------------------------------------------------------------------------- @node Define, Error, Continue, Statements @subsection The @code{define} Statement @cindex @code{define} (statement) A @code{define} statement is of the form @example define @var{$var} := @var{expr}; @end example The expression @var{expr} is evaluated and the result is assigned to the variable @var{$var}. The variable may not be defined before this statement; it is defined by the statement and only exists until the statement sequence in which the assignment is situated has been processed fully. You can assign the elements of a list value to multiple variables at once: @example define <@var{$var1}, @var{$var2}, ... > := @var{expr}; @end example The first, second, ... element of @var{expr}, which must be a list, is assigned to the new variable @var{$var1}, @var{$var2}, ... respectively. The number of variables must match the length of the list value. @c ---------------------------------------------------------------------------- @node Error, Foreach, Define, Statements @subsection The @code{error} Statement @cindex @code{error} (statement) The statement @code{error} terminates the execution of @emph{all} paths and displays the given expression, which must be a string, and the line of the source text: @example error @var{message}; @end example @c ---------------------------------------------------------------------------- @node Foreach, If, Error, Statements @subsection The @code{foreach} Statement @cindex @code{foreach} (statement) You may wish to manipulate all elements of a list or a record @emph{sequentially} in @var{one} rule path. For this purpose, the @code{foreach} statement was introduced. It has the following format: @example foreach @var{$var} in @var{expr}: @var{statements} end foreach; @end example Sequentually, @var{$var} is assigned a number of values, depending on the type of @var{expr}, and the statement sequence @var{statements} is executed for each of those assignments. Every time the @var{statements} are being walked through, the variable @var{$var} is defined again. Its scope is the block @var{statements}. @itemize @bullet @item If @var{expr} is a list, @var{$var} is assigned the first, second, third, ... element of @var{expr}. @item If @var{expr} is a record, @var{$var} is assigned the first, second, ... attribute name of @var{expr}. @item If @var{expr} is a positive number @var{n}, the variable @var{$var} is assigned the numbers 1, 2, ..., @var{n} sequentially. @item If @var{expr} is a negative number @var{n}, the variable @var{$var} is assigned the numbers -1, -2, ..., @var{-n} sequentially. @item If @var{expr} is an empty list, an empty record or the number 0, the foreach loop is terminated immediately. @end itemize @c ---------------------------------------------------------------------------- @node If, Repeat, Foreach, Statements @subsection The @code{if} Statement @cindex @code{if} (statement) @cindex @code{else} (keyword) @cindex @code{elseif} (keyword) An @code{if} statement has the following form: @example if @var{condition1} then @var{statements1} elseif @var{condition2} then @var{statements2} else @var{statements3} end if; @end example The @code{elseif} part may be repeated unrestrictedly (including zero times), the @code{else} part may be omitted. First, @var{condition1} is evaluated. If it is satisfied, the statement sequence @var{statements1} is executed. If the first condition is not satisfied, @var{condition2} is evaluated; if the result is true, @var{statements2} is executed. This procedure is repeated for every @code{elseif} part until a condition is satisfied. If the @code{if} condition and @code{elseif} conditions fail, the statement sequence @var{statements3} is executed (if it exists). After the @code{if} statement has been processed, the following statement is executed. The @code{if} after the @code{end} may be omitted. @c ---------------------------------------------------------------------------- @node Repeat, Require, If, Statements @subsection The @code{repeat} Statement @cindex @code{repeat} (statement) You may wish to repeat a sequence of statements while a specific condition holds. This can be realised by the @code{repeat} loop. It has the following form: @example repeat @var{statements1} while @var{condition}; @var{statements2} end repeat; @end example The statements @var{statements1} are executed. Then, @var{condition} is tested. If it holds, the @var{statements2} are executed and the @code{repeat} statement is executed again. If @var{condition} does not hold, execution proceeds after the @code{repeat} statement. If @var{statements1} is empty, the @code{repeat} loop is equivalent to a while loop in C: @example repeat while @var{condition}; @var{statements} end repeat; @end example If @var{statements2} is empty, the @code{repeat} loop is equivalent to a do-while loop in C: @example repeat @var{statements} while @var{condition}; end repeat; @end example @c ---------------------------------------------------------------------------- @node Require, Result, Repeat, Statements @subsection The @code{require} Statement @cindex @code{require} (statement) A statement of the form @example require @var{condition}; @end example or @example ? @var{condition}; @end example tests whether @var{condition} is true. If this is not the case the rule path is terminated @emph{without} error message. Test statements should be used to decide whether the combination of a state and a link is grammatical. @c ---------------------------------------------------------------------------- @node Result, Return, Require, Statements @subsection The @code{result} Statement @cindex @code{result} (statement) @cindex @code{accept} (keyword) @table @emph @item In combi rules: The statement @example result @var{expr}, rules @var{rule1}, @var{rule2}, ...; @end example specifies the Result feature structure of the rule and the successor rules. The value @var{expr} is the Result feature structure. Behind the keyword @code{rules} the names of all successor rules are enumerated. For every successor rule that is being executed a new rule path will be created. The rule set may be enclosed in parentheses. If you want successor rules to be executed only if no other rule has been successful, you can put their names behind the other rules' names and write an @code{else} in front of them: @example result @var{expr}, rules @var{rule1}, @var{rule2} else @var{rule3}, @var{rule4} else ...; @end example If none of the normal rules (here: @var{rule1} and @var{rule2}) has been successful, @var{rule3} and @var{rule4} are executed. If these rule also fail, the next rules are executed, and so on. A rule has been successful if at least one @code{result} statement has been executed. @item In combi-rules and end-rules: If the input is to be accepted by the @code{result} statement (and therefore no successor rules are to be called) the following format has to be used: @example result @var{expr}, accept; @end example If this statement is reached in a rule path, the input is accepted as grammatically well-formed. The value @var{expr} is returned as the result of the morphological or syntactic analysis. @item In filters: The format of a @code{result} statement in a filter or robust-rule is @example result @var{expr}; @end example If this statement is reached, the value @var{expr} is used as a result of the executed rule. @item In robust-rules: The format of a @code{result} statement in a robust-rule: @example result @var{feature_structure}; @end example or @example result @var{surface}, @var{feature_structure}; @end example The word form @var{surface} with feature structure @var{feature_structure} is used as a result of the robust-rule. @var{surface} must be a prefix of the input that has not been parsed yet. If it is omitted, the input up to, but excluding, the first space is taken. @item In allo-rules: The format of the @code{result} statement in an allo rule is: @example result @var{surface}, @var{feature_structure}; @end example It creates an entry in the allomorph lexicon. The allomorph surface @var{surface} must be a string; @var{feature_structure} is the feature structure of the allomorph. @end table @c ---------------------------------------------------------------------------- @node Return, Select, Result, Statements @subsection The @code{return} Statement @cindex @code{return} (statement) In a subrule, the @code{return} statement is of the following form: @example return @var{expr}; @end example The value of @var{expr} is returned to the rule that invoked this subrule and the subrule execution is finished. In a pruning rule, the @code{return} statement is of the same form. Here, @var{expr} must be a list a list of the symbols @code{yes} and/or @code{no}. Each state in the feature structure list, which is the pruning rule parameter, corresponds to a symbol in the result list. If the symbol is @code{yes}, the corresponding state is preserved. If the symbol is @code{no}, the state is abandoned. @c ---------------------------------------------------------------------------- @node Select, Stop, Return, Statements @subsection The @code{select} Statement @cindex @code{select} (statement) By using the @code{select} statement, more than one continuation of an analysis path can be generated. Its format is: @example select @var{statements1} or @var{statements2} or @var{statements3} ... end select; @end example This creates as many rule paths as there are statement sequences. In the first rule path, @var{statements1} are executed, in the second one @var{statements2} are executed, etc. Each rule path continues by executing the statements following the @code{select} statement. The keyword @code{select} behind the @code{end} can be omitted. @c ---------------------------------------------------------------------------- @node Stop, , Select, Statements @subsection The @code{stop} Statement @cindex @code{stop} (statement) The @code{stop} statement terminates the current rule path. Its format is: @example stop; @end example @c ---------------------------------------------------------------------------- @node Files, Syntax Summary, Statements, The Language @section Files @cindex files A Malaga grammar system comprises several files: a symbol file, a lexicon file, an allomorph rule file, a morphology rule file, an extended symbol file (optional), and a syntax rule file (optional). The type of a file can be seen by the ending of the file name. A grammar for the English language may consist of the files @file{english.sym}, @file{english.lex}, @file{english.all}, @file{english.mor} and @file{english.syn}. @menu * Symbol File:: The definition of all morphology symbols. * Extended Symbol File:: Additional syntax symbols. * Lexicon File:: The lexicon from which allomorphs will be created. * Allomorph Rule File:: The rules that create the allomorphs. * Combi-Rule Files:: The LAG rules that combine the allomorphs or words. @end menu @c ---------------------------------------------------------------------------- @node Symbol File, Extended Symbol File, Files, Files @subsection The Symbol File @cindex files, symbol @cindex symbol files A symbol file has the suffix @file{.sym}. It contains the symbol table. @c ---------------------------------------------------------------------------- @node Extended Symbol File, Lexicon File, Symbol File, Files @subsection The Extended Symbol File @cindex files, extended symbol @cindex symbol files, extended @cindex extended symbol files An extended symbol file has the suffix @file{.esym}. It contains an additional symbol table that contains symbols which may only be used in the syntax rule file. @c ---------------------------------------------------------------------------- @node Lexicon File, Allomorph Rule File, Extended Symbol File, Files @subsection The Lexicon File @cindex files, lexicon @cindex lexicon files A lexicon file has the suffix @file{.lex}. It consists of any number of values and constant definitions, each terminated by a semicolon. Each value stands for a lexical entry. A value may contain named constants and the operators @samp{.}, @samp{+}, @samp{-}, @samp{*}, and @samp{/}. values, the lexical entries; The format of the lexical entries is free, although it should be consistent with the conception of the whole rule system. @c ---------------------------------------------------------------------------- @node Allomorph Rule File, Combi-Rule Files, Lexicon File, Files @subsection The Allomorph Rule File @cindex files, allomorph rule @cindex rule files, allomorph @cindex allomorph rule files The allomorph lexicon is generated from the base form lexicon by applying the allo-rule on the base form entries. The allomorph generation rule file has the suffix @file{.all} and consists of one allo-rule, an optional output-filter, and any number of subrules and constant definitions. For every lexical entry, the allo-rule is executed with the value of the lexicon entry as parameter. The allo-rule can generate allomorphs using the @code{result} statement. After all allomorphs have been produced, the output-filter is executed once for each surface in the (intermediate) allomorph lexicon. As parameter, the output-filter gets the list of feature structures that share that surface. An entry in the final allomorph lexicon is created everytime the @code{result} statement is executed. The surface cannot be changed by the output-filter. @c ---------------------------------------------------------------------------- @node Combi-Rule Files, , Allomorph Rule File, Files @subsection The Combi-Rule Files @cindex files, combi-rule @cindex files, syntax rule @cindex files, morphology rule @cindex rule files, syntax @cindex rule files, morphology @cindex combi-rule files @cindex syntax rule files @cindex morphology rule files A grammar system includes up to two combination rules files: one for morphological combination with the suffix @file{.mor} and (optionally) one for syntactic combination with the suffix @file{.syn}. A combination rule file consists of an initial state and any number of combi-rules, subrules, and constant definitions. A syntax rule file may contain one optional pruning-rule, one optional input-filter and one optional output-filter; a morphology rule file may contain one optional robust-rule, one optional pruning-rule and one optional output-filter. Beginning with the rules listed up in the initial state, the rules and their successors are processed until a @code{result} statement with the keyword @code{accept} is encountered in every path. A path dies if there is no more input (from the lexicon or from the morphology) that can be processed. In morphology, if analysis has created no result and robust analysis has been switched on, the robust-rule will be called with the analysis surface and can create a result. In syntax, when a new wordfom has been imported from morphology, the input-filter can take a look at its feature structuress and create new result feature structures. If a pruning-rule is present, pruning has been activated, and the number of current LAG states is not less than @code{mor-pruning} (in morphology) or @code{syn-pruning} (in syntax), the concatenation of the next allomorph (in morphology) or word form (in syntax) is preceded by the following step: The feature structures of all current LAG states are merged into a list, which is the parameter of the pruning rule. The pruning-rule must execute a @code{return} statement with a list of the symbols @code{yes} and @code{no}. Each state in the feature structure list corresponds to a symbol in the result list. If the symbol is @code{yes}, the corresponding state is preserved. If the symbol is @code{no}, the state is abandoned. After analysis has completed, the output-filter can take a look at all result feature structures and create new result feature structures. This can be used to merge similar feature structures or drop some results. @c ---------------------------------------------------------------------------- @node Syntax Summary, , Files, The Language @section Summary of the Malaga Syntax @cindex syntax, Malaga The syntax of Malaga source texts is defined formally by a sort of EBNF notation: @itemize @bullet @item Terminals like @code{assert} and @samp{:=} stand for themselves. @item Nonterminals like @var{assignment} are defined by @dfn{productions}. @item A bar `|' separates alternatives. @item Brackets `[]' enclose optional parts. @item Curly braces `@{@}' enclose parts that are repeated zero times, one time, or multiple times. @item Parentheses `()' are used for grouping. @end itemize The start productions for Malaga source texts are @var{lexicon-file}, @var{rule-file}, and @var{symbol-file}. A nonterminal marked with @samp{*} in its definition is a lexical symbol. @table @var @item assert-statement: (@code{assert} | @samp{!}) @var{condition} @samp{;} @item assignment: @var{path} (@samp{:=} | @samp{:=+} | @samp{:=-} | @samp{:=*} | @samp{:=/}) @var{expression} @samp{;} | @samp{<} @var{path} @{@samp{,} @var{path}@} @samp{>} @samp{:=} @var{expression} @samp{;} @item break-statement: @code{break} [@var{label}] @samp{;} @item choose-statement: @code{choose} @var{variable} @code{in} @var{expression} @samp{;} @item comment*: @samp{#} @{@var{printing-char}@} @item comparison: [@code{not}] (@var{expression} [@var{comparison-operator} @var{expression}] | @var{match-comparison}) @item comparison-operator: @samp{=} | @samp{/=} | @samp{~} | @samp{/~} | @code{in} | @code{less} | @code{greater} | @code{less_equal} | @code{greater_equal} @item condition: @var{comparison} (@{@code{and} @var{comparison}@} | @{@code{or} @var{comparison}@}) @item constant*: @samp{@@} @var{identifier} @item constant-definition: (@code{define} | @code{default}) @var{constant} @samp{:=} @var{constant-expression} @samp{;} @item constant-expression: @var{expression} @item continue-statement: @code{continue} [@var{label}] @samp{;} @item define-statement: @code{define} @var{variable} @samp{:=} @var{expression} @samp{;} | @code{define} @samp{<} @var{variable} @{@samp{,} @var{variable}@} @samp{>} @samp{:=} @var{expression} @samp{;} @item error-statement: @code{error} @var{expression} @samp{;} @item expression: @var{term} @{(@samp{+} | @samp{-}) @var{term}@} @item factor: @var{value} @{@samp{.} @var{value}@} @item foreach-statement: [@var{label} @samp{:}] @code{foreach} @var{variable} @code{in} @var{expression} @samp{:} @var{statements} @code{end} [@code{foreach}] @samp{;} @item identifier*: (@var{letter} | @samp{_} | @samp{&}) @{@var{letter} | @var{digit} | @samp{_} | @samp{&}@} @item if-statement: @code{if} @var{condition} @code{then} @var{statements} @{@code{elseif} @var{condition} @code{then} @var{statements}@} [@code{else} @var{statements}] @code{end} [@code{if}] @samp{;} @item if-expression: @code{if} @var{condition} @code{then} @var{expression} @{@code{elseif} @var{condition} @code{then} @var{expression}@} @code{else} @var{expression} @code{end} [@code{if}] @item include: @code{include} @var{string} @samp{;} @item initial: @code{initial} @var{constant-expression} @samp{,} @var{rule-set} @samp{;} @item label: @var{identifier} @item lexicon-file: @{@var{constant-definition} | @var{constant-expression} @samp{;}@} @item list: @samp{<} @{@var{expression} @{@samp{,} @var{expression}@}@} @samp{>} @item match: @var{constant-expression} [@samp{:} @var{variable}] | @var{variable} @samp{:} @var{constant-expression} @item match-comparison: @var{expression} @code{matches} ( @samp{(} @var{match} @{@samp{,} @var{match}@} @samp{)} | @var{match} @{@samp{,} @var{match}@} ) @item number*: @var{digit} @{@var{digit}@} ( @samp{L} | @samp{R} | [@samp{.} @var{digit} @{@var{digit}@}] [@samp{E} @var{digit} @{@var{digit}@}] ) @item path: @var{variable} @{@samp{.} @var{value}@} @item record: @samp{[} @{@var{symbol-value-pair} @{@samp{,} @var{symbol-value-pair}@}@} @samp{]} @item repeat-statement: @code{repeat} @var{statements} @code{while} @var{condition} @samp{;} @var{statements} @code{end} [@code{repeat}] @samp{;} @item require-statement: (@code{require} | @samp{?}) @var{condition} @samp{;} @item result-statement: @code{result} @var{expression} [@samp{,} (@var{rule-set} | @code{accept})] @samp{;} @item return-statement: @code{return} @var{expression} @samp{;} @item rule: @var{rule-type} @var{rule-name} @samp{(} @var{variable} @{@samp{,} @var{variable}@} @samp{)} @samp{:} @var{statements} @code{end} [@var{rule-type}] [@var{rule-name}] @samp{;} @item rule-file: @{@var{rule} | @var{constant-definition} | @var{initial} | @var{include}@} @item rule-name: @var{identifier} @item rule-set: @code{rules} (@var{rules} @{@code{else} @var{rules}@} | @samp{(} @var{rules} @{@code{else} @var{rules}@} @samp{)}) @item rule-type: @code{allo_rule} | @code{combi_rule} | @code{end_rule} | @code{pruning_rule} | @code{robust_rule} | @code{input_filter} | @code{output_filter} | @code{subrule} @item rules: @var{rule-name} @{@samp{,} @var{rule-name}@} @item select-statement: @code{select} @var{statements} @{@code{or} @var{statements}@} @code{end} [@code{select}] @samp{;} @item statements: @{@var{assert-statement} | @var{assignment} | @var{break-statement} | @var{choose-statement} | @var{continue-statement} | @var{define-statement} | @var{error-statement} | @var{foreach-statement} | @var{if-statement} | @var{select-statement} | @var{repeat-statement} | @var{require-statement} | @var{result-statement} | @var{return-statement} | @var{stop-statement}@} @item stop-statement: @code{stop} @samp{;} @item string*: @samp{"} @{@var{char-except-double-quotes} | @samp{\"} | @samp{\\}@} @samp{"} @item subrule-invocation: @var{rule-name} @samp{(} @var{expression} @{@samp{,} @var{expression}@} @item symbol: @var{identifier} @item symbol-definition: symbol [@samp{:=} @samp{<} @var{symbol} @{@samp{,} @var{symbol}@} @samp{>}] @samp{;} @item symbol-file: @{@var{symbol-definition} | @var{include}@} @item symbol-value-pair: @var{expression} @samp{:} @var{expression} @item term: @var{factor} @{(@samp{*} | @samp{/}) @var{factor}@} @item value: [@samp{-}] (@var{symbol} | @var{string} | @var{number} | @var{list} | @var{record} | @var{constant} | @var{subrule-invocation} | @var{variable} | @samp{(} @var{condition} @samp{)}) | @var{if-expression} @item variable*: @samp{$} @var{identifier} @end table @c ---------------------------------------------------------------------------- @node Index, , The Language, Top @unnumbered Index @printindex cp @bye @c End of file. =============================================================== malaga-7.12/malaga.info0000644000175000017500000050613710761600771014325 0ustar bjoernbjoernThis is malaga.info, produced by makeinfo version 4.8 from ./malaga.texi. INFO-DIR-SECTION Malaga - a Natural Language Analysis System START-INFO-DIR-ENTRY * Malaga: (malaga). A Grammar Development Environment for Natural Languages. * malaga: (malaga)malaga. Analyse words/sentences using a Malaga grammar. * mallex: (malaga)mallex. Run allomorph rules on lexicon entries. * malmake: (malaga)malmake. Compile all files of a Malaga grammar. * malrul: (malaga)malrul. Compile a rule file of a Malaga grammar. * malsym: (malaga)malsym. Compile a symbol file of a Malaga grammar. END-INFO-DIR-ENTRY  File: malaga.info, Node: Top, Next: Introduction, Prev: (dir), Up: (dir) Malaga 7.12 *********** This is the documentation for Malaga, a software package for the development and application of grammars that are used for the analysis of words and sentences of natural languages. Copyright (C) 1995 Bjoern Beutel. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation. * Menu: * Introduction:: What is Malaga? * Formalism:: The grammar formalism used by Malaga. * The Programs:: Invoking `malaga' and its friends. * Commands:: Interactive commands for `malaga' and `mallex'. * Options:: Interactive options for `malaga' and `mallex'. * The Language:: Definition of the Programming Language Malaga. * Index:: The Index.  File: malaga.info, Node: Introduction, Next: Formalism, Prev: Top, Up: Top 1 Introduction ************** The Name "Malaga" is used with two different meanings: on the one hand, it is the name of a special purpose programming language, namely a language to implement grammars for natural languages. On the other hand, it is the name of a program package for development of Malaga Grammars and testing them by analysing words and sentences. "Malaga" is an acronym for "Merely a Left-Associative Grammar Application". The program package "Malaga" has been developed by Bjoern Beutel. Gerald Schueller has implemented parts of the debugger, parts of the Emacs Malaga mode, and the original Tree and Variable output via TCL/Tk. So far, morphology grammars for several natural languages have been developed with Malaga, including the Albanian, Bulgarian, English, Finnish, German, Italian, Korean and Spanish language.  File: malaga.info, Node: Formalism, Next: The Programs, Prev: Introduction, Up: Top 2 Malaga's Grammar Formalism **************************** A formal grammar for a natural language can be used to check whether a sentence or a word form is grammatically well-formed (a word form is a special inflectional form of a word, so "book" and "books" are two different word forms of the word "book"). Furthermore, a grammar can describe the structure and meaning of a sentence or a word form by a data structure that has been constructed during the analysis process. Malaga is using a formalism that is derived of the Left-Associative Grammar (LAG), which has been developed by Roland Hausser. An LAG analyses a sentence (or a word form) step by step: its parts are concatenated from the left to the right, hence the name "Left-Associative Grammar". A single LAG rule can only join two parts to a bigger one: it concatenates the state part (which is the beginning of the sentence or word form that has already been analysed) and the link part (which is the next word form or the next allomorph). In contrast to LAG, Malaga's formalism already reads in the first part of a word form or of a sentence by applying a rule. Take a look at the following sentence: Shakespeare liked writing comedies. The sentence is being analysed by five rule applications: "" + "Shakespeare" "Shakespeare" + "liked" "Shakespeare liked" + "writing" "Shakespeare liked writing" + "comedies" "Shakespeare liked writing comedies" + "." To apply a rule it's not sufficient to know the spelling of a word or an allomorph. A rule also requires morphological and syntactic information, such as word class, gender, meaning of a suffix etc. This information, which is associated with an element of an utterance, like a sentence, a word form or an allomorph, is called its "feature structure". The analysis of a sentence or a word form returns such a feature structure as result. Now let us take a closer look at how a sentence is analysed. 1. Before we can start to analyse a sentence, the analysis automaton must be in an "initial state". The initial state includes: * a feature structure for that state, and * the "combination rule" checking whether it is allowed to start with a specific word form. This rule also builds the feature structure of the successor state (whose surface consists of the first word form). 2. The next word form that is going to be added is read and analysed morphologically. If there is no valid word form, the analysis process aborts. 3. The feature structure that morphology assigns to this word form is called the link's feature structure. The feature structure of the input that has been analysed syntactically so far is called the state's feature structure. 4. The active combination rule checks whether it is allowed to combine the state's surface (which may be empty if the rule is operating on the initial state) with the link, i.e., the next word form. The combination rule takes the feature structures of the state and of the link as parameters. They can be compared by logical tests, and finally the feature structure of the successor state (whose surface includes the word form that has been read), is constructed by the rule. The rule also specifies which "successor rule" is active in the successor state. Execution then continues at step 2. Instead of specifying a successor rule, a rule can also _accept_ the analysed sentence. In that case, the feature structure of the successor state will be used as the feature structure of the complete analysed sentence. Morphological analysis operates analogously, except that a word form, composed from allomorphs, is being analysed. The link (step 2) is found in the allomorph lexicon. This sketch is of course simplified. There can be ambiguities in an analysis, induced by several causes: * The initial state may contain several rules to analyse the first word form or allomorph. * A rule may have multiple successor rules. * In morphology, the continuation of the input may match several trie entries. * In syntax analysis, the link may be assigned several feature structures by morphology. These ambiguities are coped with by dividing the analysis into several subanalyses: if there are two lexicon entries for a word form, for example, the analysis continues using the first entry (and its feature structure) as well as the second one. You can compare this with a branching path. The analyses will be continued independently of each other. So, one analysis path can accept the input while the other fails. Each analysis path can divide repeatedly when other ambiguities are met. If several analysis paths are continued until they accept, the analysis process returns more than one result.  File: malaga.info, Node: The Programs, Next: Commands, Prev: Formalism, Up: Top 3 The Malaga Programs ********************* The Malaga programs are all started in a similar manner: either you give the name of a "project file" as argument (this is not possible if you start `malrul' or `malsym'), or you give the name of the files that are needed by the program (for `malmake' and `malaga', you have to give the project file as argument). The file type is recognised by the file name ending. Assume you've written a grammar that consists of a symbol file `english.sym', an allomorph rule file `english.all', a lexicon file `english.lex' and a morphology rule file `english.mor', and you have also written a project file `english.pro'. You first have to create binary files from these files: malmake english.pro The source files must be in the Unicode UTF-8 format, which is also used for input and output by the Malaga programs. The binary files have the same name as their source counterparts, but have a `_l' (for little endian processors like x86), a `_b' (for big endian processors like HPPA) or a `_c' (for other architectures) appended. Now you can start the program `malaga' by entering the following command line: `malaga english.pro'. The names of the grammar files will be read from the project file. If you want to know about the command line arguments of a Malaga program, you can get help by using the option `-help' or `-h', like `mallex -help' If you just want to know which version of a Malaga program you are using, you can get the version number by using the option `-version' or `-v', like `malrul -version' The program just emits a few lines with information about its version number and about using and copying it. * Menu: * Projects:: Describing the parts of a Malaga grammar. * Profiles:: Settings for `malaga', `mallex' and `malshow'. * malaga:: Analysing words and sentences. * mallex:: Generating and debugging the allomorph lexicon. * malmake:: Controlling the compilation of a Malaga grammar. * malrul:: Compiling a Malaga rule file. * malsym:: Compiling a Malaga symbol file.  File: malaga.info, Node: Projects, Next: Profiles, Prev: The Programs, Up: The Programs 3.1 Projects ============ A couple of files, taken together, form a Malaga grammar: The "lexicon file" (`.lex') A lexicon of base forms. The "prelex file" (`.prelex', optional) A precompiled lexicon in binary format. The "allomorph rule file" (`.all') A file with rules which generate the allomorphs of the base forms. The "morphology rule file" (`.mor') A file with rules which combine allomorphs to word forms. The "symbol file" (`.sym') A file with the symbols that may be used in rules and feature structures. The "syntax rule file" (`.syn', optional) A file with rules that combine word forms to sentences. The "extended symbol file" (`.esym', optional) A file with additional symbols that may only be used in a syntax rule file. You can group these files together to a "project". To do this, you have to write a project file, with a name ending in `.pro', in which you list the names of the several files, each one behind a keyword (each file type in a line on its own). Imagine you have written a grammar that consists of the files `standard.sym', `webster.lex', `english.all', `english.mor', and `english.syn'. The project file for this grammar will look like this: sym: standard.sym lex: webster.lex all: english.all mor: english.mor syn: english.syn In your source files, you can include further source files by using the `include' statement; so a binary file of your grammar may be dependent on several source files. The program `malmake' uses the information in the project file to check for dependencies between source files and binaries, so the project file must contain the name of all source files for a specific binary. Relative path names are always relative to the directory of the project file. Assume, you've got a lexicon file `webster.lex' that looks like this: include "suffixes.lex"; include "verbs.lex"; include "adjectives.lex"; include "nouns.lex"; include "particles.lex"; include "abbreviations.lex"; include "names.lex"; include "numbers.lex"; In this case, you must write the names of all these files in the `lex:' line of your project file behind the name of the real lexicon file: lex: webster.lex suffixes.lex verbs.lex adjectives.lex lex: nouns.lex particles.lex abbreviations.lex names.lex numbers.lex Since there is a number of files in this example, the `lex:' line has been divided into two lines, each line starting with `lex:'. If you want to extend an existing project (for example, you might want to add a syntax rule file to a morphology grammar), you can include the project file of the morphology grammar in the project file of your syntax grammar by using a line starting with `include:': include: /projects/grammars/english/english.pro syn: english-syntax.syn The file entries in the project file of the morphology are treated as if they would replace the `include:' line. Relative paths in the included file are relative to the _included_ directory, not the _including_ directory. The programs `malaga' and `mallex' can set options like `hidden' or `robust' from the project file, so you do not need to set these options each time you start `malaga'. Each line in the project file that starts with `malaga:' and `mallex:', respectively, will be executed when `malaga' and `mallex', respectively, has been started, but you may only use the `set' command, so you can only set options in the project file. Here is an example: ... malaga: set hidden +semantics malaga: set robust-rule on mallex: set hidden +semantics +syntax ... When you start `malaga', the commands `set hidden +semantics' and `set robust-rule on' will be executed; when you start `mallex', the command `set hidden +semantics +syntax' will be executed. Options in project files that are read in by `include:' lines in other project files will be executed as if they were in place of the `include:' line. Lines in project files that start with `info:' contain information about the grammar. In `malaga', you get this information if you use the command `info'. Example: info: ===================================== info: Deutsche Malaga Morphologie 3.0 info: written by Oliver Lorenz, 11.04.1997 info: ===================================== The Korean writing system, Hangul, needs special treatment, because the characters it uses are syllables that must be split up into individual letters for morphological analysis. Such a conversion is built-in into malaga. To activate this Hangul support, insert the following line into your project file: split-hangul-syllables: yes If Hangul support has been switch on, you may also enter Hangul text in a Latin transcription that is based on the Yale transcription. Transcribed text must be contained in curly brackets, and each syllable must start with a dot, for example `{.cwess.ta}'. Malaga can also display Hangul text in Latin transcription if Hangul support has been activated. This can be controlled by the option `roman-hangul'. When Malaga splits Hangul syllables, you must be aware that string operations work with Hangul letters, even if you have entered syllables in you grammar source code: * In a pattern, a character class that contains a syllable will match each single Hangul letter that is part of that syllable. Only use single letters in character classes. If you want to select between different syllables, use alternatives, separated by vertical bars. * In a pattern, when a postfix operator (`*', `?', or `+') follows a Hangul syllable, it will only operate on the last letter of that syllable. If you want the operator to work on the whole syllable, put the syllable in parentheses. * The functions `substring' and `length' will count single characters, not syllables.  File: malaga.info, Node: Profiles, Next: malaga, Prev: Projects, Up: The Programs 3.2 The Malaga Profiles `.malagarc' or `malaga.ini' =================================================== If you prefer some options that you want to use with every Malaga project, you may create a personal profile. On POSIX systems, it is located in your home directory and is called `.malagarc'. In Microsoft Windows (NT based) systems, it is located in your user profile directory and is called `malaga.ini'. In Microsoft Windows (DOS based) systems, it is located in the root directory of your system drive and is also called `malaga.ini'. You can enter `malaga' and `mallex' options in the same manner as you do in the project file: malaga: set display-cmd "malshow" malaga: set use-display yes mallex: set display-cmd "malshow" mallex: set use-display yes The settings in your personal profile override the settings in the project file. You can set some attributes of the graphical user interface `malshow', like the position, the size, and the font size of each window that is opened by `malshow'. The following attributes are available: `*_geometry:' Defines the size and/or position of a window. The "*" must be replaced by the name of the window, which may be `allomorphs', `path', `result', `tree', `variables', or `expressions'. The attribute must be followed by an expression like `628x480+640+512'. The first two numbers (`628x480') define the width and the height of the window in pixels, the last two numbers (`+640+512') define the position of its upper left corner. `font:' The attribute must be followed by the name of the font family to use. `font_size:' The attribute must be followed by an integer font size, given in points. The available font sizes are 8, 10, 12, 14, 18, and 24 points. `show_indexes:' The attribute must be followed by `yes' or `no', which determines whether state indexes are shown in the Tree and Path windows. `hanging_style:' The attribute must be followed by `yes' or `no', which determines whether horizontally adjacent complex values are aligned at their top lines ("hanging style") or at their bottom lines ("non-hanging style"). `inline_path:' The attribute must be followed by `yes' or `no', which determines whether the components of a state or a link in a path will be arranged horizontally or vertically. For small feature-structures, e.g. in formal grammars, horizontal arrangement is better readable, while full-blown natural language grammar paths look better in vertical arrangement. `show_tree:' A three-valued attribute that determines which states of a tree are shown. Possible values are: `full', `no_dead_ends' and `result_paths'. Here is an example which sets every option available: allomorphs_geometry: 628x480+640+0 path_geometry: 628x480+640+0 result_geometry: 628x480+640+0 tree_geometry: 628x480+640+512 variables_geometry: 628x480+640+512 expressions_geometry: 628x480+640+0 font: helvetica font_size: 12 show_indexes: yes hanging_style: yes inline_path: yes show_tree: no_dead_ends  File: malaga.info, Node: malaga, Next: mallex, Prev: Profiles, Up: The Programs 3.3 The Program `malaga' ======================== The program `malaga' is the user interface for analysing word forms and sentences, displaying the results and finding bugs in a grammar. Start `malaga' with the name of a project file as argument: malaga english.pro When `malaga' has been started, it loads the symbol file, the lexicon file and the morphology rule file, and the syntax rule file, if there is one. After loading, the "prompt" appears. Then `malaga' is ready to execute your commands: $ malaga english.pro This is malaga, version 7.12. Copyright (C) 1995 Bjoern Beutel. This program is part of Malaga, a system for Natural Language Analysis. You can distribute it under the terms of the GNU General Public License. malaga> You can now enter any `malaga' command. If you are not sure about the name of a command, use the command `help' to get an overview of all `malaga' commands. If you want to quit `malaga', enter the command `quit'. You can use the following command line options when you start `malaga': `-morphology' or `-m' Starts `malaga' in "morphology mode". That is, word forms are being read in from the standard input stream and analysed (one word form per line). The analysis result is being written to the standard output stream. `-syntax' or `-s' Starts `malaga' in "syntax mode". That is, sentences are being read in from the standard input stream and analysed (one sentence per line). The analysis result is being written to the standard output stream. `-quoted' or `-q' When `malaga' has been started in syntax or morphology mode, and the option `-quoted' has been used, then each input line must be enclosed in double quotes which are removed prior to analysis. Within the double quotes there may be any combination of printable characters except the backslash `\' and the double quotes. These characters must be preceded by a `\' (escape character). `-input' or `-i' Starts `malaga' in "argument analysis mode". That is, the argument following the `-input' is being analysed. Either the `-morphology' or the `-syntax' option must also be given. The analysis result is being sent to the standard output stream in a structured format.  File: malaga.info, Node: mallex, Next: malmake, Prev: malaga, Up: The Programs 3.4 The Program `mallex' ======================== By using `mallex', you can make the allomorph rules process the entries of a base form lexicon. You can start `mallex' either with the name of a project file or with the names of the needed grammar files: mallex english.pro or mallex english.sym english.all english.lex If you are not using a project file, you must give * the name of the symbol file (`.sym'), * the name of the allomorph rule file (`.all'), * the name of the lexicon file (`.lex', in batch mode), and * the name of the prelex file (`.prelex', in batch mode, optional). Normally, `mallex' runs interactively: it loads the symbol file and the allomorph rule file. Then the "prompt" appears: $ mallex english.pro This is mallex, version 7.12. Copyright (C) 1995 Bjoern Beutel. This program is part of Malaga, a system for Natural Language Analysis. You can distribute it under the terms of the GNU General Public License. mallex> You can now enter any `mallex' command. If you do not remember the command names, you can use the command `help' to see an overview of the `mallex' commands. If you want to quit `mallex', enter the command `quit'. If you have started `mallex' by using the option `-binary' or `-b', it creates the run time lexicon file from the base form lexicon file and the optional prelex file. If the lexicons are very big or the allomorph rules are very complex, this can take some time. After creation, `mallex' exits. If you have started `mallex' by using the option `-prelex' or `-p', it creates a precompiled lexicon file from the source lexicon file and the optional prelex file and exits. You can use the following command line options when you start `mallex': `-binary' or `-b' Runs `mallex' in batch mode and creates the run-time lexicon. `-readable' or `-r' Runs `mallex' in batch mode and outputs the allomorph lexicon in readable form on the standard output stream. `-prelex' or `-p' Runs `mallex' in batch mode, but doesn't apply the allomorph filter yet. Outputs the allomorph lexicon as a `.prelex' binary file.  File: malaga.info, Node: malmake, Next: malrul, Prev: mallex, Up: The Programs 3.5 The Program `malmake' ========================= The program `malmake' reads a project file, checks if all grammar files needed do exist, and translates all grammar files that have not yet been translated or whose source files have changed since they have been translated. `malmake' itself calls the programs `malsym', `mallex' and `malrul' if needed. An example: assume you have written a morphology grammar whose grammar files are bundled in a project file `english.pro': sym: rules/english.sym all: rules/english.all lex: rules/english.lex lex/adjectives.lex lex: lex/particles.lex lex/suffixes.lex lex/verbs.lex lex: lex/nouns.lex lex/abbreviations.lex lex/numbers.lex mor: rules/english.mor mallex: set hidden +semantics +syntax malaga: set hidden +semantics When executing `malmake dmm.pro' for the first time, the symbol file, the rule files and the lexicon file will be translated: $ malmake dmm.pro compiling "dmm.sym" compiling "dmm.all" compiling "dmm.mor" compiling "dmm.lex" project is up to date $ If you want all files to be recompiled on all accounts, use the option `-new' or `-n'. The translation of a big lexicon can take some minutes, since the allomorph rules have to be executed for each lexicon entry.  File: malaga.info, Node: malrul, Next: malsym, Prev: malmake, Up: The Programs 3.6 The Program `malrul' ======================== The program `malrul' translates Malaga rule files, i.e. files that have the endings `.all', `.mor' or `.syn'. The compiled file gets the suffix `_l', `_b', or `_c', depending on the endianness of your processor. Give the following arguments if you are starting `malrul': * the name of the rule file that is to be translated, and * the name of the associated symbol file (`.sym' or `.esym'). The order of the arguments is arbitrary. Here is an example: malrul english.mor english.sym  File: malaga.info, Node: malsym, Prev: malrul, Up: The Programs 3.7 The Program `malsym' ======================== `malsym' can translate Malaga symbol files, i.e. files having the ending `.sym' or `.esym'. The translated file gets the suffix `_l', `_b', or `_c', depending on the endianness of your processor. For example: malsym english.sym If you are translating an extended symbol file with the ending `.esym', enter the name of the compiled symbol file after the command line option `-use' or `-u': malsym english.esym -use english.sym This argument is needed since extended symbol files are extensions of ordinary symbol files. If you use the command line option `-split-hangul-syllables' when starting `malsym', the symbol file and all the Malaga files that use it will split up Hangul syllables in individual letters internally. This option is invoked by `malmake' if the project file contains the line `split-hangul-syllables: yes'.  File: malaga.info, Node: Commands, Next: Options, Prev: The Programs, Up: Top 4 The Commands of `malaga' and `mallex' *************************************** Since the user interfaces of `malaga' and `mallex' are very similar and since they have a bunch of commands in common, I will describe them in a common chapter. Commands that can be used in `malaga' or in `mallex' only, are marked by the name of the program in which they can be used. * Menu: * backtrace:: Show where rule execution has stopped. * break:: Add a new breakpoint. * clear-cache:: Clear the word cache. * continue:: Continue execution up to next breakpoint. * debug-ga:: Debug Generating Allomorphs. * debug-ga-file:: Debug Generating Allomorphs from a file. * debug-ga-line:: Debug Generating Allomorphs from a single line in a file. * debug-ma:: Debug Morphology Analysis. * debug-ma-line:: Debug Morphology Analysis of a line in a file. * debug-sa:: Debug Syntax Analysis. * debug-sa-line:: Debug Syntax Analysis of a line in a file. * debug-state:: Debug rule execution at an analysis state. * delete:: Delete breakpoints. * down:: Show code position and variables in calling rule. * finish:: Continue execution up to return or path termination. * frame:: Show code position and variables of a frame. * ga:: Generate Allomorphs. * ga-file:: Generate Allomorphs from a file. * ga-line:: Generate Allomorphs from a single line in a file. * get:: Get current values of options. * help:: Get help about commands and options. * info:: Get info about current grammar. * list:: List current breakpoints. * ma:: Analyse a word. * ma-file:: Analyse words in a file. * ma-line:: Analyse a word at line in a file. * mg:: Generate words from allomorphs. * next:: Continue execution up to next line, skip subrules. * print:: Display a variable or constant or a part of it. * quit:: Quit `malaga' or `mallex'. * read-constants:: Read constant definitions in lexicon file. * result:: Show results. * run:: Continue execution up to the end. * sa:: Analyse a sentence. * sa-file:: Analyse sentences in a file. * sa-line:: Analyse a sentence at a line in a file. * set:: Set values of options. * sg:: Generate sentences from words. * step:: Continue execution up to next line, enter subrules. * transmit:: Send value to transmit process and display answer. * tree:: Display analysis tree. * up:: Show code position and variables in called rule. * variables:: Display current variables. * walk:: Execute until next rule. * where:: Show current analysis state.  File: malaga.info, Node: backtrace, Next: break, Prev: Commands, Up: Commands 4.1 The Command `backtrace' =========================== If you are executing your rules in debug mode or the rules were interrupted by an error, this command shows where rule execution currently stopped. If it stopped in a subrule, all calling rules are also shown. The currently examined rule is marked with a `*': debug> backtrace *2: "dmm.mor", line 1218, rule "deletePOS" 1: "dmm.mor", line 31, rule "Start" debug> This means, rule execution stopped in frame 2, line 1218 of `dmm.mor', in rule `deletePOS'. This subrule was called from frame 1, line 31 in `dmm.mor', in rule `Start'.  File: malaga.info, Node: break, Next: clear-cache, Prev: backtrace, Up: Commands 4.2 The Command `break' ======================= If you want to stop the rules at a specific point, for example to take a look at the variables, you can use the command `break' to set "breakpoints". A breakpoint is a point in the rule source text where rule execution is interrupted, so you can enter commands in debug mode. Breakpoints are only active in debug mode, this means you have started rule execution by a debug command or you have continued rule execution by one of the commands `step', `next', `walk', or `continue'. Behind the command name, `break', you can give one of the following arguments: A line number. A breakpoint is set at this line in the current source file. If there is no statement starting at this line, the breakpoint will be set at the nearest line where a statement starts. You can, for example, set a breakpoint at line 245 in the current source file by entering the command break 245 A file name and a line number. A breakpoint is set at this line in this file. If there is no statement starting at this line, the breakpoint will be set at the nearest line where a statement starts. An example: break english.syn 59 A rule name. A breakpoint is set at the first statement in this rule. An example: break final_rule If the rule name or the file name is ambiguous, you can insert an abbreviation for the rule system you refer to. Put it in front of the rule name or the file name. The following abbreviations are used: * `all' for allomorph rules, * `mor' for morphology rules, * `syn' for syntax rules, If you omit any argument, the breakpoint is set on the current line in the current file (this is helpful in debug mode). Every breakpoint gets a unique number once it has been set, so you can delete it later, when you do not need it any longer. You can list the breakpoints using the command `list' and delete them using `delete'.  File: malaga.info, Node: clear-cache, Next: continue, Prev: break, Up: Commands 4.3 The Command `clear-cache' (`malaga') ======================================== If you have changed your settings so that the wordform cache is no longer valid, you can clear the cache using `clear-cache'. This can be necessary if you have turned on/off input or output filters or modified switches.  File: malaga.info, Node: continue, Next: debug-ga, Prev: clear-cache, Up: Commands 4.4 The Command `continue' ========================== This command can only be executed in debug mode. It resumes rule execution and may be followed by: _Nothing._ Rule execution is continued until a breakpoint is met or the rules have been executed completely. _A line number._ Rule execution is continued until a breakpoint is met, the rules have been executed completely or the given line in the current source file is met. If there is no statement starting at this line, execution will be stopped at the nearest line where a statement starts. You can, for example, continue execution until line 245 in the current source file is met by entering the command continue 245 _A file name and a line number._ Rule execution is continued until a breakpoint is met, the rules have been executed completely or the given line in the given file is met. If there is no statement starting at this line, execution will be stopped at the nearest line where a statement starts. An example: continue english.syn 59 _A rule name._ Rule execution is continued until a breakpoint is met, the rules have been executed completely or the first statement of the given rule is met. An example: continue final_rule _A comparison._ The comparison must be of the form `VARIABLE = VALUE', where VARIABLE may be any variable name, maybe followed by a path, and VALUE may be any Malaga value. Rule execution is continued until a breakpoint is met, the rules have been executed completely or until VARIABLE is defined and its value is VALUE.  File: malaga.info, Node: debug-ga, Next: debug-ga-file, Prev: continue, Up: Commands 4.5 The Command `debug-ga' (`mallex') ===================================== Use `debug-ga' to find errors in your allomorph rules. This command works like `ga', but the allomorph generation will be stopped before the first statement of the first rule is executed: mallex> debug-ga [surface: "john", class: name] at rule "irregular_verb" debug> The prompt `debug>' that appears instead of `mallex>' indicates that `mallex' is currently executing the allomorph rules but has been interrupted. Since this ability has been developed to support the _debugging_ of Malaga rules, this mode is called "debug mode". When `mallex' arrives at the start of a new rule in debug mode (as in the example above), the name of this rule is displayed. When in debug mode, you can always get the name of the current rule using the command `rule'. If you're running `mallex' from Emacs, another Emacs window will display the source file. An arrow is used to show to the statement that will be executed next. ... allo_rule irregular_verb ($entry): =>? $entry.class = verb; ... In debug mode, you can, for example, get the variables that are currently defined (using `variable' or `print'), and you can execute statements (using `step', `next', `walk', `continue', or `run'). If you want to quit the debug mode, just enter `run'. The remaining statements for generation will then be executed without interruption.  File: malaga.info, Node: debug-ga-file, Next: debug-ga-line, Prev: debug-ga, Up: Commands 4.6 The Command `debug-ga-file' (`mallex') ========================================== Use the command `debug-ga-file' to make the allomorph rules work on a lexicon file in debug mode. Assume you have written a lexicon file `mini.lex': [surface: "m{a}n", class: noun]; [surface: "table", class: noun]; [surface: "wise", class: adjective]; To let the rules process this lexicon in debug mode, enter: debug-ga-file mini.lex  File: malaga.info, Node: debug-ga-line, Next: debug-ma, Prev: debug-ga-file, Up: Commands 4.7 The Command `debug-ga-line' (`mallex') ========================================== Use the command `debug-ga-line' to make the allomorph rules generate allomorphs for a single lexicon entry in debug mode. Assume you want to test the second line in the lexicon file `mini.lex': [surface: "m{a}n", class: noun]; [surface: "table", class: noun]; [surface: "wise", class: adjective]; Enter the following line: debug-ga-line mini.lex 2 Then `mallex' stops in debug mode at the entry of the first allomorph rule that is being executed for the lexicon entry [surface: "table", class:noun]; If there is no lexicon entry at this line, the subsequent lexicon entry will be taken.  File: malaga.info, Node: debug-ma, Next: debug-ma-line, Prev: debug-ga-line, Up: Commands 4.8 The Command `debug-ma' (`malaga') ===================================== Use the command `debug-ma' to find errors in your morphology combination rules. This command analyses the rest of the command line morphologically and executes the morphology combination rules in debug mode. Debug mode is explained for the command `debug-ga'.  File: malaga.info, Node: debug-ma-line, Next: debug-sa, Prev: debug-ma, Up: Commands 4.9 The Command `debug-ma-line' (`malaga') ========================================== Use the command `debug-ma-line' to find errors in your morphology combination rules. This command analyses the rest of the command line morphologically and executes the morphology combination rules in debug mode. Debug mode is explained for the command `debug-ga'.  File: malaga.info, Node: debug-sa, Next: debug-sa-line, Prev: debug-ma-line, Up: Commands 4.10 The Command `debug-sa' (`malaga') ====================================== Use the command `debug-sa' to find errors in your syntax combination rules. This command analyses the rest of the command line syntactically and executes the syntax combination rules in debug mode. Debug mode is explained for the command `debug-ga'.  File: malaga.info, Node: debug-sa-line, Next: debug-state, Prev: debug-sa, Up: Commands 4.11 The Command `debug-sa-line' (`malaga') =========================================== Use the command `debug-sa-line' to find errors in your syntax combination rules. This command analyses the rest of the command line morphologically and executes the morphology combination rules in debug mode. Debug mode is explained for the command `debug-ga'.  File: malaga.info, Node: debug-state, Next: delete, Prev: debug-sa-line, Up: Commands 4.12 The Command `debug-state' (`malaga') ========================================= Use the command `debug-state' to execute the successor rules of a specific LAG state in debug mode. Previously, you must have already analysed a word or a sentence, respectively. Let malaga display the analysis tree by entering `tree', move the mouse pointer over the state you want to debug, and press the left mouse button. A window opens in which this state's feature structure is shown. The window's title line contains the index of the state. Use this number as argument for `debug-state'. The last analysis input will be analysed again, and analysis stops when reaching the first successor rule of the specified state and malaga switches to debug mode. Debug mode is explained for the command `debug-ga'.  File: malaga.info, Node: delete, Next: down, Prev: debug-state, Up: Commands 4.13 The Command `delete' ========================= If you want to delete a breakpoint, use the command `delete' with the number of the breakpoints as argument. Enter `delete all' to delete all breakpoints.  File: malaga.info, Node: down, Next: finish, Prev: delete, Up: Commands 4.14 The Command `down' ======================= If you want to look at the source and the variables of the (sub)rule that is currently being called by the current subrule, you can do this by entering `down'. You can list the frames via `backtrace'.  File: malaga.info, Node: finish, Next: frame, Prev: down, Up: Commands 4.15 The Command `finish' ========================= This command can only be executed in debug mode. The rule execution will be resumed and continues until a `return' statement is met or until the current rule path will be terminated.  File: malaga.info, Node: frame, Next: ga, Prev: finish, Up: Commands 4.16 The Command `frame' ======================== If you want to look at the source and the variables of a (sub)rule that has called the current subrule, directly or indirectly, you can do this by typing `frame' and the number of the frame you want to examine. You can list the frames via `backtrace'.  File: malaga.info, Node: ga, Next: ga-file, Prev: frame, Up: Commands 4.17 The Command `ga' (`mallex') ================================ Use the command `ga' (short for _generate allomorphs_) to generate allomorphs. This is useful for testing allomorph generation from within `mallex'. When you enter the command, give a lexicon entry as argument. All allomorphs that are generated from this entry by the allomorph rules, are displayed on screen. For example: mallex> ga [Lemma: "!", POS: Punctuation, Type: ExclamationMark] "!": [POS: , Punctuation: <[Allomorph: "!", BaseForm: "!", concatStem: no, concatSx: no, POS: Punctuation, Type: ExclamationMark, terminal: yes]>, Surface: "!"] mallex> If the rules create multiple allomorphs from an entry, they are displayed one after another.  File: malaga.info, Node: ga-file, Next: ga-line, Prev: ga, Up: Commands 4.18 The Command `ga-file' (`mallex') ===================================== Use the command `ga-file' to make the allomorph rules generate allomorphs for a lexicon file. Assume you have written a lexicon file `mini.lex': [surface: "m{a}n", class: noun]; [surface: "table", class: noun]; [surface: "wise", class: adjective]; To generate the allomorphs for this lexicon, enter `ga-file mini.lex'. This will produce a readable allomorph file whose name ends in `.out'; for `mini.lex' its name will be `mini.lex.out': "man": [class: noun, syn: singular] "men": [class: noun, syn: plural] "table": [class: noun] "wise": [class: adjective, restr: complete] "wis": [class: adjective, restr: inflect]  File: malaga.info, Node: ga-line, Next: get, Prev: ga-file, Up: Commands 4.19 The Command `ga-line' (`mallex') ===================================== Use the command `ga-line' to make the allomorph rules generate allomorphs for a single lexicon entry. Assume you want to test the second line in the lexicon file `mini.lex': [surface: "m{a}n", class: noun]; [surface: "table", class: noun]; [surface: "wise", class: adjective]; Enter the following line: ga-line mini.lex 2 Then `mallex' generates allomorphs for `[surface: "table", class:noun];'. If there is no lexicon entry at this line, the subsequent lexicon entry will be taken.  File: malaga.info, Node: get, Next: help, Prev: ga-line, Up: Commands 4.20 The Command `get' ====================== This command is used to query settings of `malaga' or `mallex'. Enter it together with the name of the option whose setting you want to know. The possible options are described in the next chapter. If you just enter `get', all settings will be shown.  File: malaga.info, Node: help, Next: info, Prev: get, Up: Commands 4.21 The Command `help' ======================= Use this command to get a list of the commands you can use. If you give the name of a command or an option as argument, a short explanation of this item will be displayed. If a name represents a command as well as an option, prepend `command' or `option' to it.  File: malaga.info, Node: info, Next: list, Prev: help, Up: Commands 4.22 The Command `info' (`malaga') ================================== This command gives you information about the grammar you are using. It takes no argument.  File: malaga.info, Node: list, Next: ma, Prev: info, Up: Commands 4.23 The Command `list' ======================= If you enter the command `list', all breakpoints are listed. For each breakpoint, its number, the name of the source file and the source line is shown.  File: malaga.info, Node: ma, Next: ma-file, Prev: list, Up: Commands 4.24 The Command `ma' (`malaga') ================================ The command `ma' (for _morphological analysis_) starts a word form analysis. Give the word form that you want to be analysed as argument: ma house Malaga will show the results automatically, and it will also show the analysis tree automatically if you specified it using the `auto-tree' option. You can look at the results using `result' or at the entire analysis tree using `tree'. If you do not enter a word form behind the command `ma', `malaga' re-analyses the last input.  File: malaga.info, Node: ma-file, Next: ma-line, Prev: ma, Up: Commands 4.25 The Command `ma-file' (`malaga') ===================================== The command `ma-file' can be used to analyse files that contain word lists. A word list consists of a number of word forms, each word form on a line on its own. There may be empty lines in a word list. The following example is a word list called `word-list': table men's blue handicap To analyse this word list, enter: ma-file word-list result This will produce a file `result' that contains the analysis results. If the second argument is missing, the result will be written to a file whose name ends in `.out'; for `word-list', its name will be `word-list.out': 1: "table": [class: noun, ...] 2: "men's": [class: noun, ...] 3: "blue": [class: noun, ...] 3: "blue": [class: adjective, ...] 3: "blue": [class: name, ...] 4: "handicap: unknown The number at the line start represents the line number of the analysed original word form. The output format can be changed by using the options `result-format' and `unknown-format'. If a runtime error occurs during the analysis of a word, the line will be output in the format given by the option `error-format'. After the analysis, some statistics will be displayed: * The number of analysed word forms. * The number of recognised word forms. * The number of word forms recognised by combi-rules and end-rules. * The number of word forms recognised by robust-rules. * The number of word forms whose analyses produced errors. * The average number of results per word form. * The analysis run time. * The average number of word forms that have been analysed per second. * The number of cache accesses. * The number of cache hits.  File: malaga.info, Node: ma-line, Next: mg, Prev: ma-file, Up: Commands 4.26 The Command `ma-line' (`malaga') ===================================== You can use this command to analyse a single line in a text file morphologically. Assume you want to analyse the word in the third line in the file `words'. Then enter the following command: ma-line words 3 Malaga will show the results automatically, and it will also show the analysis tree automatically if you specified it using the `auto-tree' option. You can look at the results using `result' or at the entire analysis tree using `tree'.  File: malaga.info, Node: mg, Next: next, Prev: ma-line, Up: Commands 4.27 The Command `mg' (`malaga') ================================ Use the command `mg' to generate all word forms that consist of a specified set of allomorphs. For example, the command mg 3 un able believe This generates all word forms that consist of up to three allomorphs, where only the specified allomorphs (`un', `able', and `believe') are used. The word forms are numbered from 1 onward, but different analyses of the same word form get the same index. The output will look like this: malaga> mg 3 un able believe 1: "able" 2: "believe" 3: "unable" 4: "unbelieveable" malaga> Please note that generation does not know of filters, pruning rules and default rules.  File: malaga.info, Node: next, Next: print, Prev: mg, Up: Commands 4.28 The Command `next' ======================= This command can only be executed in debug mode. The rule execution will be resumed and continues until a different source line is met, a different path is going to be executed since the old one has terminated, or until the rules have been executed completely. It is like `step', but subrules will be executed without interruption. If you specify a number as argument, the command will be repeated as often as specified.  File: malaga.info, Node: print, Next: quit, Prev: next, Up: Commands 4.29 The Command `print' ======================== The command `print' is used to display the current values of Malaga variables or named constants, or parts of them. You can specify any variable or constant names (including the `$' or `@') as arguments to this command; you can also specify a path of attributes and/or indexes (with suffix `L' or `R') behind each of the variable or constant names. In that case, only the values of the specified paths are displayed: debug> print $word $word = [class: pronoun, result: S2] debug> print $word.class $word.class = pronoun debug> print @plan.1L.name $plan.1L = declarative debug> If the option `use-display' is on and `malshow' is used as `display-cmd', the expressions will be displayed in window on their own. If the `Expressions' window is not open yet, it will open now. If there is an open `Expressions' window, the new expressions and their values will be displayed in this window. You can left-click on an expression to make its value disappear or appear again. You can middle-click or right-click on an expression to erase it. The `Expressions' window has a menu with some commands: `Window' `Export Postscript...' Export the displayed expressions as an Embedded Postscript file. Currently, only ASCII, Latin-1 Supplement, Hangul Compatibility Jamo and Hangul Syllables can be converted to Postscript. `Close' Close the `Expressions' window. `Style' `Font Size ...' Select an item to adjust the font size. `Hanging' Normally, all values and subvalues are aligned at their bottom. If this option is active, records are "hanging down": they are aligned at their top. `Expressions' `Clear All' Clear all expressions. `Show All' Display the values of all expressions currently displayed. `Hide All' Suppress the values of all expressions currently displayed.  File: malaga.info, Node: quit, Next: read-constants, Prev: print, Up: Commands 4.30 The Command `quit' ======================= Use this command to leave `malaga' or `mallex'.  File: malaga.info, Node: read-constants, Next: result, Prev: quit, Up: Commands 4.31 The Command `read-constants' (`mallex') ============================================ If you want to parse lexicon entries that use Malaga constants (prefixed by `@'), these constants can be read in using the command `read-constants LEXICON-FILE'. It parses LEXICON-FILE and memorizes all constant definitions in it.  File: malaga.info, Node: result, Next: run, Prev: read-constants, Up: Commands 4.32 The Command `result' ========================= If you have previously analysed a word form or a sentence using `ma', `ma-line', `sa', or `sa-line' (in `malaga'), or you have generated allomorphs using `ga' or `ga-line' (in `mallex'), you can display the results with `result'. `use-display' is off: The results will be sent to standard output. `use-display' is on and `malshow' is used as `display-cmd': The results will show in a window on their own which is called `Results' for `malaga' and `Allomorphs' for `mallex'. They are numbered from 1 onward. If you are executing the command `result' for the first time, or if you have closed a `Results/Allomorphs' window that you'd opened before, a window will open, displaying the values of all results/allomorphs of the last analysis/generation. If there is a `Results/Allomorphs' window currently opened, the new results/allomorphs will be displayed in this window. The `Result/Allomorphs' window has a menu with some commands: `Window' `Export Postscript...' Export the displayed results as an Embedded Postscript file. Currently, only ASCII, Latin-1 Supplement, Hangul Compatibility Jamo and Hangul Syllables can be converted to Postscript. `Close' Close the `Result/Allomorphs' window. `Style' `Font Size ...' Select an item to adjust the font size. `Hanging' Normally, all values and subvalues are aligned at their bottom. If this option is active, records are "hanging down": they are aligned at their top.  File: malaga.info, Node: run, Next: sa, Prev: result, Up: Commands 4.33 The Command `run' ====================== This command can only be used in debug mode. The rule execution will be resumed, and the rules will be executed completely without any interruption. If you have invoked debug mode by the command `debug-node', rule execution will be stopped again when another link is going to be analysed.  File: malaga.info, Node: sa, Next: sa-file, Prev: run, Up: Commands 4.34 The Command `sa' (`malaga') ================================ If you have started `malaga' with a syntax file in your command line or in the project file, you can start syntactic analyses using the command `sa' (short for _syntactic analysis_). Put the sentence you want to be analysed as argument behind the command name: sa The man is in town. Malaga will show the results automatically, and it will also show the analysis tree automatically if you specified it using the `tree' option. You can look at the results using `result' or at the entire analysis tree using `tree'. If you do not enter a sentence behind the command `sa', `malaga' re-analyses the last input.  File: malaga.info, Node: sa-file, Next: sa-line, Prev: sa, Up: Commands 4.35 The Command `sa-file' (`malaga') ===================================== Using the command `sa-file', you can analyse files that contain sentence lists. In a sentence list, each sentence stands in a line on its own; empty lines are permitted. Here is an example, a sentence list named `sentence-list': He sleeps. He slept. He has slept. He had slept. To analyse this sentence list, enter: sa-file sentence-list result This will produce a file `result' that contains the analysis results. If the second argument is missing, the result will be written to a file whose name ends in `.out'; for `sentence-list', its name will be `sentence-list.out'. 1: "He sleeps.": [functor: [syn: , sem: <"sleep">]] 2: "He slept.": [functor: [syn: , sem: <"sleep">]] 3: "He has slept.": [functor: [syn: , sem: <"have", "sleep">]] 4: "He had slept.": [functor: [syn: , sem: <"have", "sleep">]] The number at the line start represents the line number of the analysed original sentence. The output format can be changed by using the options `result-format' and `unknown-format'. If a runtime error occurs during the analysis of a sentence, the line's output will be in the format given by the option `error-format'. After the analysis, some statistics will be displayed: * The number of analysed sentences. * The number of recognised sentences. * The number of sentences recognised by combi-rules and end-rules. * The number of sentences recognised by robust-rules. * The number of sentences whose analyses produced errors. * The average number of results per sentence. * The analysis run time. * The average number of sentences that have been analysed per second. * The number of cache accesses. * The number of cache hits.  File: malaga.info, Node: sa-line, Next: set, Prev: sa-file, Up: Commands 4.36 The Command `sa-line' (`malaga') ===================================== If you have started `malaga' with a syntax file in your command line or in the project file, you can start syntactic analyses using the command `sa-line' (short for _syntactic analysis_). Assume you want to analyse the sentence in the third line in the file `sentences'. Then enter the following command: sa-line sentences 3 Malaga will show the results automatically, and it will also show the analysis tree automatically if you specified it using the `auto-tree' option. You can look at the results using `result' or at the entire analysis tree using `tree'.  File: malaga.info, Node: set, Next: sg, Prev: sa-line, Up: Commands 4.37 The Command `set' ====================== This command is used to change the settings of `malaga' or `mallex'. The command line `set OPTION ARGUMENT' changes OPTION to ARGUMENT. If you want to get the current state of an option, use the command `get'. Options can also be set in the project file. The possible options are described in the next chapter.  File: malaga.info, Node: sg, Next: step, Prev: set, Up: Commands 4.38 The Command `sg' (`malaga') ================================ Use `sg' to generate sentences that are composed of a specified set of word forms. For example, enter: sg 3 . ? he she sleeps All sentences that consist of up to three word forms, where only the specified word forms (".", "?", "he", "she", and "sleeps") are used. The sentences are numbered from 1 onward, but different analyses of the same sentence get the same index. The output looks like this: malaga> sg 3 . ? he she sleeps 1: "he sleeps ." 2: "he sleeps ?" 3: "she sleeps ." 4: "she sleeps ?" malaga> Please note that generation does not know of filters, pruning rules and default rules.  File: malaga.info, Node: step, Next: transmit, Prev: sg, Up: Commands 4.39 The Command `step' ======================= This command can only be executed in debug mode. The rule execution will be resumed and continues until a different source line is met, a different path is going to be executed since the old one has terminated, or until the rules have been executed completely.  File: malaga.info, Node: transmit, Next: tree, Prev: step, Up: Commands 4.40 The Command `transmit' =========================== If you have specified a transmit command line (to do this, use the option `transmit-cmd'), you can send a command to it: malaga> set transmit-cmd cat malaga> transmit [surf: "go", POS: verb]; [POS: verb, surf: "go"] malaga>  File: malaga.info, Node: tree, Next: up, Prev: transmit, Up: Commands 4.41 The Command `tree' (`malaga') ================================== If you've started a grammatical analysis using one of the commands `ma' or `sa' (or their debug variants), you can make `malaga' display the result by entering tree If the analysis has not yet finished (in debug mode or in case of an error), a partial tree will be shown. If you're executing the command `tree' for the first time, or if you've closed the `Tree' window before, a new tree window will open in which the current analysis tree will be displayed. If there is already a `Tree' window open, the new analysis tree will be displayed in this window. In the upper left corner of the `Tree' window, you will see the sentence or the word form that has been analysed. Below, the analysis tree is displayed. An analysis path always follows the edges from the left to the right. A circle node stands for a LAG state, a two-circle node stands for an end state. A crossed circle stands for a LAG state that has been removed by a pruning-rule, and a crossed two-circle node stands for an end state that is invalid because it has some remaining input still remaining. A box node is not a state, but a "dead end", which means that no rule has created a state at this position. Above each edge, the link's surface of the corresponding rule application is displayed. Below the edge, you'll see the name of the applied rule. You can click on a node using the left mouse button. Then another window will open, namely the `Path' window. The `Path' window displays the surface, the feature structure and the successor rules of the state you've clicked on. The node will be highlighted by a red border. If you press the right mouse button while the mouse is on a node, a pop-up menu will appear. You can then either select that this node is the first node of the path to be displayed, or you can select it to be the last one. All rule applications, from the first node up to the last node in the path, will be displayed in the `Path' window. The corresponding path will be highlighted in the `Tree' window. If you're clicking on a link surface using any mouse button, the surface and its feature structure will be displayed in the `Path' window. You can also click on rule names using any mouse button. Then the corresponding rule application will be displayed in the `Path' window, i.e. the surfaces and feature structures of the original state, the link, and the successor state, and the successor rules. There are some commands that can be initiated from the `Tree' menu bar: `Window' `Export Postscript...' Export the displayed analysis tree as an Embedded Postscript file. Currently, only ASCII, Latin-1 Supplement, Hangul Compatibility Jamo and Hangul Syllables can be converted to Postscript. `Close' Close the `Tree' window. `Style' Select an item in this menu to adjust the font size. `Tree' Specify which nodes of the analysis tree are actually displayed and whether state indexes are shown. `Full Tree' All analysis states are displayed, and also boxes for rule applications that did not succeed (dead ends). `No Dead Ends' All analysis states are displayed. `Complete paths' Only the nodes that are part of a complete analysis are displayed. `Show State Indexes' Toggles the display of the state's indexes. `End States' Select an end state to display in the `Path' window. `Show First' Display the first end state. `Show Previous' If there is an end state displayed in the `Path' window, jump to the previous one. `Show Next' If there is an end state displayed in the `Path' window, jump to the next one. `Show Last' Display the last end state. The `Path' window has got its own menu bar which contains the menus `Window', `Style', and `End States' with the same menu items as the corresponding menus in the `Tree' window, and two additional options in `Style': `Hanging' Normally, all values and subvalues are aligned at their bottom. If this option is active, records are "hanging down": they are aligned at their top. `Inline' Normally, a state is displayed with surface, feature structure and rule set stacked. If this option is active, they are displayed aligned on on line. The `Path' window also has a menu `Path', in which you can specify whether state indexes are shown: `Show State Indexes' Toggles the display of the state's indexes.  File: malaga.info, Node: up, Next: variables, Prev: tree, Up: Commands 4.42 The Command `up' ===================== If you want to look at the source and the variables of the (sub)rule that has called the current subrule, you can do this by entering `up'. You can list the frames via `backtrace'.  File: malaga.info, Node: variables, Next: walk, Prev: up, Up: Commands 4.43 The Command `variables' ============================ If you invoke `variables', you get the values of all Malaga variables that are currently defined. The variables will be shown in the order of their definitions. You can only use the command `variables' in debug mode or if the previous analysis has stopped with an error in the combination rules. If the option `use-display' is off, the variables will be sent to standard output: malaga> sa-debug You are so beautiful. entering rule "Noun", surf: "", link: "You", state: 1 debug> variables $sentence = [class: main_clause, parts: <>] $word = [class: pronoun, result: S2] debug> If the option `use-display' is on and `malshow' is used as `display-cmd', the variables will be displayed in window on their own. If the `Variables' window is not open yet, it will open now. If there is an open `Variables' window, the new variable contents will be displayed in this window. You can left-click on a variable name to make its value disappear or appear again. The `Variables' window has a menu with some commands: `Window' `Export Postscript...' Export the displayed variables as an Embedded Postscript file. Currently, only ASCII, Latin-1 Supplement, Hangul Compatibility Jamo and Hangul Syllables can be converted to Postscript. `Close' Close the `Variables' window. `Style' `Font Size ...' Select an item to adjust the font size. `Hanging' Normally, all values and subvalues are aligned at their bottom. If this option is active, records are "hanging down": they are aligned at their top. `Variables' `Show All' Display the values of all variables currently defined. `Hide All' Suppress the values of all variables currently defined.  File: malaga.info, Node: walk, Next: where, Prev: variables, Up: Commands 4.44 The Command `walk' ======================= This command works in debug mode only. The rule execution will be continued and stopped again as soon as a new rule is executed, a breakpoint is met or there are no more rules to execute.  File: malaga.info, Node: where, Prev: walk, Up: Commands 4.45 The Command `where' ======================== This command can only be used in debugger mode or after rule execution has been stopped by an error. It displays the name of the rule that has been executed; additionally, the surfaces of state and link are displayed in `malaga'. For example: debug> where at rule "flexion", surf: "hous", link: "es", state: 2 debug>  File: malaga.info, Node: Options, Next: The Language, Prev: Commands, Up: Top 5 The Options of `malaga' and `mallex' ************************************** The programs `malaga' and `mallex' share some of their options, so I will describe them in a common chapter. Options can be set using the command `set', and you can get the current value of an option using `get'. Options that can be used in `malaga' or in `mallex' only, are marked by the name of the program in which they can be used. * Menu: * alias:: Shortcuts for other commands. * allo-format:: The output format for allomorphs in readable form. * auto-tree:: Is the analysis tree displayed automatically after analysis? * auto-variables:: Are variables displayed automatically in debug mode? * cache-size:: The size of the word form cache. * display-cmd:: The command line for the display GUI. * error-format:: The output-format for analyses that reported an error. * hidden:: The attributes whose values are hidden in output. * mor-incomplete:: Will we accept words that have been incompletely parsed? * mor-out-filter:: Will the morphology output filter be executed? * mor-pruning:: Number of states needed to call the morphology pruning rule. * result-format:: The output format for successful analyses. * result-list:: Pack all analysis results in a single list. * robust-rule:: Will the robust rule be executed? * roman-hangul:: Will Hangul be transcribed? (for Hangul grammars only) * sort-records:: The order of the attributes in a record when displayed. * switch:: User options that can be read by the grammar. * syn-incomplete:: Will we accept sentences that have been incompletely parsed? * syn-in-filter:: Will the syntax input filter be executed? * syn-out-filter:: Will the syntax output filter be executed? * syn-pruning:: Number of states needed to call the syntax pruning rule. * transmit-cmd:: The command line for the transmit process. * unknown-format:: The output format for analyses that got no results. * use-display:: Will the program in `display-cmd' be used for output?  File: malaga.info, Node: alias, Next: allo-format, Prev: Options, Up: Options 5.1 The Option `alias' ====================== With `alias', you can define abbreviations for longer command lines. As arguments, give an alias name and an expansion (a command line which the name will stand for). If the expansion contains spaces, enclose it in double quotes. Use `set alias NAME' to delete alias NAME. If you type the name of an alias at your command line, its expansion will be executed. The character sequence `%a' in your alias definition will be replaced by what follows the alias name in the command line. Aliases cannot be nested.  File: malaga.info, Node: allo-format, Next: auto-tree, Prev: alias, Up: Options 5.2 The Option `allo-format' (`mallex') ======================================= With `allo-format', you can change the output format for the generated allomorphs. Enter a format string as argument. If the format string contains spaces, enclose it in double quotes. If the argument is an empty string (`""'), no allomorphs will be shown. In the format string, the following sequences have a special meaning: `%c' Will be replaced by the allomorph's feature structure. `%n' Will be replaced by the allomorph's number. `%s' Will be replaced by the allomorph's surface.  File: malaga.info, Node: auto-tree, Next: auto-variables, Prev: allo-format, Up: Options 5.3 The Option `auto-tree' (`malaga') ===================================== You can use `auto-tree' to make `malaga' execute the `tree' command each time when you invoked an analysis by `ma' or `sa'. Set it in one of the following ways: `set auto-tree yes' The `tree' command will be executed after each analysis. `set auto-tree no' The `tree' command will not be executed automatically.  File: malaga.info, Node: auto-variables, Next: cache-size, Prev: auto-tree, Up: Options 5.4 The Option `auto-variables' =============================== When `malaga' or `mallex' stops in debug mode while executing a malaga rule, they can automatically show the defined variables at this point. Use the option `auto-variables' to set this behaviour. `set auto-variables yes' The `variables' command will be executed each time when `malaga' or `mallex' stops in debug mode. `set auto-variables no' The `variables' command will not be executed automatically.  File: malaga.info, Node: cache-size, Next: display-cmd, Prev: auto-variables, Up: Options 5.5 The Option `cache-size' (`malaga') ====================================== Malaga has a cache for word forms. You can set the cache size, i.e. the maximum number of words in the cache, to N with `set cache-size N'. If you set the cache size to 0, the cache will be deactivated. When malaga analyses a word form or sentence, it tries to get a word form from the cache before it uses the morphology combination rules. Therefore, malaga separates the first word form from the remaining input. It uses spacing characters as separators; so if a word-form contains a space or does not end with a space, caching will not work.  File: malaga.info, Node: display-cmd, Next: error-format, Prev: cache-size, Up: Options 5.6 The Option `display-cmd' ============================ The programs `malaga' and `mallex' normally use the program `malshow' for GUI-based display of Malaga trees, results or variables. If you want to use a different display program, set the command line that starts this program with the `display' option, like this: set display-cmd "java -classpath /opt/malaga/amalgam Amalgam"  File: malaga.info, Node: error-format, Next: hidden, Prev: display-cmd, Up: Options 5.7 The Option `error-format' (`malaga') ======================================== With `error-format', you can change the output format for items that produced an analysis error. Enter a format string as argument. If the format string contains spaces, enclose it in double quotes. If the argument is an empty string (`""'), no forms that produced an error will be shown. In the format string, the following sequences have a special meaning: `%e' Will be replaced by the error message for the analysed form. `%l' Will be replaced by the line number of the analysed form. `%n' Will be replaced by the number of analysis states for this form. `%s' Will be replaced by the surface.  File: malaga.info, Node: hidden, Next: mor-incomplete, Prev: error-format, Up: Options 5.8 The Option `hidden' ======================= Some grammars can produce very large feature structures, so it can be useful not to show the values of some specified attributes. To achieve this, use the option `hidden'. You can give any number of arguments to this option. The following arguments are available: `+ATTRIBUTE-NAME' The specified attribute name will be put in parentheses if it occurs in a value; the attribute value will not be shown. `-ATTRIBUTE-NAME' The specified attribute will be shown completely again in the future. `none' All attributes will be shown completely again in the future.  File: malaga.info, Node: mor-incomplete, Next: mor-out-filter, Prev: hidden, Up: Options 5.9 The Option `mor-incomplete' (`malaga') ========================================== If you want to get morphological analysis results not only for the whole input line, but for any grammatically well-formed prefix of the input line, you can use the option `mor-incomplete': `set mor-incomplete yes' Accept words that have been incompletely parsed. `set mor-incomplete no' Only accept words that have been completely parsed. Note that this option has no effect in subordinate morphological analyses that are needed by syntactic analysis.  File: malaga.info, Node: mor-out-filter, Next: mor-pruning, Prev: mor-incomplete, Up: Options 5.10 The Option `mor-out-filter' (`malaga') =========================================== Use the option `mor-out-filter' to switch the morphology output-filter on or off: `set mor-out-filter yes' Activate the filter. `set mor-out-filter no' Deactivate the filter.  File: malaga.info, Node: mor-pruning, Next: result-format, Prev: mor-out-filter, Up: Options 5.11 The Option `mor-pruning' (`malaga') ======================================== In your morphology rules, you may have specified a pruning rule that can prune the morphology analysis tree, i.e. it can reduce the number of parallel paths. If you want this pruning rule to be executed, use the option `mor-pruning'. Use one of the following arguments: `set mor-pruning N' Call the morphology pruning rule whenever at least N states have consumed the same amount of input, for N > 0. `set mor-pruning 0' Deactivate the morphology pruning rule.  File: malaga.info, Node: result-format, Next: result-list, Prev: mor-pruning, Up: Options 5.12 The Option `result-format' (`malaga') ========================================== With `result-format', you can change the output format for analysed items that have been recognised. Enter a format string as argument. If the format string contains spaces, enclose it in double quotes. If the argument is an empty string (`""'), no recognised forms will be shown. In the format string, the following sequences have a special meaning: `%c' Will be replaced by the result feature structure of the analysis. `%l' Will be replaced by the line number of the analysed form. `%n' Will be replaced by the number of analysis states for this form. `%r' Will be replaced by the reading index (the results for a form are indexed from 1 to the number of results). `%s' Will be replaced by the surface.  File: malaga.info, Node: result-list, Next: robust-rule, Prev: result-format, Up: Options 5.13 The Option `result-list' (`malaga') ======================================== With this command, you can specify whether you want malaga to pack all analysis results into a single list. This option only has an impact in filter mode or when a file is being analysed. Even results of different lengths are combined; this could not be achieved by an output-filter. Results of different lenghts can occur when the option `mor-incomplete' or `syn-incomplete' is active. `set result-list yes' Combine results into a single list. `set result-list no' Leave results unchanged.  File: malaga.info, Node: robust-rule, Next: roman-hangul, Prev: result-list, Up: Options 5.14 The Option `robust-rule' (`malaga') ======================================== With this command, you can specify if you want to run a robust-rule for the word forms that could not be recognised by LAG rules. The robust-rule gets the surface of an unknown word form as parameter and it can create one or more results by executing the `result' statement. `set robust-rule yes' Enable the robust rule. `set robust-rule no' Disable the robust rule.  File: malaga.info, Node: roman-hangul, Next: sort-records, Prev: robust-rule, Up: Options 5.15 The Option `roman-hangul' ============================== If you are using the option `split-hangul-syllables: yes' in your project file, Malaga can transcribe Hangul using Latin letters, basing on the Yale system. The transcribed text is enclosed in curly braces, and each syllable starts with a dot. `set roman-hangul yes' Display Hangul using Latin transcription. `set roman-hangul no' Display Hangul directly.  File: malaga.info, Node: sort-records, Next: switch, Prev: roman-hangul, Up: Options 5.16 The Option `sort-records' ============================== There are different ways to determine the order in which the attributes of a record are displayed. With `sort-records', you can choose between three order schemes: `set sort-records internal' The attributes will be displayed in the order they have internally. `set sort-records alphabetic' The attributes will be ordered alphabetically by their names. `set sort-records definition' The attributes will be ordered by their names; the order is the same as in the symbol table.  File: malaga.info, Node: switch, Next: syn-incomplete, Prev: sort-records, Up: Options 5.17 The Option `switch' ======================== Malaga rules can query simple Malaga values ("switches") that you can change during run time. Use the option `switch' to change the values: `set switch NAME VALUE' Set the switch NAME, which must be a symbol, to VALUE, which can be any Malaga value.  File: malaga.info, Node: syn-incomplete, Next: syn-in-filter, Prev: switch, Up: Options 5.18 The Option `syn-incomplete' (`malaga') =========================================== If you want to get syntactic analysis results not only for the whole input line, but for any grammatically well-formed prefix of the sentence, you can use the option `syn-incomplete': `set syn-incomplete yes' Accept sentences that have been incompletely parsed. `set syn-incomplete no' Only accept sentences that have been completely parsed.  File: malaga.info, Node: syn-in-filter, Next: syn-out-filter, Prev: syn-incomplete, Up: Options 5.19 The Option `syn-in-filter' (`malaga') ========================================== Use the option `syn-in-filter' to switch the syntax input-filter on or off: `set syn-in-filter yes' Activate the filter. `set syn-in-filter no' Deactivate the filter.  File: malaga.info, Node: syn-out-filter, Next: syn-pruning, Prev: syn-in-filter, Up: Options 5.20 The Option `syn-out-filter' (`malaga') =========================================== Use the option `syn-out-filter' to switch the syntax output-filter on or off: `set syn-out-filter yes' Activate the filter. `set syn-out-filter no' Deactivate the filter.  File: malaga.info, Node: syn-pruning, Next: transmit-cmd, Prev: syn-out-filter, Up: Options 5.21 The Option `syn-pruning' (`malaga') ======================================== In your syntax rules, you may have specified a pruning rule that can prune the syntax analysis tree, i.e. it can reduce the number of parallel paths. If you want this pruning rule to be executed, use the option `syn-pruning'. Use one of the following arguments: `set syn-pruning N' Call the syntax pruning rule whenever at least N states have consumed the same amount of input, for N > 0. `set syn-pruning 0' Deactivate the syntax pruning rule.  File: malaga.info, Node: transmit-cmd, Next: unknown-format, Prev: syn-pruning, Up: Options 5.22 The Option `transmit-cmd' ============================== If you want to use the `transmit' function in `malaga' or `mallex', you have to set a command line that starts the transmit process using the `transmit-cmd' option. Here is an example: set transmit-cmd "perl my-transmit-program.pl"  File: malaga.info, Node: unknown-format, Next: use-display, Prev: transmit-cmd, Up: Options 5.23 The Option `unknown-format' (`malaga') =========================================== With `unknown-format', you can change the output format for analysed items that have not been recognised. Enter a format string as argument. If the format string contains spaces, enclose it in double quotes. If the argument is an empty string (`""'), no unrecognised forms will be shown. In the format string, the following sequences have a special meaning: `%l' Will be replaced by the line number of the analysed form. `%n' Will be replaced by the number of analysis states for this form. `%s' Will be replaced by the surface.  File: malaga.info, Node: use-display, Prev: unknown-format, Up: Options 5.24 The Option `use-display' ============================= If you want the output of the commands `result' and `variables' to be shown by the `Display' process, use the option `use-display': `set use-display yes' Use the `Display' process to show the output of `result' and `variables'. `set use-display no' Send the output of `result' and `variables' to your terminal.  File: malaga.info, Node: The Language, Next: Index, Prev: Options, Up: Top 6 The Programming Language Malaga ********************************* * Menu: * Characterisation:: The abstract characteristics of the language. * Source Texts:: General rules for Malaga source files. * Values:: The types that make any Malaga data. * Expressions:: How operators can combine values. * Conditions:: Expressions yielding a boolean value. * Boolean Operators:: The Operators `and', `or' and `not'. * Symbol Table:: All symbols have to be defined here. * Initial State:: The initial LAG state. * Constant Definition:: Constants can be used in lexicon and rule files. * Rules:: Rules are comparable to functions in C. * Statements:: The atoms of which a rule is constructed. * Files:: The Files that make a Malaga grammar. * Syntax Summary:: Formal Description of the Malaga syntax.  File: malaga.info, Node: Characterisation, Next: Source Texts, Prev: The Language, Up: The Language 6.1 Characterisation of Malaga ============================== A malaga rule file resembles much in programming languages like Pascal or C (of course, those languages do not have a Left-Associative Grammar formalism built in). A malaga source file must be translated before execution, this is the same as for compiler languages. But the generated Malaga code is not a machine code, but an _intermediate code_ and has to be executed ("interpreted") by an analysis program. Malaga may be characterised as follows, as far as programming structures and data structures are concerned: _structured values:_ The basic values in Malaga are symbols (names that can be used e.g. for categories or subcategories), numbers (floating point numbers), and strings. Values can be combined to ordered lists or records (also known as attribute-value matrixes). A value in a list or a record can be a list or a record itself. An "ambiguous" symbol like `singular_plural' can be assigned a list of symbols like `'; such a symbol is called a "multi-symbol". _structured statements:_ In Malaga, the concept of statement blocks is implemented in a similar way as it is in the programming language Pascal. There are structured control statements to select or repeat a statement sequence. A variable is always defined "locally", i.e. it only exists from the point where it has been defined up to the end of the statement sequence in which it has been defined. _no type restrictions:_ Any value can be assigned to a variable and the programmer can freely define the structure of values. _no side effects:_ Malaga is, unlike programming languages like Pascal or C, free of side effects. If a variable gets a value, no other variable will be changed. Analysis paths are independent of each other. _termination:_ A Malaga grammar that contains no recursive subrules and no `repeat' statements is guaranteed to terminate, i.e. it can never hang in a loop. _variables:_ In a `define' statement, a variable is defined and gets an initial value. Use an assignment to set a variable that has already been defined to a new value. _operators:_ Many generative grammar theories or linguistical programming languages use the concept of unification of feature structures. Malaga does not use unification, but it offers some operators to build feature structures explicitly. Since Malaga does without unification, analyses are much faster.  File: malaga.info, Node: Source Texts, Next: Values, Prev: Characterisation, Up: The Language 6.2 Malaga Source Texts ======================= Source texts in Malaga must be in the Unicode UTF-8 format. They are format-free; this means that between lexical symbols (strings, identifiers, keywords, numerals and symbols such as `+', `~' or `:=') there may be blanks or newlines (whitespaces) or comments. Between two identifiers or two keywords there _must_ be at least one whitespace to separate them syntactically. * Menu: * Comments:: How to insert comments in your source file. * Include:: How to read other files from your source file. * Identifiers:: Names in Malaga source files.  File: malaga.info, Node: Comments, Next: Include, Prev: Source Texts, Up: Source Texts 6.2.1 Comments -------------- A comment may be inserted everywhere where a whitespace may be inserted. A comment begins with the symbol `#' and extends to the end of the line. Comments are being ignored.  File: malaga.info, Node: Include, Next: Identifiers, Prev: Comments, Up: Source Texts 6.2.2 The `include' Statement ----------------------------- A Malaga file may contain the statement include "FILENAME"; In a rule file, it can stand everywhere a rule can stand. In lexicon files, it can stand in place of a value; in symbol files, it can replace a symbol definition. The text of the included file is inserted verbatim at the very location where the `include' statement occurs. The file name has to be stated relatively to the directory of the file which contains the `include' statement.  File: malaga.info, Node: Identifiers, Prev: Include, Up: Source Texts 6.2.3 Identifiers ----------------- In Malaga, names for variables, constants, symbols, and rules, and (see below for explanation) are called "identifiers". An identifier may consist of uppercase and lowercase characters, the underscore `_', the ampersand `&', the vertical bar `|', and, from the second character on, also of digits. Uppercase and lowercase characters are not distinguished, i.e., Malaga is _not_ case-sensitive. Malaga keywords must not be used as identifiers. A variable name must start with a `$', a constant name must start with a `@'. The same identifier may be used as variable name, constant name, symbol name, or rule name independently. Malaga can distinguish them by the context in which they occur. Valid identifiers would be `Noun', `noun' (the same as the first), `R2D2', `Vb_aux', `A|G|D', `_INF'. Identifiers like `2Noun', `Verb.Frame', `OK?', `_~INF' are _not_ valid.  File: malaga.info, Node: Values, Next: Expressions, Prev: Source Texts, Up: The Language 6.3 Values ========== Malaga expressions can have values with very complex structures. To describe how those values can be composed from simple values a few rules suffice. Simple values in Malaga are "symbols", "numbers", and "strings", which can be composed to form "records" and "lists". * Menu: * Symbols:: The atomic datatype that is basic to Malaga. * Numbers:: Floating point numbers, also used for indexes. * Strings:: A sequence of characters, used to store text. * Lists:: An ordered sequence of subvalues. * Records:: A set of attribute-value pairs.  File: malaga.info, Node: Symbols, Next: Numbers, Prev: Values, Up: Values 6.3.1 Symbols ------------- The central data type in Malaga is the symbol. It is used for describing syntactic or semantic properties of an allomorph, a word, or a sentence. A symbol is an identifier like `Verb', `reflexive', `Sing_1'. The symbols `nil', `yes', `no', `symbol', `string', `number', `list', and `record' are predefined and have special meanings.  File: malaga.info, Node: Numbers, Next: Strings, Prev: Symbols, Up: Values 6.3.2 Numbers ------------- A number in Malaga consists of an integer part, an optional fractional part and an optional exponent of the form `E[+|-]n'. There must be a dot between the integer part and the fractional part. Examples: `0', `1', `1.0', `13.75', `1.2E-5'. Alternatively, a number may consist of an integer number followed by `L', indicating that the number is intended as a list index counting from the _left_ border), or by `R', indicating that the number is intended as a list index counting from the _right_ border. Examples: `5L' = `5', `12R' = `-12'.  File: malaga.info, Node: Strings, Next: Lists, Prev: Numbers, Up: Values 6.3.3 Strings ------------- A string may consist of any number of characters (it may also be empty). It must be enclosed in double quotes and must not extend over more than one line. Within the double quotes there may be any combination of printable characters except the backslash `\' and the double quotes. When part of a string, these characters must be preceded by a `\' (escape character). Examples: `"Hello"', `"He says: \"Great\""'.  File: malaga.info, Node: Lists, Next: Records, Prev: Strings, Up: Values 6.3.4 Lists ----------- A list is an ordered sequence of values. The values are separated by commas and enclosed in angle brackets: A list may as well be empty. The elements in a list may be arbitrarily complex; they may also be lists or records.  File: malaga.info, Node: Records, Prev: Lists, Up: Values 6.3.5 Records ------------- A record is a collection of attributes. An _attribute_ consists of a symbol, the _attribute name_, and an associated _attribute value_, which can be an arbitrary Malaga value. The attribute name serves as an access key for the attribute value, so all attributes in a record must have distinct names. Records are noted down as follows: [NAME1: VALUE1, NAME2: VALUE2, ...] where NAME I denotes an attribute name and VALUE I the associated attribute value. Example: `[Class: Verb, Reg: Reg, Val: dirObj]'. A record with no attributes, `[]', is called "empty record".  File: malaga.info, Node: Expressions, Next: Conditions, Prev: Values, Up: The Language 6.4 Expressions =============== An expression is the form in which a value is used in Malaga. Values can be written as follows: [Surf: "he", Class: Pron, Case&Number: S3] Variables (these are placeholders for values within a rule) can as well be used as expressions: $Pron Furthermore, constants (placeholders for values in a rule file) can be used as expressions: @combination_table All three forms can be mixed: [Surf: "he", Class: Pron, Case&Number: $result] Furthermore, there are operators which modify values or combine two values to form a new value. Complex values can be composed using those operators. All operators have a priority assigned. An operator with higher priority is applied before an operator with lower priority. If two operators have the same priority, they are applied from the left to the right. The order in which the operators are to be applied can be changed by bracketing with round parentheses `()'. unary `-' very high priority `.' high priority `*', `/' middle priority `+', `-' low priority * Menu: * Malaga Variables:: Containers for Malaga Values in a Rule. * Constants:: Global containers for Malaga Values. * Subrule Calls:: Call a subrule from another rule. * Atoms:: The atoms of a multisymbol. * Capital:: Does a string begin with a capital letter? * Floor:: Round down to the next integer. * Length:: The length of a list or a string. * Multi:: The multisymbol of the given atoms list. * Set:: Make a list contain unique elements only. * Substring:: Get a substring of a string. * Switch:: Get a user-defined value. * Transmit:: Call the transmit process. * Value_String:: Convert a value to a string. * Value_Type:: Get the type of a value. * If Expression:: Evaluate one of several expressions. * Unary Minus:: Negate a value. * Operator Dot:: Select an attribute or a list element. * Operator Plus:: Concat strings, lists or records, or add. * Operator Minus:: Delete an attribute or an element, or subtract. * Operator Times:: Intersect lists, concat records, or multiply. * Operator Divide:: Delete elements from a list, or divide.  File: malaga.info, Node: Malaga Variables, Next: Constants, Prev: Expressions, Up: Expressions 6.4.1 Variables --------------- A variable is marked by a `$' preceding its name. The name may be any valid identifier. A variable is defined by the `define' statement; it receives a value and may from this point on be used in all expressions within the statement sequence. In such a statement sequence (and all subordinated statement sequences) a variable with the same name must not be defined again.  File: malaga.info, Node: Constants, Next: Subrule Calls, Prev: Malaga Variables, Up: Expressions 6.4.2 Constants --------------- A constant is marked by a `@' preceding its name. The name may be any valid identifier. A constant is defined by a constant definition in a rule file, outside a rule. It is assigned a value and can be used in subsequent rules and constant definitions in that rule file.  File: malaga.info, Node: Subrule Calls, Next: Atoms, Prev: Constants, Up: Expressions 6.4.3 Subrule Invokations ------------------------- A subrule is invoked when an expression `SUBRULE(VALUE1, VALUE2, ...)' is evaluated. The expression yields the value that is returned by the `return' statement in the subrule. The number of parameters in a subrule invokation must match the number of parameters in the subrule definition. There is a number of default subrules which are predefined. They are called "functions".  File: malaga.info, Node: Atoms, Next: Capital, Prev: Subrule Calls, Up: Expressions 6.4.4 The Function `atoms' -------------------------- The expression `atoms(SYMBOL)' yields the list of atomic symbols for SYMBOL. If SYMBOL is not a multi-symbol, it yields the list `'.  File: malaga.info, Node: Capital, Next: Floor, Prev: Atoms, Up: Expressions 6.4.5 The Function `capital' ---------------------------- The expression `capital(STRING)' yields `yes' if the first character of STRING is a capital letter, else it yields `no'.  File: malaga.info, Node: Floor, Next: Length, Prev: Capital, Up: Expressions 6.4.6 The Function `floor' -------------------------- The expression `floor(NUMBER)' yields the largest integer number that is not greater than NUMBER.  File: malaga.info, Node: Length, Next: Multi, Prev: Floor, Up: Expressions 6.4.7 The Function `length' --------------------------- The expression `length(LIST)' yields the number of elements in LIST. The expression `length(STRING)' yields the number of characters in STRING.  File: malaga.info, Node: Multi, Next: Set, Prev: Length, Up: Expressions 6.4.8 The Function `multi' -------------------------- The expression `multi(LIST)' where LIST is a list of symbols, yields the multi-symbol whose atomic list corresponds to LIST. If LIST contains a single atomic symbol, this symbol will be yield by the expression.  File: malaga.info, Node: Set, Next: Substring, Prev: Multi, Up: Expressions 6.4.9 The Function `set' ------------------------ The expression `set(LIST)' yields a list which contains each element of LIST, but only once. That means, the list is converted to a set.  File: malaga.info, Node: Substring, Next: Switch, Prev: Set, Up: Expressions 6.4.10 The Function `substring' ------------------------------- The expression `substring(STRING, START_INDEX, END_INDEX)' yields the substring of STRING that starts at START_INDEX and ends at END_INDEX, both inclusive. A positive index counts from the string start: `1L' is the index of the first character; a negative index counts from the string end: `1R' is the index of the last character. If END_INDEX is omitted, it is assumed to be the same as START_INDEX, so `substring(STRING, INDEX)' yields the character at INDEX in STRING. If END_INDEX is less than START_INDEX, the function yields an empty string.  File: malaga.info, Node: Switch, Next: Transmit, Prev: Substring, Up: Expressions 6.4.11 The Function `switch' ---------------------------- The expression `switch(SYMBOL)' yields the current value of the switch associated to SYMBOL. Use the option `switch' to change this value.  File: malaga.info, Node: Transmit, Next: Value_String, Prev: Switch, Up: Expressions 6.4.12 The Function `transmit' ------------------------------ The expression `transmit(VALUE)' writes VALUE, converted to text format, to the transmit process via pipe and reads a value in text format from the transmit process via pipe. The answer is converted to the internal Malaga value format and returned as the result of the expression. When this function is evaluated, the transmit process is started if it is not running. The command line of the transmit process is specified by the option `transmit'.  File: malaga.info, Node: Value_String, Next: Value_Type, Prev: Transmit, Up: Expressions 6.4.13 The Function `value_string' ---------------------------------- The expression `value_string(VALUE)' returns VALUE converted to text format as a string.  File: malaga.info, Node: Value_Type, Next: If Expression, Prev: Value_String, Up: Expressions 6.4.14 The Function `value_type' -------------------------------- The expression `value_type(VALUE)' yields the type of VALUE. The type information is coded as one of the symbols `symbol', `string', `number', `list', or `record'.  File: malaga.info, Node: If Expression, Next: Unary Minus, Prev: Value_Type, Up: Expressions 6.4.15 The `if' Expression -------------------------- An `if' expression has the following form: if CONDITION1 then EXPRESSION1 elseif CONDITION2 then EXPRESSION2 else EXPRESSION3 end if The `elseif' part may be repeated unrestrictedly (including zero times). First, CONDITION1 is evaluated. If it is satisfied, the expression EXPRESSION1 is evaluated and yields the value of the `if' expression. If CONDITION1 is not satisfied, each condition following an `elseif' keyword is evaluated in turn, until a condition is found that is satisfied. The expression that follows this condition will be evaluated and yields the value of the `if' expression. If the `if' condition and `elseif' conditions all fail, the expression EXPRESSION3 will be evaluated and yields the value of the `if' expression. The `if' after the `end' may be omitted.  File: malaga.info, Node: Unary Minus, Next: Operator Dot, Prev: If Expression, Up: Expressions 6.4.16 Unary `-' ---------------- A `-' in front of a value of type `number' negates that value.  File: malaga.info, Node: Operator Dot, Next: Operator Plus, Prev: Unary Minus, Up: Expressions 6.4.17 The Operator `.' ----------------------- This operator may only be used in the following ways: `RECORD.SYMBOL' This yields the attribute value of the attribute of RECORD whose name is SYMBOL. If there is no attribute in RECORD whose name is SYMBOL, the expression yields the special symbol `nil'. `LIST.NUMBER' This yields the element of LIST at position NUMBER. If there is no element at position NUMBER in LIST, the expression yields the special symbol `nil'. `VALUE.LIST' Here, LIST must be a list `' of symbols and/or numbers. This expression serves as an abbreviation for `VALUE.E1.E2...'.  File: malaga.info, Node: Operator Plus, Next: Operator Minus, Prev: Operator Dot, Up: Expressions 6.4.18 The Operator `+' ----------------------- This operator may only be used in the following ways: `STRING1 + STRING2' This yields the concatenation of STRING1 and STRING2. `LIST1 + LIST2' This yields the concatenation of LIST1 and LIST2. `NUMBER1 + NUMBER2' This yields the sum of NUMBER1 and NUMBER2. `RECORD1 + RECORD2' This yields a record wich consists of all attributes of RECORD1 and RECORD2. If RECORD1 and RECORD2 have a common attribute names, the corresponding attributes in the result record will have the attribute values from RECORD2, in contrast to the operator `*'.  File: malaga.info, Node: Operator Minus, Next: Operator Times, Prev: Operator Plus, Up: Expressions 6.4.19 The Operator `-' ----------------------- This operator may only be used in the following ways: `RECORD - SYMBOL' This yields RECORD without the attribute named SYMBOL, if SYMBOL is an attribute name in RECORD. If not, the expression yields RECORD. `RECORD - LIST' Here, LIST must be a list of symbols. This yields RECORD without the attributes in LIST. `LIST - NUMBER' This yields LIST without the element at index NUMBER. If this element does not exist, the expression yields LIST. `LIST1 - LIST2' This yields the multi-set difference of the two lists LIST1 and LIST2. This means, it yields the list LIST1, but the first N appearances of each element will be deleted, if that element appears N times in LIST2. `NUMBER1 - NUMBER2' This yields the difference of NUMBER1 and NUMBER2.  File: malaga.info, Node: Operator Times, Next: Operator Divide, Prev: Operator Minus, Up: Expressions 6.4.20 The Operator `*' ----------------------- This operator may only be used in the following ways: `RECORD * SYMBOL' This yields the record which only contains the attribute of RECORD whose name is SYMBOL. `RECORD1 * RECORD2' This yields a record wich consists of all attributes of RECORD1 and RECORD2. If RECORD1 and RECORD2 have a common attribute names, the corresponding attributes in the result record will have the attribute values from RECORD1, in contrast to the operator `+'. `RECORD * LIST' Her, LIST must be a list of symbols. This yields the record which only contains the attributes of RECORD whose names are in LIST. `LIST1 * LIST2' This yields the "intersection" of the lists interpreted as multi-sets; if an element is M times contained in LIST1 and N times contained in LIST2, it will be `min(M, N)' times contained in the result. `NUMBER1 * NUMBER2' This yields the product of NUMBER1 and NUMBER2.  File: malaga.info, Node: Operator Divide, Prev: Operator Times, Up: Expressions 6.4.21 The Operator `/' ----------------------- This operator may only be used in the following ways: `LIST1 / LIST2' This yields the list which contains all elements of LIST1 which are not elements of LIST2. `LIST / NUMBER' This yields the list which contains all elements of LIST without the leftmost NUMBER elements, if NUMBER is positive, or without the rightmost -NUMBER elements, if NUMBER is negative. `NUMBER1 / NUMBER2' Here, NUMBER2 must not be 0. This yields the quotient of NUMBER1 and NUMBER2.  File: malaga.info, Node: Conditions, Next: Boolean Operators, Prev: Expressions, Up: The Language 6.5 Conditions ============== A condition can either be true or false, as in `Verb = Verb' or `Verb = Noun', respectively. An expression that is evaluated to any of the symbols `yes' or `no' is a valid condition. A condition can be used in all places where a non-constant value is needed. It will evaluate to `yes' or `no'. In this case, the condition must be surrounded by parentheses. * Menu: * Equality Tests:: Compare any values for equality. * Number Comparisons:: Test which number is greater. * Congruency Tests:: Check lists or multi-symbols for common elements. * Operator In:: Test an element or attribute for inclusion. * Regular Expressions:: String patterns.  File: malaga.info, Node: Equality Tests, Next: Number Comparisons, Prev: Conditions, Up: Conditions 6.5.1 The Operators `=' and `/=' -------------------------------- The condition `EXPR1 = EXPR2' tests whether the expressions EXPR1 and EXPR2 are equal. Depending on the types of EXPR1 and EXPR2, equality is defined as follows: EXPR1 and EXPR2 are both symbols or both numbers. In this case EXPR1 and EXPR2 must be identical. EXPR1 and EXPR2 are strings. In this case EXPR1 and EXPR2 must be the same, but the test is case-insensitive. EXPR1 and EXPR2 are lists. In this case EXPR1 and EXPR2 must have the same length, and, for each I, the I-th element of EXPR1 must be equal to the I-th element of EXPR2. EXPR1 and EXPR2 are records. In this case EXPR1 and EXPR2 must contain the same attribute names, though not necessarily in the same order. For each attribute name, the attribute value of EXPR1 and the attribute value of EXPR2 must be equal. If EXPR1 and EXPR2 do not have the same type and are both different from the symbol `nil', the test results in an error; the symbol `nil' can be compared to any value without error message. The test `EXPR1 /= EXPR2' holds if and only if the test `EXPR1 = EXPR2' does not hold.  File: malaga.info, Node: Number Comparisons, Next: Congruency Tests, Prev: Equality Tests, Up: Conditions 6.5.2 The Operators `less', `less_equal', `greater', `greater_equal' -------------------------------------------------------------------- A condition of type `EXPR1 OPERATOR EXPR2' compares two numbers. Here, OPERATOR can have the following values: `less' The condition holds if EXPR1 has a smaller value than EXPR2. `less_equal' The condition holds if EXPR1 has a smaller value than EXPR2 or both numbers are equal. `greater' The condition holds if EXPR1 has a bigger value than EXPR2 `greater_equal' The condition holds if EXPR1 has a bigger value than EXPR2 or both numbers are equal. If either EXPR1 or EXPR2 is no number, an error will be reported.  File: malaga.info, Node: Congruency Tests, Next: Operator In, Prev: Number Comparisons, Up: Conditions 6.5.3 The Operators `~' and `/~' -------------------------------- The operator `~' can be used in the following ways: `LIST1 ~ LIST2' This tests whether LIST1 and LIST2 do "congruate", this means, whether they have at least one element in common. `SYMBOL1 ~ SYMBOL2' This tests if `atoms(SYMBOL1)' and `atoms(SYMBOL2)', the lists of their atomic symbols, do congruate. The comparison `EXPR1 /~ EXPR2' holds if and only if the comparison `EXPR1 ~ EXPR2' does not hold.  File: malaga.info, Node: Operator In, Next: Regular Expressions, Prev: Congruency Tests, Up: Conditions 6.5.4 The Operator `in' ----------------------- The operator `in' can be only used in the following ways: `SYMBOL in RECORD' This condition holds if and only if RECORD contains an attribute named SYMBOL. `VALUE in LIST' This condition holds if and only if VALUE is an element of LIST.  File: malaga.info, Node: Regular Expressions, Prev: Operator In, Up: Conditions 6.5.5 The `matches' Condition (Regular Expressions) --------------------------------------------------- The condition `EXPR matches PATTERN' or `EXPR matches (PATTERN)' interprets PATTERN as a pattern (a regular expression) and tests whether EXPR matches PATTERN. Patterns are defined as follows: PATTERN ::= ALTERNATIVE {`|' ALTERNATIVE} The string must be identical with one of the alternatives. ALTERNATIVE ::= {ATOM [`*' | `?' | `+']} An alternative is a (possibly empty) sequence of atoms. An atom in a pattern corresponds to a character in a string. By using an optional postfix operator it is possible to specify for any atom how often it may be repeated within the string at that location: zero times or once (`?'), at least once (`+'), or arbitrarily often, including zero times (`*'). Normally, these operators are _greedy_, i.e. they try to match as much as possible. If you put a `?' behind a postfix operator, it will try to match as few characters as possible. This can make a difference if you're assigning variables in your pattern. ATOM ::= `(' PATTERN `)' A pattern may be grouped by parentheses. ATOM ::= `[' [`^'] RANGE {RANGE} `]' A character class. It represents exactly one character from one of the ranges. If the symbol `^' is the first one in the class, the expression represents exactly one character that is _not_ contained in one of the ranges. ATOM ::= `.' Represents any character. ATOM ::= CHARACTER Represents the character itself. RANGE ::= CHARACTER1 [`-' CHARACTER2] The range contains any character with a code at least as big as the code of CHARACTER1 and not bigger than the code of CHARACTER2. The code of CHARACTER2 must be at least as big as the code of CHARACTER1. If CHARACTER2 is omitted, the range only contains CHARACTER1. CHARACTER ::= Any character except `*?+[]^-.\|()' To use one of the characters `*?+[]^-.|()', it must be preceded by a `\\' (pattern escape). To insert the pattern escape itself, you have to double it: `\\\\'. You can divide the pattern into segments: $surf matches ("un|in|im|ir|il", ".*", "(en)?") is is the same as $surf matches ("(un|in|im|ir|il).*(en)?") A section of the string can be stored in a variable by suffixing the respective pattern with `: VARIABLE_NAME', as in $surf matches ("un|in|im|ir|il": $a, ".*") For backwards compatibility, you may also prefix the pattern with the variable name, as in $surf matches $a: "un|in|im|ir|il", ".*" The variables defined by pattern matching are only defined in the statement sequence which is being executed if the pattern matching is successful. A `matches' condition may not have variable definitions in it if it is * contained in a disjunction (an `or' condition), * contained in a negation (a `not' condition), or * used as a truth value (e.g. in an assignment).  File: malaga.info, Node: Boolean Operators, Next: Symbol Table, Prev: Conditions, Up: The Language 6.6 The Operators `not', `and', and `or' ======================================== Conditions can be combined logically: `not COND' This is true if condition COND is false. `COND1 and COND2 and COND3 and ...' This is true if all conditions COND1, COND2, COND3, ... are true. The conditions are tested one by one from left to right until one of them is false. This is called "short-cut evaluation". `COND1 or COND2 or COND3 or ...' This is true if at least one of the conditions COND1, COND2, COND3, ... is true. The conditions are tested one by one from left to right until one of them is true. This is also a form of short-cut evaluation. The operator `not' takes exactly one argument. If its argument contains another logical operator, put it in parentheses `()', as in `not (COND1 or COND2)'. The operators `and' and `or' may not be mixed as in `COND1 and COND2 or COND3'; here the order of evaluation would be ambiguous. Use parentheses `()' to indicate in wich order the condition is to be evaluated, as in `(COND1 and COND2) or COND3'.  File: malaga.info, Node: Symbol Table, Next: Initial State, Prev: Boolean Operators, Up: The Language 6.7 The Symbol Table ==================== Every symbol used in a grammar has to be defined at least once in the "symbol table". Every symbol must be followed by a semicolon: `verb; noun; adjective;' Symbols that are being defined that way are called "atoms". A symbol can also be defined as a "molecule". Then the entry for this symbol has the following format: SYMBOL := LIST; The LIST for this symbol must consist of at least two atoms; no atom may occur more than once in the list. This list will be used by the operators `~' and `/~', `atoms', and `multi'. The lists in the symbol table must be different from each other; it does not suffice that they only differ in the order of their elements. If a symbol is defined more than once in the symbol table, the definitions must all match: Either the symbol must always be defined atomic or it must always be molecular with the same atom-list.  File: malaga.info, Node: Initial State, Next: Constant Definition, Prev: Symbol Table, Up: The Language 6.8 The Initial State ===================== The initial state in a combination rule file is defined as follows: initial VALUE, rules RULE1, RULE2, ...; The initial state of a combi rule file specifies a feature structure and a list of rules (behind the keyword `rules'). Each of the rules will be applied to read in the first allomorph (in morphology) or word form (in syntax). The list may be enclosed in parentheses. A combi rule or an end rule is successful if it creates at least one new state, otherwise it fails. If you want rules to be executed only if all other rules failed, you can put their names behind the other rules' names and write an `else' in front of them: initial VALUE, rules RULE1, RULE2 else RULE3, RULE4 else ...; If both rules RULE1 and RULE2 fail, RULE3 and RULE4 are executed. If these rules also fail, the next rules are executed, and so on.  File: malaga.info, Node: Constant Definition, Next: Rules, Prev: Initial State, Up: The Language 6.9 The Constant Definition =========================== A constant definition is of the form define @CONSTANT := EXPR; The constant expression EXPR will be evalued and the constant @CONSTANT will be defined to have this value. The constant must not have been defined previously. The constant is valid from this definition up to the end of the rule file. If you use the keyword `default' instead of `define', you provide a default value for @CONSTANT. This means, the value is only preliminary and may be changed by a normal constant definition. After a constant has been used in an expression, its value may not be changed any more.  File: malaga.info, Node: Rules, Next: Statements, Prev: Constant Definition, Up: The Language 6.10 Rules ========== A rule is a sequence of statements that is executed as a unit: combi_rule NAME($PARAM1, $PARAM2, ...): STATEMENT1 STATEMENT2 ... end NAME; A rule has to begin with one of the keywords `allo_rule', `combi_rule', `end_rule', `pruning_rule', `robust_rule', `input_filter', `output_filter' or `subrule'. It is followed by its _parameter list_, a list of variable names. The variables will be assigned the parameter values when the rule is executed. The number of parameters depends on the rule type. The rule names have the following meanings: `allo_rule($LEX_ENTRY)' An allo-rule must occur exactly once in an allomorph rule file. It analyses a lexical entry and must generate one or more allomorph entries via `result'. An allomorph rule has one parameter, namely the lexicon entry. `combi_rule($STATE, $LINK, $SURF, $INDEX)' Any number of combi-rules may occur in a combi-rule file. Before processing such a rule, the "link" is read in, which is either the word form or the allomorph that follows the state's surface. The first parameter of the rule is the state's feature structure, the second is the link's feature structure, the third is the link's surface, and the fourth is the link's index. The third and the fourth parameter are optional. A combi-rule may state a successor rule set or accept the analysed input (both via `result'). `end_rule($STATE, $REMAIN_INPUT)' Any number of end-rules may occur in a combi-rule file. The first parameter is the state's feature structure, the second, which is optional, is the remaining input. If the rule takes only one parameter, it is only called if the remaining input is empty or begins with a space. An end rule may accept the analysed input via `result'. `pruning_rule($LIST)' A pruning-rule may occur at most once in a combi-rule file. During analysis, it can decide which states are still valid and which are to be deleted. The parameter is a list of feature structures of the states that have consumed the same input so far. The pruning-rule must execute a `return' statement with a list of the symbols `yes' and/or `no'. Each state in $LIST corresponds to a symbol in the result list. If the symbol is `yes', the corresponding state is preserved. If the symbol is `no', the state is abandoned. `robust_rule($SURFACE, $REMAIN_INPUT)' A robust-rule can only appear at most once a morphology rule file. If robust analysis has been switched on by the `robust' command, and a word form could not be recognised by the combi-rules, the robust-rule is executed with the surface of the next word form as its first parameter. The next word form is defined as the remaining input up to (but excluding) the next space. The optional second parameter contains the whole remaining input. A robust-rule can accept any prefix of the remaining input via `result'. `input_filter($FEATURE_STRUCTURE_LIST)' An input-filter may occur at most once in a syntax rule file. The input-filter is called after a word form has been analysed. It gets one parameter, namely the list of the analysis results, and it transforms it to one or more filtered results (via `result'). `output_filter($FEATURE_STRUCTURE_LIST)' An output-filter may occur at most once in any rule file. _In allo-rule files:_ The output-filter is called after all lexicon entry have been processed by the allo-rules. The filter is called for every allomorph surface. It gets one parameter, namely the list of the generated feature structures with that surface, and it transforms it to one or more filtered allomorph feature structures (via `result'). _In combi-rule files:_ The output-filter is called after an item has been analysed. It gets one parameter, namely the list of the analysis results, and it transforms it to one or more filtered results (via `result'). `subrule($PARAM1, $PARAM2, ...)' Any number of subrules may occur in any rule file. A subrule can be invoked from other rules and it must return a value to this rule via `return'. It can have any number of parameters (at least one). If a rule is executed, all statements in the rule are processed sequentially. After that, the rule execution is terminated. Thereby, the `if' statement, the `foreach' statement, and the `select' statement may change the processing order. Special conditions apply if: 1. A condition in a `require' statement does not hold. In this case the processing of the current rule path is terminated. This is not an error. 2. The `stop' statement was executed. In this case the processing of the current rule path is terminated. This is not an error. 3. An `assert' condition does not hold. In this case the processing of the whole grammar is terminated and an error message is displayed. This rule termination can be used to find bugs in the rule system or in the lexicon. 4. The `error' statement was executed. In this case the processing of the whole grammar is terminated and an error message is displayed. 5. The `return' statement was executed in a subrule or in a pruning rule. In a subrule, this terminates the subrule int the current rule path and immediately returns to the calling rule. In a pruning rule, this terminates the pruning rule.  File: malaga.info, Node: Statements, Next: Files, Prev: Rules, Up: The Language 6.11 Statements =============== A rule body contains a sequence of statements. The statements are the assignment and the statements beginning with `assert', `choose', `define', `error', `foreach', `if', `repeat', `require', `result', `return', `select', and `stop'. * Menu: * Assert:: Report an error if condition is not met. * The Assignment:: Assign a new value to a variable. * Break:: Break a `foreach' loop. * Choose:: Branch the current path for different values. * Continue:: Go to the next pass of a `foreach' loop. * Define:: Define a new variable. * Error:: Report an error. * Foreach:: Repeat statements for a given number of iterations. * If:: Conditionally execute statements. * Repeat:: Repeat statements for an unknown number of iterations. * Require:: Terminate the current path if condition is not met. * Result:: Emit a result in a rule. * Return:: Terminate the current subrule and return a value. * Select:: Branch the current path for different statement sequences. * Stop:: Terminate a path.  File: malaga.info, Node: Assert, Next: The Assignment, Prev: Statements, Up: Statements 6.11.1 The `assert' Statement ----------------------------- The statement `assert CONDITION;' or `! CONDITION;' tests whether CONDITION holds. If this is not the case, an error message with the line number in the source code is displayed and the processing of _all_ paths is terminated. The `assert' statement should be used to check whether there are structural flaws in the lexicon or the rule system.  File: malaga.info, Node: The Assignment, Next: Break, Prev: Assert, Up: Statements 6.11.2 The Assignment --------------------- To set the value of an already defined variable to a different value, use a statement of the following form: $VAR := EXPR; The expression EXPR is evaluated and the result is assigned to the variable $VAR. The variable must have already been defined. You can assign the elements of a list value to multiple variables at once: <$VAR1, $VAR2, ... > := EXPR; The first, second, ... element of EXPR, which must be a list, is assigned to variable $VAR1, $VAR2, ... respectively. Any of these variables may be followed by a path. The number of variables must match the length of the list value. You can optionally specify a path behind the variable that is to be set by an assignment: $VAR.PART1.PART2 := VALUE; In this case, only the value of `$VAR.PART1.PART2' will be set to VALUE; the remainder of the variable $VAR will be unchanged. Each PART must be an expression that evaluates to a symbol, a number or a list of symbols and numbers. You can also use one of four other assignment operators instead of the operator `:=': The statement `$VAR :=+ VALUE;' is a shorthand for `$VAR := $VAR + VALUE;'. The same holds for the assignment operators `:=-', `:=*', and `:=/'. Here, $VAR may be followed by a path again.  File: malaga.info, Node: Break, Next: Choose, Prev: The Assignment, Up: Statements 6.11.3 The `break' Statement ---------------------------- The `break' statement leaves the `foreach' loop with LABEL. break LABEL; If the label is omitted, the break statement leaves the innermost `foreach' loop it is contained in. The statement must be situated in the body of the `foreach' loop it wants to leave.  File: malaga.info, Node: Choose, Next: Continue, Prev: Break, Up: Statements 6.11.4 The `choose' Statement ----------------------------- The `choose' statement chooses an element of a list. Its format is: choose $VAR in EXPR; For every element in the list EXPR a rule path is created; in this rule path the element is stored in the variable $VAR. Thus the number of rule paths can multiply. If, for example, EXPR has the value `', the currently processed rule path has three continuations: In the first one $VAR has the value `A', in the second one it has the value `B' and in the third one it has the value `C'. The three paths behave independently from now on. The `choose' statement can also be used for records. In that case, the variable $VAR gets a different attribute name of the record EXPR in each path. The `choose' statement also works for numbers: * If EXPR is a positive number N, the variable $VAR is assigned the numbers 1, 2, ..., N, respectively, in each path. * If EXPR is a negative number -N, the variable $VAR is assigned the numbers -1, -2, ..., -N, respectively, in each path.  File: malaga.info, Node: Continue, Next: Define, Prev: Choose, Up: Statements 6.11.5 The `continue' Statement ------------------------------- The `continue' statement terminates the current pass of the `foreach' loop with LABEL and starts the next pass. If the current pass is the last one, the loop will be left. continue LABEL; If the label is omitted, the statement affects the innermost `foreach' loop it is contained in. The statement must be situated in the body of the `foreach' loop it wants to affect.  File: malaga.info, Node: Define, Next: Error, Prev: Continue, Up: Statements 6.11.6 The `define' Statement ----------------------------- A `define' statement is of the form define $VAR := EXPR; The expression EXPR is evaluated and the result is assigned to the variable $VAR. The variable may not be defined before this statement; it is defined by the statement and only exists until the statement sequence in which the assignment is situated has been processed fully. You can assign the elements of a list value to multiple variables at once: define <$VAR1, $VAR2, ... > := EXPR; The first, second, ... element of EXPR, which must be a list, is assigned to the new variable $VAR1, $VAR2, ... respectively. The number of variables must match the length of the list value.  File: malaga.info, Node: Error, Next: Foreach, Prev: Define, Up: Statements 6.11.7 The `error' Statement ---------------------------- The statement `error' terminates the execution of _all_ paths and displays the given expression, which must be a string, and the line of the source text: error MESSAGE;  File: malaga.info, Node: Foreach, Next: If, Prev: Error, Up: Statements 6.11.8 The `foreach' Statement ------------------------------ You may wish to manipulate all elements of a list or a record _sequentially_ in ONE rule path. For this purpose, the `foreach' statement was introduced. It has the following format: foreach $VAR in EXPR: STATEMENTS end foreach; Sequentually, $VAR is assigned a number of values, depending on the type of EXPR, and the statement sequence STATEMENTS is executed for each of those assignments. Every time the STATEMENTS are being walked through, the variable $VAR is defined again. Its scope is the block STATEMENTS. * If EXPR is a list, $VAR is assigned the first, second, third, ... element of EXPR. * If EXPR is a record, $VAR is assigned the first, second, ... attribute name of EXPR. * If EXPR is a positive number N, the variable $VAR is assigned the numbers 1, 2, ..., N sequentially. * If EXPR is a negative number N, the variable $VAR is assigned the numbers -1, -2, ..., -N sequentially. * If EXPR is an empty list, an empty record or the number 0, the foreach loop is terminated immediately.  File: malaga.info, Node: If, Next: Repeat, Prev: Foreach, Up: Statements 6.11.9 The `if' Statement ------------------------- An `if' statement has the following form: if CONDITION1 then STATEMENTS1 elseif CONDITION2 then STATEMENTS2 else STATEMENTS3 end if; The `elseif' part may be repeated unrestrictedly (including zero times), the `else' part may be omitted. First, CONDITION1 is evaluated. If it is satisfied, the statement sequence STATEMENTS1 is executed. If the first condition is not satisfied, CONDITION2 is evaluated; if the result is true, STATEMENTS2 is executed. This procedure is repeated for every `elseif' part until a condition is satisfied. If the `if' condition and `elseif' conditions fail, the statement sequence STATEMENTS3 is executed (if it exists). After the `if' statement has been processed, the following statement is executed. The `if' after the `end' may be omitted.  File: malaga.info, Node: Repeat, Next: Require, Prev: If, Up: Statements 6.11.10 The `repeat' Statement ------------------------------ You may wish to repeat a sequence of statements while a specific condition holds. This can be realised by the `repeat' loop. It has the following form: repeat STATEMENTS1 while CONDITION; STATEMENTS2 end repeat; The statements STATEMENTS1 are executed. Then, CONDITION is tested. If it holds, the STATEMENTS2 are executed and the `repeat' statement is executed again. If CONDITION does not hold, execution proceeds after the `repeat' statement. If STATEMENTS1 is empty, the `repeat' loop is equivalent to a while loop in C: repeat while CONDITION; STATEMENTS end repeat; If STATEMENTS2 is empty, the `repeat' loop is equivalent to a do-while loop in C: repeat STATEMENTS while CONDITION; end repeat;  File: malaga.info, Node: Require, Next: Result, Prev: Repeat, Up: Statements 6.11.11 The `require' Statement ------------------------------- A statement of the form require CONDITION; or ? CONDITION; tests whether CONDITION is true. If this is not the case the rule path is terminated _without_ error message. Test statements should be used to decide whether the combination of a state and a link is grammatical.  File: malaga.info, Node: Result, Next: Return, Prev: Require, Up: Statements 6.11.12 The `result' Statement ------------------------------ _In combi rules:_ The statement result EXPR, rules RULE1, RULE2, ...; specifies the Result feature structure of the rule and the successor rules. The value EXPR is the Result feature structure. Behind the keyword `rules' the names of all successor rules are enumerated. For every successor rule that is being executed a new rule path will be created. The rule set may be enclosed in parentheses. If you want successor rules to be executed only if no other rule has been successful, you can put their names behind the other rules' names and write an `else' in front of them: result EXPR, rules RULE1, RULE2 else RULE3, RULE4 else ...; If none of the normal rules (here: RULE1 and RULE2) has been successful, RULE3 and RULE4 are executed. If these rule also fail, the next rules are executed, and so on. A rule has been successful if at least one `result' statement has been executed. _In combi-rules and end-rules:_ If the input is to be accepted by the `result' statement (and therefore no successor rules are to be called) the following format has to be used: result EXPR, accept; If this statement is reached in a rule path, the input is accepted as grammatically well-formed. The value EXPR is returned as the result of the morphological or syntactic analysis. _In filters:_ The format of a `result' statement in a filter or robust-rule is result EXPR; If this statement is reached, the value EXPR is used as a result of the executed rule. _In robust-rules:_ The format of a `result' statement in a robust-rule: result FEATURE_STRUCTURE; or result SURFACE, FEATURE_STRUCTURE; The word form SURFACE with feature structure FEATURE_STRUCTURE is used as a result of the robust-rule. SURFACE must be a prefix of the input that has not been parsed yet. If it is omitted, the input up to, but excluding, the first space is taken. _In allo-rules:_ The format of the `result' statement in an allo rule is: result SURFACE, FEATURE_STRUCTURE; It creates an entry in the allomorph lexicon. The allomorph surface SURFACE must be a string; FEATURE_STRUCTURE is the feature structure of the allomorph.  File: malaga.info, Node: Return, Next: Select, Prev: Result, Up: Statements 6.11.13 The `return' Statement ------------------------------ In a subrule, the `return' statement is of the following form: return EXPR; The value of EXPR is returned to the rule that invoked this subrule and the subrule execution is finished. In a pruning rule, the `return' statement is of the same form. Here, EXPR must be a list a list of the symbols `yes' and/or `no'. Each state in the feature structure list, which is the pruning rule parameter, corresponds to a symbol in the result list. If the symbol is `yes', the corresponding state is preserved. If the symbol is `no', the state is abandoned.  File: malaga.info, Node: Select, Next: Stop, Prev: Return, Up: Statements 6.11.14 The `select' Statement ------------------------------ By using the `select' statement, more than one continuation of an analysis path can be generated. Its format is: select STATEMENTS1 or STATEMENTS2 or STATEMENTS3 ... end select; This creates as many rule paths as there are statement sequences. In the first rule path, STATEMENTS1 are executed, in the second one STATEMENTS2 are executed, etc. Each rule path continues by executing the statements following the `select' statement. The keyword `select' behind the `end' can be omitted.  File: malaga.info, Node: Stop, Prev: Select, Up: Statements 6.11.15 The `stop' Statement ---------------------------- The `stop' statement terminates the current rule path. Its format is: stop;  File: malaga.info, Node: Files, Next: Syntax Summary, Prev: Statements, Up: The Language 6.12 Files ========== A Malaga grammar system comprises several files: a symbol file, a lexicon file, an allomorph rule file, a morphology rule file, an extended symbol file (optional), and a syntax rule file (optional). The type of a file can be seen by the ending of the file name. A grammar for the English language may consist of the files `english.sym', `english.lex', `english.all', `english.mor' and `english.syn'. * Menu: * Symbol File:: The definition of all morphology symbols. * Extended Symbol File:: Additional syntax symbols. * Lexicon File:: The lexicon from which allomorphs will be created. * Allomorph Rule File:: The rules that create the allomorphs. * Combi-Rule Files:: The LAG rules that combine the allomorphs or words.  File: malaga.info, Node: Symbol File, Next: Extended Symbol File, Prev: Files, Up: Files 6.12.1 The Symbol File ---------------------- A symbol file has the suffix `.sym'. It contains the symbol table.  File: malaga.info, Node: Extended Symbol File, Next: Lexicon File, Prev: Symbol File, Up: Files 6.12.2 The Extended Symbol File ------------------------------- An extended symbol file has the suffix `.esym'. It contains an additional symbol table that contains symbols which may only be used in the syntax rule file.  File: malaga.info, Node: Lexicon File, Next: Allomorph Rule File, Prev: Extended Symbol File, Up: Files 6.12.3 The Lexicon File ----------------------- A lexicon file has the suffix `.lex'. It consists of any number of values and constant definitions, each terminated by a semicolon. Each value stands for a lexical entry. A value may contain named constants and the operators `.', `+', `-', `*', and `/'. values, the lexical entries; The format of the lexical entries is free, although it should be consistent with the conception of the whole rule system.  File: malaga.info, Node: Allomorph Rule File, Next: Combi-Rule Files, Prev: Lexicon File, Up: Files 6.12.4 The Allomorph Rule File ------------------------------ The allomorph lexicon is generated from the base form lexicon by applying the allo-rule on the base form entries. The allomorph generation rule file has the suffix `.all' and consists of one allo-rule, an optional output-filter, and any number of subrules and constant definitions. For every lexical entry, the allo-rule is executed with the value of the lexicon entry as parameter. The allo-rule can generate allomorphs using the `result' statement. After all allomorphs have been produced, the output-filter is executed once for each surface in the (intermediate) allomorph lexicon. As parameter, the output-filter gets the list of feature structures that share that surface. An entry in the final allomorph lexicon is created everytime the `result' statement is executed. The surface cannot be changed by the output-filter.  File: malaga.info, Node: Combi-Rule Files, Prev: Allomorph Rule File, Up: Files 6.12.5 The Combi-Rule Files --------------------------- A grammar system includes up to two combination rules files: one for morphological combination with the suffix `.mor' and (optionally) one for syntactic combination with the suffix `.syn'. A combination rule file consists of an initial state and any number of combi-rules, subrules, and constant definitions. A syntax rule file may contain one optional pruning-rule, one optional input-filter and one optional output-filter; a morphology rule file may contain one optional robust-rule, one optional pruning-rule and one optional output-filter. Beginning with the rules listed up in the initial state, the rules and their successors are processed until a `result' statement with the keyword `accept' is encountered in every path. A path dies if there is no more input (from the lexicon or from the morphology) that can be processed. In morphology, if analysis has created no result and robust analysis has been switched on, the robust-rule will be called with the analysis surface and can create a result. In syntax, when a new wordfom has been imported from morphology, the input-filter can take a look at its feature structuress and create new result feature structures. If a pruning-rule is present, pruning has been activated, and the number of current LAG states is not less than `mor-pruning' (in morphology) or `syn-pruning' (in syntax), the concatenation of the next allomorph (in morphology) or word form (in syntax) is preceded by the following step: The feature structures of all current LAG states are merged into a list, which is the parameter of the pruning rule. The pruning-rule must execute a `return' statement with a list of the symbols `yes' and `no'. Each state in the feature structure list corresponds to a symbol in the result list. If the symbol is `yes', the corresponding state is preserved. If the symbol is `no', the state is abandoned. After analysis has completed, the output-filter can take a look at all result feature structures and create new result feature structures. This can be used to merge similar feature structures or drop some results.  File: malaga.info, Node: Syntax Summary, Prev: Files, Up: The Language 6.13 Summary of the Malaga Syntax ================================= The syntax of Malaga source texts is defined formally by a sort of EBNF notation: * Terminals like `assert' and `:=' stand for themselves. * Nonterminals like ASSIGNMENT are defined by "productions". * A bar `|' separates alternatives. * Brackets `[]' enclose optional parts. * Curly braces `{}' enclose parts that are repeated zero times, one time, or multiple times. * Parentheses `()' are used for grouping. The start productions for Malaga source texts are LEXICON-FILE, RULE-FILE, and SYMBOL-FILE. A nonterminal marked with `*' in its definition is a lexical symbol. ASSERT-STATEMENT: (`assert' | `!') CONDITION `;' ASSIGNMENT: PATH (`:=' | `:=+' | `:=-' | `:=*' | `:=/') EXPRESSION `;' | `<' PATH {`,' PATH} `>' `:=' EXPRESSION `;' BREAK-STATEMENT: `break' [LABEL] `;' CHOOSE-STATEMENT: `choose' VARIABLE `in' EXPRESSION `;' COMMENT*: `#' {PRINTING-CHAR} COMPARISON: [`not'] (EXPRESSION [COMPARISON-OPERATOR EXPRESSION] | MATCH-COMPARISON) COMPARISON-OPERATOR: `=' | `/=' | `~' | `/~' | `in' | `less' | `greater' | `less_equal' | `greater_equal' CONDITION: COMPARISON ({`and' COMPARISON} | {`or' COMPARISON}) CONSTANT*: `@' IDENTIFIER CONSTANT-DEFINITION: (`define' | `default') CONSTANT `:=' CONSTANT-EXPRESSION `;' CONSTANT-EXPRESSION: EXPRESSION CONTINUE-STATEMENT: `continue' [LABEL] `;' DEFINE-STATEMENT: `define' VARIABLE `:=' EXPRESSION `;' | `define' `<' VARIABLE {`,' VARIABLE} `>' `:=' EXPRESSION `;' ERROR-STATEMENT: `error' EXPRESSION `;' EXPRESSION: TERM {(`+' | `-') TERM} FACTOR: VALUE {`.' VALUE} FOREACH-STATEMENT: [LABEL `:'] `foreach' VARIABLE `in' EXPRESSION `:' STATEMENTS `end' [`foreach'] `;' IDENTIFIER*: (LETTER | `_' | `&') {LETTER | DIGIT | `_' | `&'} IF-STATEMENT: `if' CONDITION `then' STATEMENTS {`elseif' CONDITION `then' STATEMENTS} [`else' STATEMENTS] `end' [`if'] `;' IF-EXPRESSION: `if' CONDITION `then' EXPRESSION {`elseif' CONDITION `then' EXPRESSION} `else' EXPRESSION `end' [`if'] INCLUDE: `include' STRING `;' INITIAL: `initial' CONSTANT-EXPRESSION `,' RULE-SET `;' LABEL: IDENTIFIER LEXICON-FILE: {CONSTANT-DEFINITION | CONSTANT-EXPRESSION `;'} LIST: `<' {EXPRESSION {`,' EXPRESSION}} `>' MATCH: CONSTANT-EXPRESSION [`:' VARIABLE] | VARIABLE `:' CONSTANT-EXPRESSION MATCH-COMPARISON: EXPRESSION `matches' ( `(' MATCH {`,' MATCH} `)' | MATCH {`,' MATCH} ) NUMBER*: DIGIT {DIGIT} ( `L' | `R' | [`.' DIGIT {DIGIT}] [`E' DIGIT {DIGIT}] ) PATH: VARIABLE {`.' VALUE} RECORD: `[' {SYMBOL-VALUE-PAIR {`,' SYMBOL-VALUE-PAIR}} `]' REPEAT-STATEMENT: `repeat' STATEMENTS `while' CONDITION `;' STATEMENTS `end' [`repeat'] `;' REQUIRE-STATEMENT: (`require' | `?') CONDITION `;' RESULT-STATEMENT: `result' EXPRESSION [`,' (RULE-SET | `accept')] `;' RETURN-STATEMENT: `return' EXPRESSION `;' RULE: RULE-TYPE RULE-NAME `(' VARIABLE {`,' VARIABLE} `)' `:' STATEMENTS `end' [RULE-TYPE] [RULE-NAME] `;' RULE-FILE: {RULE | CONSTANT-DEFINITION | INITIAL | INCLUDE} RULE-NAME: IDENTIFIER RULE-SET: `rules' (RULES {`else' RULES} | `(' RULES {`else' RULES} `)') RULE-TYPE: `allo_rule' | `combi_rule' | `end_rule' | `pruning_rule' | `robust_rule' | `input_filter' | `output_filter' | `subrule' RULES: RULE-NAME {`,' RULE-NAME} SELECT-STATEMENT: `select' STATEMENTS {`or' STATEMENTS} `end' [`select'] `;' STATEMENTS: {ASSERT-STATEMENT | ASSIGNMENT | BREAK-STATEMENT | CHOOSE-STATEMENT | CONTINUE-STATEMENT | DEFINE-STATEMENT | ERROR-STATEMENT | FOREACH-STATEMENT | IF-STATEMENT | SELECT-STATEMENT | REPEAT-STATEMENT | REQUIRE-STATEMENT | RESULT-STATEMENT | RETURN-STATEMENT | STOP-STATEMENT} STOP-STATEMENT: `stop' `;' STRING*: `"' {CHAR-EXCEPT-DOUBLE-QUOTES | `\"' | `\\'} `"' SUBRULE-INVOCATION: RULE-NAME `(' EXPRESSION {`,' EXPRESSION} SYMBOL: IDENTIFIER SYMBOL-DEFINITION: symbol [`:=' `<' SYMBOL {`,' SYMBOL} `>'] `;' SYMBOL-FILE: {SYMBOL-DEFINITION | INCLUDE} SYMBOL-VALUE-PAIR: EXPRESSION `:' EXPRESSION TERM: FACTOR {(`*' | `/') FACTOR} VALUE: [`-'] (SYMBOL | STRING | NUMBER | LIST | RECORD | CONSTANT | SUBRULE-INVOCATION | VARIABLE | `(' CONDITION `)') | IF-EXPRESSION VARIABLE*: `$' IDENTIFIER  File: malaga.info, Node: Index, Prev: The Language, Up: Top Index ***** [index] * Menu: * * (operator): Operator Times. (line 6) * + (operator): Operator Plus. (line 6) * - (operator): Operator Minus. (line 6) * .malagarc (file): Profiles. (line 6) * / (operator): Operator Divide. (line 6) * /= (operator): Equality Tests. (line 6) * /~ (operator): Congruency Tests. (line 6) * = (operator): Equality Tests. (line 6) * accept (keyword): Result. (line 6) * alias (option): alias. (line 6) * allo-format (mallex option): allo-format. (line 6) * allo_rule (rule): Rules. (line 6) * allomorph rule files: Allomorph Rule File. (line 6) * and (operator): Boolean Operators. (line 6) * assignment: The Assignment. (line 6) * atoms: Symbol Table. (line 12) * atoms (function): Atoms. (line 6) * attribute order: sort-records. (line 6) * attributes: Records. (line 6) * auto-tree (malaga option): auto-tree. (line 6) * auto-variables (option): auto-variables. (line 6) * backtrace (command): backtrace. (line 6) * Beutel, Bjoern: Introduction. (line 13) * binary (command line option): mallex. (line 57) * boolean operators: Boolean Operators. (line 6) * break (command): break. (line 6) * break (statement): Break. (line 6) * breakpoints: break. (line 6) * cache-size (malaga option): cache-size. (line 6) * capital (function): Capital. (line 6) * choose (statement): Choose. (line 6) * clear-cache (malaga command): clear-cache. (line 6) * combi-rule files: Combi-Rule Files. (line 6) * combi_rule (rule): Rules. (line 6) * commands: Commands. (line 6) * comments: Comments. (line 6) * conditions: Conditions. (line 6) * constant definition: Constant Definition. (line 6) * constants: Constants. (line 6) * continue (command): continue. (line 6) * continue (statement): Continue. (line 6) * debug-ga (mallex command): debug-ga. (line 6) * debug-ga-file (mallex command): debug-ga-file. (line 6) * debug-ga-line (mallex command): debug-ga-line. (line 6) * debug-ma (malaga command): debug-ma. (line 6) * debug-ma-line (malaga command): debug-ma-line. (line 6) * debug-sa (malaga command): debug-sa. (line 6) * debug-sa-line (malaga command): debug-sa-line. (line 6) * debug-state (malaga command): debug-state. (line 6) * define (statement): Define. (line 6) * definition, constant: Constant Definition. (line 6) * delete (command): delete. (line 6) * display-cmd (option): display-cmd. (line 6) * down (command): down. (line 6) * else (keyword) <1>: If. (line 6) * else (keyword): If Expression. (line 6) * elseif (keyword) <1>: If. (line 6) * elseif (keyword): If Expression. (line 6) * empty record: Records. (line 19) * end_rule (rule): Rules. (line 6) * error (statement): Error. (line 6) * error-format (malaga option): error-format. (line 6) * escape character (\): Strings. (line 11) * expressions: Expressions. (line 6) * expressions, regular: Regular Expressions. (line 6) * extended symbol files: Extended Symbol File. (line 6) * failing rule: Initial State. (line 15) * files: Files. (line 6) * files, allomorph rule: Allomorph Rule File. (line 6) * files, combi-rule: Combi-Rule Files. (line 6) * files, extended symbol: Extended Symbol File. (line 6) * files, lexicon: Lexicon File. (line 6) * files, morphology rule: Combi-Rule Files. (line 6) * files, symbol: Symbol File. (line 6) * files, syntax rule: Combi-Rule Files. (line 6) * finish (command): finish. (line 6) * floor (function): Floor. (line 6) * font family: Profiles. (line 36) * font size: Profiles. (line 40) * foreach (statement): Foreach. (line 6) * Formalism: Formalism. (line 6) * frame (command): frame. (line 6) * functions: Subrule Calls. (line 16) * ga (mallex command): ga. (line 6) * ga-file (mallex command): ga-file. (line 6) * ga-line (mallex command): ga-line. (line 6) * geometry: Profiles. (line 27) * get (command): get. (line 6) * greater (operator): Number Comparisons. (line 6) * greater_equal (operator): Number Comparisons. (line 6) * Hangul: Projects. (line 118) * Hangul, transcribed: roman-hangul. (line 6) * help (command line option): The Programs. (line 34) * help (command): help. (line 6) * hidden (option): hidden. (line 6) * identifiers: Identifiers. (line 6) * if (expression): If Expression. (line 6) * if (statement): If. (line 6) * in (operator): Operator In. (line 6) * include (statement): Include. (line 6) * indexes, state: Profiles. (line 45) * info (malaga command): info. (line 6) * initial state: Initial State. (line 6) * input (command line option): malaga. (line 53) * input_filter (rule): Rules. (line 6) * LAG: Formalism. (line 6) * length (function): Length. (line 6) * less (operator): Number Comparisons. (line 6) * less_equal (operator): Number Comparisons. (line 6) * lexicon files: Lexicon File. (line 6) * list (command): list. (line 6) * list assignment: The Assignment. (line 15) * lists: Lists. (line 6) * ma (malaga command): ma. (line 6) * ma-file (malaga command): ma-file. (line 6) * ma-line (malaga command): ma-line. (line 6) * malaga (program): malaga. (line 6) * Malaga, programming language: The Language. (line 6) * malaga.ini (file): Profiles. (line 6) * mallex (program): mallex. (line 6) * malmake (program): malmake. (line 6) * matches (operator): Regular Expressions. (line 6) * mg (malaga command): mg. (line 6) * molecules: Symbol Table. (line 12) * mor-incomplete (malaga option): mor-incomplete. (line 6) * mor-out-filter (malaga option): mor-out-filter. (line 6) * mor-pruning (malaga option): mor-pruning. (line 6) * morphology (command line option): malaga. (line 33) * morphology rule files: Combi-Rule Files. (line 6) * multi (function): Multi. (line 6) * next (command): next. (line 6) * no (symbol): Conditions. (line 6) * not (operator): Boolean Operators. (line 6) * numbers: Numbers. (line 6) * operator priority: Expressions. (line 31) * options: Options. (line 6) * or (operator): Boolean Operators. (line 6) * order, attribute: sort-records. (line 6) * output_filter (rule): Rules. (line 6) * patterns, string: Regular Expressions. (line 6) * prelex (command line option): mallex. (line 64) * print (command): print. (line 6) * priority, operator: Expressions. (line 31) * profile: Profiles. (line 6) * projects: Projects. (line 6) * Pruning <1>: syn-pruning. (line 6) * Pruning: mor-pruning. (line 6) * pruning_rule (rule): Rules. (line 6) * quit (command): quit. (line 6) * quoted (command line option): malaga. (line 45) * read-constants (mallex command): read-constants. (line 6) * readable (command line option): mallex. (line 60) * record, empty: Records. (line 19) * records: Records. (line 6) * regular expressions: Regular Expressions. (line 6) * repeat (statement): Repeat. (line 6) * require (statement): Require. (line 6) * result (command): result. (line 6) * result (statement): Result. (line 6) * result-format (malaga option): result-format. (line 6) * result-list (malaga option): result-list. (line 6) * return (statement) <1>: Return. (line 6) * return (statement): Subrule Calls. (line 10) * robust-rule (malaga option): robust-rule. (line 6) * robust_rule (rule): Rules. (line 6) * roman-hangul (option): roman-hangul. (line 6) * rule files, allomorph: Allomorph Rule File. (line 6) * rule files, morphology: Combi-Rule Files. (line 6) * rule files, syntax: Combi-Rule Files. (line 6) * rule, failing: Initial State. (line 15) * rule, successful: Initial State. (line 15) * rules: Rules. (line 6) * run (command): run. (line 6) * sa (malaga command): sa. (line 6) * sa-file (malaga command): sa-file. (line 6) * sa-line (malaga command): sa-line. (line 6) * Schueller, Gerald: Introduction. (line 14) * select (statement): Select. (line 6) * set (command): set. (line 6) * set (function): Set. (line 6) * sg (malaga command): sg. (line 6) * sort-records (option): sort-records. (line 6) * split-hangul-syllables: Projects. (line 125) * state indexes: Profiles. (line 45) * state, initial: Initial State. (line 6) * statements: Statements. (line 6) * step (command): step. (line 6) * stop (statement): Stop. (line 6) * string patterns: Regular Expressions. (line 6) * strings: Strings. (line 6) * subrule (rule): Rules. (line 6) * subrules, calling: Subrule Calls. (line 6) * substring (function): Substring. (line 6) * successful rule: Initial State. (line 15) * switch (function): Switch. (line 6) * switch (option): switch. (line 6) * symbol definition: Symbol Table. (line 6) * symbol files: Symbol File. (line 6) * symbol files, extended: Extended Symbol File. (line 6) * symbol table: Symbol Table. (line 6) * symbols: Symbols. (line 6) * syn-in-filter (malaga option): syn-in-filter. (line 6) * syn-incomplete (malaga option): syn-incomplete. (line 6) * syn-out-filter (malaga option): syn-out-filter. (line 6) * syn-pruning (malaga option): syn-pruning. (line 6) * syntax (command line option): malaga. (line 39) * syntax rule files: Combi-Rule Files. (line 6) * syntax, Malaga: Syntax Summary. (line 6) * transcribed Hangul: roman-hangul. (line 6) * transmit (command): transmit. (line 6) * transmit (function): Transmit. (line 6) * transmit-cmd (option): transmit-cmd. (line 6) * tree (malaga command): tree. (line 6) * unknown-format (malaga option): unknown-format. (line 6) * up (command): up. (line 6) * use-display (option): use-display. (line 6) * value_string (function): Value_String. (line 6) * value_type (function): Value_Type. (line 6) * values: Values. (line 6) * variables (command): variables. (line 6) * version (command line option): The Programs. (line 38) * walk (command): walk. (line 6) * where (command): where. (line 6) * window geometry: Profiles. (line 27) * yes (symbol): Conditions. (line 6) * ~ (operator): Congruency Tests. (line 6)  Tag Table: Node: Top597 Node: Introduction1955 Node: Formalism2880 Node: The Programs7861 Node: Projects10007 Node: Profiles16013 Node: malaga19286 Node: mallex21678 Node: malmake23928 Node: malrul25324 Node: malsym25960 Node: Commands26925 Node: backtrace29799 Node: break30497 Node: clear-cache32555 Node: continue32946 Node: debug-ga34695 Node: debug-ga-file36225 Node: debug-ga-line36768 Node: debug-ma37571 Node: debug-ma-line38006 Node: debug-sa38452 Node: debug-sa-line38879 Node: debug-state39326 Node: delete40218 Node: down40512 Node: finish40842 Node: frame41157 Node: ga41537 Node: ga-file42540 Node: ga-line43358 Node: get44024 Node: help44400 Node: info44786 Node: list45023 Node: ma45298 Node: ma-file45927 Node: ma-line47766 Node: mg48373 Node: next49161 Node: print49706 Node: quit51805 Node: read-constants51989 Node: result52399 Node: run54126 Node: sa54538 Node: sa-file55297 Node: sa-line57194 Node: set57920 Node: sg58354 Node: step59127 Node: transmit59515 Node: tree59903 Node: up64598 Node: variables64903 Node: walk66880 Node: where67199 Node: Options67647 Node: alias69780 Node: allo-format70423 Node: auto-tree71097 Node: auto-variables71595 Node: cache-size72177 Node: display-cmd72901 Node: error-format73387 Node: hidden74183 Node: mor-incomplete74913 Node: mor-out-filter75563 Node: mor-pruning75941 Node: result-format76604 Node: result-list77531 Node: robust-rule78215 Node: roman-hangul78774 Node: sort-records79303 Node: switch79957 Node: syn-incomplete80364 Node: syn-in-filter80903 Node: syn-out-filter81273 Node: syn-pruning81646 Node: transmit-cmd82292 Node: unknown-format82693 Node: use-display83430 Node: The Language83898 Node: Characterisation84872 Node: Source Texts87556 Node: Comments88259 Node: Include88560 Node: Identifiers89166 Node: Values90147 Node: Symbols90809 Node: Numbers91253 Node: Strings91906 Node: Lists92430 Node: Records92792 Node: Expressions93461 Node: Malaga Variables95822 Node: Constants96329 Node: Subrule Calls96737 Node: Atoms97268 Node: Capital97556 Node: Floor97820 Node: Length98058 Node: Multi98343 Node: Set98690 Node: Substring98962 Node: Switch99661 Node: Transmit99949 Node: Value_String100554 Node: Value_Type100811 Node: If Expression101144 Node: Unary Minus102128 Node: Operator Dot102329 Node: Operator Plus103096 Node: Operator Minus103827 Node: Operator Times104790 Node: Operator Divide105890 Node: Conditions106523 Node: Equality Tests107322 Node: Number Comparisons108613 Node: Congruency Tests109417 Node: Operator In110020 Node: Regular Expressions110435 Node: Boolean Operators113496 Node: Symbol Table114691 Node: Initial State115706 Node: Constant Definition116709 Node: Rules117455 Node: Statements123149 Node: Assert124371 Node: The Assignment124874 Node: Break126246 Node: Choose126661 Node: Continue127805 Node: Define128332 Node: Error129125 Node: Foreach129443 Node: If130650 Node: Repeat131605 Node: Require132524 Node: Result132960 Node: Return135463 Node: Select136163 Node: Stop136841 Node: Files137049 Node: Symbol File137914 Node: Extended Symbol File138125 Node: Lexicon File138451 Node: Allomorph Rule File139018 Node: Combi-Rule Files140018 Node: Syntax Summary142247 Node: Index146853  End Tag Table malaga-7.12/malaga.el0000644000175000017500000005570610761577654014010 0ustar bjoernbjoern;; Copyright (C) 1995 Gerald Schueller. ;; Copyright (C) 1995 Bjoern Beutel. (provide 'malaga) (defconst malaga-version "7.12" "Version of Malaga.") ;; malaga mode (for editing malaga files). ==================================== (setq auto-mode-alist ; Files for which malaga mode will be invoked. (append '(("\\.all$" . malaga-mode) ("\\.esym$" . malaga-mode) ("\\.lex$" . malaga-mode) ("\\.mal$" . malaga-mode) ("\\.mor$" . malaga-mode) ("\\.sym$" . malaga-mode) ("\\.syn$" . malaga-mode) ("\\.pro$" . malaga-project-mode) ) auto-mode-alist)) ;;----------------------------------------------------------------------------- (defun malaga-mode () "Major mode for editing Malaga code. \\ Key bindings: \\[malaga-electric-tab], \\[malaga-electric-semicolon] \ and \\[malaga-electric-terminate-line] indent code. \\[malaga-goto-previous-rule] jumps to previous malaga rule. \\[malaga-goto-next-rule] jumps to next malaga rule. \\[malaga-goto-rule] jumps to malaga rule with specific name. \\[malmake] creates malmake process. \\[malaga] creates malaga process. \\[mallex] creates mallex process. \\[malaga-delete-arrow] deletes the debugger arrow. Commands: malaga-upcase-keywords malaga-downcase-keywords Variables controlling malaga-mode for all buffers: malaga-indent-level malaga-change-to-project-directory" (interactive) (kill-all-local-variables) (use-local-map malaga-mode-map) (setq major-mode 'malaga-mode) (setq mode-name "Malaga") (setq parse-sexp-ignore-comments t) (set-syntax-table malaga-mode-syntax-table) (make-local-variable 'indent-line-function) (setq indent-line-function 'malaga-indent-line) (make-local-variable 'comment-start) (setq comment-start "\# ") (make-local-variable 'comment-end) (setq comment-end "") (make-local-variable 'comment-start-skip) (setq comment-start-skip "# *") (make-local-variable 'completion-ignore-case) (setq completion-ignore-case t) (malaga-font) (malaga-init-menu) (run-hooks 'malaga-mode-hook)) ;;----------------------------------------------------------------------------- (defun malaga-init-menu () "Initialize menu for malaga mode." (let ((malaga-items '("Malaga" ["Previous rule" malaga-goto-previous-rule t] ["Next rule" malaga-goto-next-rule t] ["Jump to rule..." malaga-goto-rule t] "-----" ["Comment region" comment-region (mark)] ["Uncomment region" (comment-region (region-beginning) (region-end) -1) (mark)] "-----" ["UPCASE keywords" malaga-upcase-keywords t] ["downcase keywords" malaga-downcase-keywords t] "-----" ["Call malmake..." malmake t] ["Call mallex..." mallex t] ["Call malaga..." malaga t] ["Change to project directory" (setq malaga-change-to-project-directory (not malaga-change-to-project-directory)) :style toggle :selected malaga-change-to-project-directory] ))) (cond ((string-match "XEmacs\\|Lucid" emacs-version) (set-buffer-menubar (copy-sequence current-menubar)) (add-submenu nil malaga-items)) (t (require 'easymenu) (easy-menu-define malaga-menu malaga-mode-map "Malaga menu" malaga-items))))) ;; Data Structures for malaga mode. =========================================== (defconst malaga-keywords-list '("accept" "allo_rule" "and" "assert" "break" "choose" "combi_rule" "continue" "default" "define" "else" "elseif" "end" "end_rule" "error" "foreach" "greater" "greater_equal" "if" "in" "include" "initial" "input_filter" "less" "less_equal" "matches" "not" "or" "output_filter" "parallel" "pruning_rule" "repeat" "require" "result" "return" "robust_rule" "rules" "select" "stop" "subrule" "then" "while") "The keywords used in malaga rule files (as a list).") (defvar malaga-keywords nil "The keywords used in malaga rule files (as an obarray for completion).") (setq malaga-keywords (make-vector 127 0)) (mapcar (function (lambda (x) (intern x malaga-keywords))) malaga-keywords-list) (defconst malaga-ident-re "\\([A-Za-z\240-\377][A-Za-z_&|0-9\240-\377]*\\)") (defconst malaga-rule-re (concat "\\<\\(allo_rule\\|combi_rule\\|end_rule\\|input_filter" "\\|output_filter\\|pruning_rule\\|robust_rule\\|subrule\\)\\>")) (defconst malaga-begin-block-re (concat "\\(" malaga-rule-re "[\t ]*\\({\\|" malaga-ident-re "[\t ]*(\\)\\)" "\\|\\<\\(foreach\\|if\\|parallel\\|repeat\\|select\\)\\>" "[\t ]*[^\t ;]")) (defconst malaga-end-block-re "\\") (defconst malaga-sub-block-re "\\<\\(and\\|else\\|elseif\\|or\\|while\\)\\>") (defconst malaga-noindent-re "\\<\\(and\\|else\\|elseif\\|end\\|or\\|while\\|then\\)\\>") (defconst malaga-autoindent-lines-re (concat "\\<\\(and\\|[A-Za-z_]+rule\\|end\\|else\\|elseif\\|foreach\\|if" "\\|of\\|parallel\\|select\\|while\\)\\>")) (defvar malaga-mode-syntax-table nil "Syntax table in use in Malaga-mode buffers.") (setq malaga-mode-syntax-table (make-syntax-table)) (modify-syntax-entry ?# "<" malaga-mode-syntax-table) (modify-syntax-entry ?\n ">" malaga-mode-syntax-table) (modify-syntax-entry ?\\ "\\" malaga-mode-syntax-table) (modify-syntax-entry ?& "w" malaga-mode-syntax-table) (modify-syntax-entry ?| "w" malaga-mode-syntax-table) (modify-syntax-entry ?$ "w" malaga-mode-syntax-table) (modify-syntax-entry ?@ "w" malaga-mode-syntax-table) (modify-syntax-entry ?_ "w" malaga-mode-syntax-table) (modify-syntax-entry ?< "(>" malaga-mode-syntax-table) (modify-syntax-entry ?> ")<" malaga-mode-syntax-table) (modify-syntax-entry ?{ "(}" malaga-mode-syntax-table) (modify-syntax-entry ?} "){" malaga-mode-syntax-table) (modify-syntax-entry ?( "()" malaga-mode-syntax-table) (modify-syntax-entry ?) ")(" malaga-mode-syntax-table) (modify-syntax-entry ?[ "(]" malaga-mode-syntax-table) (modify-syntax-entry ?] ")[" malaga-mode-syntax-table) (modify-syntax-entry ?= "." malaga-mode-syntax-table) (modify-syntax-entry ?~ "." malaga-mode-syntax-table) (modify-syntax-entry ?, "." malaga-mode-syntax-table) (modify-syntax-entry ?\; "." malaga-mode-syntax-table) (modify-syntax-entry ?: "." malaga-mode-syntax-table) (modify-syntax-entry ?. "." malaga-mode-syntax-table) (modify-syntax-entry ?+ "." malaga-mode-syntax-table) (modify-syntax-entry ?- "." malaga-mode-syntax-table) (modify-syntax-entry ?/ "." malaga-mode-syntax-table) (modify-syntax-entry ?? "." malaga-mode-syntax-table) (modify-syntax-entry ?* "." malaga-mode-syntax-table) (defvar malaga-mode-map () "Keymap used in Malaga mode.") (setq malaga-mode-map (make-sparse-keymap)) (define-key malaga-mode-map "\t" 'malaga-electric-tab) (define-key malaga-mode-map ";" 'malaga-electric-semicolon) (define-key malaga-mode-map "\r" 'malaga-electric-terminate-line) (if (string-match "XEmacs\\|Lucid" emacs-version) (define-key malaga-mode-map "\C-h" 'backward-delete-char-untabify) (define-key malaga-mode-map "\177" 'backward-delete-char-untabify)) (define-key malaga-mode-map "\C-c\C-d" 'malaga-delete-arrow) (define-key malaga-mode-map "\C-c\C-p" 'malmake) (define-key malaga-mode-map "\C-c\C-r" 'malaga) (define-key malaga-mode-map "\C-c\C-l" 'mallex) (define-key malaga-mode-map "\M-n" 'malaga-goto-next-rule) (define-key malaga-mode-map "\M-p" 'malaga-goto-previous-rule) (define-key malaga-mode-map "\M-g" 'malaga-goto-rule) ;; User configuration for malaga mode. ======================================== (defconst malaga-indent-level 2 "*Indentation of Malaga statements with respect to containing block.") ;; Font-lock functions. ======================================================= (defconst malaga-font-lock-keywords (list (list (concat "\\([@\$]" malaga-ident-re "\\>\\)") 1 'font-lock-variable-name-face) (list (concat "\\<\\(" (mapconcat 'identity malaga-keywords-list "\\|") "\\)\\>") 1 'font-lock-keyword-face)) "Expressions to highlight in Malaga mode.") (defun malaga-font () "Set font-lock variables for malaga mode." (make-local-variable 'font-lock-keywords-case-fold-search) ; For GNU Emacs. (setq font-lock-keywords-case-fold-search t) (put major-mode 'font-lock-keywords-case-fold-search t) ; For XEmacs. (make-local-variable 'font-lock-defaults) (setq font-lock-defaults '(malaga-font-lock-keywords nil t))) ;; Electric keys. ============================================================= (defun malaga-electric-terminate-line () "Terminate line and indent next line." (interactive) ;; Check if current line should be indented. (save-excursion (beginning-of-line) (skip-chars-forward " \t") (if (looking-at malaga-autoindent-lines-re) (malaga-indent-line))) ;; Remove trailing whitespaces. (delete-horizontal-space) (newline) (malaga-indent-line)) ;;----------------------------------------------------------------------------- (defun malaga-electric-semicolon () "Insert a semicolon and indent line." (interactive) (if (looking-at "[ \t]*$") (malaga-electric-tab)) (insert ";")) ;;----------------------------------------------------------------------------- (defun malaga-electric-tab () "Function called when TAB is pressed in Malaga mode." (interactive) (let ((old-point (point-marker))) (save-excursion (beginning-of-line) (malaga-indent-line)) (beginning-of-line) (skip-chars-forward " \t") (if (> old-point (point)) (goto-char old-point)))) ;; Other malaga mode functions. =============================================== (defun malaga-change-keywords (change-word) "Apply function CHANGE-WORD to all keywords in current buffer." (save-excursion (let ((keywords (concat "\\<\\(" (mapconcat 'identity malaga-keywords-list "\\|") "\\)\\>")) (ref-point (point-min)) state) (goto-char (point-min)) (while (re-search-forward keywords nil t) (setq state (parse-partial-sexp ref-point (point))) (if (or (nth 3 state) (nth 4 state)) () (setq ref-point (point)) (funcall change-word -1)))))) (defun malaga-upcase-keywords () "Upcase all malaga keywords in the buffer." (interactive) (malaga-change-keywords 'upcase-word)) (defun malaga-downcase-keywords () "Downcase all malaga keywords in the buffer." (interactive) (malaga-change-keywords 'downcase-word)) (defun malaga-goto-previous-rule () "Go to beginning of previous rule in current buffer." (interactive) (if (not (search-backward-regexp (concat "^" malaga-rule-re) nil t)) (message "No previous rule."))) (defun malaga-goto-next-rule () "Go to beginning of next rule in current buffer." (interactive) (let ((old-point (point))) (forward-char) (if (search-forward-regexp (concat "^" malaga-rule-re) nil t) (beginning-of-line) (goto-char old-point) (message "No next rule.")))) (defun malaga-goto-rule (rule-name) "Go to beginning of RULE-NAME in current buffer." (interactive "sRule Name: ") (let ((old-point (point))) (goto-char (point-min)) (if (search-forward-regexp (concat "^" malaga-rule-re "[\t {]+" rule-name) nil t) (beginning-of-line) (goto-char old-point) (message "No rule \"%s\"." rule-name)))) (defun malaga-delete-arrow () "Delete the source file arrow for the current buffer." (interactive) (setq overlay-arrow-string nil)) ;; Indentation. =============================================================== (defconst malaga-indent-alist '((block . (+ ind malaga-indent-level)) (contexp . ind) (string . 0) (comment . 0) (unknown . 0))) ;;----------------------------------------------------------------------------- (defun malaga-indent-line () "Indent current line as a Malaga code." (let* ((indent-str (malaga-calculate-indent)) (type (car indent-str)) (ind (car (cdr indent-str )))) (if (and (looking-at "\#") (= 0 (current-column))) () (delete-horizontal-space) (cond ((looking-at malaga-rule-re) ;; Some things should not be indented. ()) ((looking-at malaga-noindent-re) ;; Other things should have no extra indent. (indent-to ind)) (t ;; But most lines are treated this way: (indent-to (eval (cdr (assoc type malaga-indent-alist))))))))) ;;----------------------------------------------------------------------------- (defun malaga-calculate-indent () "Calculate the indent of the current Malaga line. Return a list of two elements: (INDENT-TYPE INDENT-LEVEL)." (save-excursion (let* ((state (save-excursion (parse-partial-sexp (point-min) (point)))) (nest 0) (par 0) (indent t) (complete nil) (type (catch 'nesting ;; Check if inside a string or parenthesis. (cond ((nth 3 state) (throw 'nesting 'string)) ((nth 4 state) (throw 'nesting 'comment)) ((> (car state) 0) (skip-chars-forward " \t") (if (looking-at "[\]\>\)\}]") (setq indent nil)) (goto-char (nth 1 state)) (cond (indent (forward-char) (skip-chars-forward " \t"))) (setq par (current-column)) (throw 'nesting 'contexp))) ;; Loop until correct indent is found. (while t (backward-sexp 1) (cond (; Nest block outwards. (looking-at malaga-begin-block-re) (if (= nest 0) (throw 'nesting 'block) (setq nest (1- nest)))) (; Nest block inwards. (looking-at malaga-end-block-re) (setq complete t nest (1+ nest))) (; If, else or foreach statement. (and (not complete) (looking-at malaga-sub-block-re)) (throw 'nesting 'block)) (; No known statements. (bobp) (throw 'nesting 'unknown)) (; Found complete statement. (save-excursion (forward-sexp 1) (= (following-char) ?\;)) (setq complete t)) (; No known statements. (= (point) (point-min)) (throw 'nesting 'unknown))))))) ;; Return type of block and indent level. (if (> par 0) ; Unclosed Parenthesis. (list 'contexp par) (list type (malaga-indent-level)))))) ;;----------------------------------------------------------------------------- (defun malaga-indent-level () "Return the indent-level of the current statement." (save-excursion (beginning-of-line) (skip-chars-forward " \t") (current-column))) ;; Malaga project mode. ======================================================= (defvar malaga-project-mode-map () "Keymap used in Malaga project mode.") (setq malaga-project-mode-map (make-sparse-keymap)) (define-key malaga-project-mode-map "\C-c\C-p" 'malmake) (define-key malaga-project-mode-map "\C-c\C-r" 'malaga) (define-key malaga-project-mode-map "\C-c\C-l" 'mallex) (defun malaga-project-mode () "Major mode for editing Malaga project files. \\ Key bindings: \\[malmake] creates malmake process. \\[malaga] creates malaga process. \\[mallex] creates mallex process." (interactive) (kill-all-local-variables) (setq major-mode 'malaga-project-mode) (setq mode-name "Malaga-project") (use-local-map malaga-project-mode-map) (run-hooks 'malaga-project-mode-hook)) ;; Malaga process mode. ======================================================= (require 'comint) (defvar malaga-last-frame nil "Where malaga-display-line should put the debugging arrow.") (defvar malaga-process-mode-map () "Keymap used in Malaga process mode.") (setq malaga-process-mode-map (copy-keymap comint-mode-map)) (define-key malaga-process-mode-map "\t" 'comint-dynamic-complete-filename) (define-key malaga-process-mode-map "\C-c\C-d" 'malaga-delete-arrow) (define-key malaga-process-mode-map "\C-c\C-p" 'malmake) (define-key malaga-process-mode-map "\C-c\C-r" 'malaga) (define-key malaga-process-mode-map "\C-c\C-l" 'mallex) ;;----------------------------------------------------------------------------- (defun malaga-process-mode () "Major mode for running a malaga, mallex or malmake process. \\ Key bindings: \\[comint-dynamic-complete-filename] completes a filename. \\[malmake] creates malmake process. \\[malaga] creates malaga process. \\[mallex] creates mallex process. \\[malaga-delete-arrow] deletes the debugger arrow. Variables controlling malaga-process-mode for all buffers: malaga-change-to-project-directory" (interactive) (comint-mode) (run-hooks 'shell-mode-hook) (setq major-mode 'malaga-process-mode) (setq mode-name "Malaga-process") (setq mode-line-process '(": %s")) (use-local-map malaga-process-mode-map) (make-local-variable 'comint-prompt-regexp) (setq comint-prompt-regexp "^\(malaga|mallex|debug\)> *") (setq paragraph-start comint-prompt-regexp) (run-hooks 'malaga-process-mode-hook)) ;;----------------------------------------------------------------------------- (defun malaga-sentinel (proc msg) "malaga-sentinel is called if the process malaga exits. The sentinel receives two arguments: the process malaga and a string describing the type of event, normally finished." (cond ((null (buffer-name (process-buffer proc))) ;; Buffer killed. ;; Stop displaying an arrow in a source file. (setq overlay-arrow-string nil) (set-process-buffer proc nil)) ((memq (process-status proc) '(signal exit)) (setq overlay-arrow-string nil) (let* ((obuf (current-buffer))) ;; Save-excursion isn't the right thing ;; if process-buffer is current-buffer. (unwind-protect (progn (set-buffer (process-buffer proc)) (accept-process-output) ;; Fix the mode line. (setq mode-line-process (concat ": " (symbol-name (process-status proc)))) ;; Force mode line redisplay soon. (set-buffer-modified-p (buffer-modified-p)) (if (eobp) (insert ?\n mode-name " " msg) (save-excursion (goto-char (point-max)) (insert ?\n mode-name " " msg))) ;; If buffer and mode line will show that the process ;; is dead, we can delete it now. Otherwise it ;; will stay around until M-x list-processes. (delete-process proc)) ;; Restore old buffer, but don't restore old point ;; if obuf is the gud buffer. (set-buffer obuf)))))) ;;----------------------------------------------------------------------------- (defun malaga-display-line (process file line column) "Put the overlay-arrow on LINE and COLUMN in FILE for PROCESS." (let* ((last-nonmenu-event t) ; Prevent use of dialog box for questions. (source-buffer (find-file-noselect file)) position line-start) ;; Make overlay-arrow-position a marker. (or (markerp overlay-arrow-position) (setq overlay-arrow-position (make-marker))) (set-buffer source-buffer) (save-restriction (widen) (goto-line line) (setq line-start (point)) (move-to-column column) (setq position (point))) (if (or (< position (point-min)) (> position (point-max))) (widen)) (cond ((equal "malmake" (process-name process)) (switch-to-buffer source-buffer) (goto-char position) (setq overlay-arrow-string nil) (display-buffer (process-buffer process))) (t (set-window-point (display-buffer source-buffer) position) (goto-char position) (set-marker overlay-arrow-position line-start source-buffer) (setq overlay-arrow-string "=>") (switch-to-buffer (process-buffer process)))))) ;;----------------------------------------------------------------------------- (defun malaga-marker-filter (string) "Detect file/line markers in STRING." (cond ((string-match "\\(SHOW \"\\([^\"]+\\)\":\\([0-9]+\\):\\([0-9]+\\)\n\\)" string) (setq malaga-last-frame (list (substring string (match-beginning 2) (match-end 2)) (string-to-int (substring string (match-beginning 3) (match-end 3))) (string-to-int (substring string (match-beginning 4) (match-end 4))))) (setq string (concat (substring string 0 (match-beginning 1)) (substring string (match-end 1)))))) string) ;;----------------------------------------------------------------------------- (defun malaga-filter (proc string) "Insert STRING from malaga process PROC into the buffer." (let ((inhibit-quit t) (old-buffer (current-buffer))) (set-buffer (process-buffer proc)) ;; Print the process output, checking for source file markers. (comint-output-filter proc (malaga-marker-filter string)) (set-buffer old-buffer) ;; Check for a filename-and-line number. (cond (malaga-last-frame (malaga-display-line proc (nth 0 malaga-last-frame) (nth 1 malaga-last-frame) (nth 2 malaga-last-frame)) (setq malaga-last-frame nil))))) ;;----------------------------------------------------------------------------- (defun malaga-init (process-name project-file &optional option) "Call malaga, mallex or malmake and create the appropriate buffer." (let ((buffer-name (concat "*" process-name "*")) (process-environment process-environment) (program-name process-name) process-buffer) (cond ((or (not (get-process process-name)) (y-or-n-p "There is another process running. Kill it? ")) (if (get-process process-name) (delete-process process-name)) (setq process-buffer (get-buffer-create buffer-name)) (set-buffer process-buffer) (kill-region (point-min) (point-max)) (if (equal process-name "malmake") (display-buffer process-buffer) (switch-to-buffer process-buffer)) (if malaga-change-to-project-directory (setq default-directory (file-name-directory project-file))) (insert "\nCurrent directory: " default-directory "\n\n") (setenv "MALAGA_MODE" "t") (if option (make-comint process-name program-name nil project-file option) (make-comint process-name program-name nil project-file)) (malaga-process-mode) (setq mode-line-buffer-identification (concat process-name ": " (file-name-sans-extension (file-name-nondirectory project-file)))) (set-process-filter (get-buffer-process process-buffer) 'malaga-filter) (set-process-sentinel (get-buffer-process process-buffer) 'malaga-sentinel))))) ;; Creating malaga-processes. ================================================= (defvar malaga-project-file "" "The default malaga project file.") (defconst malaga-change-to-project-directory t "*If non-nil, the buffer directory is set to the project directory when malaga, mallex or malmake is started.") (defun malaga-read-project-file-name () "Read the name of the malaga project file." (setq malaga-project-file (expand-file-name (read-file-name "Project file: " (file-name-directory malaga-project-file) malaga-project-file t (file-name-nondirectory malaga-project-file))))) (defun malaga (project-file) "Run malaga with PROJECT-FILE in buffer *malaga*." (interactive (list (malaga-read-project-file-name))) (malaga-init "malaga" project-file)) (defun mallex (project-file) "Run mallex with PROJECT-FILE in buffer *mallex*." (interactive (list (malaga-read-project-file-name))) (malaga-init "mallex" project-file)) (defun malmake (project-file) "Run malmake with PROJECT-FILE in buffer *malmake*." (interactive (list (malaga-read-project-file-name))) (save-some-buffers) (malaga-init "malmake" project-file)) ;; End of file. =============================================================== malaga-7.12/grammars/0000755000175000017500000000000010764165477014037 5ustar bjoernbjoernmalaga-7.12/grammars/german/0000755000175000017500000000000010764165477015310 5ustar bjoernbjoernmalaga-7.12/grammars/german/german.all0000644000175000017500000000062710230777010017234 0ustar bjoernbjoern# Allomorph rules for german. # Copyright © 2004 Björn Beutel. allo_rule generate_allos( $lex_entry ): if forms in $lex_entry then choose $form in $lex_entry.forms; result $form.surf, $lex_entry - forms + ($form - surf); else result $lex_entry.surf, $lex_entry - surf + [base: $lex_entry.surf]; end; end; # End of file. ================================================================ malaga-7.12/grammars/german/german.esym0000644000175000017500000000076510230776736017462 0ustar bjoernbjoern# Symbols that are only needed in syntax part of german. # Copyright © 2004 Björn Beutel. clause_type; main_clause; # may be later identified as declarative or interrogative subclause; # subordinate of another clause rel_clause; # subordinate of a noun declarative; interrogative; constituents; superclause; function; form; # function resp. form of a phrase predicate; arguments; modifiers; # End of file. ================================================================ malaga-7.12/grammars/german/german.lex0000644000175000017500000006601710230777111017263 0ustar bjoernbjoern# Lexicon for german. # Copyright © 2004 Björn Beutel. # Pronouns. =================================================================== [surf: "ich", POS: pronoun, case: sg1]; [surf: "meiner", POS: pronoun, case: gen_sg]; [surf: "mir", POS: pronoun, case: dat_sg]; [surf: "mich", POS: pronoun, case: acc_sg]; [surf: "du", POS: pronoun, case: sg2]; [surf: "deiner", POS: pronoun, case: gen_sg]; [surf: "dir", POS: pronoun, case: dat_sg]; [surf: "dich", POS: pronoun, case: acc_sg]; [surf: "er", POS: pronoun, case: sg3, gender: masc]; [surf: "sie", POS: pronoun, case: sg3|pl3|acc, gender: fem]; [surf: "es", POS: pronoun, case: sg3|acc_sg, gender: neut]; [surf: "seiner", POS: pronoun, case: gen_sg, gender: masc|neut]; [surf: "ihrer", POS: pronoun, case: gen_sg, gender: fem]; [surf: "ihm", POS: pronoun, case: dat_sg, gender: masc|neut]; [surf: "ihr", POS: pronoun, case: pl2|dat_sg, gender: fem]; [surf: "ihn", POS: pronoun, case: acc_sg, gender: masc]; [surf: "wir", POS: pronoun, case: pl1]; [surf: "unser", POS: pronoun, case: gen_pl]; [surf: "uns", POS: pronoun, case: dat_pl|acc_pl]; [surf: "euer", POS: pronoun, case: gen_pl]; [surf: "euch", POS: pronoun, case: dat_pl|acc_pl]; [surf: "ihnen", POS: pronoun, case: dat_pl]; # Relative pronouns. ========================================================== [surf: "der", POS: rel_pronoun, case: sg3, gender: masc]; [surf: "dessen", POS: rel_pronoun, case: gen_sg, gender: masc|neut]; [surf: "dem", POS: rel_pronoun, case: dat_sg, gender: masc|neut]; [surf: "den", POS: rel_pronoun, case: acc_sg, gender: masc]; [surf: "das", POS: rel_pronoun, case: sg3|acc_sg, gender: neut]; [surf: "dem", POS: rel_pronoun, case: dat_sg, gender: neut]; [surf: "die", POS: rel_pronoun, case: sg3|acc_sg, gender: fem]; [surf: "der", POS: rel_pronoun, case: gen_sg|dat_sg, gender: fem]; [surf: "die", POS: rel_pronoun, case: nom_pl|acc_pl]; [surf: "deren", POS: rel_pronoun, case: gen_pl]; [surf: "denen", POS: rel_pronoun, case: dat_pl]; # Determiners. ================================================================ [surf: "der", POS: determiner, case: sg3, gender: masc, adj_ending: e]; [surf: "dem", POS: determiner, case: dat_sg, gender: masc|neut, adj_ending: en]; [surf: "den", POS: determiner, case: acc_sg, gender: masc, adj_ending: en]; [surf: "das", POS: determiner, case: sg3|acc_sg, gender: neut, adj_ending: e]; [surf: "des", POS: determiner, case: gen_sg, gender: masc|neut, adj_ending: en]; [surf: "die", POS: determiner, case: sg3|acc_sg, gender: fem, adj_ending: e]; [surf: "der", POS: determiner, case: gen_sg|dat_sg, gender: fem, adj_ending: en]; [surf: "die", POS: determiner, case: nom_pl|acc_pl, adj_ending: en]; [surf: "der", POS: determiner, case: gen_pl, adj_ending: en]; [surf: "den", POS: determiner, case: dat_pl, adj_ending: en]; [surf: "ein", POS: determiner, case: sg3, gender: masc, adj_ending: er]; [surf: "eines", POS: determiner, case: gen_sg, gender: masc|neut, adj_ending: en]; [surf: "einem", POS: determiner, case: dat_sg, gender: masc|neut, adj_ending: en]; [surf: "einen", POS: determiner, case: acc_sg, gender: masc, adj_ending: en]; [surf: "ein", POS: determiner, case: sg3|acc_sg, gender: neut, adj_ending: es]; [surf: "eine", POS: determiner, case: sg3|acc_sg, gender: fem, adj_ending: e]; [surf: "einer", POS: determiner, case: gen_sg|dat_sg, gender: fem, adj_ending: en]; # Prepositions. =============================================================== [surf: "auf", POS: preposition, subtype: local, case: dat]; [surf: "auf", POS: preposition, subtype: directional, case: acc]; [surf: "durch", POS: preposition, subtype: directional, case: acc]; [surf: "hinter", POS: preposition, subtype: local, case: dat]; [surf: "hinter", POS: preposition, subtype: directional, case: acc]; [surf: "in", POS: preposition, subtype: local, case: dat]; [surf: "in", POS: preposition, subtype: directional, case: acc]; [surf: "mittels", POS: preposition, subtype: modal, case: gen]; [surf: "nach", POS: preposition, subtype: temporal, case: dat]; [surf: "neben", POS: preposition, subtype: local, case: dat]; [surf: "neben", POS: preposition, subtype: directional, case: acc]; [surf: "unter", POS: preposition, subtype: local, case: dat]; [surf: "unter", POS: preposition, subtype: directional, case: acc]; [surf: "über", POS: preposition, subtype: local, case: dat]; [surf: "über", POS: preposition, subtype: directional, case: acc]; [surf: "vor", POS: preposition, subtype: local, case: dat]; [surf: "vor", POS: preposition, subtype: directional, case: acc]; [surf: "vor", POS: preposition, subtype: temporal, case: dat]; # Punctuation marks. ========================================================== [surf: ".", POS: punctuation]; [surf: ",", POS: punctuation]; [surf: "?", POS: punctuation]; # Adverbs. ==================================================================== [surf: "dort", POS: adverb, subtype: local]; [surf: "dorthin", POS: adverb, subtype: directional]; [surf: "gestern", POS: adverb, subtype: temporal]; [surf: "heute", POS: adverb, subtype: temporal]; [surf: "hier", POS: adverb, subtype: local]; [surf: "hierher", POS: adverb, subtype: directional]; # Prefixes. =================================================================== [surf: "ab", POS: prefix]; [surf: "an", POS: prefix]; [surf: "auf", POS: prefix]; [surf: "aus", POS: prefix]; [surf: "daneben", POS: prefix]; [surf: "durch", POS: prefix]; [surf: "entzwei", POS: prefix]; [surf: "heraus", POS: prefix]; [surf: "herunter", POS: prefix]; [surf: "hin", POS: prefix]; [surf: "los", POS: prefix]; [surf: "nach", POS: prefix]; [surf: "nieder", POS: prefix]; [surf: "um", POS: prefix]; [surf: "unter", POS: prefix]; [surf: "vor", POS: prefix]; [surf: "weg", POS: prefix]; [surf: "zu", POS: prefix]; [surf: "zusammen", POS: prefix]; # Subordinating conjunctions. ================================================= [surf: "weil", POS: sub_conjunction, subtype: causal]; [surf: "wohin", POS: sub_conjunction, subtype: directional, constituent: directional]; [surf: "wo", POS: sub_conjunction, subtype: local, constituent: local]; [surf: "wo", POS: sub_conjunction, subtype: local]; [surf: "als", POS: sub_conjunction, subtype: temporal]; [surf: "bevor", POS: sub_conjunction, subtype: temporal]; [surf: "nachdem", POS: sub_conjunction, subtype: temporal]; [surf: "während", POS: sub_conjunction, subtype: temporal]; [base: "dass", POS: sub_conjunction, subtype: acc, forms: <[surf: "dass"], [surf: "daß"]>]; [surf: "was", POS: sub_conjunction, subtype: sg3|acc_sg, constituent: sg3|acc_sg]; [surf: "wer", POS: sub_conjunction, subtype: sg3, constituent: sg3]; [surf: "wenn", POS: sub_conjunction, subtype: temporal]; # Adjectives. ================================================================= [base: "alt", POS: adjective, forms: <[surf: "alte", adj_ending: e], [surf: "altem", adj_ending: em], [surf: "alten", adj_ending: en], [surf: "alter", adj_ending: er], [surf: "altes", adj_ending: es]>]; [base: "jung", POS: adjective, forms: <[surf: "junge", adj_ending: e], [surf: "jungem", adj_ending: em], [surf: "jungen", adj_ending: en], [surf: "junger", adj_ending: er], [surf: "junges", adj_ending: es]>]; [base: "groß", POS: adjective, forms: <[surf: "große", adj_ending: e], [surf: "großem", adj_ending: em], [surf: "großen", adj_ending: en], [surf: "großer", adj_ending: er], [surf: "großes", adj_ending: es]>]; [base: "klein", POS: adjective, forms: <[surf: "kleine", adj_ending: e], [surf: "kleinem", adj_ending: em], [surf: "kleinen", adj_ending: en], [surf: "kleiner", adj_ending: er], [surf: "kleines", adj_ending: es]>]; [base: "schön", POS: adjective, forms: <[surf: "schöne", adj_ending: e], [surf: "schönem", adj_ending: em], [surf: "schönen", adj_ending: en], [surf: "schöner", adj_ending: er], [surf: "schönes", adj_ending: es]>]; [base: "hässlich", POS: adjective, forms: <[surf: "häßliche", adj_ending: e], [surf: "hässliche", adj_ending: e], [surf: "häßlichem", adj_ending: em], [surf: "hässlichem", adj_ending: em], [surf: "häßlichen", adj_ending: en], [surf: "hässlichen", adj_ending: en], [surf: "häßlicher", adj_ending: er], [surf: "hässlicher", adj_ending: er], [surf: "häßliches", adj_ending: es], [surf: "hässliches", adj_ending: es]>]; [base: "schlau", POS: adjective, forms: <[surf: "schlaue", adj_ending: e], [surf: "schlauem", adj_ending: em], [surf: "schlauen", adj_ending: en], [surf: "schlauer", adj_ending: er], [surf: "schlaues", adj_ending: es]>]; [base: "dumm", POS: adjective, forms: <[surf: "dumme", adj_ending: e], [surf: "dummem", adj_ending: em], [surf: "dummen", adj_ending: en], [surf: "dummer", adj_ending: er], [surf: "dummes", adj_ending: es]>]; # Verbs. ====================================================================== [base: "geben", POS: verb, valencies: <, >, prefixes: <[surf: "an", valencies: <>], [surf: "ab", valencies: <>]>, forms: <[surf: "gebe", subtype: finite, subject: sg1, tense: present], [surf: "gibst", subtype: finite, subject: sg2, tense: present], [surf: "gibt", subtype: finite, subject: sg3, tense: present], [surf: "geben", subtype: finite, subject: pl13, tense: present], [surf: "gebt", subtype: finite, subject: pl2, tense: present], [surf: "gab", subtype: finite, subject: sg13, tense: preterite], [surf: "gabst", subtype: finite, subject: sg2, tense: preterite], [surf: "gaben", subtype: finite, subject: pl13, tense: preterite], [surf: "gabt", subtype: finite, subject: pl2, tense: preterite], [surf: "geben", subtype: infinitive], [surf: "gegeben", subtype: participle_2_haben]>]; [base: "haben", POS: verb, valencies: <, >, forms: <[surf: "habe", subtype: finite, subject: sg1, tense: present], [surf: "hast", subtype: finite, subject: sg2, tense: present], [surf: "hat", subtype: finite, subject: sg3, tense: present], [surf: "haben", subtype: finite, subject: pl13, tense: present], [surf: "habt", subtype: finite, subject: pl2, tense: present], [surf: "hatte", subtype: finite, subject: sg13, tense: preterite], [surf: "hattest", subtype: finite, subject: sg2, tense: preterite], [surf: "hatten", subtype: finite, subject: pl13, tense: preterite], [surf: "hattet", subtype: finite, subject: pl2, tense: preterite], [surf: "haben", subtype: infinitive], [surf: "gehabt", subtype: participle_2_haben]>]; [base: "lieben", POS: verb, valencies: <>, forms: <[surf: "liebe", subtype: finite, subject: sg1, tense: present], [surf: "liebst", subtype: finite, subject: sg2, tense: present], [surf: "liebt", subtype: finite, subject: sg3|pl2, tense: present], [surf: "lieben", subtype: finite, subject: pl13, tense: present], [surf: "liebte", subtype: finite, subject: sg13, tense: preterite], [surf: "liebtest", subtype: finite, subject: sg2, tense: preterite], [surf: "liebten", subtype: finite, subject: pl13, tense: preterite], [surf: "liebtet", subtype: finite, subject: pl2, tense: preterite], [surf: "lieben", subtype: infinitive], [surf: "geliebt", subtype: participle_2_haben]>]; [base: "sein", POS: verb, valencies: <, , >, forms: <[surf: "bin", subtype: finite, subject: sg1, tense: present], [surf: "bist", subtype: finite, subject: sg2, tense: present], [surf: "ist", subtype: finite, subject: sg3, tense: present], [surf: "sind", subtype: finite, subject: pl13, tense: present], [surf: "seid", subtype: finite, subject: pl2, tense: present], [surf: "war", subtype: finite, subject: sg13, tense: preterite], [surf: "warst", subtype: finite, subject: sg1, tense: preterite], [surf: "waren", subtype: finite, subject: pl13, tense: preterite], [surf: "wart", subtype: finite, subject: pl2, tense: preterite], [surf: "sein", subtype: infinitive], [surf: "gewesen", subtype: participle_2_sein]>]; [base: "spielen", POS: verb, valencies: <>, forms: <[surf: "spiele", subtype: finite, subject: sg1, tense: present], [surf: "spielst", subtype: finite, subject: sg2, tense: present], [surf: "spielt", subtype: finite, subject: sg3|pl2, tense: present], [surf: "spielen", subtype: finite, subject: pl13, tense: present], [surf: "spielte", subtype: finite, subject: sg13, tense: preterite], [surf: "spieltest", subtype: finite, subject: sg2, tense: preterite], [surf: "spielten", subtype: finite, subject: pl13, tense: preterite], [surf: "spieltet", subtype: finite, subject: pl2, tense: preterite], [surf: "spielen", subtype: infinitive], [surf: "gespielt", subtype: participle_2_haben]>]; [base: "schreiben", POS: verb, valencies: <, >, forms: <[surf: "schreibe", subtype: finite, subject: sg1, tense: present], [surf: "schreibst", subtype: finite, subject: sg2, tense: present], [surf: "schreibt", subtype: finite, subject: sg3|pl2, tense: present], [surf: "schreiben", subtype: finite, subject: pl13, tense: present], [surf: "schrieb", subtype: finite, subject: sg13, tense: preterite], [surf: "schriebst", subtype: finite, subject: sg2, tense: preterite], [surf: "schrieben", subtype: finite, subject: pl13, tense: preterite], [surf: "schriebt", subtype: finite, subject: pl2, tense: preterite], [surf: "schreiben", subtype: infinitive], [surf: "geschrieben", subtype: participle_2_haben]>]; [base: "schlafen", POS: verb, valencies: <<>>, forms: <[surf: "schlafe", subtype: finite, subject: sg1, tense: present], [surf: "schläfst", subtype: finite, subject: sg2, tense: present], [surf: "schläft", subtype: finite, subject: sg3, tense: present], [surf: "schlafen", subtype: finite, subject: pl13, tense: present], [surf: "schlaft", subtype: finite, subject: pl2, tense: present], [surf: "schlief", subtype: finite, subject: sg13, tense: preterite], [surf: "schliefst", subtype: finite, subject: sg2, tense: preterite], [surf: "schliefen", subtype: finite, subject: pl13, tense: preterite], [surf: "schlieft", subtype: finite, subject: pl2, tense: preterite], [surf: "schlafen", subtype: infinitive], [surf: "geschlafen", subtype: participle_2_haben]>]; [base: "bedürfen", POS: verb, valencies: <>, forms: <[surf: "bedarf", subtype: finite, subject: sg13, tense: present], [surf: "bedarfst", subtype: finite, subject: sg2, tense: present], [surf: "bedürfen", subtype: finite, subject: pl13, tense: present], [surf: "bedürft", subtype: finite, subject: pl2, tense: present], [surf: "bedürft", subtype: finite, subject: pl2, tense: preterite], [surf: "bedurfte", subtype: finite, subject: sg13, tense: preterite], [surf: "bedurftest", subtype: finite, subject: sg2, tense: preterite], [surf: "bedurften", subtype: finite, subject: pl13, tense: preterite], [surf: "bedurftet", subtype: finite, subject: pl2, tense: preterite], [surf: "bedürfen", subtype: infinitive], [surf: "bedurft", subtype: participle_2_haben]>]; [base: "lesen", POS: verb, valencies: <>, forms: <[surf: "lese", subtype: finite, subject: sg1, tense: present], [surf: "liest", subtype: finite, subject: sg23, tense: present], [surf: "lesen", subtype: finite, subject: pl13, tense: present], [surf: "lest", subtype: finite, subject: pl2, tense: present], [surf: "las", subtype: finite, subject: sg13, tense: preterite], [surf: "last", subtype: finite, subject: sg2|pl2, tense: preterite], [surf: "lasen", subtype: finite, subject: pl13, tense: preterite], [surf: "lesen", subtype: infinitive], [surf: "gelesen", subtype: participle_2_haben]>]; [base: "beißen", POS: verb, valencies: <>, forms: <[surf: "beiße", subtype: finite, subject: sg1, tense: present], [surf: "beißt", subtype: finite, subject: sg23|pl2, tense: present], [surf: "beißen", subtype: finite, subject: pl13, tense: present], [surf: "biß", subtype: finite, subject: sg13, tense: preterite], [surf: "biss", subtype: finite, subject: sg13, tense: preterite], [surf: "bissest", subtype: finite, subject: sg2, tense: preterite], [surf: "bissen", subtype: finite, subject: pl13, tense: preterite], [surf: "bisset", subtype: finite, subject: pl2, tense: preterite], [surf: "beißen", subtype: infinitive], [surf: "gebissen", subtype: participle_2_haben]>]; [base: "sehen", POS: verb, valencies: <>, forms: <[surf: "sehe", subtype: finite, subject: sg1, tense: present], [surf: "siehst", subtype: finite, subject: sg2, tense: present], [surf: "sieht", subtype: finite, subject: sg3, tense: present], [surf: "sehen", subtype: finite, subject: pl13, tense: present], [surf: "seht", subtype: finite, subject: pl2, tense: present], [surf: "sah", subtype: finite, subject: sg13, tense: preterite], [surf: "sahst", subtype: finite, subject: sg2, tense: preterite], [surf: "sahen", subtype: finite, subject: pl13, tense: preterite], [surf: "saht", subtype: finite, subject: pl2, tense: preterite], [surf: "sehen", subtype: infinitive], [surf: "gesehen", subtype: participle_2_haben]>]; [base: "zeigen", POS: verb, valencies: <, >, forms: <[surf: "zeige", subtype: finite, subject: sg1, tense: present], [surf: "zeigst", subtype: finite, subject: sg2, tense: present], [surf: "zeigt", subtype: finite, subject: sg3|pl2, tense: present], [surf: "zeigen", subtype: finite, subject: pl13, tense: present], [surf: "zeigte", subtype: finite, subject: sg13, tense: preterite], [surf: "zeigtest", subtype: finite, subject: sg2, tense: preterite], [surf: "zeigten", subtype: finite, subject: pl13, tense: preterite], [surf: "zeigtet", subtype: finite, subject: pl2, tense: preterite], [surf: "zeigen", subtype: infinitive], [surf: "gezeigt", subtype: participle_2_haben]>]; [base: "gehen", POS: verb, valencies: <<>, , , >, prefixes: <[surf: "vor", valencies: <<>>], [surf: "nach", valencies: <, <>>], [surf: "unter", valencies: <<>>]>, forms: <[surf: "gehe", subtype: finite, subject: sg1, tense: present], [surf: "gehst", subtype: finite, subject: sg2, tense: present], [surf: "geht", subtype: finite, subject: sg3|pl2, tense: present], [surf: "gehen", subtype: finite, subject: pl13, tense: present], [surf: "ging", subtype: finite, subject: sg13, tense: preterite], [surf: "gingst", subtype: finite, subject: sg2, tense: preterite], [surf: "gingen", subtype: finite, subject: pl13, tense: preterite], [surf: "gingt", subtype: finite, subject: pl2, tense: preterite], [surf: "gehen", subtype: infinitive], [surf: "gegangen", subtype: participle_2_sein]>]; [base: "wollen", POS: verb, valencies: <, , >, forms: <[surf: "will", subtype: finite, subject: sg13, tense: present], [surf: "willst", subtype: finite, subject: sg2, tense: present], [surf: "wollen", subtype: finite, subject: pl13, tense: present], [surf: "wollt", subtype: finite, subject: pl2, tense: present], [surf: "wollte", subtype: finite, subject: sg13, tense: preterite], [surf: "wolltest", subtype: finite, subject: sg2, tense: preterite], [surf: "wollten", subtype: finite, subject: pl13, tense: preterite], [surf: "wolltet", subtype: finite, subject: pl2, tense: preterite], [surf: "wollen", subtype: infinitive], [surf: "gewollt", subtype: participle_2_haben]>]; [base: "hauen", POS: verb, valencies: <>, prefixes: <[surf: "an", valencies: <>], [surf: "aus", valencies: <>], [surf: "entzwei", valencies: <>], [surf: "herunter", valencies: <>], [surf: "ab", valencies: <>], [surf: "auf", valencies: <>], [surf: "heraus", valencies: <>], [surf: "hin", valencies: <>], [surf: "los", valencies: <>], [surf: "nieder", valencies: <>], [surf: "um", valencies: <>], [surf: "weg", valencies: <>], [surf: "zusammen", valencies: <>], [surf: "zu", valencies: <>], [surf: "durch", valencies: <>], [surf: "daneben", valencies: <<>>]>, forms: <[surf: "haue", subtype: finite, subject: sg1, tense: present], [surf: "haust", subtype: finite, subject: sg2, tense: present], [surf: "haut", subtype: finite, subject: sg3|pl2, tense: present], [surf: "hauen", subtype: finite, subject: pl13, tense: present], [surf: "haute", subtype: finite, subject: sg13, tense: preterite], [surf: "hautest", subtype: finite, subject: sg2, tense: preterite], [surf: "hauten", subtype: finite, subject: pl13, tense: preterite], [surf: "hautet", subtype: finite, subject: pl2, tense: preterite], [surf: "hauen", subtype: infinitive], [surf: "gehauen", subtype: participle_2_haben]>]; # Substantives. =============================================================== [base: "Bahnhof", POS: substantive, gender: masc, forms: <[surf: "Bahnhof", case: nom_sg|dat_sg|acc_sg], [surf: "Bahnhofe", case: dat_sg], [surf: "Bahnhofs", case: gen_sg], [surf: "Bahnhofes", case: gen_sg], [surf: "Bahnhöfe", case: nom_pl|gen_pl|acc_pl], [surf: "Bahnhöfen", case: dat_pl]>]; [base: "Brief", POS: substantive, gender: masc, forms: <[surf: "Brief", case: nom_sg|dat_sg|acc_sg], [surf: "Briefs", case: gen_sg], [surf: "Briefes", case: gen_sg], [surf: "Briefe", case: dat_sg|nom_pl|gen_pl|acc_pl], [surf: "Briefen", case: dat_pl]>]; [base: "Buch", POS: substantive, gender: neut, forms: <[surf: "Buch", case: nom_sg|dat_sg|acc_sg], [surf: "Buchs", case: gen_sg], [surf: "Buche", case: dat_sg], [surf: "Buches", case: gen_sg], [surf: "Bücher", case: nom_pl|gen_pl|acc_pl], [surf: "Büchern", case: dat_pl]>]; [base: "Fenster", POS: substantive, gender: neut, forms: <[surf: "Fenster", case: nom_sg|dat_sg|acc_sg|nom_pl|gen_pl|acc_pl], [surf: "Fenstern", case: dat_pl], [surf: "Fensters", case: gen_sg]>]; [base: "Flasche", POS: substantive, gender: fem, forms: <[surf: "Flasche", case: singular], [surf: "Flaschen", case: plural]>]; [base: "Fluss", POS: substantive, gender: masc, forms: <[surf: "Fluss", case: nom_sg|dat_sg|acc_sg], [surf: "Fluß", case: nom_sg|dat_sg|acc_sg], [surf: "Flusse", case: dat_sg], [surf: "Flusses", case: gen_sg], [surf: "Flüsse", case: nom_pl|gen_pl|acc_pl], [surf: "Flüssen", case: dat_pl]>]; [base: "Frau", POS: substantive, gender: fem, forms: <[surf: "Frau", case: singular], [surf: "Frauen", case: plural]>]; [base: "Garten", POS: substantive, gender: masc, forms: <[surf: "Garten", case: nom_sg|dat_sg|acc_sg], [surf: "Gartens", case: gen_sg], [surf: "Gärten", case: plural]>]; [base: "Gleis", POS: substantive, gender: neut, forms: <[surf: "Gleis", case: nom_sg|dat_sg|acc_sg], [surf: "Gleise", case: dat_sg|nom_pl|gen_pl|acc_pl], [surf: "Gleisen", case: dat_pl], [surf: "Gleises", case: gen_sg]>]; [base: "Haus", POS: substantive, gender: neut, forms: <[surf: "Haus", case: nom_sg|dat_sg|acc_sg], [surf: "Hauses", case: gen_sg], [surf: "Hause", case: dat_sg], [surf: "Häuser", case: nom_pl|gen_pl|acc_pl], [surf: "Häusern", case: dat_pl]>]; [base: "Kind", POS: substantive, gender: neut, forms: <[surf: "Kind", case: nom_sg|dat_sg|acc_sg], [surf: "Kinde", case: dat_sg], [surf: "Kinds", case: gen_sg], [surf: "Kindes", case: gen_sg], [surf: "Kinder", case: nom_pl|gen_pl|acc_pl], [surf: "Kindern", case: dat_pl]>]; [base: "Kuchen", POS: substantive, gender: masc, forms: <[surf: "Kuchen", case: nom_sg|dat_sg|acc_sg|plural], [surf: "Kuchens", case: gen_sg]>]; [base: "Küche", POS: substantive, gender: fem, forms: <[surf: "Küche", case: singular], [surf: "Küchen", case: plural]>]; [base: "Kuss", POS: substantive, gender: masc, forms: <[surf: "Kuss", case: nom_sg|dat_sg|acc_sg], [surf: "Kusses", case: gen_sg], [surf: "Küsse", case: nom_pl|gen_pl|acc_pl], [surf: "Küssen", case: dat_pl]>]; [base: "Liebe", POS: substantive, gender: fem, forms: <[surf: "Liebe", case: singular], [surf: "Lieben", case: plural]>]; [base: "Mann", POS: substantive, gender: masc, forms: <[surf: "Mann", case: nom_sg|dat_sg|acc_sg], [surf: "Manne", case: dat_sg], [surf: "Manns", case: gen_sg], [surf: "Mannes", case: gen_sg], [surf: "Männer", case: nom_pl|gen_pl|acc_pl], [surf: "Männern", case: dat_pl]>]; [base: "Mädchen", POS: substantive, gender: neut, forms: <[surf: "Mädchen", case: nom_sg|dat_sg|acc_sg|plural], [surf: "Mädchens", case: gen_sg]>]; [base: "Stadt", POS: substantive, gender: fem, forms: <[surf: "Stadt", case: singular], [surf: "Städte", case: nom_pl|gen_pl|acc_pl], [surf: "Städten", case: dat_pl]>]; [base: "Stuhl", POS: substantive, gender: masc, forms: <[surf: "Stuhl", case: nom_sg|dat_sg|acc_sg], [surf: "Stuhle", case: dat_sg], [surf: "Stuhls", case: gen_sg], [surf: "Stuhles", case: gen_sg], [surf: "Stühle", case: nom_pl|gen_pl|acc_pl], [surf: "Stühlen", case: dat_pl]>]; [base: "Tisch", POS: substantive, gender: masc, forms: <[surf: "Tisch", case: nom_sg|dat_sg|acc_sg], [surf: "Tische", case: dat_sg|nom_pl|gen_pl|acc_pl], [surf: "Tischs", case: gen_sg], [surf: "Tisches", case: gen_sg], [surf: "Tischen", case: dat_pl]>]; [base: "Weg", POS: substantive, gender: masc, forms: <[surf: "Weg", case: nom_sg|dat_sg|acc_sg], [surf: "Wege", case: dat_sg|nom_pl|gen_pl|acc_pl], [surf: "Wegs", case: gen_sg], [surf: "Wegen", case: dat_pl]>]; # Names. ====================================================================== [base: "Andrea", POS: name, gender: fem, forms: <[surf: "Andrea", case: sg3|dat_sg|acc_sg], [surf: "Andreas", case: gen_sg]>]; [base: "Andreas", POS: name, gender: masc, forms: <[surf: "Andreas", case: sg3|dat_sg|acc_sg], [surf: "Andreas'", case: gen_sg]>]; [base: "Björn", POS: name, gender: masc, forms: <[surf: "Björn", case: sg3|dat_sg|acc_sg], [surf: "Björns", case: gen_sg]>]; [base: "Chomsky", POS: name, gender: masc, forms: <[surf: "Chomsky", case: sg3|dat_sg|acc_sg], [surf: "Chomskys", case: gen_sg]>]; [base: "Fido", POS: name, gender: masc, forms: <[surf: "Fido", case: sg3|dat_sg|acc_sg], [surf: "Fidos", case: gen_sg]>]; [base: "Gerald", POS: name, gender: masc, forms: <[surf: "Gerald", case: sg3|dat_sg|acc_sg], [surf: "Geralds", case: gen_sg]>]; [base: "Gero", POS: name, gender: masc, forms: <[surf: "Gero", case: sg3|dat_sg|acc_sg], [surf: "Geros", case: gen_sg]>]; [base: "Hausser", POS: name, gender: masc, forms: <[surf: "Hausser", case: sg3|dat_sg|acc_sg], [surf: "Haussers", case: gen_sg]>]; [base: "Jörg", POS: name, gender: masc, forms: <[surf: "Jörg", case: sg3|dat_sg|acc_sg], [surf: "Jörgs", case: gen_sg]>]; [base: "Julia", POS: name, gender: fem, forms: <[surf: "Julia", case: sg3|dat_sg|acc_sg], [surf: "Julias", case: gen_sg]>]; [base: "Katz und Maus", POS: name, forms: <[surf: "Katz und Maus", case: pl3|dat_pl|acc_pl]>]; [base: "Kind und Kegel", POS: name, forms: <[surf: "Kind und Kegel", case: pl3|dat_pl|acc_pl]>]; [base: "Marco", POS: name, gender: masc, forms: <[surf: "Marco", case: sg3|dat_sg|acc_sg], [surf: "Marcos", case: gen_sg]>]; [base: "Max", POS: name, gender: masc, forms: <[surf: "Max", case: sg3|dat_sg|acc_sg], [surf: "Max'", case: gen_sg]>]; [base: "Michael", POS: name, gender: masc, forms: <[surf: "Michael", case: sg3|dat_sg|acc_sg], [surf: "Michaels", case: gen_sg]>]; [base: "Oliver", POS: name, gender: masc, forms: <[surf: "Oliver", case: sg3|dat_sg|acc_sg], [surf: "Olivers", case: gen_sg]>]; # End of file. ================================================================ malaga-7.12/grammars/german/german.mor0000644000175000017500000000060510230777133017263 0ustar bjoernbjoern# Morphology combination rules for german. # Copyright © 2004 Björn Beutel. initial [], rules morpho_rule; combi_rule morpho_rule( $state, $link ): result $link, rules end_check; end; end_rule end_check( $state, $following ): ? $following matches "[\\.,\\?]?( .*)?"; result $state, accept; end; # End of file ================================================================= malaga-7.12/grammars/german/german.pro0000644000175000017500000000103610230776762017274 0ustar bjoernbjoern# Project file for a small German example Syntax Grammar. # Copyright © 2004 Björn Beutel. sym: german.sym all: german.all lex: german.lex mor: german.mor syn: german.syn esym: german.esym malaga: set sort-records definition mallex: set sort-records definition info: A small German example syntax that recognizes sentences info: including subordinate clauses, and genitive attributes. info: It is using a small German full form lexicon for test purposes. # End of file. ================================================================ malaga-7.12/grammars/german/german.sym0000644000175000017500000000613010230777060017274 0ustar bjoernbjoern# Symbols for german. # Copyright © 2004 Björn Beutel. # Symbols for all lexicon entries. ============================================ surf; # Attribute: surface of a lexicon entry. base; # Attribute: base form of a lexicon entry. POS; # Attribute: part of speech. Possible values: pronoun; rel_pronoun; determiner; preposition; punctuation; prefix; name; substantive; adjective; adverb; verb; sub_conjunction; subtype; # Attribute: further distinguishing a specific POS. forms; # Attribute: single flexional forms of a lemma as a list. # Substantives. ============================================================== # POS: substantive; case; sg1; sg2; sg3; # 1st, 2nd, 3rd person singular. pl1; pl2; pl3; # 1st, 2nd, 3rd person plural. gen_sg; gen_pl; dat_sg; dat_pl; acc_sg; acc_pl; nom := ; gen := ; dat := ; acc := ; singular := ; plural := ; sg2|pl2 := ; sg23|pl2 := ; sg3|pl3|acc := ; sg3|dat|acc := ; sg3|acc_sg := ; sg3|dat_sg|acc_sg := ; pl2|dat_sg := ; pl3|acc := ; pl3|dat_pl|acc_pl := ; nom_sg|dat_sg|acc_sg := ; nom_sg|dat_sg|acc_sg|nom_pl|gen_pl|acc_pl := ; nom_sg|dat_sg|acc_sg|plural := ; nom_pl|gen_pl|acc_pl := ; nom_pl|acc_pl := ; gen_sg|dat_sg := ; dat_sg|nom_pl|gen_pl|acc_pl := ; dat_pl|acc_pl := ; pl13 := ; sg3|pl2 := ; sg13 := ; sg23 := ; gender; fem; masc; neut; masc|neut := ; # Adjectives. ================================================================= # POS: adjective; adj_ending; e; em; en; er; es; # Adverbs. ==================================================================== # POS: adverb; type; directional; local; modal; temporal; causal; # Verbs. ====================================================================== # POS: verb; type; finite; participle_2_haben; participle_2_sein; infinitive; participle_2 := ; subject; # See case for substantive. tense; present; preterite; valencies; # <> prefixes; # <[word_form: ..., valencies: ... ]> # Subordinating conjunctions. ================================================= # POS: sub_conjunction; subtype; # See subtype for adverbs. constituent; # See case for substantive. # End of file. ================================================================ malaga-7.12/grammars/german/german.syn0000644000175000017500000002750210375557202017307 0ustar bjoernbjoern# Syntax combination rules for german. # Copyright © 2004 Björn Beutel. #------------------------------------------------------------------------------ initial [constituents: <>, clause_type: main_clause], rules (constituent, subclause_start, finite_verb); #------------------------------------------------------------------------------ combi_rule constituent( $clause, $word, $surf ): # Read a constituent (but not a finite verb or a subclause). if $word.POS in then $clause.constituents :=+ <[function: $word.case, surf: $surf]>; result $clause, rules (constituent, finite_verb, main_clause_end, subclause_initial_comma); $clause :=+ $word * gender + [subclause: rel_clause]; result $clause, rules (subclause_initial_comma); elseif $word.POS = adverb then $clause.constituents :=+ <[function: $word.subtype, surf: $surf]>; result $clause, rules (constituent, finite_verb, subclause_initial_comma, main_clause_end); elseif $word.POS = determiner then define $result := ($word * + [superclause: $clause, function: $word.case, surf: $surf]); result $result, rules (substantive); elseif $word.POS = preposition then # A prepositional phrase consists of a preposition and a noun phrase. define $result := [superclause: $clause, case: $word.case, function: $word.subtype, surf: $surf]; result $result, rules (obligate_NP); elseif $word.POS = verb and $word.subtype /= finite then if $clause.clause_type /= main_clause then # In a subclause, the finite verb follows the infinite verb. $clause.constituents :=+ <[function: verb, surf: $surf]>; $clause :=+ [valencies: $word.valencies, verb: $word.subtype]; result $clause, rules (finite_verb); else # In a main clause, the valency frame must contain the subtype of the # nonfinite verb. require valencies in $clause; # Select the right valency frame. choose $valencies in $clause.valencies; require length( $valencies ) = 1 and $valencies.1L ~ $word.subtype; $clause.constituents :=+ <[function: verb, surf: $surf]>; $clause :=+ $word * valencies; result $clause, rules (subclause_initial_comma, main_clause_end); end if; elseif $word.POS = prefix then # A prefix will be deleted out of the valency frame of the finite verb. # Has a finite verb with prefix list already been read in? require prefixes in $clause; # Select the right prefix. choose $prefix in $clause.prefixes; require $prefix.surf = $surf; $clause.constituents :=+ <[function: prefix, surf: $surf]>; $clause :=+ $prefix * valencies; $clause :=- prefixes; result $clause, rules (constituent, subclause_initial_comma, main_clause_end); end if; end combi_rule; #------------------------------------------------------------------------------ combi_rule obligate_NP( $clause, $word, $surf ): # Read a noun phrase whose result category is already given # (may be used as part of a prepositional phrase). if $word.POS in then require $clause.case ~ $word.case; define $result := $clause.superclause; $result.constituents :=+ <[function: $clause.function, surf: $clause.surf + " " + $surf]>; result $result, rules (constituent, finite_verb, main_clause_end, subclause_initial_comma); $result :=+ $word * gender + [subclause: rel_clause]; result $result, rules subclause_initial_comma; elseif $word.POS = determiner then require $clause.case ~ $word.case; $clause :=+ ($word * + [surf: $clause.surf + " " + $surf]); result $clause, rules (substantive); end if; end combi_rule; #------------------------------------------------------------------------------ combi_rule substantive( $clause, $word, $surf ): # Read an adjective or a substantive. if $word.POS = substantive then require $clause.case ~ $word.case; if gender in $clause then require $clause.gender ~ $word.gender; else $clause :=+ $word * gender; end if; select define $result := $clause.superclause; $result.constituents :=+ <$clause * + [surf: $clause.surf + " " + $surf]>; result $result, rules (constituent, finite_verb, subclause_initial_comma, main_clause_end); $result :=+ $clause * gender + [subclause: rel_clause]; result $result, rules (subclause_initial_comma); or $clause :=- ; $clause.surf :=+ " " + $surf; result $clause, rules (attribute); end select; elseif $word.POS = adjective then require $clause.adj_ending ~ $word.adj_ending; $clause.surf :=+ " " + $surf; result $clause, rules (substantive); end if; end combi_rule; #------------------------------------------------------------------------------ combi_rule attribute( $clause, $word, $surf ): # Read postnominal attributes of a noun phrase. if $word.POS = pronoun and $word.case ~ gen then define $result := $clause.superclause; $result.constituents :=+ <[function: $clause.case, surf: $clause.surf + " " + $surf]>; result $result, rules (constituent, finite_verb, subclause_initial_comma, main_clause_end); $result :=+ $clause * gender + [subclause: rel_clause]; result $result, rules (subclause_initial_comma); elseif $word.POS = determiner and $word.case ~ gen then $clause :=+ $word * ; $clause.surf :=+ " " + $surf; result $clause, rules (substantive); elseif $word.POS = preposition and $word.subtype ~ local then $clause :=+ $word * case; $clause.surf :=+ " " + $surf; result $clause, rules (obligate_NP); end if; end combi_rule; #------------------------------------------------------------------------------ combi_rule finite_verb( $clause, $word, $surf ): # Read the finite verb form. # Do we read a finite verb? require $word.POS = verb and $word.subtype = finite; if $clause.clause_type = main_clause then # In a main clause, the valencies of the finite verb must be stored. foreach $constituent in $clause.constituents: require verb /= $constituent.function; end foreach; define $result := $clause + $word * ; $result.constituents :=+ <[function: verb, surf: $surf]>; result $result, rules (constituent, subclause_initial_comma, main_clause_end); else # In a subclause, the finite verb ends the subclause. $clause.constituents :=+ <[function: verb, surf: $surf]>; define $valency_frame := nil; if verb in $clause then choose $auxiliar_Valency in $word.valencies; require length( $auxiliar_valency ) = 1; require $auxiliar_valency.1 ~ $clause.verb; $valency_frame := $clause.valencies; else $valency_frame := $word.valencies; end if; define $constituent := fill_valencies( $word.subject, $valency_frame, $clause.constituents ); define $result := $clause.superclause; if $clause.clause_type = rel_clause then if not modifiers in $result.constituents.1R then $result.constituents.1R :=+ [modifiers: <>]; end if; $result.constituents.1R.modifiers :=+ <$constituent>; else $constituent :=+ [sub_conjunction: $clause.sub_conjunction.surf]; $result.constituents :=+ <$constituent + [function:$clause.sub_conjunction.function]>; end if; result $result, rules (subclause_end, main_clause_end); end if; end combi_rule; #------------------------------------------------------------------------------ combi_rule subclause_initial_comma( $clause, $word, $surf ): # Read the comma that starts a subclause. require $word.POS = punctuation and $surf = ","; result $clause, rules (subclause_start); end combi_rule; #------------------------------------------------------------------------------ combi_rule subclause_start( $clause, $word, $surf ): # Read the conjunction or relative pronoun that starts a subclause. if not subclause in $clause then $clause :=+ [subclause: subclause]; end if; $clause := [superclause: $clause - subclause, clause_type: $clause.subclause, constituents: <>]; if $clause.clause_type = subclause and $word.POS = sub_conjunction then $clause :=+ [sub_conjunction: [function: $word.subtype, surf: $surf]]; if constituent in $word then $clause.constituents :=+ <[function: $word.constituent, surf: $surf]>; end if; elseif $clause.clause_type = rel_clause and $word.POS = rel_pronoun then # Check if gender is congruent if gender in $clause.superclause and gender in $word then require $clause.superclause.gender ~ $word.gender; end if; $clause.constituents :=+ <[function: $word.case, surf: $surf]>; else stop; end if; result $clause, rules (constituent, finite_verb); end combi_rule; #------------------------------------------------------------------------------ combi_rule subclause_end( $clause, $word, $surf ): # Read the comma that finishes a subclause. require $word.POS = punctuation and $surf = ","; result $clause, rules (constituent, finite_verb, subclause_start); end combi_rule; #------------------------------------------------------------------------------ combi_rule main_clause_end( $clause, $word, $surf ): # Read the punctuation sign that finishes a main clause. require $word.POS = punctuation; require $clause.clause_type = main_clause; require length( $clause.constituents ) greater_equal 2; define $clause_type := nil; if $surf = "." and $clause.constituents.2L.function = verb then $clause_type := declarative; elseif ($surf = "?" and ($clause.constituents.1L.function = verb or $clause.constituents.2L.function = verb)) then $clause_type := interrogative; else stop; end if; define $result := ([clause_type: $clause_type] + fill_valencies( $clause.subject, $clause.valencies, $clause.constituents )); result $result, accept; end combi_rule; #------------------------------------------------------------------------------ subrule fill_valencies( $subject, $valency_frame, $constituents ): # Check if $constituents fill all valencies for $subject and $valency_frame. # If the test succeeds, return a record with the attributes predicate, # arguments, and modifiers. choose $valencies in $valency_frame; # Check if all valencies are filled. define $arguments := <>; define $other_constituents := $constituents; foreach $valency in + $valencies: define $agrees_with := $valency; if $valency = subject then $agrees_with := $subject; elseif $valency ~ nom then $valency := nom; end if; choose $index in length( $other_constituents ); define $constituent := $other_constituents.$index; $other_constituents :=- $index; require $agrees_with ~ $constituent.function; $arguments :=+ <$constituent + [function: $valency]>; end foreach; # Check if all other constituents are modifiers or parts of the predicate. define $predicate := nil; define $modifiers := <>; foreach $constituent in $other_constituents: require $constituent.function in ; if $constituent.function in then if $predicate = nil then $predicate := $constituent.surf; else $predicate :=+ " " + $constituent.surf; end if; else $modifiers :=+ <$constituent>; end if; end foreach; define $result := [predicate: $predicate, arguments: $arguments]; if $modifiers /= <> then $result :=+ [modifiers: $modifiers]; end if; return $result; end subrule; # End of file. ================================================================ malaga-7.12/grammars/german/sentences0000644000175000017500000000164610230776644017221 0ustar bjoernbjoernGerald schreibt Oliver einen Brief. Einen Brief schreibt Andrea Björn. Einen schönen Brief schreibt der Mann der Frau. Die Frau schreibt dem Mann einen schönen Brief. Heute schreibt Andreas der Frau einen Brief, weil er die Frau liebt. Jörg schreibt Max einen Brief, weil Max eines Briefes bedarf. Schreibt Max Marco einen Brief? Schreibt er ihm einen Brief? Er schreibt ihm einen Brief. Er schläft. Er schlief. Er hat geschlafen. Er hatte geschlafen. Er hat geschlafen, weil er eine Frau war. Der alte Mann gibt, nachdem die Frau in das Haus gegangen war, dem Mädchen eine schöne Flasche. Ich schreibe der Frau, daß du gestern hier gewesen bist. Ich gehe hinter dem Bahnhof auf das Gleis. Ich gehe auf dem Gleis hinter den Bahnhof. Der junge Mann gab der Frau, als sie, nachdem ihr das Kind einen Brief geschrieben hatte, in das Haus ging, den Brief. Er haut den jungen Mann nieder. Der Tisch des Mannes ist ein alter Tisch. malaga-7.12/grammars/formal/0000755000175000017500000000000010764165477015317 5ustar bjoernbjoernmalaga-7.12/grammars/formal/quadratic.mor0000644000175000017500000000127710270501522017773 0ustar bjoernbjoern# morphological combination rules for words of the form a^(n^2) initial , rules read_even; combi_rule read_even( $state, $link ): require $link = A; if $state.1L = A then $state :=+ ; result $state, rules read_odd; result $state, accept; else $state :=- 1L; $state :=+ ; result $state, rules read_even; end; end; combi_rule read_odd( $state, $link ): require $link = A; if $state.1L = B then $state :=+ ; result $state, rules read_even; result $state, accept; else $state :=- 1L; $state :=+ ; result $state, rules read_odd; end; end; # end of file ================================================================= malaga-7.12/grammars/formal/formal.all0000644000175000017500000000035210230777202017250 0ustar bjoernbjoern# allomorph rules for formal Malaga grammars ================================== allo_rule allomorph_rule( $entry ): result $entry.1L, $entry.2L; end; # end of file ================================================================= malaga-7.12/grammars/formal/formal.lex0000644000175000017500000000032410230777202017267 0ustar bjoernbjoern# lexicon for formal Malaga grammars ========================================== <"a", A>; <"b", B>; <"c", C>; <"d", D>; <"e", E>; # end of file ================================================================= malaga-7.12/grammars/formal/formal.sym0000644000175000017500000000026110230777202017307 0ustar bjoernbjoern# symbol file for formal Malaga grammars ====================================== A; B; C; D; E; # end of file ================================================================= malaga-7.12/grammars/formal/same_count_mixed.pro0000644000175000017500000000047010230777202021344 0ustar bjoernbjoern# the project file for the grammar "same_count_mixed" sym: formal.sym all: formal.all lex: formal.lex mor: same_count_mixed.mor info: A formal grammar that recognizes all non-empty words info: consisting of as many "a"s as "b"s # end of file ================================================================= malaga-7.12/grammars/formal/choose_count.mor0000644000175000017500000000137310270501675020514 0ustar bjoernbjoern# morphological combination rules for words of the form # a^m b^n c^m | a^m b^n c^n initial <>, rules r1; combi_rule r1( $state, $link ): require $link = A; $state :=+ ; result $state, rules r1, r2; end; combi_rule r2( $state, $link ): require $link = B; $state :=+ ; result $state, rules r2, r3, r4; end; combi_rule r3( $state, $link ): require $link = C and $state.1L = A; $state :=- 1L; result $state, rules r3, finish; end; combi_rule r4( $state, $link ): require $link = C and $state.1R = B; $state :=- 1R; result $state, rules r4, finish; end; end_rule finish( $state ): require $state.1L = $state.1R; result nil, accept; end finish; # end of file ================================================================= malaga-7.12/grammars/formal/quadratic.pro0000644000175000017500000000040710230777202017776 0ustar bjoernbjoern# the project file for the grammar "quadratic" sym: formal.sym all: formal.all lex: formal.lex mor: quadratic.mor info: A formal grammar that recognizes words of the form a^(n^2). # end of file ================================================================= malaga-7.12/grammars/formal/palindrome.mor0000644000175000017500000000123210270502006020135 0ustar bjoernbjoern# morphological combination rules for all non-empty palindromes # over the lexicon items. initial <>, rules left_rule, mid_rule; combi_rule left_rule( $state, $link ): $state :=+ <$link>; result $state, rules left_rule, mid_rule, right_rule; end combi_rule; combi_rule mid_rule( $state, $link ): result $state, rules right_rule, finish; end combi_rule; combi_rule right_rule( $state, $link ): require $state.1R = $link; $state :=- 1R; result $state, rules right_rule, finish; end; end_rule finish( $state ): require $state = <>; result $state, accept; end finish; # end of file ================================================================= malaga-7.12/grammars/formal/growing_blocks.pro0000644000175000017500000000054410230777202021034 0ustar bjoernbjoern# the project file for the grammar "growing_blocks" sym: formal.sym all: formal.all lex: formal.lex mor: growing_blocks.mor info: A formal grammar that recognizes words that consist of alternating blocks info: of "a"s and "b"s, each block at least as long as the previous. # end of file ================================================================= malaga-7.12/grammars/formal/growing_blocks.mor0000644000175000017500000000135410270501744021031 0ustar bjoernbjoern# morphological combination rules for words that consist of alternating blocks # of "a"s and "b"s, each block at least as long as the previous one. initial <>, rules build; combi_rule build( $state, $link ): require $link in ; require $state.1L in ; result $state + <$link>, rules build, delete; result $state + <$link>, accept; end; combi_rule delete( $state, $link ): require $link in ; require not $state.1L in ; if $state.2L in then result $state - 1L + <$link>, rules build, delete; result $state - 1L + <$link>, accept; else result $state - 1L + <$link>, rules delete; end; end; # end of file ================================================================= malaga-7.12/grammars/formal/repeat_word.mor0000644000175000017500000000103010270501636020322 0ustar bjoernbjoern# morphological combination rules for words of the form ww, # where w is a non-empty sequence of lexicon items. initial <>, rules read_start; combi_rule read_start( $state, $link ): $state :=+ <$link>; result $state, rules read_start, read_end; end; combi_rule read_end( $state, $link ): require $state.1L = $link; $state :=- 1L; if $state = <> then result $state, accept; else result $state, rules read_end; end; end combi_rule; # end of file ================================================================= malaga-7.12/grammars/formal/repeat_word.pro0000644000175000017500000000047710230777202020343 0ustar bjoernbjoern# the project file for the grammar "repeat_word" sym: formal.sym all: formal.all lex: formal.lex mor: repeat_word.mor info: A formal grammar that recognizes words of the form ww, info: where w is a non-empty sequence of lexicon items. # end of file ================================================================= malaga-7.12/grammars/formal/max_count.pro0000644000175000017500000000050010230777202020010 0ustar bjoernbjoern# the project file for the grammar "max_count" sym: formal.sym all: formal.all lex: formal.lex mor: max_count.mor info: A grammar for all words that consists of k "a"s, followed by l "b"s, info: followed by m "c"s, where m = max{k, l}. # end of file ================================================================= malaga-7.12/grammars/formal/choose_count.pro0000644000175000017500000000044410230777202020512 0ustar bjoernbjoern# the project file for the grammar "choose_count" sym: formal.sym all: formal.all lex: formal.lex mor: choose_count.mor info: A formal grammar that recognises words of the form info: a^m b^n c^m | a^m b^n c^n # end of file ================================================================= malaga-7.12/grammars/formal/max_count.mor0000644000175000017500000000137210270501772020016 0ustar bjoernbjoern# morphological combination rules for all words that consists of k "a"s, # followed by l "b"s, followed by m "c"s, where m = max{k, l}. initial <>, rules r1; combi_rule r1( $state, $link ): require $link = A; $state :=+ ; result $state, rules r1, r2; end; combi_rule r2( $state, $link ): require $link = B; $state :=+ ; result $state, rules r2, r3; end combi_rule; combi_rule r3( $state, $link ): require $link = C; require $state /= <>; if $state.1L = A then $state :=- 1L; end if; if $state.1R = B then $state :=- 1R; end if; if $state = <> then result $state, accept; else result $state, rules r3; end if; end combi_rule; # end of file ================================================================= malaga-7.12/grammars/formal/same_count_mixed.mor0000644000175000017500000000071010270622067021340 0ustar bjoernbjoern# morphological combination rules for all non-empty words consisting of # as many "a"s as "b"s initial <>, rules rule; combi_rule rule( $state, $link ): require $link in ; if $state = <> or $state.1L = $link then $state :=+ <$link>; else $state :=- 1L; end; end; end_rule finish( $state ): require $state = <>; result $state, accept; end finish; # end of file ================================================================= malaga-7.12/grammars/formal/same_count_with_noise.mor0000644000175000017500000000123010270502041022365 0ustar bjoernbjoern# morphological combination rules for words consisting of n "a"s and n "b"s # behind, and "c"s arbitrarily spread everywhere. initial <>, rules A; combi_rule A( $state, $link ): if $link = A then $state :=+ ; result $state, rules A, B; elseif $link = C then result $state, rules A; end; end A; combi_rule B( $state, $link ): if $link = B and $state /= <> then $state :=- 1L; result $state, rules B, C; elseif $link = C then result $state, rules B, C; end; end B; end_rule C( $state ): require $state = <>; result $state, accept; end C; # end of file ================================================================= malaga-7.12/grammars/formal/same_count_with_noise.pro0000644000175000017500000000056310230777202022411 0ustar bjoernbjoern# the project file for the grammar "same_count_with_noise" sym: formal.sym all: formal.all lex: formal.lex mor: same_count_with_noise.mor info: A formal grammar that recognizes words consisting of info: n "a"s and n "b"s behind, and "c"s arbitrarily spread in info: anywhere in the word # end of file ================================================================= malaga-7.12/grammars/formal/palindrome.pro0000644000175000017500000000044710230777202020157 0ustar bjoernbjoern# the project file for the grammar "palindrome" sym: formal.sym all: formal.all lex: formal.lex mor: palindrome.mor info: A formal grammar that recognizes all non-empty palindromes info: over the lexicon items. # end of file ================================================================= malaga-7.12/grammars/numeral/0000755000175000017500000000000010764165477015502 5ustar bjoernbjoernmalaga-7.12/grammars/numeral/numeral.all0000644000175000017500000000026710230777330017625 0ustar bjoernbjoern# allomorph rules for numeral allo_rule generate_allo( $lex ): result $lex.surf, $lex - surf; end; # end of file ================================================================= malaga-7.12/grammars/numeral/numeral.lex0000644000175000017500000000177010230777330017645 0ustar bjoernbjoern# lexicon for numeral [surf: "one", ones: 1]; [surf: "two", ones: 2]; [surf: "three", ones: 3]; [surf: "four", ones: 4]; [surf: "five", ones: 5]; [surf: "six", ones: 6]; [surf: "seven", ones: 7]; [surf: "eight", ones: 8]; [surf: "nine", ones: 9]; [surf: "ten", tens: 1, ones: 0]; [surf: "eleven", tens: 1, ones: 1]; [surf: "twelve", tens: 1, ones: 2]; [surf: "thirteen", tens: 1, ones: 3]; [surf: "fourteen", tens: 1, ones: 4]; [surf: "fifteen", tens: 1, ones: 5]; [surf: "sixteen", tens: 1, ones: 6]; [surf: "seventeen", tens: 1, ones: 7]; [surf: "eighteen", tens: 1, ones: 8]; [surf: "nineteen", tens: 1, ones: 9]; [surf: "twenty", tens: 2]; [surf: "thirty", tens: 3]; [surf: "fourty", tens: 4]; [surf: "fifty", tens: 5]; [surf: "sixty", tens: 6]; [surf: "seventy", tens: 7]; [surf: "eighty", tens: 8]; [surf: "ninety", tens: 9]; [surf: "hundred"]; [surf: "thousand"]; [surf: "-"]; [surf: " "]; # end of file ================================================================= malaga-7.12/grammars/numeral/numeral.mor0000644000175000017500000000613510230777330017652 0ustar bjoernbjoern# morphology combination rules for numeral initial [ones: 0, tens: 0, hundreds: 0, thousands: 0], rules ones, tens, thousand, hundred; #------------------------------------------------------------------------------ combi_rule dash_to_ones( $state, $link, $surface ): # Read a "-" in front of "one", ..., "nine". require $surface = "-"; result $state, rules ones; end dash_to_ones; #------------------------------------------------------------------------------ combi_rule blank_to_ones_or_tens( $state, $link, $surface ): # Read a blank in front of "one", ..., "ninety". require $surface = " "; result $state, rules ones, tens; end blank_to_ones_or_tens; #------------------------------------------------------------------------------ combi_rule ones( $state, $link ): # Read "one", "two", ..., "nineteen" require ones in $link; if tens in $link then require $state.tens = 0; $state.tens := $link.tens; end if; $state.ones := $link.ones; result $state, rules blank_to_thousand, blank_to_hundred, finish; end combi_rule; #------------------------------------------------------------------------------ combi_rule tens( $state, $link ): # Read "twenty", ..., "ninety". require $state.tens = 0; require tens in $link and not ones in $link; $state.tens := $link.tens; result $state, rules dash_to_ones, blank_to_thousand, finish; end combi_rule; #------------------------------------------------------------------------------ combi_rule blank_to_hundred( $state, $link, $surface ): # Read a blank in front of "hundred". require $surface = " "; result $state, rules hundred; end blank_to_hundred; #------------------------------------------------------------------------------ combi_rule hundred( $state, $link, $surface ): # Read "hundred". require $surface = "hundred"; require $state.hundreds = 0 and $state.tens = 0; if $state.ones = 0 then $state :=+ [ones: 1]; end if; $state :=+ [hundreds: $state.ones, ones: 0]; result $state, rules blank_to_ones_or_tens, blank_to_thousand, finish; end combi_rule; #------------------------------------------------------------------------------ combi_rule blank_to_thousand( $state, $link, $surface ): # Read a blank in front of "thousand". require $surface = " "; result $state, rules thousand; end blank_to_thousand; #------------------------------------------------------------------------------ combi_rule thousand( $state, $link, $surface ): # Read "thousand". require $surface = "thousand"; require $state.thousands = 0; if $state.ones = 0 and $state.tens = 0 and $state.hundreds = 0 then $state :=+ [ones: 1]; end if; define $result := [ones: 0, tens: 0, hundreds: 0, thousands: ($state.hundreds * 100 + $state.tens * 10 + $state.ones)]; result $result, rules blank_to_ones_or_tens, finish; end combi_rule; #------------------------------------------------------------------------------ end_rule finish( $state ): result ($state.thousands * 1000 + $state.hundreds * 100 + $state.tens * 10 + $state.ones), accept; end finish; # end of file ================================================================= malaga-7.12/grammars/numeral/numeral.pro0000644000175000017500000000047710230777330017660 0ustar bjoernbjoern# project file for English Numeral Morphology mor: numeral.mor all: numeral.all sym: numeral.sym lex: numeral.lex info: A grammar that recognizes English numerals up to info: "nine hundred ninety-nine thousand nine hundred ninety-nine" # end of file ================================================================= malaga-7.12/grammars/numeral/numeral.sym0000644000175000017500000000022310230777330017655 0ustar bjoernbjoern# symbol file for numeral surf; ones; tens; hundreds; thousands; # end of file =================================================================