--- /dev/null
+# Makefile for GNU C Preprocessor.
+#
+# hacked from gcc Makefile by kvigor.
+#
+# Copyright (C) 1987, 1988, 1990, 1991, 1992, 1993, 1994, 1995
+# 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+#This file is part of GNU CC.
+
+#GNU CC is free software; you can redistribute it and/or modify
+#it under the terms of the GNU General Public License as published by
+#the Free Software Foundation; either version 2, or (at your option)
+#any later version.
+
+#GNU CC 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 GNU CC; see the file COPYING. If not, write to
+#the Free Software Foundation, 59 Temple Place - Suite 330,
+#Boston MA 02111-1307, USA.
+
+PRJDIR = ../..
+TARGET = $(PRJDIR)/bin/sdcpp2
+
+# This is the default target.
+all: $(TARGET)
+
+# Directory where sources are, from where we are.
+srcdir = @srcdir@
+
+
+
+LIBS = @LIBS@
+ALL_CFLAGS = $(INTERNAL_CFLAGS) $(X_CFLAGS) $(T_CFLAGS) \
+ $(CFLAGS) $(WARN_CFLAGS) $(XCFLAGS) @DEFS@
+ALL_CPPFLAGS = $(CPPFLAGS) $(X_CPPFLAGS) $(T_CPPFLAGS)
+
+CC = @CC@
+AR = ar
+AR_FLAGS = rc
+RANLIB = @RANLIB@
+SHELL = /bin/sh
+# on sysV, define this as cp.
+INSTALL = @INSTALL@
+# Some systems may be missing symbolic links, regular links, or both.
+# Allow configure to check this and use "ln -s", "ln", or "cp" as appropriate.
+LN=@LN@
+LN_S=@LN_S@
+# These permit overriding just for certain files.
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+@SET_MAKE@
+# Some compilers can't handle cc -c blah.c -o foo/blah.o.
+# In stage2 and beyond, we force this to "-o $@" since we know we're using gcc.
+OUTPUT_OPTION = @OUTPUT_OPTION@
+
+# Some versions of `touch' (such as the version on Solaris 2.8)
+# do not correctly set the timestamp due to buggy versions of `utime'
+# in the kernel. So, we use `echo' instead.
+STAMP = echo timestamp >
+
+# Where to find some libiberty headers.
+LIBIBERTY_DIR = $(srcdir)/libiberty
+OBSTACK_H = $(LIBIBERTY_DIR)/obstack.h
+SPLAY_TREE_H= $(LIBIBERTY_DIR)/splay-tree.h
+
+# Test to see whether <limits.h> exists in the system header files.
+LIMITS_H_TEST = [ -f $(SYSTEM_HEADER_DIR)/limits.h ]
+
+# Common prefix for installation directories.
+# NOTE: This directory must exist when you start installation.
+prefix = @prefix@
+# Directory in which to put localized header files. On the systems with
+# gcc as the native cc, `local_prefix' may not be `prefix' which is
+# `/usr'.
+# NOTE: local_prefix *should not* default from prefix.
+local_prefix = @local_prefix@
+# Directory in which to put host dependent programs and libraries
+exec_prefix = @exec_prefix@
+# Directory in which to put the executable for the command `gcc'
+bindir = @bindir@
+includedir = $(local_prefix)/include
+# where the info files go
+exeext = @host_exeext@
+
+# Top build directory, relative to here.
+top_builddir = .
+
+# Whether we were configured with NLS.
+USE_NLS = @USE_NLS@
+
+# Internationalization library.
+INTLLIBS = @INTLLIBS@
+
+# Change this to a null string if obstacks are installed in the
+# system library.
+OBSTACK=obstack.o
+
+# End of variables for you to override.
+
+install: all
+ $(INSTALL) -s $(TARGET) $(bindir)/sdcpp
+
+clean:
+ -rm -f $(TARGET) *.o core libcpp.a
+
+distclean: clean
+ -rm -f auto-host.h auto-build.h cstamp-h Makefile
+ -rm -f config.status config.run config.cache config.bak config.log *~
+
+# This tells GNU Make version 3 not to put all variables in the environment.
+.NOEXPORT:
+
+# GCONFIG_H lists the config files that the generator files depend on, while
+# CONFIG_H lists the the ones ordinary gcc files depend on, which includes
+# a file generated by gencodes.
+CONFIG_H = config.h
+SYSTEM_H = system.h hwint.h
+
+# sed inserts variable overrides after the following line.
+####target overrides
+@target_overrides@
+
+####host overrides
+@host_overrides@
+
+####cross overrides
+@cross_defines@
+@cross_overrides@
+
+####build overrides
+@build_overrides@
+#\f
+
+INCLUDES = -I$(srcdir) -I$(LIBIBERTY_DIR)
+
+# Always use -I$(srcdir)/config when compiling.
+.c.o:
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
+
+# cstamp-h.in controls rebuilding of config.in.
+# It is named cstamp-h.in and not stamp-h.in so the mostlyclean rule doesn't
+# delete it. A stamp file is needed as autoheader won't update the file if
+# nothing has changed.
+# It remains in the source directory and is part of the distribution.
+# This follows what is done in shellutils, fileutils, etc.
+# "echo timestamp" is used instead of touch to be consistent with other
+# packages that use autoconf (??? perhaps also to avoid problems with patch?).
+# ??? Newer versions have a maintainer mode that may be useful here.
+$(srcdir)/config.in: $(srcdir)/cstamp-h.in $(srcdir)/acconfig.h
+$(srcdir)/cstamp-h.in: $(srcdir)/configure.in $(srcdir)/acconfig.h
+ (cd $(srcdir) && autoheader)
+ @rm -f $(srcdir)/cstamp-h.in
+ echo timestamp > $(srcdir)/cstamp-h.in
+auto-host.h: cstamp-h ; @true
+cstamp-h: config.in config.status
+ CONFIG_HEADERS=auto-host.h:config.in LANGUAGES="$(CONFIG_LANGUAGES)" $(SHELL) config.status
+
+# Really, really stupid make features, such as SUN's KEEP_STATE, may force
+# a target to build even if it is up-to-date. So we must verify that
+# config.status does not exist before failing.
+config.status: $(srcdir)/configure version.c
+ @if [ ! -f config.status ] ; then \
+ echo You must configure gcc. Look at http://gcc.gnu.org/install/ for details.; \
+ false; \
+ else \
+ LANGUAGES="$(CONFIG_LANGUAGES)" $(SHELL) config.status --recheck; \
+ fi
+
+version.o: version.c version.h
+
+hashtable.o: hashtable.c hashtable.h $(CONFIG_H) $(SYSTEM_H) $(OBSTACK_H)
+
+prefix.o: prefix.c $(CONFIG_H) $(SYSTEM_H) Makefile prefix.h
+ $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ -DPREFIX=\"$(prefix)\" \
+ -c $(srcdir)/prefix.c
+
+intl.o: intl.c intl.h Makefile
+ $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ -DLOCALEDIR=\"$(localedir)\" \
+ -c $(srcdir)/intl.c
+
+#\f
+# Remake cpp and protoize.
+
+PREPROCESSOR_DEFINES = \
+ -DGCC_INCLUDE_DIR=\"$(libsubdir)/include\" \
+ -DGPLUSPLUS_INCLUDE_DIR=\"$(gcc_gxx_include_dir)\" \
+ -DGPLUSPLUS_TOOL_INCLUDE_DIR=\"$(gcc_gxx_include_dir)/$(target_alias)\" \
+ -DGPLUSPLUS_BACKWARD_INCLUDE_DIR=\"$(gcc_gxx_include_dir)/backward\" \
+ -DLOCAL_INCLUDE_DIR=\"$(includedir)\" \
+ -DCROSS_INCLUDE_DIR=\"$(gcc_tooldir)/sys-include\" \
+ -DTOOL_INCLUDE_DIR=\"$(gcc_tooldir)/include\"
+
+LIBCPP_OBJS = cpplib.o cpplex.o cppmacro.o cppexp.o cppfiles.o \
+ cpphash.o cpperror.o cppinit.o cppdefault.o \
+ hashtable.o mkdeps.o prefix.o version.o mbchar.o
+
+LIBCPP_DEPS = cpplib.h cpphash.h hashtable.h intl.h $(OBSTACK_H) $(SYSTEM_H)
+
+# Most of the other archives built/used by this makefile are for
+# targets. This one is strictly for the host.
+libcpp.a: $(LIBCPP_OBJS)
+ -rm -rf libcpp.a
+ $(AR) $(AR_FLAGS) libcpp.a $(LIBCPP_OBJS)
+ -$(RANLIB) libcpp.a
+
+MY_LIBIBERTY_BITS = intl.o safe-ctype.o obstack.o splay-tree.o \
+ lbasename.o
+
+$(TARGET): cppmain.o intl.o $(MY_LIBIBERTY_BITS) libcpp.a $(LIBDEPS)
+ $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ cppmain.o \
+ $(MY_LIBIBERTY_BITS) libcpp.a $(LIBS)
+
+cppmain.o: cppmain.c $(CONFIG_H) cpplib.h intl.h $(SYSTEM_H)
+
+cpperror.o: cpperror.c $(CONFIG_H) $(LIBCPP_DEPS)
+cppexp.o: cppexp.c $(CONFIG_H) $(LIBCPP_DEPS)
+cpplex.o: cpplex.c $(CONFIG_H) $(LIBCPP_DEPS) mbchar.h
+cppmacro.o: cppmacro.c $(CONFIG_H) $(LIBCPP_DEPS)
+cpplib.o: cpplib.c $(CONFIG_H) $(LIBCPP_DEPS)
+cpphash.o: cpphash.c $(CONFIG_H) $(LIBCPP_DEPS)
+cppfiles.o: cppfiles.c $(CONFIG_H) $(LIBCPP_DEPS) $(SPLAY_TREE_H) mkdeps.h
+cppinit.o: cppinit.c $(CONFIG_H) $(LIBCPP_DEPS) cppdefault.h \
+ mkdeps.h prefix.h output.h version.h
+safe-ctype.o: $(LIBIBERTY_DIR)/safe-ctype.c $(LIBIBERTY_DIR)/safe-ctype.h $(CONFIG_H) $(LIBCPP_DEPS)
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
+obstack.o: $(LIBIBERTY_DIR)/obstack.c $(LIBIBERTY_DIR)/obstack.h $(CONFIG_H) $(LIBCPP_DEPS)
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
+splay-tree.o: $(LIBIBERTY_DIR)/splay-tree.c $(LIBIBERTY_DIR)/splay-tree.h $(CONFIG_H) $(LIBCPP_DEPS)
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
+lbasename.o: $(LIBIBERTY_DIR)/lbasename.c $(CONFIG_H) $(LIBCPP_DEPS)
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
+cppdefault.o: cppdefault.c $(CONFIG_H) $(SYSTEM_H) cppdefault.h Makefile
+ $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(PREPROCESSOR_DEFINES) \
+ -c $(srcdir)/cppdefault.c
+
+mkdeps.o: mkdeps.c $(CONFIG_H) $(SYSTEM_H) mkdeps.h
+
--- /dev/null
+/* Define to 1 if NLS is requested. */
+#undef ENABLE_NLS
+
+/* Define as 1 if you have catgets and don't want to use GNU gettext. */
+#undef HAVE_CATGETS
+
+/* Define as 1 if you have gettext and don't want to use GNU gettext. */
+#undef HAVE_GETTEXT
+
+/* Define if your locale.h file contains LC_MESSAGES. */
+#undef HAVE_LC_MESSAGES
+
+/* Define as 1 if you have the stpcpy function. */
+#undef HAVE_STPCPY
+
+/* Define if your assembler supports specifying the maximum number
+ of bytes to skip when using the GAS .p2align command. */
+#undef HAVE_GAS_MAX_SKIP_P2ALIGN
+
+/* Define if your assembler supports .balign and .p2align. */
+#undef HAVE_GAS_BALIGN_AND_P2ALIGN
+
+/* Define if your assembler uses the old HImode fild and fist notation. */
+#undef HAVE_GAS_FILDS_FISTS
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef ssize_t
+
+@BOTTOM@
+
+/* Bison unconditionally undefines `const' if neither `__STDC__' nor
+ __cplusplus are defined. That's a problem since we use `const' in
+ the GCC headers, and the resulting bison code is therefore type
+ unsafe. Thus, we must match the bison behavior here. */
+
+#ifndef __STDC__
+#ifndef __cplusplus
+#undef const
+#define const
+#endif
+#endif
--- /dev/null
+dnl See whether we can include both string.h and strings.h.
+AC_DEFUN(gcc_AC_HEADER_STRING,
+[AC_CACHE_CHECK([whether string.h and strings.h may both be included],
+ gcc_cv_header_string,
+[AC_TRY_COMPILE([#include <string.h>
+#include <strings.h>], , gcc_cv_header_string=yes, gcc_cv_header_string=no)])
+if test $gcc_cv_header_string = yes; then
+ AC_DEFINE(STRING_WITH_STRINGS, 1, [Define if you can safely include both <string.h> and <strings.h>.])
+fi
+])
+
+dnl See whether we need a declaration for a function.
+dnl The result is highly dependent on the INCLUDES passed in, so make sure
+dnl to use a different cache variable name in this macro if it is invoked
+dnl in a different context somewhere else.
+dnl gcc_AC_CHECK_DECL(SYMBOL,
+dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, INCLUDES]]])
+AC_DEFUN(gcc_AC_CHECK_DECL,
+[AC_MSG_CHECKING([whether $1 is declared])
+AC_CACHE_VAL(gcc_cv_have_decl_$1,
+[AC_TRY_COMPILE([$4],
+[#ifndef $1
+char *(*pfn) = (char *(*)) $1 ;
+#endif], eval "gcc_cv_have_decl_$1=yes", eval "gcc_cv_have_decl_$1=no")])
+if eval "test \"`echo '$gcc_cv_have_decl_'$1`\" = yes"; then
+ AC_MSG_RESULT(yes) ; ifelse([$2], , :, [$2])
+else
+ AC_MSG_RESULT(no) ; ifelse([$3], , :, [$3])
+fi
+])dnl
+
+dnl Check multiple functions to see whether each needs a declaration.
+dnl Arrange to define HAVE_DECL_<FUNCTION> to 0 or 1 as appropriate.
+dnl gcc_AC_CHECK_DECLS(SYMBOLS,
+dnl [ACTION-IF-NEEDED [, ACTION-IF-NOT-NEEDED [, INCLUDES]]])
+AC_DEFUN(gcc_AC_CHECK_DECLS,
+[for ac_func in $1
+do
+changequote(, )dnl
+ ac_tr_decl=HAVE_DECL_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+changequote([, ])dnl
+gcc_AC_CHECK_DECL($ac_func,
+ [AC_DEFINE_UNQUOTED($ac_tr_decl, 1) $2],
+ [AC_DEFINE_UNQUOTED($ac_tr_decl, 0) $3],
+dnl It is possible that the include files passed in here are local headers
+dnl which supply a backup declaration for the relevant prototype based on
+dnl the definition of (or lack of) the HAVE_DECL_ macro. If so, this test
+dnl will always return success. E.g. see libiberty.h's handling of
+dnl `basename'. To avoid this, we define the relevant HAVE_DECL_ macro to
+dnl 1 so that any local headers used do not provide their own prototype
+dnl during this test.
+#undef $ac_tr_decl
+#define $ac_tr_decl 1
+ $4
+)
+done
+dnl Automatically generate config.h entries via autoheader.
+if test x = y ; then
+ patsubst(translit([$1], [a-z], [A-Z]), [\w+],
+ [AC_DEFINE([HAVE_DECL_\&], 1,
+ [Define to 1 if we found this declaration otherwise define to 0.])])dnl
+fi
+])
+
+dnl See if symbolic links work and if not, try to substitute either hard links or simple copy.
+AC_DEFUN(gcc_AC_PROG_LN_S,
+[AC_MSG_CHECKING(whether ln -s works)
+AC_CACHE_VAL(gcc_cv_prog_LN_S,
+[rm -f conftestdata_t
+echo >conftestdata_f
+if ln -s conftestdata_f conftestdata_t 2>/dev/null
+then
+ gcc_cv_prog_LN_S="ln -s"
+else
+ if ln conftestdata_f conftestdata_t 2>/dev/null
+ then
+ gcc_cv_prog_LN_S=ln
+ else
+ gcc_cv_prog_LN_S=cp
+ fi
+fi
+rm -f conftestdata_f conftestdata_t
+])dnl
+LN_S="$gcc_cv_prog_LN_S"
+if test "$gcc_cv_prog_LN_S" = "ln -s"; then
+ AC_MSG_RESULT(yes)
+else
+ if test "$gcc_cv_prog_LN_S" = "ln"; then
+ AC_MSG_RESULT([no, using ln])
+ else
+ AC_MSG_RESULT([no, and neither does ln, so using cp])
+ fi
+fi
+AC_SUBST(LN_S)dnl
+])
+
+dnl See if hard links work and if not, try to substitute either symbolic links or simple copy.
+AC_DEFUN(gcc_AC_PROG_LN,
+[AC_MSG_CHECKING(whether ln works)
+AC_CACHE_VAL(gcc_cv_prog_LN,
+[rm -f conftestdata_t
+echo >conftestdata_f
+if ln conftestdata_f conftestdata_t 2>/dev/null
+then
+ gcc_cv_prog_LN="ln"
+else
+ if ln -s conftestdata_f conftestdata_t 2>/dev/null
+ then
+ gcc_cv_prog_LN="ln -s"
+ else
+ gcc_cv_prog_LN=cp
+ fi
+fi
+rm -f conftestdata_f conftestdata_t
+])dnl
+LN="$gcc_cv_prog_LN"
+if test "$gcc_cv_prog_LN" = "ln"; then
+ AC_MSG_RESULT(yes)
+else
+ if test "$gcc_cv_prog_LN" = "ln -s"; then
+ AC_MSG_RESULT([no, using ln -s])
+ else
+ AC_MSG_RESULT([no, and neither does ln -s, so using cp])
+ fi
+fi
+AC_SUBST(LN)dnl
+])
+
+dnl Define MKDIR_TAKES_ONE_ARG if mkdir accepts only one argument instead
+dnl of the usual 2.
+AC_DEFUN(gcc_AC_FUNC_MKDIR_TAKES_ONE_ARG,
+[AC_CACHE_CHECK([if mkdir takes one argument], gcc_cv_mkdir_takes_one_arg,
+[AC_TRY_COMPILE([
+#include <sys/types.h>
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifdef HAVE_DIRECT_H
+# include <direct.h>
+#endif], [mkdir ("foo", 0);],
+ gcc_cv_mkdir_takes_one_arg=no, gcc_cv_mkdir_takes_one_arg=yes)])
+if test $gcc_cv_mkdir_takes_one_arg = yes ; then
+ AC_DEFINE(MKDIR_TAKES_ONE_ARG, 1, [Define if host mkdir takes a single argument.])
+fi
+])
+
+AC_DEFUN(gcc_AC_PROG_INSTALL,
+[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+# 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
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+AC_MSG_CHECKING(for a BSD compatible install)
+if test -z "$INSTALL"; then
+AC_CACHE_VAL(ac_cv_path_install,
+[ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ # OSF/1 installbsd also uses dspmsg, but is usable.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+])dnl
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+dnl We do special magic for INSTALL instead of AC_SUBST, to get
+dnl relative paths right.
+AC_MSG_RESULT($INSTALL)
+AC_SUBST(INSTALL)dnl
+
+# 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}'
+AC_SUBST(INSTALL_PROGRAM)dnl
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+AC_SUBST(INSTALL_DATA)dnl
+])
+
+#serial 1
+dnl This test replaces the one in autoconf.
+dnl Currently this macro should have the same name as the autoconf macro
+dnl because gettext's gettext.m4 (distributed in the automake package)
+dnl still uses it. Otherwise, the use in gettext.m4 makes autoheader
+dnl give these diagnostics:
+dnl configure.in:556: AC_TRY_COMPILE was called before AC_ISC_POSIX
+dnl configure.in:556: AC_TRY_RUN was called before AC_ISC_POSIX
+
+undefine([AC_ISC_POSIX])
+AC_DEFUN(AC_ISC_POSIX,
+ [
+ dnl This test replaces the obsolescent AC_ISC_POSIX kludge.
+ AC_CHECK_LIB(cposix, strerror, [LIBS="$LIBS -lcposix"])
+ ]
+)
+
+
+dnl GCC_PATH_PROG(VARIABLE, PROG-TO-CHECK-FOR [, VALUE-IF-NOT-FOUND [, PATH]])
+dnl like AC_PATH_PROG but use other cache variables
+AC_DEFUN(GCC_PATH_PROG,
+[# Extract the first word of "$2", so it can be a program name with args.
+set dummy $2; ac_word=[$]2
+AC_MSG_CHECKING([for $ac_word])
+AC_CACHE_VAL(gcc_cv_path_$1,
+[case "[$]$1" in
+ /*)
+ gcc_cv_path_$1="[$]$1" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ gcc_cv_path_$1="[$]$1" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word. This closes a longstanding sh security hole.
+ ac_dummy="ifelse([$4], , $PATH, [$4])"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ gcc_cv_path_$1="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+dnl If no 3rd arg is given, leave the cache variable unset,
+dnl so GCC_PATH_PROGS will keep looking.
+ifelse([$3], , , [ test -z "[$]gcc_cv_path_$1" && gcc_cv_path_$1="$3"
+])dnl
+ ;;
+esac])dnl
+$1="$gcc_cv_path_$1"
+if test -n "[$]$1"; then
+ AC_MSG_RESULT([$]$1)
+else
+ AC_MSG_RESULT(no)
+fi
+AC_SUBST($1)dnl
+])
+
+
+
+dnl GCC_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
+dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
+AC_DEFUN(GCC_PATH_PROG_WITH_TEST,
+[# Extract the first word of "$2", so it can be a program name with args.
+set dummy $2; ac_word=[$]2
+AC_MSG_CHECKING([for $ac_word])
+AC_CACHE_VAL(gcc_cv_path_$1,
+[case "[$]$1" in
+ /*)
+ gcc_cv_path_$1="[$]$1" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in ifelse([$5], , $PATH, [$5]); do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if [$3]; then
+ gcc_cv_path_$1="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+dnl If no 4th arg is given, leave the cache variable unset,
+dnl so GCC_PATH_PROGS will keep looking.
+ifelse([$4], , , [ test -z "[$]gcc_cv_path_$1" && gcc_cv_path_$1="$4"
+])dnl
+ ;;
+esac])dnl
+$1="$gcc_cv_path_$1"
+if test -n "[$]$1"; then
+ AC_MSG_RESULT([$]$1)
+else
+ AC_MSG_RESULT(no)
+fi
+AC_SUBST($1)dnl
+])
+
+# Check whether mmap can map an arbitrary page from /dev/zero or with
+# MAP_ANONYMOUS, without MAP_FIXED.
+AC_DEFUN([AC_FUNC_MMAP_ANYWHERE],
+[AC_CHECK_FUNCS(getpagesize)
+# The test program for the next two tests is the same except for one
+# set of ifdefs.
+changequote({{{,}}})dnl
+{{{cat >ct-mmap.inc <<'EOF'
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <setjmp.h>
+#include <stdio.h>
+
+#if !defined (MAP_ANONYMOUS) && defined (MAP_ANON)
+# define MAP_ANONYMOUS MAP_ANON
+#endif
+
+/* This mess was copied from the GNU getpagesize.h. */
+#ifndef HAVE_GETPAGESIZE
+# ifdef HAVE_UNISTD_H
+# include <unistd.h>
+# endif
+
+/* Assume that all systems that can run configure have sys/param.h. */
+# ifndef HAVE_SYS_PARAM_H
+# define HAVE_SYS_PARAM_H 1
+# endif
+
+# ifdef _SC_PAGESIZE
+# define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+# ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+# ifdef EXEC_PAGESIZE
+# define getpagesize() EXEC_PAGESIZE
+# else /* no EXEC_PAGESIZE */
+# ifdef NBPG
+# define getpagesize() NBPG * CLSIZE
+# ifndef CLSIZE
+# define CLSIZE 1
+# endif /* no CLSIZE */
+# else /* no NBPG */
+# ifdef NBPC
+# define getpagesize() NBPC
+# else /* no NBPC */
+# ifdef PAGESIZE
+# define getpagesize() PAGESIZE
+# endif /* PAGESIZE */
+# endif /* no NBPC */
+# endif /* no NBPG */
+# endif /* no EXEC_PAGESIZE */
+# else /* no HAVE_SYS_PARAM_H */
+# define getpagesize() 8192 /* punt totally */
+# endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
+
+#ifndef MAP_FAILED
+# define MAP_FAILED -1
+#endif
+
+#undef perror_exit
+#define perror_exit(str, val) \
+ do { perror(str); exit(val); } while (0)
+
+/* Some versions of cygwin mmap require that munmap is called with the
+ same parameters as mmap. GCC expects that this is not the case.
+ Test for various forms of this problem. Warning - icky signal games. */
+
+static sigset_t unblock_sigsegv;
+static jmp_buf r;
+static size_t pg;
+static int devzero;
+
+static char *
+anonmap (size)
+ size_t size;
+{
+#ifdef USE_MAP_ANON
+ return (char *) mmap (0, size, PROT_READ|PROT_WRITE,
+ MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+#else
+ return (char *) mmap (0, size, PROT_READ|PROT_WRITE,
+ MAP_PRIVATE, devzero, 0);
+#endif
+}
+
+static void
+sigsegv (unused)
+ int unused;
+{
+ sigprocmask (SIG_UNBLOCK, &unblock_sigsegv, 0);
+ longjmp (r, 1);
+}
+
+/* Basic functionality test. */
+void
+test_0 ()
+{
+ char *x = anonmap (pg);
+ if (x == (char *) MAP_FAILED)
+ perror_exit("test 0 mmap", 2);
+
+ *(int *)x += 1;
+
+ if (munmap(x, pg) < 0)
+ perror_exit("test 0 munmap", 3);
+}
+
+/* 1. If we map a 2-page region and unmap its second page, the first page
+ must remain. */
+static void
+test_1 ()
+{
+ char *x = anonmap (pg * 2);
+ if (x == (char *)MAP_FAILED)
+ perror_exit ("test 1 mmap", 4);
+
+ signal (SIGSEGV, sigsegv);
+ if (setjmp (r))
+ perror_exit ("test 1 fault", 5);
+
+ x[0] = 1;
+ x[pg] = 1;
+
+ if (munmap (x + pg, pg) < 0)
+ perror_exit ("test 1 munmap 1", 6);
+ x[0] = 2;
+
+ if (setjmp (r) == 0)
+ {
+ x[pg] = 1;
+ perror_exit ("test 1 no fault", 7);
+ }
+ if (munmap (x, pg) < 0)
+ perror_exit ("test 1 munmap 2", 8);
+}
+
+/* 2. If we map a 2-page region and unmap its first page, the second
+ page must remain. */
+static void
+test_2 ()
+{
+ char *x = anonmap (pg * 2);
+ if (x == (char *)MAP_FAILED)
+ perror_exit ("test 2 mmap", 9);
+
+ signal (SIGSEGV, sigsegv);
+ if (setjmp (r))
+ perror_exit ("test 2 fault", 10);
+
+ x[0] = 1;
+ x[pg] = 1;
+
+ if (munmap (x, pg) < 0)
+ perror_exit ("test 2 munmap 1", 11);
+
+ x[pg] = 2;
+
+ if (setjmp (r) == 0)
+ {
+ x[0] = 1;
+ perror_exit ("test 2 no fault", 12);
+ }
+
+ if (munmap (x+pg, pg) < 0)
+ perror_exit ("test 2 munmap 2", 13);
+}
+
+/* 3. If we map two adjacent 1-page regions and unmap them both with
+ one munmap, both must go away.
+
+ Getting two adjacent 1-page regions with two mmap calls is slightly
+ tricky. All OS's tested skip over already-allocated blocks; therefore
+ we have been careful to unmap all allocated regions in previous tests.
+ HP/UX allocates pages backward in memory. No OS has yet been observed
+ to be so perverse as to leave unmapped space between consecutive calls
+ to mmap. */
+
+static void
+test_3 ()
+{
+ char *x, *y, *z;
+
+ x = anonmap (pg);
+ if (x == (char *)MAP_FAILED)
+ perror_exit ("test 3 mmap 1", 14);
+ y = anonmap (pg);
+ if (y == (char *)MAP_FAILED)
+ perror_exit ("test 3 mmap 2", 15);
+
+ if (y != x + pg)
+ {
+ if (y == x - pg)
+ z = y, y = x, x = z;
+ else
+ {
+ fprintf (stderr, "test 3 nonconsecutive pages - %lx, %lx\n",
+ (unsigned long)x, (unsigned long)y);
+ exit (16);
+ }
+ }
+
+ signal (SIGSEGV, sigsegv);
+ if (setjmp (r))
+ perror_exit ("test 3 fault", 17);
+
+ x[0] = 1;
+ y[0] = 1;
+
+ if (munmap (x, pg*2) < 0)
+ perror_exit ("test 3 munmap", 18);
+
+ if (setjmp (r) == 0)
+ {
+ x[0] = 1;
+ perror_exit ("test 3 no fault 1", 19);
+ }
+
+ signal (SIGSEGV, sigsegv);
+ if (setjmp (r) == 0)
+ {
+ y[0] = 1;
+ perror_exit ("test 3 no fault 2", 20);
+ }
+}
+
+int
+main ()
+{
+ sigemptyset (&unblock_sigsegv);
+ sigaddset (&unblock_sigsegv, SIGSEGV);
+ pg = getpagesize ();
+#ifndef USE_MAP_ANON
+ devzero = open ("/dev/zero", O_RDWR);
+ if (devzero < 0)
+ perror_exit ("open /dev/zero", 1);
+#endif
+
+ test_0();
+ test_1();
+ test_2();
+ test_3();
+
+ exit(0);
+}
+EOF}}}
+changequote([,])dnl
+
+AC_CACHE_CHECK(for working mmap from /dev/zero,
+ ac_cv_func_mmap_dev_zero,
+[AC_TRY_RUN(
+ [#include "ct-mmap.inc"],
+ ac_cv_func_mmap_dev_zero=yes,
+ [if test $? -lt 4
+ then ac_cv_func_mmap_dev_zero=no
+ else ac_cv_func_mmap_dev_zero=buggy
+ fi],
+ # If this is not cygwin, and /dev/zero is a character device, it's probably
+ # safe to assume it works.
+ [case "$host_os" in
+ cygwin* | win32 | pe | mingw* ) ac_cv_func_mmap_dev_zero=buggy ;;
+ * ) if test -c /dev/zero
+ then ac_cv_func_mmap_dev_zero=yes
+ else ac_cv_func_mmap_dev_zero=no
+ fi ;;
+ esac])
+])
+if test $ac_cv_func_mmap_dev_zero = yes; then
+ AC_DEFINE(HAVE_MMAP_DEV_ZERO, 1,
+ [Define if mmap can get us zeroed pages from /dev/zero.])
+fi
+
+AC_CACHE_CHECK([for working mmap with MAP_ANON(YMOUS)],
+ ac_cv_func_mmap_anon,
+[AC_TRY_RUN(
+ [#define USE_MAP_ANON
+#include "ct-mmap.inc"],
+ ac_cv_func_mmap_anon=yes,
+ [if test $? -lt 4
+ then ac_cv_func_mmap_anon=no
+ else ac_cv_func_mmap_anon=buggy
+ fi],
+ # Unlike /dev/zero, it is not safe to assume MAP_ANON(YMOUS) works
+ # just because it's there. Some SCO Un*xen define it but don't implement it.
+ ac_cv_func_mmap_anon=no)
+])
+if test $ac_cv_func_mmap_anon = yes; then
+ AC_DEFINE(HAVE_MMAP_ANON, 1,
+ [Define if mmap can get us zeroed pages using MAP_ANON(YMOUS).])
+fi
+rm -f ct-mmap.inc
+])
+
+# Check whether mmap can map a plain file, without MAP_FIXED.
+AC_DEFUN([AC_FUNC_MMAP_FILE],
+[AC_CACHE_CHECK(for working mmap of a file, ac_cv_func_mmap_file,
+[# Create a file one thousand bytes long.
+for i in 1 2 3 4 5 6 7 8 9 0
+do for j in 1 2 3 4 5 6 7 8 9 0
+do echo $i $j xxxxx
+done
+done > conftestdata$$
+
+AC_TRY_RUN([
+/* Test by Zack Weinberg. Modified from MMAP_ANYWHERE test by
+ Richard Henderson and Alexandre Oliva.
+ Check whether read-only mmap of a plain file works. */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+int main()
+{
+ char *x;
+ int fd;
+ struct stat st;
+
+ fd = open("conftestdata$$", O_RDONLY);
+ if (fd < 0)
+ exit(1);
+
+ if (fstat (fd, &st))
+ exit(2);
+
+ x = (char*)mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (x == (char *) -1)
+ exit(3);
+
+ if (x[0] != '1' || x[1] != ' ' || x[2] != '1' || x[3] != ' ')
+ exit(4);
+
+ if (munmap(x, st.st_size) < 0)
+ exit(5);
+
+ exit(0);
+}], ac_cv_func_mmap_file=yes, ac_cv_func_mmap_file=no,
+ac_cv_func_mmap_file=no)])
+if test $ac_cv_func_mmap_file = yes; then
+ AC_DEFINE(HAVE_MMAP_FILE, 1,
+ [Define if read-only mmap of a plain file works.])
+fi
+])
+
+dnl Locate a program and check that its version is acceptable.
+dnl AC_PROG_CHECK_VER(var, name, version-switch,
+dnl version-extract-regexp, version-glob)
+AC_DEFUN(gcc_AC_CHECK_PROG_VER,
+[AC_CHECK_PROG([$1], [$2], [$2])
+if test -n "[$]$1"; then
+ # Found it, now check the version.
+ AC_CACHE_CHECK(for modern $2, gcc_cv_prog_$2_modern,
+[changequote(<<,>>)dnl
+ ac_prog_version=`<<$>>$1 $3 2>&1 |
+ sed -n 's/^.*patsubst(<<$4>>,/,\/).*$/\1/p'`
+changequote([,])dnl
+ echo "configure:__oline__: version of $2 is $ac_prog_version" >&AC_FD_CC
+changequote(<<,>>)dnl
+ case $ac_prog_version in
+ '') gcc_cv_prog_$2_modern=no;;
+ <<$5>>)
+ gcc_cv_prog_$2_modern=yes;;
+ *) gcc_cv_prog_$2_modern=no;;
+ esac
+changequote([,])dnl
+])
+else
+ gcc_cv_prog_$2_modern=no
+fi
+])
+
+dnl Determine if enumerated bitfields are unsigned. ISO C says they can
+dnl be either signed or unsigned.
+dnl
+AC_DEFUN(gcc_AC_C_ENUM_BF_UNSIGNED,
+[AC_CACHE_CHECK(for unsigned enumerated bitfields, gcc_cv_enum_bf_unsigned,
+[AC_TRY_RUN(#include <stdlib.h>
+enum t { BLAH = 128 } ;
+struct s_t { enum t member : 8; } s ;
+int main(void)
+{
+ s.member = BLAH;
+ if (s.member < 0) exit(1);
+ exit(0);
+
+}, gcc_cv_enum_bf_unsigned=yes, gcc_cv_enum_bf_unsigned=no, gcc_cv_enum_bf_unsigned=yes)])
+if test $gcc_cv_enum_bf_unsigned = yes; then
+ AC_DEFINE(ENUM_BITFIELDS_ARE_UNSIGNED, 1,
+ [Define if enumerated bitfields are treated as unsigned values.])
+fi])
+
+dnl Host type sizes probe.
+dnl By Kaveh R. Ghazi. One typo fixed since.
+dnl
+AC_DEFUN([gcc_AC_COMPILE_CHECK_SIZEOF],
+[changequote(<<, >>)dnl
+dnl The name to #define.
+define(<<AC_TYPE_NAME>>, translit(sizeof_$1, [a-z *], [A-Z_P]))dnl
+dnl The cache variable name.
+define(<<AC_CV_NAME>>, translit(ac_cv_sizeof_$1, [ *], [_p]))dnl
+changequote([, ])dnl
+AC_MSG_CHECKING(size of $1)
+AC_CACHE_VAL(AC_CV_NAME,
+[for ac_size in 4 8 1 2 16 $3 ; do # List sizes in rough order of prevalence.
+ AC_TRY_COMPILE([#include "confdefs.h"
+#include <sys/types.h>
+$2
+], [switch (0) case 0: case (sizeof ($1) == $ac_size):;], AC_CV_NAME=$ac_size)
+ if test x$AC_CV_NAME != x ; then break; fi
+done
+])
+if test x$AC_CV_NAME = x ; then
+ AC_MSG_ERROR([cannot determine a size for $1])
+fi
+AC_MSG_RESULT($AC_CV_NAME)
+AC_DEFINE_UNQUOTED(AC_TYPE_NAME, $AC_CV_NAME, [The number of bytes in type $1])
+undefine([AC_TYPE_NAME])dnl
+undefine([AC_CV_NAME])dnl
+])
+
+dnl Probe number of bits in a byte.
+dnl Note C89 requires CHAR_BIT >= 8.
+dnl
+AC_DEFUN(gcc_AC_C_CHAR_BIT,
+[AC_CACHE_CHECK(for CHAR_BIT, gcc_cv_decl_char_bit,
+[AC_EGREP_CPP(found,
+[#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef CHAR_BIT
+found
+#endif], gcc_cv_decl_char_bit=yes, gcc_cv_decl_char_bit=no)
+])
+if test $gcc_cv_decl_char_bit = no; then
+ AC_CACHE_CHECK(number of bits in a byte, gcc_cv_c_nbby,
+[i=8
+ gcc_cv_c_nbby=
+ while test $i -lt 65; do
+ AC_TRY_COMPILE(,
+ [switch(0) {
+ case (unsigned char)((unsigned long)1 << $i) == ((unsigned long)1 << $i):
+ case (unsigned char)((unsigned long)1<<($i-1)) == ((unsigned long)1<<($i-1)):
+ ; }],
+ [gcc_cv_c_nbby=$i; break])
+ i=`expr $i + 1`
+ done
+ test -z "$gcc_cv_c_nbby" && gcc_cv_c_nbby=failed
+])
+if test $gcc_cv_c_nbby = failed; then
+ AC_MSG_ERROR(cannot determine number of bits in a byte)
+else
+ AC_DEFINE_UNQUOTED(CHAR_BIT, $gcc_cv_c_nbby,
+ [Define as the number of bits in a byte, if \`limits.h' doesn't.])
+fi
+fi])
+
+dnl Host character set probe.
+dnl The EBCDIC values match the table in config/i370/i370.c;
+dnl there are other versions of EBCDIC but GCC won't work with them.
+dnl
+AC_DEFUN([gcc_AC_C_CHARSET],
+[AC_CACHE_CHECK(execution character set, ac_cv_c_charset,
+ [AC_EGREP_CPP(ASCII,
+[#if '\n' == 0x0A && ' ' == 0x20 && '0' == 0x30 \
+ && 'A' == 0x41 && 'a' == 0x61 && '!' == 0x21
+ASCII
+#endif], ac_cv_c_charset=ASCII)
+ if test x${ac_cv_c_charset+set} != xset; then
+ AC_EGREP_CPP(EBCDIC,
+[#if '\n' == 0x15 && ' ' == 0x40 && '0' == 0xF0 \
+ && 'A' == 0xC1 && 'a' == 0x81 && '!' == 0x5A
+EBCDIC
+#endif], ac_cv_c_charset=EBCDIC)
+ fi
+ if test x${ac_cv_c_charset+set} != xset; then
+ ac_cv_c_charset=unknown
+ fi])
+if test $ac_cv_c_charset = unknown; then
+ AC_MSG_ERROR([*** Cannot determine host character set.])
+elif test $ac_cv_c_charset = EBCDIC; then
+ AC_DEFINE(HOST_EBCDIC, 1,
+ [Define if the host execution character set is EBCDIC.])
+fi])
+
+dnl Utility macro used by next two tests.
+dnl AC_EXAMINE_OBJECT(C source code,
+dnl commands examining object file,
+dnl [commands to run if compile failed]):
+dnl
+dnl Compile the source code to an object file; then convert it into a
+dnl printable representation. All unprintable characters and
+dnl asterisks (*) are replaced by dots (.). All white space is
+dnl deleted. Newlines (ASCII 0x10) in the input are preserved in the
+dnl output, but runs of newlines are compressed to a single newline.
+dnl Finally, line breaks are forcibly inserted so that no line is
+dnl longer than 80 columns and the file ends with a newline. The
+dnl result of all this processing is in the file conftest.dmp, which
+dnl may be examined by the commands in the second argument.
+dnl
+AC_DEFUN([gcc_AC_EXAMINE_OBJECT],
+[AC_LANG_SAVE
+AC_LANG_C
+dnl Next bit cribbed from AC_TRY_COMPILE.
+cat > conftest.$ac_ext <<EOF
+[#line __oline__ "configure"
+#include "confdefs.h"
+$1
+]EOF
+if AC_TRY_EVAL(ac_compile); then
+ od -c conftest.o |
+ sed ['s/^[0-7]*[ ]*/ /
+ s/\*/./g
+ s/ \\n/*/g
+ s/ [0-9][0-9][0-9]/./g
+ s/ \\[^ ]/./g'] |
+ tr -d '
+ ' | tr -s '*' '
+' | fold | sed '$a\
+' > conftest.dmp
+ $2
+ifelse($3, , , else
+ $3
+)dnl
+fi
+rm -rf conftest*
+AC_LANG_RESTORE])
+
+dnl Host endianness probe.
+dnl This tests byte-within-word endianness. GCC actually needs
+dnl to know word-within-larger-object endianness. They are the
+dnl same on all presently supported hosts.
+dnl Differs from AC_C_BIGENDIAN in that it does not require
+dnl running a program on the host, and it defines the macro we
+dnl want to see.
+dnl
+AC_DEFUN([gcc_AC_C_COMPILE_ENDIAN],
+[AC_CACHE_CHECK(byte ordering, ac_cv_c_compile_endian,
+[ac_cv_c_compile_endian=unknown
+gcc_AC_EXAMINE_OBJECT([
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif
+/* This structure must have no internal padding. */
+ struct {
+ char prefix[sizeof "\nendian:" - 1];
+ short word;
+ char postfix[2];
+ } tester = {
+ "\nendian:",
+#if SIZEOF_SHORT == 4
+ ('A' << (CHAR_BIT * 3)) | ('B' << (CHAR_BIT * 2)) |
+#endif
+ ('A' << CHAR_BIT) | 'B',
+ 'X', '\n'
+};],
+ [if grep 'endian:AB' conftest.dmp >/dev/null 2>&1; then
+ ac_cv_c_compile_endian=big-endian
+ elif grep 'endian:BA' conftest.dmp >/dev/null 2>&1; then
+ ac_cv_c_compile_endian=little-endian
+ fi])
+])
+if test $ac_cv_c_compile_endian = unknown; then
+ AC_MSG_ERROR([*** unable to determine endianness])
+elif test $ac_cv_c_compile_endian = big-endian; then
+ AC_DEFINE(HOST_WORDS_BIG_ENDIAN, 1,
+ [Define if the host machine stores words of multi-word integers in
+ big-endian order.])
+fi
+])
+
--- /dev/null
+/* ANSI and traditional C compatability macros
+ Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* ANSI and traditional C compatibility macros
+
+ ANSI C is assumed if __STDC__ is #defined.
+
+ Macro ANSI C definition Traditional C definition
+ ----- ---- - ---------- ----------- - ----------
+ PTR `void *' `char *'
+ LONG_DOUBLE `long double' `double'
+ VOLATILE `volatile' `'
+ SIGNED `signed' `'
+ PTRCONST `void *const' `char *'
+ ANSI_PROTOTYPES 1 not defined
+
+ CONST is also defined, but is obsolete. Just use const.
+
+ obsolete -- DEFUN (name, arglist, args)
+
+ Defines function NAME.
+
+ ARGLIST lists the arguments, separated by commas and enclosed in
+ parentheses. ARGLIST becomes the argument list in traditional C.
+
+ ARGS list the arguments with their types. It becomes a prototype in
+ ANSI C, and the type declarations in traditional C. Arguments should
+ be separated with `AND'. For functions with a variable number of
+ arguments, the last thing listed should be `DOTS'.
+
+ obsolete -- DEFUN_VOID (name)
+
+ Defines a function NAME, which takes no arguments.
+
+ obsolete -- EXFUN (name, (prototype)) -- obsolete.
+
+ Replaced by PARAMS. Do not use; will disappear someday soon.
+ Was used in external function declarations.
+ In ANSI C it is `NAME PROTOTYPE' (so PROTOTYPE should be enclosed in
+ parentheses). In traditional C it is `NAME()'.
+ For a function that takes no arguments, PROTOTYPE should be `(void)'.
+
+ obsolete -- PROTO (type, name, (prototype) -- obsolete.
+
+ This one has also been replaced by PARAMS. Do not use.
+
+ PARAMS ((args))
+
+ We could use the EXFUN macro to handle prototype declarations, but
+ the name is misleading and the result is ugly. So we just define a
+ simple macro to handle the parameter lists, as in:
+
+ static int foo PARAMS ((int, char));
+
+ This produces: `static int foo();' or `static int foo (int, char);'
+
+ EXFUN would have done it like this:
+
+ static int EXFUN (foo, (int, char));
+
+ but the function is not external...and it's hard to visually parse
+ the function name out of the mess. EXFUN should be considered
+ obsolete; new code should be written to use PARAMS.
+
+ DOTS is also obsolete.
+
+ Examples:
+
+ extern int printf PARAMS ((const char *format, ...));
+*/
+
+#ifndef _ANSIDECL_H
+
+#define _ANSIDECL_H 1
+
+
+/* Every source file includes this file,
+ so they will all get the switch for lint. */
+/* LINTLIBRARY */
+
+
+#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(_WIN32)
+/* All known AIX compilers implement these things (but don't always
+ define __STDC__). The RISC/OS MIPS compiler defines these things
+ in SVR4 mode, but does not define __STDC__. */
+
+#define PTR void *
+#define PTRCONST void *CONST
+#define LONG_DOUBLE long double
+
+#ifndef IN_GCC
+#define AND ,
+#define NOARGS void
+#define VOLATILE volatile
+#define SIGNED signed
+#endif /* ! IN_GCC */
+
+#define PARAMS(paramlist) paramlist
+#define ANSI_PROTOTYPES 1
+
+#define VPARAMS(ARGS) ARGS
+#define VA_START(va_list,var) va_start(va_list,var)
+
+/* These are obsolete. Do not use. */
+#ifndef IN_GCC
+#define CONST const
+#define DOTS , ...
+#define PROTO(type, name, arglist) type name arglist
+#define EXFUN(name, proto) name proto
+#define DEFUN(name, arglist, args) name(args)
+#define DEFUN_VOID(name) name(void)
+#endif /* ! IN_GCC */
+
+#else /* Not ANSI C. */
+
+#define PTR char *
+#define PTRCONST PTR
+#define LONG_DOUBLE double
+
+#ifndef IN_GCC
+#define AND ;
+#define NOARGS
+#define VOLATILE
+#define SIGNED
+#endif /* !IN_GCC */
+
+#ifndef const /* some systems define it in header files for non-ansi mode */
+#define const
+#endif
+
+#define PARAMS(paramlist) ()
+
+#define VPARAMS(ARGS) (va_alist) va_dcl
+#define VA_START(va_list,var) va_start(va_list)
+
+/* These are obsolete. Do not use. */
+#ifndef IN_GCC
+#define CONST
+#define DOTS
+#define PROTO(type, name, arglist) type name ()
+#define EXFUN(name, proto) name()
+#define DEFUN(name, arglist, args) name arglist args;
+#define DEFUN_VOID(name) name()
+#endif /* ! IN_GCC */
+
+#endif /* ANSI C. */
+
+/* Using MACRO(x,y) in cpp #if conditionals does not work with some
+ older preprocessors. Thus we can't define something like this:
+
+#define HAVE_GCC_VERSION(MAJOR, MINOR) \
+ (__GNUC__ > (MAJOR) || (__GNUC__ == (MAJOR) && __GNUC_MINOR__ >= (MINOR)))
+
+and then test "#if HAVE_GCC_VERSION(2,7)".
+
+So instead we use the macro below and test it against specific values. */
+
+/* This macro simplifies testing whether we are using gcc, and if it
+ is of a particular minimum version. (Both major & minor numbers are
+ significant.) This macro will evaluate to 0 if we are not using
+ gcc at all. */
+#ifndef GCC_VERSION
+#define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
+#endif /* GCC_VERSION */
+
+/* Define macros for some gcc attributes. This permits us to use the
+ macros freely, and know that they will come into play for the
+ version of gcc in which they are supported. */
+
+#if (GCC_VERSION < 2007)
+# define __attribute__(x)
+#endif
+
+/* Attribute __malloc__ on functions was valid as of gcc 2.96. */
+#ifndef ATTRIBUTE_MALLOC
+# if (GCC_VERSION >= 2096)
+# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
+# else
+# define ATTRIBUTE_MALLOC
+# endif /* GNUC >= 2.96 */
+#endif /* ATTRIBUTE_MALLOC */
+
+/* Attributes on labels were valid as of gcc 2.93. */
+#ifndef ATTRIBUTE_UNUSED_LABEL
+# if (GCC_VERSION >= 2093)
+# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED
+# else
+# define ATTRIBUTE_UNUSED_LABEL
+# endif /* GNUC >= 2.93 */
+#endif /* ATTRIBUTE_UNUSED_LABEL */
+
+#ifndef ATTRIBUTE_UNUSED
+#define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
+#endif /* ATTRIBUTE_UNUSED */
+
+#ifndef ATTRIBUTE_NORETURN
+#define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
+#endif /* ATTRIBUTE_NORETURN */
+
+#ifndef ATTRIBUTE_PRINTF
+#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n)))
+#define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2)
+#define ATTRIBUTE_PRINTF_2 ATTRIBUTE_PRINTF(2, 3)
+#define ATTRIBUTE_PRINTF_3 ATTRIBUTE_PRINTF(3, 4)
+#define ATTRIBUTE_PRINTF_4 ATTRIBUTE_PRINTF(4, 5)
+#define ATTRIBUTE_PRINTF_5 ATTRIBUTE_PRINTF(5, 6)
+#endif /* ATTRIBUTE_PRINTF */
+
+/* We use __extension__ in some places to suppress -pedantic warnings
+ about GCC extensions. This feature didn't work properly before
+ gcc 2.8. */
+#if GCC_VERSION < 2008
+#define __extension__
+#endif
+
+/* Bootstrap support: Autoconf will possibly define the `inline' or
+ `const' keywords as macros, however this is only valid for the
+ stage1 compiler. If we detect a modern version of gcc,
+ unconditionally reset the values. This makes sure the right thing
+ happens in stage2 and later. We need to do this very early;
+ i.e. before any header files that might use these keywords.
+ Otherwise conflicts might occur. */
+
+#if (GCC_VERSION >= 2007)
+# ifdef __STDC__
+# undef const
+# endif
+# undef inline
+# define inline __inline__ /* __inline__ prevents -pedantic warnings */
+# ifndef HAVE_LONG_DOUBLE
+# define HAVE_LONG_DOUBLE 1
+# endif
+#endif /* GCC >= 2.7 */
+
+#endif /* ansidecl.h */
--- /dev/null
+#include "auto-host.h"
+#include "sdcc.h"
--- /dev/null
+/* config.in. Generated automatically from configure.in by autoheader. */
+
+/* Define to empty if the keyword does not work. */
+#undef const
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef gid_t
+
+/* Define if you have the ANSI # stringizing operator in cpp. */
+#undef HAVE_STRINGIZE
+
+/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define if you have <vfork.h>. */
+#undef HAVE_VFORK_H
+
+/* Define as __inline if that's what the C compiler calls it. */
+#undef inline
+
+/* Define if your C compiler doesn't accept -c and -o together. */
+#undef NO_MINUS_C_MINUS_O
+
+/* Define to `long' if <sys/types.h> doesn't define. */
+#undef off_t
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef pid_t
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+#undef size_t
+
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef uid_t
+
+/* Define vfork as fork if vfork does not work. */
+#undef vfork
+
+/* Define as 1 if you have the stpcpy function. */
+#undef HAVE_STPCPY
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef ssize_t
+
+/* Define if you have the atoll function. */
+#undef HAVE_ATOLL
+
+/* Define if you have the atoq function. */
+#undef HAVE_ATOQ
+
+/* Define if you have the clock function. */
+#undef HAVE_CLOCK
+
+/* Define if you have the dcgettext function. */
+#undef HAVE_DCGETTEXT
+
+/* Define if you have the getpagesize function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define if you have the getrlimit function. */
+#undef HAVE_GETRLIMIT
+
+/* Define if you have the getrusage function. */
+#undef HAVE_GETRUSAGE
+
+/* Define if you have the kill function. */
+#undef HAVE_KILL
+
+/* Define if you have the lstat function. */
+#undef HAVE_LSTAT
+
+/* Define if you have the munmap function. */
+#undef HAVE_MUNMAP
+
+/* Define if you have the nl_langinfo function. */
+#undef HAVE_NL_LANGINFO
+
+/* Define if you have the putenv function. */
+#undef HAVE_PUTENV
+
+/* Define if you have the setenv function. */
+#undef HAVE_SETENV
+
+/* Define if you have the setlocale function. */
+#undef HAVE_SETLOCALE
+
+/* Define if you have the setrlimit function. */
+#undef HAVE_SETRLIMIT
+
+/* Define if you have the stpcpy function. */
+#undef HAVE_STPCPY
+
+/* Define if you have the strcasecmp function. */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the strchr function. */
+#undef HAVE_STRCHR
+
+/* Define if you have the strdup function. */
+#undef HAVE_STRDUP
+
+/* Define if you have the strrchr function. */
+#undef HAVE_STRRCHR
+
+/* Define if you have the strstr function. */
+#undef HAVE_STRSTR
+
+/* Define if you have the times function. */
+#undef HAVE_TIMES
+
+/* Define if you have the <argz.h> header file. */
+#undef HAVE_ARGZ_H
+
+/* Define if you have the <direct.h> header file. */
+#undef HAVE_DIRECT_H
+
+/* Define if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define if you have the <iconv.h> header file. */
+#undef HAVE_ICONV_H
+
+/* Define if you have the <langinfo.h> header file. */
+#undef HAVE_LANGINFO_H
+
+/* Define if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define if you have the <locale.h> header file. */
+#undef HAVE_LOCALE_H
+
+/* Define if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
+/* Define if you have the <nl_types.h> header file. */
+#undef HAVE_NL_TYPES_H
+
+/* Define if you have the <stddef.h> header file. */
+#undef HAVE_STDDEF_H
+
+/* Define if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define if you have the <sys/file.h> header file. */
+#undef HAVE_SYS_FILE_H
+
+/* Define if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define if you have the <sys/resource.h> header file. */
+#undef HAVE_SYS_RESOURCE_H
+
+/* Define if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define if you have the <sys/times.h> header file. */
+#undef HAVE_SYS_TIMES_H
+
+/* Define if you have the <time.h> header file. */
+#undef HAVE_TIME_H
+
+/* Define if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define if you have the i library (-li). */
+#undef HAVE_LIBI
+
+/* Define to enable the use of a default linker. */
+#undef DEFAULT_LINKER
+
+/* Define to enable the use of a default assembler. */
+#undef DEFAULT_ASSEMBLER
+
+/* Define if you want more run-time sanity checks. This one gets a grab
+ bag of miscellaneous but relatively cheap checks. */
+#undef ENABLE_CHECKING
+
+/* Define if you want all operations on trees (the basic data
+ structure of the front ends) to be checked for dynamic type safety
+ at runtime. This is moderately expensive. */
+#undef ENABLE_TREE_CHECKING
+
+/* Define if you want all operations on RTL (the basic data structure
+ of the optimizer and back end) to be checked for dynamic type safety
+ at runtime. This is quite expensive. */
+#undef ENABLE_RTL_CHECKING
+
+/* Define if you want the garbage collector to do object poisoning and
+ other memory allocation checks. This is quite expensive. */
+#undef ENABLE_GC_CHECKING
+
+/* Define if you want the garbage collector to operate in maximally
+ paranoid mode, validating the entire heap and collecting garbage at
+ every opportunity. This is extremely expensive. */
+#undef ENABLE_GC_ALWAYS_COLLECT
+
+/* Define if you want the C and C++ compilers to support multibyte
+ character sets for source code. */
+#undef MULTIBYTE_CHARS
+
+/* Define if your compiler understands volatile. */
+#undef HAVE_VOLATILE
+
+/* Define if your compiler supports the `long double' type. */
+#undef HAVE_LONG_DOUBLE
+
+/* The number of bytes in type short */
+#undef SIZEOF_SHORT
+
+/* The number of bytes in type int */
+#undef SIZEOF_INT
+
+/* The number of bytes in type long */
+#undef SIZEOF_LONG
+
+/* Define if the host execution character set is EBCDIC. */
+#undef HOST_EBCDIC
+
+/* Always define this when using the GNU C Library */
+#undef _GNU_SOURCE
+
+/* Define if you have a working <stdbool.h> header file. */
+#undef HAVE_STDBOOL_H
+
+/* Define if you can safely include both <string.h> and <strings.h>. */
+#undef STRING_WITH_STRINGS
+
+/* Define as the number of bits in a byte, if `limits.h' doesn't. */
+#undef CHAR_BIT
+
+/* Define if the host machine stores words of multi-word integers in
+ big-endian order. */
+#undef HOST_WORDS_BIG_ENDIAN
+
+/* Define to the floating point format of the host machine, if not IEEE. */
+#undef HOST_FLOAT_FORMAT
+
+/* Define to 1 if the host machine stores floating point numbers in
+ memory with the word containing the sign bit at the lowest address,
+ or to 0 if it does it the other way around.
+
+ This macro should not be defined if the ordering is the same as for
+ multi-word integers. */
+#undef HOST_FLOAT_WORDS_BIG_ENDIAN
+
+/* Define if you have a working <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define if printf supports %p. */
+#undef HAVE_PRINTF_PTR
+
+/* Define if mmap can get us zeroed pages from /dev/zero. */
+#undef HAVE_MMAP_DEV_ZERO
+
+/* Define if mmap can get us zeroed pages using MAP_ANON(YMOUS). */
+#undef HAVE_MMAP_ANON
+
+/* Define if read-only mmap of a plain file works. */
+#undef HAVE_MMAP_FILE
+
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_GETENV
+
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_ABORT
+
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_ERRNO
+
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_MALLOC
+
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_REALLOC
+
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_CALLOC
+
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_FREE
+
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_BASENAME
+
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_GETOPT
+
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_CLOCK
+
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_GETRLIMIT
+
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_SETRLIMIT
+
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_GETRUSAGE
+
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_TIMES
+
+/* Define if <sys/times.h> defines struct tms. */
+#undef HAVE_STRUCT_TMS
+
+/* Define if <time.h> defines clock_t. */
+#undef HAVE_CLOCK_T
+
+/* Define if host mkdir takes a single argument. */
+#undef MKDIR_TAKES_ONE_ARG
+
+/* Define to the name of the distribution. */
+#undef PACKAGE
+
+/* Define to the version of the distribution. */
+#undef VERSION
+
+/* Define to 1 if installation paths should be looked up in Windows32
+ Registry. Ignored on non windows32 hosts. */
+#undef ENABLE_WIN32_REGISTRY
+
+/* Define to be the last portion of registry key on windows hosts. */
+#undef WIN32_REGISTRY_KEY
+
+/* Define if your assembler supports .subsection and .subsection -1 starts
+ emitting at the beginning of your section. */
+#undef HAVE_GAS_SUBSECTION_ORDERING
+
+/* Define if your assembler supports .weak. */
+#undef HAVE_GAS_WEAK
+
+/* Define if your assembler supports .hidden. */
+#undef HAVE_GAS_HIDDEN
+
+/* Define if your assembler supports .uleb128. */
+#undef HAVE_AS_LEB128
+
+/* Define if your assembler mis-optimizes .eh_frame data. */
+#undef USE_AS_TRADITIONAL_FORMAT
+
+/* Define if your assembler supports .register. */
+#undef HAVE_AS_REGISTER_PSEUDO_OP
+
+/* Define if your assembler supports -relax option. */
+#undef HAVE_AS_RELAX_OPTION
+
+/* Define if the assembler supports 64bit sparc. */
+#undef AS_SPARC64_FLAG
+
+/* Define if your assembler supports offsetable %lo(). */
+#undef HAVE_AS_OFFSETABLE_LO10
+
+/* Define if your assembler supports dwarf2 .file/.loc directives,
+ and preserves file table indicies exactly as given. */
+#undef HAVE_AS_DWARF2_DEBUG_LINE
+
+/* Define 0/1 to force the choice for exception handling model. */
+#undef CONFIG_SJLJ_EXCEPTIONS
+
+
+/* Bison unconditionally undefines `const' if neither `__STDC__' nor
+ __cplusplus are defined. That's a problem since we use `const' in
+ the GCC headers, and the resulting bison code is therefore type
+ unsafe. Thus, we must match the bison behavior here. */
+
+#ifndef __STDC__
+#ifndef __cplusplus
+#undef const
+#define const
+#endif
+#endif
--- /dev/null
+/* Generated automatically. */
+static const char configuration_arguments[] = " : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) ";
+static const char thread_model[] = "";
--- /dev/null
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --with-gnu-ld arrange to work with GNU ld."
+ac_help="$ac_help
+ --with-ld arrange to use the specified ld (full pathname)"
+ac_help="$ac_help
+ --with-gnu-as arrange to work with GNU as"
+ac_help="$ac_help
+ --with-as arrange to use the specified as (full pathname)"
+ac_help="$ac_help
+ --with-stabs arrange to use stabs instead of host debug format"
+ac_help="$ac_help
+ --with-elf arrange to use ELF instead of host debug format"
+ac_help="$ac_help
+ --with-local-prefix=DIR specifies directory to put local include"
+ac_help="$ac_help
+ --enable-c-mbchar enable multibyte characters for C and C++"
+ac_help="$ac_help
+ --enable-maintainer-mode
+ enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+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=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -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 ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$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" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ 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)
+ # 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 << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$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" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ 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)
+ 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" ;;
+
+ -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 ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ 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 "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=cppmain.c
+
+# 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 its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ 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
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+
+remove=rm
+hard_link=ln
+symbolic_link='ln -s'
+copy=cp
+
+# Check for additional parameters
+
+# With GNU ld
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+ withval="$with_gnu_ld"
+ gnu_ld_flag="$with_gnu_ld"
+else
+ gnu_ld_flag=no
+fi
+
+
+# With pre-defined ld
+# Check whether --with-ld or --without-ld was given.
+if test "${with_ld+set}" = set; then
+ withval="$with_ld"
+ DEFAULT_LINKER="$with_ld"
+fi
+
+if test x"${DEFAULT_LINKER+set}" = x"set"; then
+ if test ! -x "$DEFAULT_LINKER"; then
+ echo "configure: warning: cannot execute: $DEFAULT_LINKER: check --with-ld or env. var. DEFAULT_LINKER" 1>&2
+ elif $DEFAULT_LINKER -v < /dev/null 2>&1 | grep GNU > /dev/null; then
+ gnu_ld_flag=yes
+ fi
+ cat >> confdefs.h <<EOF
+#define DEFAULT_LINKER "$DEFAULT_LINKER"
+EOF
+
+fi
+
+# With GNU as
+# Check whether --with-gnu-as or --without-gnu-as was given.
+if test "${with_gnu_as+set}" = set; then
+ withval="$with_gnu_as"
+ gas_flag="$with_gnu_as"
+else
+ gas_flag=no
+fi
+
+
+# Check whether --with-as or --without-as was given.
+if test "${with_as+set}" = set; then
+ withval="$with_as"
+ DEFAULT_ASSEMBLER="$with_as"
+fi
+
+if test x"${DEFAULT_ASSEMBLER+set}" = x"set"; then
+ if test ! -x "$DEFAULT_ASSEMBLER"; then
+ echo "configure: warning: cannot execute: $DEFAULT_ASSEMBLER: check --with-as or env. var. DEFAULT_ASSEMBLER" 1>&2
+ elif $DEFAULT_ASSEMBLER -v < /dev/null 2>&1 | grep GNU > /dev/null; then
+ gas_flag=yes
+ fi
+ cat >> confdefs.h <<EOF
+#define DEFAULT_ASSEMBLER "$DEFAULT_ASSEMBLER"
+EOF
+
+fi
+
+# With stabs
+# Check whether --with-stabs or --without-stabs was given.
+if test "${with_stabs+set}" = set; then
+ withval="$with_stabs"
+ stabs="$with_stabs"
+else
+ stabs=no
+fi
+
+
+# With ELF
+# Check whether --with-elf or --without-elf was given.
+if test "${with_elf+set}" = set; then
+ withval="$with_elf"
+ elf="$with_elf"
+else
+ elf=no
+fi
+
+
+# Specify the local prefix
+local_prefix=
+# Check whether --with-local-prefix or --without-local-prefix was given.
+if test "${with_local_prefix+set}" = set; then
+ withval="$with_local_prefix"
+ case "${withval}" in
+yes) { echo "configure: error: bad value ${withval} given for local include directory prefix" 1>&2; exit 1; } ;;
+no) ;;
+*) local_prefix=$with_local_prefix ;;
+esac
+fi
+
+
+# Default local prefix if it is empty
+if test x$local_prefix = x; then
+ local_prefix=/usr/local
+fi
+
+# Enable Multibyte Characters for C/C++
+# Check whether --enable-c-mbchar or --disable-c-mbchar was given.
+if test "${enable_c_mbchar+set}" = set; then
+ enableval="$enable_c_mbchar"
+ if test x$enable_c_mbchar != xno; then
+ cat >> confdefs.h <<\EOF
+#define MULTIBYTE_CHARS 1
+EOF
+
+fi
+fi
+
+
+# Find the native compiler
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:666: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+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 $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:696: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_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 $# -gt 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
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:747: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:779: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 790 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:795: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:821: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:826: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:835: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:854: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&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
+
+if test "x$CC" != xcc; then
+ echo $ac_n "checking whether $CC and cc understand -c and -o together""... $ac_c" 1>&6
+echo "configure:887: checking whether $CC and cc understand -c and -o together" >&5
+else
+ echo $ac_n "checking whether cc understands -c and -o together""... $ac_c" 1>&6
+echo "configure:890: checking whether cc understands -c and -o together" >&5
+fi
+set dummy $CC; ac_cc="`echo $2 |
+ sed -e 's/[^a-zA-Z0-9_]/_/g' -e 's/^[0-9]/_/'`"
+if eval "test \"`echo '$''{'ac_cv_prog_cc_${ac_cc}_c_o'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'foo(){}' > conftest.c
+# Make sure it works both with $CC and with simple cc.
+# We do the test twice because some compilers refuse to overwrite an
+# existing .o file with -o, though they will create one.
+ac_try='${CC-cc} -c conftest.c -o conftest.o 1>&5'
+if { (eval echo configure:902: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } &&
+ test -f conftest.o && { (eval echo configure:903: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; };
+then
+ eval ac_cv_prog_cc_${ac_cc}_c_o=yes
+ if test "x$CC" != xcc; then
+ # Test first that cc exists at all.
+ if { ac_try='cc -c conftest.c 1>&5'; { (eval echo configure:908: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+ ac_try='cc -c conftest.c -o conftest.o 1>&5'
+ if { (eval echo configure:910: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } &&
+ test -f conftest.o && { (eval echo configure:911: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; };
+ then
+ # cc works too.
+ :
+ else
+ # cc exists but doesn't like -o.
+ eval ac_cv_prog_cc_${ac_cc}_c_o=no
+ fi
+ fi
+ fi
+else
+ eval ac_cv_prog_cc_${ac_cc}_c_o=no
+fi
+rm -f conftest*
+
+fi
+if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+ cat >> confdefs.h <<\EOF
+#define NO_MINUS_C_MINUS_O 1
+EOF
+
+fi
+
+# autoconf is lame and doesn't give us any substitution variable for this.
+if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" = no"; then
+ NO_MINUS_C_MINUS_O=yes
+else
+ OUTPUT_OPTION='-o $@'
+fi
+
+
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:947: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 962 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:968: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 979 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:985: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 996 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1002: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+echo $ac_n "checking for inline""... $ac_c" 1>&6
+echo "configure:1027: checking for inline" >&5
+if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat > conftest.$ac_ext <<EOF
+#line 1034 "configure"
+#include "confdefs.h"
+
+int main() {
+} $ac_kw foo() {
+; return 0; }
+EOF
+if { (eval echo configure:1041: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_inline=$ac_kw; break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+
+fi
+
+echo "$ac_t""$ac_cv_c_inline" 1>&6
+case "$ac_cv_c_inline" in
+ inline | yes) ;;
+ no) cat >> confdefs.h <<\EOF
+#define inline
+EOF
+ ;;
+ *) cat >> confdefs.h <<EOF
+#define inline $ac_cv_c_inline
+EOF
+ ;;
+esac
+
+
+# sizeof(char) is 1 by definition.
+echo $ac_n "checking size of short""... $ac_c" 1>&6
+echo "configure:1069: checking size of short" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ for ac_size in 4 8 1 2 16 ; do # List sizes in rough order of prevalence.
+ cat > conftest.$ac_ext <<EOF
+#line 1075 "configure"
+#include "confdefs.h"
+#include "confdefs.h"
+#include <sys/types.h>
+
+
+int main() {
+switch (0) case 0: case (sizeof (short) == $ac_size):;
+; return 0; }
+EOF
+if { (eval echo configure:1085: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_sizeof_short=$ac_size
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ if test x$ac_cv_sizeof_short != x ; then break; fi
+done
+
+fi
+
+if test x$ac_cv_sizeof_short = x ; then
+ { echo "configure: error: cannot determine a size for short" 1>&2; exit 1; }
+fi
+echo "$ac_t""$ac_cv_sizeof_short" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_SHORT $ac_cv_sizeof_short
+EOF
+
+
+echo $ac_n "checking size of int""... $ac_c" 1>&6
+echo "configure:1108: checking size of int" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ for ac_size in 4 8 1 2 16 ; do # List sizes in rough order of prevalence.
+ cat > conftest.$ac_ext <<EOF
+#line 1114 "configure"
+#include "confdefs.h"
+#include "confdefs.h"
+#include <sys/types.h>
+
+
+int main() {
+switch (0) case 0: case (sizeof (int) == $ac_size):;
+; return 0; }
+EOF
+if { (eval echo configure:1124: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_sizeof_int=$ac_size
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ if test x$ac_cv_sizeof_int != x ; then break; fi
+done
+
+fi
+
+if test x$ac_cv_sizeof_int = x ; then
+ { echo "configure: error: cannot determine a size for int" 1>&2; exit 1; }
+fi
+echo "$ac_t""$ac_cv_sizeof_int" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_INT $ac_cv_sizeof_int
+EOF
+
+
+echo $ac_n "checking size of long""... $ac_c" 1>&6
+echo "configure:1147: checking size of long" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ for ac_size in 4 8 1 2 16 ; do # List sizes in rough order of prevalence.
+ cat > conftest.$ac_ext <<EOF
+#line 1153 "configure"
+#include "confdefs.h"
+#include "confdefs.h"
+#include <sys/types.h>
+
+
+int main() {
+switch (0) case 0: case (sizeof (long) == $ac_size):;
+; return 0; }
+EOF
+if { (eval echo configure:1163: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_sizeof_long=$ac_size
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ if test x$ac_cv_sizeof_long != x ; then break; fi
+done
+
+fi
+
+if test x$ac_cv_sizeof_long = x ; then
+ { echo "configure: error: cannot determine a size for long" 1>&2; exit 1; }
+fi
+echo "$ac_t""$ac_cv_sizeof_long" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+EOF
+
+
+
+echo $ac_n "checking execution character set""... $ac_c" 1>&6
+echo "configure:1187: checking execution character set" >&5
+if eval "test \"`echo '$''{'ac_cv_c_charset'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1192 "configure"
+#include "confdefs.h"
+#if '\n' == 0x0A && ' ' == 0x20 && '0' == 0x30 \
+ && 'A' == 0x41 && 'a' == 0x61 && '!' == 0x21
+ASCII
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "ASCII" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_c_charset=ASCII
+fi
+rm -f conftest*
+
+ if test x${ac_cv_c_charset+set} != xset; then
+ cat > conftest.$ac_ext <<EOF
+#line 1208 "configure"
+#include "confdefs.h"
+#if '\n' == 0x15 && ' ' == 0x40 && '0' == 0xF0 \
+ && 'A' == 0xC1 && 'a' == 0x81 && '!' == 0x5A
+EBCDIC
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "EBCDIC" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_c_charset=EBCDIC
+fi
+rm -f conftest*
+
+ fi
+ if test x${ac_cv_c_charset+set} != xset; then
+ ac_cv_c_charset=unknown
+ fi
+fi
+
+echo "$ac_t""$ac_cv_c_charset" 1>&6
+if test $ac_cv_c_charset = unknown; then
+ { echo "configure: error: *** Cannot determine host character set." 1>&2; exit 1; }
+elif test $ac_cv_c_charset = EBCDIC; then
+ cat >> confdefs.h <<\EOF
+#define HOST_EBCDIC 1
+EOF
+
+fi
+
+# If the native compiler is GCC, we can enable warnings even in stage1.
+# That's useful for people building cross-compilers, or just running a
+# quick `make'.
+warn_cflags=
+if test "x$GCC" = "xyes"; then
+ warn_cflags='$(GCC_WARN_CFLAGS)'
+fi
+
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:1248: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+echo $ac_n "checking whether a default assembler was specified""... $ac_c" 1>&6
+echo "configure:1276: checking whether a default assembler was specified" >&5
+if test x"${DEFAULT_ASSEMBLER+set}" = x"set"; then
+ if test x"$gas_flag" = x"no"; then
+ echo "$ac_t""yes ($DEFAULT_ASSEMBLER)" 1>&6
+ else
+ echo "$ac_t""yes ($DEFAULT_ASSEMBLER - GNU as)" 1>&6
+ fi
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking whether a default linker was specified""... $ac_c" 1>&6
+echo "configure:1288: checking whether a default linker was specified" >&5
+if test x"${DEFAULT_LINKER+set}" = x"set"; then
+ if test x"$gnu_ld_flag" = x"no"; then
+ echo "$ac_t""yes ($DEFAULT_LINKER)" 1>&6
+ else
+ echo "$ac_t""yes ($DEFAULT_LINKER - GNU ld)" 1>&6
+ fi
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for GNU C library""... $ac_c" 1>&6
+echo "configure:1300: checking for GNU C library" >&5
+if eval "test \"`echo '$''{'gcc_cv_glibc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1305 "configure"
+#include "confdefs.h"
+#include <features.h>
+int main() {
+
+#if ! (defined __GLIBC__ || defined __GNU_LIBRARY__)
+#error Not a GNU C library system
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:1315: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ gcc_cv_glibc=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gcc_cv_glibc=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gcc_cv_glibc" 1>&6
+if test $gcc_cv_glibc = yes; then
+ cat >> confdefs.h <<\EOF
+#define _GNU_SOURCE 1
+EOF
+
+fi
+
+# Find some useful tools
+echo $ac_n "checking whether ln works""... $ac_c" 1>&6
+echo "configure:1337: checking whether ln works" >&5
+if eval "test \"`echo '$''{'gcc_cv_prog_LN'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftestdata_t
+echo >conftestdata_f
+if ln conftestdata_f conftestdata_t 2>/dev/null
+then
+ gcc_cv_prog_LN="ln"
+else
+ if ln -s conftestdata_f conftestdata_t 2>/dev/null
+ then
+ gcc_cv_prog_LN="ln -s"
+ else
+ gcc_cv_prog_LN=cp
+ fi
+fi
+rm -f conftestdata_f conftestdata_t
+
+fi
+LN="$gcc_cv_prog_LN"
+if test "$gcc_cv_prog_LN" = "ln"; then
+ echo "$ac_t""yes" 1>&6
+else
+ if test "$gcc_cv_prog_LN" = "ln -s"; then
+ echo "$ac_t""no, using ln -s" 1>&6
+ else
+ echo "$ac_t""no, and neither does ln -s, so using cp" 1>&6
+ fi
+fi
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:1369: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'gcc_cv_prog_LN_S'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftestdata_t
+echo >conftestdata_f
+if ln -s conftestdata_f conftestdata_t 2>/dev/null
+then
+ gcc_cv_prog_LN_S="ln -s"
+else
+ if ln conftestdata_f conftestdata_t 2>/dev/null
+ then
+ gcc_cv_prog_LN_S=ln
+ else
+ gcc_cv_prog_LN_S=cp
+ fi
+fi
+rm -f conftestdata_f conftestdata_t
+
+fi
+LN_S="$gcc_cv_prog_LN_S"
+if test "$gcc_cv_prog_LN_S" = "ln -s"; then
+ echo "$ac_t""yes" 1>&6
+else
+ if test "$gcc_cv_prog_LN_S" = "ln"; then
+ echo "$ac_t""no, using ln" 1>&6
+ else
+ echo "$ac_t""no, and neither does ln, so using cp" 1>&6
+ fi
+fi
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1403: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+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
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# 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
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:1460: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ # OSF/1 installbsd also uses dspmsg, but is usable.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_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. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&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_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:1511: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1516 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1524: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1541 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ 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 <<EOF
+#line 1559 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ 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 <<EOF
+#line 1580 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#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)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:1591: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
+echo "configure:1615: checking whether time.h and sys/time.h may both be included" >&5
+if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1620 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+int main() {
+struct tm *tp;
+; return 0; }
+EOF
+if { (eval echo configure:1629: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_header_time=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_time=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_time" 1>&6
+if test $ac_cv_header_time = yes; then
+ cat >> confdefs.h <<\EOF
+#define TIME_WITH_SYS_TIME 1
+EOF
+
+fi
+
+echo $ac_n "checking whether string.h and strings.h may both be included""... $ac_c" 1>&6
+echo "configure:1650: checking whether string.h and strings.h may both be included" >&5
+if eval "test \"`echo '$''{'gcc_cv_header_string'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1655 "configure"
+#include "confdefs.h"
+#include <string.h>
+#include <strings.h>
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:1663: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ gcc_cv_header_string=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gcc_cv_header_string=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gcc_cv_header_string" 1>&6
+if test $gcc_cv_header_string = yes; then
+ cat >> confdefs.h <<\EOF
+#define STRING_WITH_STRINGS 1
+EOF
+
+fi
+
+echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6
+echo "configure:1684: checking for sys/wait.h that is POSIX.1 compatible" >&5
+if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1689 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
+#endif
+#ifndef WIFEXITED
+#define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+int main() {
+int s;
+wait (&s);
+s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
+; return 0; }
+EOF
+if { (eval echo configure:1705: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_header_sys_wait_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_sys_wait_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_sys_wait_h" 1>&6
+if test $ac_cv_header_sys_wait_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_SYS_WAIT_H 1
+EOF
+
+fi
+
+for ac_hdr in limits.h stddef.h string.h strings.h stdlib.h time.h \
+ fcntl.h unistd.h sys/file.h sys/time.h \
+ sys/resource.h sys/param.h sys/times.h sys/stat.h \
+ direct.h malloc.h langinfo.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1732: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1737 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1742: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+# Check for thread headers.
+
+# These tests can't be done till we know if we have limits.h.
+echo $ac_n "checking for CHAR_BIT""... $ac_c" 1>&6
+echo "configure:1773: checking for CHAR_BIT" >&5
+if eval "test \"`echo '$''{'gcc_cv_decl_char_bit'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1778 "configure"
+#include "confdefs.h"
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef CHAR_BIT
+found
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "found" >/dev/null 2>&1; then
+ rm -rf conftest*
+ gcc_cv_decl_char_bit=yes
+else
+ rm -rf conftest*
+ gcc_cv_decl_char_bit=no
+fi
+rm -f conftest*
+
+
+fi
+
+echo "$ac_t""$gcc_cv_decl_char_bit" 1>&6
+if test $gcc_cv_decl_char_bit = no; then
+ echo $ac_n "checking number of bits in a byte""... $ac_c" 1>&6
+echo "configure:1803: checking number of bits in a byte" >&5
+if eval "test \"`echo '$''{'gcc_cv_c_nbby'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ i=8
+ gcc_cv_c_nbby=
+ while test $i -lt 65; do
+ cat > conftest.$ac_ext <<EOF
+#line 1811 "configure"
+#include "confdefs.h"
+
+int main() {
+switch(0) {
+ case (unsigned char)((unsigned long)1 << $i) == ((unsigned long)1 << $i):
+ case (unsigned char)((unsigned long)1<<($i-1)) == ((unsigned long)1<<($i-1)):
+ ; }
+; return 0; }
+EOF
+if { (eval echo configure:1821: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ gcc_cv_c_nbby=$i; break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ i=`expr $i + 1`
+ done
+ test -z "$gcc_cv_c_nbby" && gcc_cv_c_nbby=failed
+
+fi
+
+echo "$ac_t""$gcc_cv_c_nbby" 1>&6
+if test $gcc_cv_c_nbby = failed; then
+ { echo "configure: error: cannot determine number of bits in a byte" 1>&2; exit 1; }
+else
+ cat >> confdefs.h <<EOF
+#define CHAR_BIT $gcc_cv_c_nbby
+EOF
+
+fi
+fi
+echo $ac_n "checking byte ordering""... $ac_c" 1>&6
+echo "configure:1846: checking byte ordering" >&5
+if eval "test \"`echo '$''{'ac_cv_c_compile_endian'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_c_compile_endian=unknown
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext <<EOF
+#line 1860 "configure"
+#include "confdefs.h"
+
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif
+/* This structure must have no internal padding. */
+ struct {
+ char prefix[sizeof "\nendian:" - 1];
+ short word;
+ char postfix[2];
+ } tester = {
+ "\nendian:",
+#if SIZEOF_SHORT == 4
+ ('A' << (CHAR_BIT * 3)) | ('B' << (CHAR_BIT * 2)) |
+#endif
+ ('A' << CHAR_BIT) | 'B',
+ 'X', '\n'
+};
+EOF
+if { (eval echo configure:1880: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ od -c conftest.o |
+ sed 's/^[0-7]*[ ]*/ /
+ s/\*/./g
+ s/ \\n/*/g
+ s/ [0-9][0-9][0-9]/./g
+ s/ \\[^ ]/./g' |
+ tr -d '
+ ' | tr -s '*' '
+' | fold | sed '$a\
+' > conftest.dmp
+ if grep 'endian:AB' conftest.dmp >/dev/null 2>&1; then
+ ac_cv_c_compile_endian=big-endian
+ elif grep 'endian:BA' conftest.dmp >/dev/null 2>&1; then
+ ac_cv_c_compile_endian=little-endian
+ fi
+fi
+rm -rf conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+
+fi
+
+echo "$ac_t""$ac_cv_c_compile_endian" 1>&6
+if test $ac_cv_c_compile_endian = unknown; then
+ { echo "configure: error: *** unable to determine endianness" 1>&2; exit 1; }
+elif test $ac_cv_c_compile_endian = big-endian; then
+ cat >> confdefs.h <<\EOF
+#define HOST_WORDS_BIG_ENDIAN 1
+EOF
+
+fi
+
+
+# See if we have the mktemp command.
+# Extract the first word of "mktemp", so it can be a program name with args.
+set dummy mktemp; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1923: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_have_mktemp_command'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$have_mktemp_command"; then
+ ac_cv_prog_have_mktemp_command="$have_mktemp_command" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_have_mktemp_command="yes"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_have_mktemp_command" && ac_cv_prog_have_mktemp_command="no"
+fi
+fi
+have_mktemp_command="$ac_cv_prog_have_mktemp_command"
+if test -n "$have_mktemp_command"; then
+ echo "$ac_t""$have_mktemp_command" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+# See if the stage1 system preprocessor understands the ANSI C
+# preprocessor stringification operator. (Used by symcat.h.)
+
+
+echo $ac_n "checking for preprocessor stringizing operator""... $ac_c" 1>&6
+echo "configure:1956: checking for preprocessor stringizing operator" >&5
+if eval "test \"`echo '$''{'ac_cv_c_stringize'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1961 "configure"
+#include "confdefs.h"
+
+#define x(y) #y
+
+char *s = x(teststring);
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "#teststring" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_c_stringize=no
+else
+ rm -rf conftest*
+ ac_cv_c_stringize=yes
+fi
+rm -f conftest*
+
+fi
+
+if test "${ac_cv_c_stringize}" = yes
+then
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRINGIZE 1
+EOF
+
+fi
+echo "$ac_t""${ac_cv_c_stringize}" 1>&6
+
+
+# Use <inttypes.h> only if it exists,
+# doesn't clash with <sys/types.h>, and declares intmax_t.
+echo $ac_n "checking for inttypes.h""... $ac_c" 1>&6
+echo "configure:1994: checking for inttypes.h" >&5
+if eval "test \"`echo '$''{'gcc_cv_header_inttypes_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1999 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <inttypes.h>
+int main() {
+intmax_t i = -1;
+; return 0; }
+EOF
+if { (eval echo configure:2007: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ gcc_cv_header_inttypes_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gcc_cv_header_inttypes_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gcc_cv_header_inttypes_h" 1>&6
+if test $gcc_cv_header_inttypes_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_INTTYPES_H 1
+EOF
+
+fi
+
+
+for ac_func in times clock strchr strrchr lstat
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2031: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2036 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* 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_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2059: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+echo $ac_n "checking for ssize_t""... $ac_c" 1>&6
+echo "configure:2085: checking for ssize_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_ssize_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2090 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])ssize_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_ssize_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_ssize_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_ssize_t" 1>&6
+if test $ac_cv_type_ssize_t = no; then
+ cat >> confdefs.h <<\EOF
+#define ssize_t int
+EOF
+
+fi
+
+
+for ac_func in getpagesize
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2121: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2126 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* 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_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2149: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+# The test program for the next two tests is the same except for one
+# set of ifdefs.
+cat >ct-mmap.inc <<'EOF'
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <setjmp.h>
+#include <stdio.h>
+
+#if !defined (MAP_ANONYMOUS) && defined (MAP_ANON)
+# define MAP_ANONYMOUS MAP_ANON
+#endif
+
+/* This mess was copied from the GNU getpagesize.h. */
+#ifndef HAVE_GETPAGESIZE
+# ifdef HAVE_UNISTD_H
+# include <unistd.h>
+# endif
+
+/* Assume that all systems that can run configure have sys/param.h. */
+# ifndef HAVE_SYS_PARAM_H
+# define HAVE_SYS_PARAM_H 1
+# endif
+
+# ifdef _SC_PAGESIZE
+# define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+# ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+# ifdef EXEC_PAGESIZE
+# define getpagesize() EXEC_PAGESIZE
+# else /* no EXEC_PAGESIZE */
+# ifdef NBPG
+# define getpagesize() NBPG * CLSIZE
+# ifndef CLSIZE
+# define CLSIZE 1
+# endif /* no CLSIZE */
+# else /* no NBPG */
+# ifdef NBPC
+# define getpagesize() NBPC
+# else /* no NBPC */
+# ifdef PAGESIZE
+# define getpagesize() PAGESIZE
+# endif /* PAGESIZE */
+# endif /* no NBPC */
+# endif /* no NBPG */
+# endif /* no EXEC_PAGESIZE */
+# else /* no HAVE_SYS_PARAM_H */
+# define getpagesize() 8192 /* punt totally */
+# endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
+
+#ifndef MAP_FAILED
+# define MAP_FAILED -1
+#endif
+
+#undef perror_exit
+#define perror_exit(str, val) \
+ do { perror(str); exit(val); } while (0)
+
+/* Some versions of cygwin mmap require that munmap is called with the
+ same parameters as mmap. GCC expects that this is not the case.
+ Test for various forms of this problem. Warning - icky signal games. */
+
+static sigset_t unblock_sigsegv;
+static jmp_buf r;
+static size_t pg;
+static int devzero;
+
+static char *
+anonmap (size)
+ size_t size;
+{
+#ifdef USE_MAP_ANON
+ return (char *) mmap (0, size, PROT_READ|PROT_WRITE,
+ MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+#else
+ return (char *) mmap (0, size, PROT_READ|PROT_WRITE,
+ MAP_PRIVATE, devzero, 0);
+#endif
+}
+
+static void
+sigsegv (unused)
+ int unused;
+{
+ sigprocmask (SIG_UNBLOCK, &unblock_sigsegv, 0);
+ longjmp (r, 1);
+}
+
+/* Basic functionality test. */
+void
+test_0 ()
+{
+ char *x = anonmap (pg);
+ if (x == (char *) MAP_FAILED)
+ perror_exit("test 0 mmap", 2);
+
+ *(int *)x += 1;
+
+ if (munmap(x, pg) < 0)
+ perror_exit("test 0 munmap", 3);
+}
+
+/* 1. If we map a 2-page region and unmap its second page, the first page
+ must remain. */
+static void
+test_1 ()
+{
+ char *x = anonmap (pg * 2);
+ if (x == (char *)MAP_FAILED)
+ perror_exit ("test 1 mmap", 4);
+
+ signal (SIGSEGV, sigsegv);
+ if (setjmp (r))
+ perror_exit ("test 1 fault", 5);
+
+ x[0] = 1;
+ x[pg] = 1;
+
+ if (munmap (x + pg, pg) < 0)
+ perror_exit ("test 1 munmap 1", 6);
+ x[0] = 2;
+
+ if (setjmp (r) == 0)
+ {
+ x[pg] = 1;
+ perror_exit ("test 1 no fault", 7);
+ }
+ if (munmap (x, pg) < 0)
+ perror_exit ("test 1 munmap 2", 8);
+}
+
+/* 2. If we map a 2-page region and unmap its first page, the second
+ page must remain. */
+static void
+test_2 ()
+{
+ char *x = anonmap (pg * 2);
+ if (x == (char *)MAP_FAILED)
+ perror_exit ("test 2 mmap", 9);
+
+ signal (SIGSEGV, sigsegv);
+ if (setjmp (r))
+ perror_exit ("test 2 fault", 10);
+
+ x[0] = 1;
+ x[pg] = 1;
+
+ if (munmap (x, pg) < 0)
+ perror_exit ("test 2 munmap 1", 11);
+
+ x[pg] = 2;
+
+ if (setjmp (r) == 0)
+ {
+ x[0] = 1;
+ perror_exit ("test 2 no fault", 12);
+ }
+
+ if (munmap (x+pg, pg) < 0)
+ perror_exit ("test 2 munmap 2", 13);
+}
+
+/* 3. If we map two adjacent 1-page regions and unmap them both with
+ one munmap, both must go away.
+
+ Getting two adjacent 1-page regions with two mmap calls is slightly
+ tricky. All OS's tested skip over already-allocated blocks; therefore
+ we have been careful to unmap all allocated regions in previous tests.
+ HP/UX allocates pages backward in memory. No OS has yet been observed
+ to be so perverse as to leave unmapped space between consecutive calls
+ to mmap. */
+
+static void
+test_3 ()
+{
+ char *x, *y, *z;
+
+ x = anonmap (pg);
+ if (x == (char *)MAP_FAILED)
+ perror_exit ("test 3 mmap 1", 14);
+ y = anonmap (pg);
+ if (y == (char *)MAP_FAILED)
+ perror_exit ("test 3 mmap 2", 15);
+
+ if (y != x + pg)
+ {
+ if (y == x - pg)
+ z = y, y = x, x = z;
+ else
+ {
+ fprintf (stderr, "test 3 nonconsecutive pages - %lx, %lx\n",
+ (unsigned long)x, (unsigned long)y);
+ exit (16);
+ }
+ }
+
+ signal (SIGSEGV, sigsegv);
+ if (setjmp (r))
+ perror_exit ("test 3 fault", 17);
+
+ x[0] = 1;
+ y[0] = 1;
+
+ if (munmap (x, pg*2) < 0)
+ perror_exit ("test 3 munmap", 18);
+
+ if (setjmp (r) == 0)
+ {
+ x[0] = 1;
+ perror_exit ("test 3 no fault 1", 19);
+ }
+
+ signal (SIGSEGV, sigsegv);
+ if (setjmp (r) == 0)
+ {
+ y[0] = 1;
+ perror_exit ("test 3 no fault 2", 20);
+ }
+}
+
+int
+main ()
+{
+ sigemptyset (&unblock_sigsegv);
+ sigaddset (&unblock_sigsegv, SIGSEGV);
+ pg = getpagesize ();
+#ifndef USE_MAP_ANON
+ devzero = open ("/dev/zero", O_RDWR);
+ if (devzero < 0)
+ perror_exit ("open /dev/zero", 1);
+#endif
+
+ test_0();
+ test_1();
+ test_2();
+ test_3();
+
+ exit(0);
+}
+EOF
+
+echo $ac_n "checking for working mmap from /dev/zero""... $ac_c" 1>&6
+echo "configure:2420: checking for working mmap from /dev/zero" >&5
+if eval "test \"`echo '$''{'ac_cv_func_mmap_dev_zero'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ # If this is not cygwin, and /dev/zero is a character device, it's probably
+ # safe to assume it works.
+ case "$host_os" in
+ cygwin* | win32 | pe | mingw* ) ac_cv_func_mmap_dev_zero=buggy ;;
+ * ) if test -c /dev/zero
+ then ac_cv_func_mmap_dev_zero=yes
+ else ac_cv_func_mmap_dev_zero=no
+ fi ;;
+ esac
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2436 "configure"
+#include "confdefs.h"
+#include "ct-mmap.inc"
+EOF
+if { (eval echo configure:2440: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_mmap_dev_zero=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ if test $? -lt 4
+ then ac_cv_func_mmap_dev_zero=no
+ else ac_cv_func_mmap_dev_zero=buggy
+ fi
+fi
+rm -fr conftest*
+fi
+
+
+fi
+
+echo "$ac_t""$ac_cv_func_mmap_dev_zero" 1>&6
+if test $ac_cv_func_mmap_dev_zero = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_MMAP_DEV_ZERO 1
+EOF
+
+fi
+
+echo $ac_n "checking for working mmap with MAP_ANON(YMOUS)""... $ac_c" 1>&6
+echo "configure:2467: checking for working mmap with MAP_ANON(YMOUS)" >&5
+if eval "test \"`echo '$''{'ac_cv_func_mmap_anon'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ # Unlike /dev/zero, it is not safe to assume MAP_ANON(YMOUS) works
+ # just because it's there. Some SCO Un*xen define it but don't implement it.
+ ac_cv_func_mmap_anon=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2477 "configure"
+#include "confdefs.h"
+#define USE_MAP_ANON
+#include "ct-mmap.inc"
+EOF
+if { (eval echo configure:2482: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_mmap_anon=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ if test $? -lt 4
+ then ac_cv_func_mmap_anon=no
+ else ac_cv_func_mmap_anon=buggy
+ fi
+fi
+rm -fr conftest*
+fi
+
+
+fi
+
+echo "$ac_t""$ac_cv_func_mmap_anon" 1>&6
+if test $ac_cv_func_mmap_anon = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_MMAP_ANON 1
+EOF
+
+fi
+rm -f ct-mmap.inc
+
+echo $ac_n "checking for working mmap of a file""... $ac_c" 1>&6
+echo "configure:2510: checking for working mmap of a file" >&5
+if eval "test \"`echo '$''{'ac_cv_func_mmap_file'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # Create a file one thousand bytes long.
+for i in 1 2 3 4 5 6 7 8 9 0
+do for j in 1 2 3 4 5 6 7 8 9 0
+do echo $i $j xxxxx
+done
+done > conftestdata$$
+
+if test "$cross_compiling" = yes; then
+ ac_cv_func_mmap_file=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2525 "configure"
+#include "confdefs.h"
+
+/* Test by Zack Weinberg. Modified from MMAP_ANYWHERE test by
+ Richard Henderson and Alexandre Oliva.
+ Check whether read-only mmap of a plain file works. */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+int main()
+{
+ char *x;
+ int fd;
+ struct stat st;
+
+ fd = open("conftestdata$$", O_RDONLY);
+ if (fd < 0)
+ exit(1);
+
+ if (fstat (fd, &st))
+ exit(2);
+
+ x = (char*)mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (x == (char *) -1)
+ exit(3);
+
+ if (x[0] != '1' || x[1] != ' ' || x[2] != '1' || x[3] != ' ')
+ exit(4);
+
+ if (munmap(x, st.st_size) < 0)
+ exit(5);
+
+ exit(0);
+}
+EOF
+if { (eval echo configure:2562: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_mmap_file=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_mmap_file=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_mmap_file" 1>&6
+if test $ac_cv_func_mmap_file = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_MMAP_FILE 1
+EOF
+
+fi
+
+
+# We will need to find libiberty.h and ansidecl.h
+saved_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -I${srcdir} -I${srcdir}/../include"
+for ac_func in getenv abort errno \
+ malloc realloc calloc free getopt clock
+do
+ ac_tr_decl=HAVE_DECL_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+echo $ac_n "checking whether $ac_func is declared""... $ac_c" 1>&6
+echo "configure:2593: checking whether $ac_func is declared" >&5
+if eval "test \"`echo '$''{'gcc_cv_have_decl_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2598 "configure"
+#include "confdefs.h"
+#undef $ac_tr_decl
+#define $ac_tr_decl 1
+
+#include "ansidecl.h"
+#include "system.h"
+
+int main() {
+#ifndef $ac_func
+char *(*pfn) = (char *(*)) $ac_func ;
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:2612: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "gcc_cv_have_decl_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "gcc_cv_have_decl_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$gcc_cv_have_decl_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6 ; cat >> confdefs.h <<EOF
+#define $ac_tr_decl 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6 ; cat >> confdefs.h <<EOF
+#define $ac_tr_decl 0
+EOF
+
+fi
+
+done
+if test x = y ; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_DECL_GETENV 1
+EOF
+ cat >> confdefs.h <<\EOF
+#define HAVE_DECL_ABORT 1
+EOF
+ cat >> confdefs.h <<\EOF
+#define HAVE_DECL_ERRNO 1
+EOF
+ \
+ cat >> confdefs.h <<\EOF
+#define HAVE_DECL_MALLOC 1
+EOF
+ cat >> confdefs.h <<\EOF
+#define HAVE_DECL_REALLOC 1
+EOF
+ cat >> confdefs.h <<\EOF
+#define HAVE_DECL_CALLOC 1
+EOF
+ cat >> confdefs.h <<\EOF
+#define HAVE_DECL_FREE 1
+EOF
+ cat >> confdefs.h <<\EOF
+#define HAVE_DECL_GETOPT 1
+EOF
+ cat >> confdefs.h <<\EOF
+#define HAVE_DECL_CLOCK 1
+EOF
+fi
+
+
+for ac_func in times
+do
+ ac_tr_decl=HAVE_DECL_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+echo $ac_n "checking whether $ac_func is declared""... $ac_c" 1>&6
+echo "configure:2673: checking whether $ac_func is declared" >&5
+if eval "test \"`echo '$''{'gcc_cv_have_decl_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2678 "configure"
+#include "confdefs.h"
+#undef $ac_tr_decl
+#define $ac_tr_decl 1
+
+#include "ansidecl.h"
+#include "system.h"
+#ifdef HAVE_SYS_TIMES_H
+#include <sys/times.h>
+#endif
+
+
+int main() {
+#ifndef $ac_func
+char *(*pfn) = (char *(*)) $ac_func ;
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:2696: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "gcc_cv_have_decl_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "gcc_cv_have_decl_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$gcc_cv_have_decl_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6 ; cat >> confdefs.h <<EOF
+#define $ac_tr_decl 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6 ; cat >> confdefs.h <<EOF
+#define $ac_tr_decl 0
+EOF
+
+fi
+
+done
+if test x = y ; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_DECL_TIMES 1
+EOF
+fi
+
+
+# More time-related stuff.
+echo $ac_n "checking for struct tms""... $ac_c" 1>&6
+echo "configure:2730: checking for struct tms" >&5
+if eval "test \"`echo '$''{'ac_cv_struct_tms'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+cat > conftest.$ac_ext <<EOF
+#line 2736 "configure"
+#include "confdefs.h"
+
+#include "ansidecl.h"
+#include "system.h"
+#ifdef HAVE_SYS_TIMES_H
+#include <sys/times.h>
+#endif
+
+int main() {
+struct tms tms;
+; return 0; }
+EOF
+if { (eval echo configure:2749: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_struct_tms=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_struct_tms=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_struct_tms" 1>&6
+if test $ac_cv_struct_tms = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRUCT_TMS 1
+EOF
+
+fi
+
+# use gcc_cv_* here because this doesn't match the behavior of AC_CHECK_TYPE.
+# revisit after autoconf 2.50.
+echo $ac_n "checking for clock_t""... $ac_c" 1>&6
+echo "configure:2772: checking for clock_t" >&5
+if eval "test \"`echo '$''{'gcc_cv_type_clock_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+cat > conftest.$ac_ext <<EOF
+#line 2778 "configure"
+#include "confdefs.h"
+
+#include "ansidecl.h"
+#include "system.h"
+
+int main() {
+clock_t x;
+; return 0; }
+EOF
+if { (eval echo configure:2788: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ gcc_cv_type_clock_t=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gcc_cv_type_clock_t=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gcc_cv_type_clock_t" 1>&6
+if test $gcc_cv_type_clock_t = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_CLOCK_T 1
+EOF
+
+fi
+
+# Restore CFLAGS from before the gcc_AC_NEED_DECLARATIONS tests.
+CFLAGS="$saved_CFLAGS"
+
+# mkdir takes a single argument on some systems.
+echo $ac_n "checking if mkdir takes one argument""... $ac_c" 1>&6
+echo "configure:2813: checking if mkdir takes one argument" >&5
+if eval "test \"`echo '$''{'gcc_cv_mkdir_takes_one_arg'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2818 "configure"
+#include "confdefs.h"
+
+#include <sys/types.h>
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifdef HAVE_DIRECT_H
+# include <direct.h>
+#endif
+int main() {
+mkdir ("foo", 0);
+; return 0; }
+EOF
+if { (eval echo configure:2835: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ gcc_cv_mkdir_takes_one_arg=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gcc_cv_mkdir_takes_one_arg=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gcc_cv_mkdir_takes_one_arg" 1>&6
+if test $gcc_cv_mkdir_takes_one_arg = yes ; then
+ cat >> confdefs.h <<\EOF
+#define MKDIR_TAKES_ONE_ARG 1
+EOF
+
+fi
+
+
+# File extensions
+manext='.1'
+objext='.o'
+
+
+
+build_xm_file=
+build_xm_defines=
+build_install_headers_dir=install-headers-tar
+build_exeext=
+host_xm_file=
+host_xm_defines=
+host_xmake_file=
+host_truncate_target=
+host_exeext=
+
+# Decode the host machine, then the target machine.
+# For the host machine, we save the xm_file variable as host_xm_file;
+# then we decode the target machine and forget everything else
+# that came from the host machine.
+#for machine in $build $host $target; do
+# . ${srcdir}/config.gcc
+#done
+
+extra_objs="${host_extra_objs} ${extra_objs}"
+
+# Default the target-machine variables that were not explicitly set.
+if test x"$tm_file" = x
+then tm_file=$cpu_type/$cpu_type.h; fi
+
+if test x"$extra_headers" = x
+then extra_headers=; fi
+
+if test x$md_file = x
+then md_file=$cpu_type/$cpu_type.md; fi
+
+if test x$out_file = x
+then out_file=$cpu_type/$cpu_type.c; fi
+
+if test x"$tmake_file" = x
+then tmake_file=$cpu_type/t-$cpu_type
+fi
+
+if test x"$dwarf2" = xyes
+then tm_file="$tm_file tm-dwarf2.h"
+fi
+
+# Handle cpp installation.
+if test x$enable_cpp != xno
+then
+ tmake_file="$tmake_file t-install-cpp"
+fi
+
+# auto-host.h is the file containing items generated by autoconf and is
+# the first file included by config.h.
+# If host=build, it is correct to have hconfig include auto-host.h
+# as well. If host!=build, we are in error and need to do more
+# work to find out the build config parameters.
+if test x$host = x$build
+then
+ build_auto=auto-host.h
+else
+ # We create a subdir, then run autoconf in the subdir.
+ # To prevent recursion we set host and build for the new
+ # invocation of configure to the build for this invocation
+ # of configure.
+ tempdir=build.$$
+ rm -rf $tempdir
+ mkdir $tempdir
+ cd $tempdir
+ case ${srcdir} in
+ /* | A-Za-z:\\/* ) realsrcdir=${srcdir};;
+ *) realsrcdir=../${srcdir};;
+ esac
+ CC=${CC_FOR_BUILD} ${realsrcdir}/configure \
+ --target=$target --host=$build --build=$build
+
+ # We just finished tests for the build machine, so rename
+ # the file auto-build.h in the gcc directory.
+ mv auto-host.h ../auto-build.h
+ cd ..
+ rm -rf $tempdir
+ build_auto=auto-build.h
+fi
+
+tm_file="${tm_file} defaults.h"
+host_xm_file="auto-host.h ansidecl.h ${host_xm_file} ${tm_file}"
+build_xm_file="${build_auto} ansidecl.h ${build_xm_file} ${tm_file}"
+xm_file="ansidecl.h ${xm_file} ${tm_file}"
+
+# Truncate the target if necessary
+if test x$host_truncate_target != x; then
+ target=`echo $target | sed -e 's/\(..............\).*/\1/'`
+fi
+
+# Get the version trigger filename from the toplevel
+if test "${with_gcc_version_trigger+set}" = set; then
+ gcc_version_trigger=$with_gcc_version_trigger
+else
+ gcc_version_trigger=${srcdir}/version.c
+fi
+gcc_version_full=`grep version_string ${gcc_version_trigger} | sed -e 's/.*"\([^"]*\)".*/\1/'`
+gcc_version=`echo ${gcc_version_full} | sed -e 's/\([^ ]*\) .*/\1/'`
+
+# Compile in configure arguments.
+if test -f configargs.h ; then
+ # Being re-configured.
+ gcc_config_arguments=`grep configuration_arguments configargs.h | sed -e 's/.*"\([^"]*\)".*/\1/'`
+ gcc_config_arguments="$gcc_config_arguments : (reconfigured) $TOPLEVEL_CONFIGURE_ARGUMENTS"
+else
+ gcc_config_arguments="$TOPLEVEL_CONFIGURE_ARGUMENTS"
+fi
+cat > configargs.h <<EOF
+/* Generated automatically. */
+static const char configuration_arguments[] = "$gcc_config_arguments";
+static const char thread_model[] = "$thread_file";
+EOF
+
+# Internationalization
+PACKAGE=sdcc
+VERSION="$gcc_version"
+cat >> confdefs.h <<EOF
+#define PACKAGE "$PACKAGE"
+EOF
+
+cat >> confdefs.h <<EOF
+#define VERSION "$VERSION"
+EOF
+
+
+
+
+ALL_LINGUAS="sv"
+
+# Get an absolute path to the GCC top-level source directory
+holddir=`pwd`
+cd $srcdir
+topdir=`pwd`
+cd $holddir
+
+out_object_file=`basename $out_file .c`.o
+
+# Figure out what assembler we will be using.
+echo $ac_n "checking what assembler to use""... $ac_c" 1>&6
+echo "configure:3000: checking what assembler to use" >&5
+gcc_cv_as=
+gcc_cv_gas_major_version=
+gcc_cv_gas_minor_version=
+gcc_cv_as_gas_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/gas
+if test -x "$DEFAULT_ASSEMBLER"; then
+ gcc_cv_as="$DEFAULT_ASSEMBLER"
+elif test -x "$AS"; then
+ gcc_cv_as="$AS"
+elif test -x as$host_exeext; then
+ # Build using assembler in the current directory.
+ gcc_cv_as=./as$host_exeext
+elif test -f $gcc_cv_as_gas_srcdir/configure.in -a -f ../gas/Makefile; then
+ # Single tree build which includes gas.
+ for f in $gcc_cv_as_gas_srcdir/configure $gcc_cv_as_gas_srcdir/configure.in $gcc_cv_as_gas_srcdir/Makefile.in
+ do
+ gcc_cv_gas_version=`grep '^VERSION=[0-9]*\.[0-9]*' $f`
+ if test x$gcc_cv_gas_version != x; then
+ break
+ fi
+ done
+ gcc_cv_gas_major_version=`expr "$gcc_cv_gas_version" : "VERSION=\([0-9]*\)"`
+ gcc_cv_gas_minor_version=`expr "$gcc_cv_gas_version" : "VERSION=[0-9]*\.\([0-9]*\)"`
+fi
+
+if test "x$gcc_cv_as" = x -a x$host = x$target; then
+ # Native build.
+ # Search the same directories that the installed compiler will
+ # search. Else we may find the wrong assembler and lose. If we
+ # do not find a suitable assembler binary, then try the user's
+ # path.
+ #
+ # Also note we have to check MD_EXEC_PREFIX before checking the
+ # user's path. Unfortunately, there is no good way to get at the
+ # value of MD_EXEC_PREFIX here. So we do a brute force search
+ # through all the known MD_EXEC_PREFIX values. Ugh. This needs
+ # to be fixed as part of the make/configure rewrite too.
+
+ if test "x$exec_prefix" = xNONE; then
+ if test "x$prefix" = xNONE; then
+ test_prefix=/usr/local
+ else
+ test_prefix=$prefix
+ fi
+ else
+ test_prefix=$exec_prefix
+ fi
+
+ # If the loop below does not find an assembler, then use whatever
+ # one we can find in the users's path.
+ # user's path.
+ gcc_cv_as=as$host_exeext
+
+ test_dirs="$test_prefix/lib/gcc-lib/$target/$gcc_version \
+ $test_prefix/lib/gcc-lib/$target \
+ /usr/lib/gcc/$target/$gcc_version \
+ /usr/lib/gcc/$target \
+ $test_prefix/$target/bin/$target/$gcc_version \
+ $test_prefix/$target/bin \
+ /usr/libexec \
+ /usr/ccs/gcc \
+ /usr/ccs/bin \
+ /udk/usr/ccs/bin \
+ /bsd43/usr/lib/cmplrs/cc \
+ /usr/cross64/usr/bin \
+ /usr/lib/cmplrs/cc \
+ /sysv/usr/lib/cmplrs/cc \
+ /svr4/usr/lib/cmplrs/cc \
+ /usr/bin"
+
+ for dir in $test_dirs; do
+ if test -f $dir/as$host_exeext; then
+ gcc_cv_as=$dir/as$host_exeext
+ break;
+ fi
+ done
+fi
+if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x; then
+ echo "$ac_t"""newly built gas"" 1>&6
+else
+ echo "$ac_t""$gcc_cv_as" 1>&6
+fi
+
+# Figure out what nm we will be using.
+echo $ac_n "checking what nm to use""... $ac_c" 1>&6
+echo "configure:3085: checking what nm to use" >&5
+if test -x nm$host_exeext; then
+ gcc_cv_nm=./nm$host_exeext
+elif test x$host = x$target; then
+ # Native build.
+ gcc_cv_nm=nm$host_exeext
+fi
+echo "$ac_t""$gcc_cv_nm" 1>&6
+
+
+echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
+echo "configure:3096: checking whether to enable maintainer-specific portions of Makefiles" >&5
+ # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then
+ enableval="$enable_maintainer_mode"
+ maintainer_mode=$enableval
+else
+ maintainer_mode=no
+fi
+
+
+echo "$ac_t""$maintainer_mode" 1>&6
+
+if test "$maintainer_mode" = "yes"; then
+ MAINT=''
+else
+ MAINT='#'
+fi
+
+# These (without "all_") are set in each config-lang.in.
+# `language' must be a single word so is spelled singularly.
+all_stagestuff=
+all_outputs='Makefile'
+# List of language makefile fragments.
+
+# Add the language fragments.
+# Languages are added via two mechanisms. Some information must be
+# recorded in makefile variables, these are defined in config-lang.in.
+# We accumulate them and plug them into the main Makefile.
+# The other mechanism is a set of hooks for each of the main targets
+# like `clean', `install', etc.
+
+language_fragments="Make-lang"
+
+# Define variables host_canonical and build_canonical
+# because some Cygnus local changes in the Makefile depend on them.
+build_canonical=${build}
+host_canonical=${host}
+target_subdir=
+if test "${host}" != "${target}" ; then
+ target_subdir=${target_alias}/
+fi
+
+
+
+
+# Nothing to do for FLOAT_H, float_format already handled.
+objdir=`pwd`
+
+
+# Substitute configuration variables
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Create the Makefile
+# and configure language subdirectories
+trap '' 1 2 15
+cat > confcache <<\EOF
+# 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. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# 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.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "$all_outputs auto-host.h:config.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@CC@%$CC%g
+s%@NO_MINUS_C_MINUS_O@%$NO_MINUS_C_MINUS_O%g
+s%@OUTPUT_OPTION@%$OUTPUT_OPTION%g
+s%@CPP@%$CPP%g
+s%@warn_cflags@%$warn_cflags%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@LN@%$LN%g
+s%@LN_S@%$LN_S%g
+s%@RANLIB@%$RANLIB%g
+s%@INSTALL@%$INSTALL%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@have_mktemp_command@%$have_mktemp_command%g
+s%@manext@%$manext%g
+s%@objext@%$objext%g
+s%@PACKAGE@%$PACKAGE%g
+s%@VERSION@%$VERSION%g
+s%@MAINT@%$MAINT%g
+s%@build_canonical@%$build_canonical%g
+s%@host_canonical@%$host_canonical%g
+s%@target_subdir@%$target_subdir%g
+s%@objdir@%$objdir%g
+s%@all_stagestuff@%$all_stagestuff%g
+s%@build_exeext@%$build_exeext%g
+s%@build_install_headers_dir@%$build_install_headers_dir%g
+s%@build_xm_file_list@%$build_xm_file_list%g
+s%@build_xm_file@%$build_xm_file%g
+s%@build_xm_defines@%$build_xm_defines%g
+s%@check_languages@%$check_languages%g
+s%@dep_host_xmake_file@%$dep_host_xmake_file%g
+s%@dep_tmake_file@%$dep_tmake_file%g
+s%@extra_c_flags@%$extra_c_flags%g
+s%@extra_headers_list@%$extra_headers_list%g
+s%@extra_objs@%$extra_objs%g
+s%@extra_parts@%$extra_parts%g
+s%@extra_passes@%$extra_passes%g
+s%@extra_programs@%$extra_programs%g
+s%@gcc_config_arguments@%$gcc_config_arguments%g
+s%@gcc_version@%$gcc_version%g
+s%@gcc_version_full@%$gcc_version_full%g
+s%@gcc_version_trigger@%$gcc_version_trigger%g
+s%@host_exeext@%$host_exeext%g
+s%@host_extra_gcc_objs@%$host_extra_gcc_objs%g
+s%@install@%$install%g
+s%@lang_tree_files@%$lang_tree_files%g
+s%@local_prefix@%$local_prefix%g
+s%@md_file@%$md_file%g
+s%@out_file@%$out_file%g
+s%@out_object_file@%$out_object_file%g
+s%@symbolic_link@%$symbolic_link%g
+s%@thread_file@%$thread_file%g
+s%@c_target_objs@%$c_target_objs%g
+/@target_overrides@/r $target_overrides
+s%@target_overrides@%%g
+/@host_overrides@/r $host_overrides
+s%@host_overrides@%%g
+s%@cross_defines@%$cross_defines%g
+/@cross_overrides@/r $cross_overrides
+s%@cross_overrides@%%g
+/@build_overrides@/r $build_overrides
+s%@build_overrides@%%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"$all_outputs"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="auto-host.h:config.in"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+host='${host}'
+build='${build}'
+target='${target}'
+target_alias='${target_alias}'
+srcdir='${srcdir}'
+symbolic_link='${symbolic_link}'
+program_transform_set='${program_transform_set}'
+program_transform_name='${program_transform_name}'
+dep_host_xmake_file='${dep_host_xmake_file}'
+host_xmake_file='${host_xmake_file}'
+dep_tmake_file='${dep_tmake_file}'
+tmake_file='${tmake_file}'
+thread_file='${thread_file}'
+gcc_config_arguments='${gcc_config_arguments}'
+gcc_version='${gcc_version}'
+gcc_version_full='${gcc_version_full}'
+gcc_version_trigger='${gcc_version_trigger}'
+local_prefix='${local_prefix}'
+build_install_headers_dir='${build_install_headers_dir}'
+build_exeext='${build_exeext}'
+host_exeext='${host_exeext}'
+out_file='${out_file}'
+gdb_needs_out_file_path='${gdb_needs_out_file_path}'
+SET_MAKE='${SET_MAKE}'
+target_list='${target_list}'
+target_overrides='${target_overrides}'
+host_overrides='${host_overrides}'
+cross_defines='${cross_defines}'
+cross_overrides='${cross_overrides}'
+build_overrides='${build_overrides}'
+cpp_install_dir='${cpp_install_dir}'
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+case x$CONFIG_HEADERS in
+xauto-host.h:config.in)
+echo > cstamp-h ;;
+esac
+
+# Avoid having to add intl to our include paths.
+if test -f intl/libintl.h; then
+ echo creating libintl.h
+ echo '#include "intl/libintl.h"' >libintl.h
+fi
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
--- /dev/null
+# configure.in for GNU CC
+# Process this file with autoconf to generate a configuration script.
+
+# Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+#This file is part of GNU CC.
+
+#GNU CC is free software; you can redistribute it and/or modify
+#it under the terms of the GNU General Public License as published by
+#the Free Software Foundation; either version 2, or (at your option)
+#any later version.
+
+#GNU CC 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 GNU CC; see the file COPYING. If not, write to
+#the Free Software Foundation, 59 Temple Place - Suite 330,
+#Boston, MA 02111-1307, USA.
+
+# Initialization and defaults
+AC_PREREQ(2.13)
+AC_INIT(cppmain.c)
+AC_CONFIG_HEADER(auto-host.h:config.in)
+
+remove=rm
+hard_link=ln
+symbolic_link='ln -s'
+copy=cp
+
+# Check for additional parameters
+
+# With GNU ld
+AC_ARG_WITH(gnu-ld,
+[ --with-gnu-ld arrange to work with GNU ld.],
+gnu_ld_flag="$with_gnu_ld",
+gnu_ld_flag=no)
+
+# With pre-defined ld
+AC_ARG_WITH(ld,
+[ --with-ld arrange to use the specified ld (full pathname)],
+DEFAULT_LINKER="$with_ld")
+if test x"${DEFAULT_LINKER+set}" = x"set"; then
+ if test ! -x "$DEFAULT_LINKER"; then
+ AC_MSG_WARN([cannot execute: $DEFAULT_LINKER: check --with-ld or env. var. DEFAULT_LINKER])
+ elif $DEFAULT_LINKER -v < /dev/null 2>&1 | grep GNU > /dev/null; then
+ gnu_ld_flag=yes
+ fi
+ AC_DEFINE_UNQUOTED(DEFAULT_LINKER,"$DEFAULT_LINKER",
+ [Define to enable the use of a default linker.])
+fi
+
+# With GNU as
+AC_ARG_WITH(gnu-as,
+[ --with-gnu-as arrange to work with GNU as],
+gas_flag="$with_gnu_as",
+gas_flag=no)
+
+AC_ARG_WITH(as,
+[ --with-as arrange to use the specified as (full pathname)],
+DEFAULT_ASSEMBLER="$with_as")
+if test x"${DEFAULT_ASSEMBLER+set}" = x"set"; then
+ if test ! -x "$DEFAULT_ASSEMBLER"; then
+ AC_MSG_WARN([cannot execute: $DEFAULT_ASSEMBLER: check --with-as or env. var. DEFAULT_ASSEMBLER])
+ elif $DEFAULT_ASSEMBLER -v < /dev/null 2>&1 | grep GNU > /dev/null; then
+ gas_flag=yes
+ fi
+ AC_DEFINE_UNQUOTED(DEFAULT_ASSEMBLER,"$DEFAULT_ASSEMBLER",
+ [Define to enable the use of a default assembler.])
+fi
+
+# With stabs
+AC_ARG_WITH(stabs,
+[ --with-stabs arrange to use stabs instead of host debug format],
+stabs="$with_stabs",
+stabs=no)
+
+# With ELF
+AC_ARG_WITH(elf,
+[ --with-elf arrange to use ELF instead of host debug format],
+elf="$with_elf",
+elf=no)
+
+# Specify the local prefix
+local_prefix=
+AC_ARG_WITH(local-prefix,
+[ --with-local-prefix=DIR specifies directory to put local include],
+[case "${withval}" in
+yes) AC_MSG_ERROR(bad value ${withval} given for local include directory prefix) ;;
+no) ;;
+*) local_prefix=$with_local_prefix ;;
+esac])
+
+# Default local prefix if it is empty
+if test x$local_prefix = x; then
+ local_prefix=/usr/local
+fi
+
+# Enable Multibyte Characters for C/C++
+AC_ARG_ENABLE(c-mbchar,
+[ --enable-c-mbchar enable multibyte characters for C and C++],
+if test x$enable_c_mbchar != xno; then
+ AC_DEFINE(MULTIBYTE_CHARS, 1,
+ [Define if you want the C and C++ compilers to support multibyte
+ character sets for source code.])
+fi)
+
+# Find the native compiler
+AC_PROG_CC
+AC_PROG_CC_C_O
+# autoconf is lame and doesn't give us any substitution variable for this.
+if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" = no"; then
+ NO_MINUS_C_MINUS_O=yes
+else
+ OUTPUT_OPTION='-o $@'
+fi
+AC_SUBST(NO_MINUS_C_MINUS_O)
+AC_SUBST(OUTPUT_OPTION)
+
+AC_PROG_CPP
+AC_C_INLINE
+
+# sizeof(char) is 1 by definition.
+gcc_AC_COMPILE_CHECK_SIZEOF(short)
+gcc_AC_COMPILE_CHECK_SIZEOF(int)
+gcc_AC_COMPILE_CHECK_SIZEOF(long)
+
+gcc_AC_C_CHARSET
+
+# If the native compiler is GCC, we can enable warnings even in stage1.
+# That's useful for people building cross-compilers, or just running a
+# quick `make'.
+warn_cflags=
+if test "x$GCC" = "xyes"; then
+ warn_cflags='$(GCC_WARN_CFLAGS)'
+fi
+AC_SUBST(warn_cflags)
+
+AC_PROG_MAKE_SET
+
+AC_MSG_CHECKING([whether a default assembler was specified])
+if test x"${DEFAULT_ASSEMBLER+set}" = x"set"; then
+ if test x"$gas_flag" = x"no"; then
+ AC_MSG_RESULT([yes ($DEFAULT_ASSEMBLER)])
+ else
+ AC_MSG_RESULT([yes ($DEFAULT_ASSEMBLER - GNU as)])
+ fi
+else
+ AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING([whether a default linker was specified])
+if test x"${DEFAULT_LINKER+set}" = x"set"; then
+ if test x"$gnu_ld_flag" = x"no"; then
+ AC_MSG_RESULT([yes ($DEFAULT_LINKER)])
+ else
+ AC_MSG_RESULT([yes ($DEFAULT_LINKER - GNU ld)])
+ fi
+else
+ AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING(for GNU C library)
+AC_CACHE_VAL(gcc_cv_glibc,
+[AC_TRY_COMPILE(
+ [#include <features.h>],[
+#if ! (defined __GLIBC__ || defined __GNU_LIBRARY__)
+#error Not a GNU C library system
+#endif],
+ [gcc_cv_glibc=yes],
+ gcc_cv_glibc=no)])
+AC_MSG_RESULT($gcc_cv_glibc)
+if test $gcc_cv_glibc = yes; then
+ AC_DEFINE(_GNU_SOURCE, 1, [Always define this when using the GNU C Library])
+fi
+
+# Find some useful tools
+gcc_AC_PROG_LN
+gcc_AC_PROG_LN_S
+AC_PROG_RANLIB
+gcc_AC_PROG_INSTALL
+
+AC_HEADER_STDC
+AC_HEADER_TIME
+gcc_AC_HEADER_STRING
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS(limits.h stddef.h string.h strings.h stdlib.h time.h \
+ fcntl.h unistd.h sys/file.h sys/time.h \
+ sys/resource.h sys/param.h sys/times.h sys/stat.h \
+ direct.h malloc.h langinfo.h)
+
+# Check for thread headers.
+
+# These tests can't be done till we know if we have limits.h.
+gcc_AC_C_CHAR_BIT
+gcc_AC_C_COMPILE_ENDIAN
+
+# See if we have the mktemp command.
+AC_CHECK_PROG(have_mktemp_command, mktemp, yes, no)
+
+# See if the stage1 system preprocessor understands the ANSI C
+# preprocessor stringification operator. (Used by symcat.h.)
+AC_C_STRINGIZE
+
+# Use <inttypes.h> only if it exists,
+# doesn't clash with <sys/types.h>, and declares intmax_t.
+AC_MSG_CHECKING(for inttypes.h)
+AC_CACHE_VAL(gcc_cv_header_inttypes_h,
+[AC_TRY_COMPILE(
+ [#include <sys/types.h>
+#include <inttypes.h>],
+ [intmax_t i = -1;],
+ [gcc_cv_header_inttypes_h=yes],
+ gcc_cv_header_inttypes_h=no)])
+AC_MSG_RESULT($gcc_cv_header_inttypes_h)
+if test $gcc_cv_header_inttypes_h = yes; then
+ AC_DEFINE(HAVE_INTTYPES_H, 1,
+ [Define if you have a working <inttypes.h> header file.])
+fi
+
+dnl Disabled until we have a complete test for buggy enum bitfields.
+dnl gcc_AC_C_ENUM_BF_UNSIGNED
+
+AC_CHECK_FUNCS(times clock strchr strrchr lstat)
+
+AC_CHECK_TYPE(ssize_t, int)
+
+AC_FUNC_MMAP_ANYWHERE
+AC_FUNC_MMAP_FILE
+
+# We will need to find libiberty.h and ansidecl.h
+saved_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -I${srcdir} -I${srcdir}/../include"
+gcc_AC_CHECK_DECLS(getenv abort errno \
+ malloc realloc calloc free getopt clock, , ,[
+#include "ansidecl.h"
+#include "system.h"])
+
+gcc_AC_CHECK_DECLS(times, , ,[
+#include "ansidecl.h"
+#include "system.h"
+#ifdef HAVE_SYS_TIMES_H
+#include <sys/times.h>
+#endif
+])
+
+# More time-related stuff.
+AC_CACHE_CHECK(for struct tms, ac_cv_struct_tms, [
+AC_TRY_COMPILE([
+#include "ansidecl.h"
+#include "system.h"
+#ifdef HAVE_SYS_TIMES_H
+#include <sys/times.h>
+#endif
+], [struct tms tms;], ac_cv_struct_tms=yes, ac_cv_struct_tms=no)])
+if test $ac_cv_struct_tms = yes; then
+ AC_DEFINE(HAVE_STRUCT_TMS, 1,
+ [Define if <sys/times.h> defines struct tms.])
+fi
+
+# use gcc_cv_* here because this doesn't match the behavior of AC_CHECK_TYPE.
+# revisit after autoconf 2.50.
+AC_CACHE_CHECK(for clock_t, gcc_cv_type_clock_t, [
+AC_TRY_COMPILE([
+#include "ansidecl.h"
+#include "system.h"
+], [clock_t x;], gcc_cv_type_clock_t=yes, gcc_cv_type_clock_t=no)])
+if test $gcc_cv_type_clock_t = yes; then
+ AC_DEFINE(HAVE_CLOCK_T, 1,
+ [Define if <time.h> defines clock_t.])
+fi
+
+# Restore CFLAGS from before the gcc_AC_NEED_DECLARATIONS tests.
+CFLAGS="$saved_CFLAGS"
+
+# mkdir takes a single argument on some systems.
+gcc_AC_FUNC_MKDIR_TAKES_ONE_ARG
+
+# File extensions
+manext='.1'
+objext='.o'
+AC_SUBST(manext)
+AC_SUBST(objext)
+
+build_xm_file=
+build_xm_defines=
+build_install_headers_dir=install-headers-tar
+build_exeext=
+host_xm_file=
+host_xm_defines=
+host_xmake_file=
+host_truncate_target=
+host_exeext=
+
+# Decode the host machine, then the target machine.
+# For the host machine, we save the xm_file variable as host_xm_file;
+# then we decode the target machine and forget everything else
+# that came from the host machine.
+#for machine in $build $host $target; do
+# . ${srcdir}/config.gcc
+#done
+
+extra_objs="${host_extra_objs} ${extra_objs}"
+
+# Default the target-machine variables that were not explicitly set.
+if test x"$tm_file" = x
+then tm_file=$cpu_type/$cpu_type.h; fi
+
+if test x"$extra_headers" = x
+then extra_headers=; fi
+
+if test x$md_file = x
+then md_file=$cpu_type/$cpu_type.md; fi
+
+if test x$out_file = x
+then out_file=$cpu_type/$cpu_type.c; fi
+
+if test x"$tmake_file" = x
+then tmake_file=$cpu_type/t-$cpu_type
+fi
+
+if test x"$dwarf2" = xyes
+then tm_file="$tm_file tm-dwarf2.h"
+fi
+
+# Handle cpp installation.
+if test x$enable_cpp != xno
+then
+ tmake_file="$tmake_file t-install-cpp"
+fi
+
+# auto-host.h is the file containing items generated by autoconf and is
+# the first file included by config.h.
+# If host=build, it is correct to have hconfig include auto-host.h
+# as well. If host!=build, we are in error and need to do more
+# work to find out the build config parameters.
+if test x$host = x$build
+then
+ build_auto=auto-host.h
+else
+ # We create a subdir, then run autoconf in the subdir.
+ # To prevent recursion we set host and build for the new
+ # invocation of configure to the build for this invocation
+ # of configure.
+ tempdir=build.$$
+ rm -rf $tempdir
+ mkdir $tempdir
+ cd $tempdir
+ case ${srcdir} in
+ /* | [A-Za-z]:[\\/]* ) realsrcdir=${srcdir};;
+ *) realsrcdir=../${srcdir};;
+ esac
+ CC=${CC_FOR_BUILD} ${realsrcdir}/configure \
+ --target=$target --host=$build --build=$build
+
+ # We just finished tests for the build machine, so rename
+ # the file auto-build.h in the gcc directory.
+ mv auto-host.h ../auto-build.h
+ cd ..
+ rm -rf $tempdir
+ build_auto=auto-build.h
+fi
+
+tm_file="${tm_file} defaults.h"
+host_xm_file="auto-host.h ansidecl.h ${host_xm_file} ${tm_file}"
+build_xm_file="${build_auto} ansidecl.h ${build_xm_file} ${tm_file}"
+xm_file="ansidecl.h ${xm_file} ${tm_file}"
+
+# Truncate the target if necessary
+if test x$host_truncate_target != x; then
+ target=`echo $target | sed -e 's/\(..............\).*/\1/'`
+fi
+
+# Get the version trigger filename from the toplevel
+if test "${with_gcc_version_trigger+set}" = set; then
+ gcc_version_trigger=$with_gcc_version_trigger
+else
+ gcc_version_trigger=${srcdir}/version.c
+fi
+changequote(,)dnl
+gcc_version_full=`grep version_string ${gcc_version_trigger} | sed -e 's/.*"\([^"]*\)".*/\1/'`
+gcc_version=`echo ${gcc_version_full} | sed -e 's/\([^ ]*\) .*/\1/'`
+
+# Compile in configure arguments.
+if test -f configargs.h ; then
+ # Being re-configured.
+ gcc_config_arguments=`grep configuration_arguments configargs.h | sed -e 's/.*"\([^"]*\)".*/\1/'`
+ gcc_config_arguments="$gcc_config_arguments : (reconfigured) $TOPLEVEL_CONFIGURE_ARGUMENTS"
+else
+ gcc_config_arguments="$TOPLEVEL_CONFIGURE_ARGUMENTS"
+fi
+cat > configargs.h <<EOF
+/* Generated automatically. */
+static const char configuration_arguments[] = "$gcc_config_arguments";
+static const char thread_model[] = "$thread_file";
+EOF
+changequote([,])dnl
+
+# Internationalization
+PACKAGE=sdcc
+VERSION="$gcc_version"
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE",
+ [Define to the name of the distribution.])
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION",
+ [Define to the version of the distribution.])
+AC_SUBST(PACKAGE)
+AC_SUBST(VERSION)
+
+ALL_LINGUAS="sv"
+
+# Get an absolute path to the GCC top-level source directory
+holddir=`pwd`
+cd $srcdir
+topdir=`pwd`
+cd $holddir
+
+out_object_file=`basename $out_file .c`.o
+
+# Figure out what assembler we will be using.
+AC_MSG_CHECKING(what assembler to use)
+gcc_cv_as=
+gcc_cv_gas_major_version=
+gcc_cv_gas_minor_version=
+gcc_cv_as_gas_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/gas
+if test -x "$DEFAULT_ASSEMBLER"; then
+ gcc_cv_as="$DEFAULT_ASSEMBLER"
+elif test -x "$AS"; then
+ gcc_cv_as="$AS"
+elif test -x as$host_exeext; then
+ # Build using assembler in the current directory.
+ gcc_cv_as=./as$host_exeext
+elif test -f $gcc_cv_as_gas_srcdir/configure.in -a -f ../gas/Makefile; then
+ # Single tree build which includes gas.
+ for f in $gcc_cv_as_gas_srcdir/configure $gcc_cv_as_gas_srcdir/configure.in $gcc_cv_as_gas_srcdir/Makefile.in
+ do
+changequote(,)dnl
+ gcc_cv_gas_version=`grep '^VERSION=[0-9]*\.[0-9]*' $f`
+changequote([,])dnl
+ if test x$gcc_cv_gas_version != x; then
+ break
+ fi
+ done
+changequote(,)dnl
+ gcc_cv_gas_major_version=`expr "$gcc_cv_gas_version" : "VERSION=\([0-9]*\)"`
+ gcc_cv_gas_minor_version=`expr "$gcc_cv_gas_version" : "VERSION=[0-9]*\.\([0-9]*\)"`
+changequote([,])dnl
+fi
+
+if test "x$gcc_cv_as" = x -a x$host = x$target; then
+ # Native build.
+ # Search the same directories that the installed compiler will
+ # search. Else we may find the wrong assembler and lose. If we
+ # do not find a suitable assembler binary, then try the user's
+ # path.
+ #
+ # Also note we have to check MD_EXEC_PREFIX before checking the
+ # user's path. Unfortunately, there is no good way to get at the
+ # value of MD_EXEC_PREFIX here. So we do a brute force search
+ # through all the known MD_EXEC_PREFIX values. Ugh. This needs
+ # to be fixed as part of the make/configure rewrite too.
+
+ if test "x$exec_prefix" = xNONE; then
+ if test "x$prefix" = xNONE; then
+ test_prefix=/usr/local
+ else
+ test_prefix=$prefix
+ fi
+ else
+ test_prefix=$exec_prefix
+ fi
+
+ # If the loop below does not find an assembler, then use whatever
+ # one we can find in the users's path.
+ # user's path.
+ gcc_cv_as=as$host_exeext
+
+ test_dirs="$test_prefix/lib/gcc-lib/$target/$gcc_version \
+ $test_prefix/lib/gcc-lib/$target \
+ /usr/lib/gcc/$target/$gcc_version \
+ /usr/lib/gcc/$target \
+ $test_prefix/$target/bin/$target/$gcc_version \
+ $test_prefix/$target/bin \
+ /usr/libexec \
+ /usr/ccs/gcc \
+ /usr/ccs/bin \
+ /udk/usr/ccs/bin \
+ /bsd43/usr/lib/cmplrs/cc \
+ /usr/cross64/usr/bin \
+ /usr/lib/cmplrs/cc \
+ /sysv/usr/lib/cmplrs/cc \
+ /svr4/usr/lib/cmplrs/cc \
+ /usr/bin"
+
+ for dir in $test_dirs; do
+ if test -f $dir/as$host_exeext; then
+ gcc_cv_as=$dir/as$host_exeext
+ break;
+ fi
+ done
+fi
+if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x; then
+ AC_MSG_RESULT("newly built gas")
+else
+ AC_MSG_RESULT($gcc_cv_as)
+fi
+
+# Figure out what nm we will be using.
+AC_MSG_CHECKING(what nm to use)
+if test -x nm$host_exeext; then
+ gcc_cv_nm=./nm$host_exeext
+elif test x$host = x$target; then
+ # Native build.
+ gcc_cv_nm=nm$host_exeext
+fi
+AC_MSG_RESULT($gcc_cv_nm)
+
+dnl Very limited version of automake's enable-maintainer-mode
+
+AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+ dnl maintainer-mode is disabled by default
+ AC_ARG_ENABLE(maintainer-mode,
+[ --enable-maintainer-mode
+ enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer],
+ maintainer_mode=$enableval,
+ maintainer_mode=no)
+
+AC_MSG_RESULT($maintainer_mode)
+
+if test "$maintainer_mode" = "yes"; then
+ MAINT=''
+else
+ MAINT='#'
+fi
+AC_SUBST(MAINT)dnl
+
+# These (without "all_") are set in each config-lang.in.
+# `language' must be a single word so is spelled singularly.
+all_stagestuff=
+all_outputs='Makefile'
+# List of language makefile fragments.
+
+# Add the language fragments.
+# Languages are added via two mechanisms. Some information must be
+# recorded in makefile variables, these are defined in config-lang.in.
+# We accumulate them and plug them into the main Makefile.
+# The other mechanism is a set of hooks for each of the main targets
+# like `clean', `install', etc.
+
+language_fragments="Make-lang"
+
+# Define variables host_canonical and build_canonical
+# because some Cygnus local changes in the Makefile depend on them.
+build_canonical=${build}
+host_canonical=${host}
+target_subdir=
+if test "${host}" != "${target}" ; then
+ target_subdir=${target_alias}/
+fi
+AC_SUBST(build_canonical)
+AC_SUBST(host_canonical)
+AC_SUBST(target_subdir)
+
+# Nothing to do for FLOAT_H, float_format already handled.
+objdir=`pwd`
+AC_SUBST(objdir)
+
+# Substitute configuration variables
+AC_SUBST(all_stagestuff)
+AC_SUBST(build_exeext)
+AC_SUBST(build_install_headers_dir)
+AC_SUBST(build_xm_file_list)
+AC_SUBST(build_xm_file)
+AC_SUBST(build_xm_defines)
+AC_SUBST(check_languages)
+AC_SUBST(dep_host_xmake_file)
+AC_SUBST(dep_tmake_file)
+AC_SUBST(extra_c_flags)
+AC_SUBST(extra_headers_list)
+AC_SUBST(extra_objs)
+AC_SUBST(extra_parts)
+AC_SUBST(extra_passes)
+AC_SUBST(extra_programs)
+AC_SUBST(gcc_config_arguments)
+AC_SUBST(gcc_version)
+AC_SUBST(gcc_version_full)
+AC_SUBST(gcc_version_trigger)
+AC_SUBST(host_exeext)
+AC_SUBST(host_extra_gcc_objs)
+AC_SUBST(install)
+AC_SUBST(lang_tree_files)
+AC_SUBST(local_prefix)
+AC_SUBST(md_file)
+AC_SUBST(out_file)
+AC_SUBST(out_object_file)
+AC_SUBST(symbolic_link)
+AC_SUBST(thread_file)
+AC_SUBST(c_target_objs)
+
+AC_SUBST_FILE(target_overrides)
+AC_SUBST_FILE(host_overrides)
+AC_SUBST(cross_defines)
+AC_SUBST_FILE(cross_overrides)
+AC_SUBST_FILE(build_overrides)
+
+# Create the Makefile
+# and configure language subdirectories
+AC_OUTPUT($all_outputs,
+[
+case x$CONFIG_HEADERS in
+xauto-host.h:config.in)
+echo > cstamp-h ;;
+esac
+
+# Avoid having to add intl to our include paths.
+if test -f intl/libintl.h; then
+ echo creating libintl.h
+ echo '#include "intl/libintl.h"' >libintl.h
+fi
+],
+[
+host='${host}'
+build='${build}'
+target='${target}'
+target_alias='${target_alias}'
+srcdir='${srcdir}'
+symbolic_link='${symbolic_link}'
+program_transform_set='${program_transform_set}'
+program_transform_name='${program_transform_name}'
+dep_host_xmake_file='${dep_host_xmake_file}'
+host_xmake_file='${host_xmake_file}'
+dep_tmake_file='${dep_tmake_file}'
+tmake_file='${tmake_file}'
+thread_file='${thread_file}'
+gcc_config_arguments='${gcc_config_arguments}'
+gcc_version='${gcc_version}'
+gcc_version_full='${gcc_version_full}'
+gcc_version_trigger='${gcc_version_trigger}'
+local_prefix='${local_prefix}'
+build_install_headers_dir='${build_install_headers_dir}'
+build_exeext='${build_exeext}'
+host_exeext='${host_exeext}'
+out_file='${out_file}'
+gdb_needs_out_file_path='${gdb_needs_out_file_path}'
+SET_MAKE='${SET_MAKE}'
+target_list='${target_list}'
+target_overrides='${target_overrides}'
+host_overrides='${host_overrides}'
+cross_defines='${cross_defines}'
+cross_overrides='${cross_overrides}'
+build_overrides='${build_overrides}'
+cpp_install_dir='${cpp_install_dir}'
+])
--- /dev/null
+/* CPP Library.
+ Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000 Free Software Foundation, Inc.
+ Contributed by Per Bothner, 1994-95.
+ Based on CCCP program by Paul Rubin, June 1986
+ Adapted to ANSI C, Richard Stallman, Jan 1987
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This file contains data definitions shared between cpplib and
+ tradcpp. */
+
+#include "config.h"
+#include "system.h"
+#include "cppdefault.h"
+
+const struct default_include cpp_include_defaults[]
+#ifdef INCLUDE_DEFAULTS
+= INCLUDE_DEFAULTS;
+#else
+= {
+#ifdef GPLUSPLUS_INCLUDE_DIR
+ /* Pick up GNU C++ generic include files. */
+ { GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1 },
+#endif
+#ifdef GPLUSPLUS_TOOL_INCLUDE_DIR
+ /* Pick up GNU C++ target-dependent include files. */
+ { GPLUSPLUS_TOOL_INCLUDE_DIR, "G++", 1, 1 },
+#endif
+#ifdef GPLUSPLUS_BACKWARD_INCLUDE_DIR
+ /* Pick up GNU C++ backward and deprecated include files. */
+ { GPLUSPLUS_BACKWARD_INCLUDE_DIR, "G++", 1, 1 },
+#endif
+#ifdef LOCAL_INCLUDE_DIR
+ /* /usr/local/include comes before the fixincluded header files. */
+ { LOCAL_INCLUDE_DIR, 0, 0, 1 },
+#endif
+#ifdef GCC_INCLUDE_DIR
+ /* This is the dir for fixincludes and for gcc's private headers. */
+ { GCC_INCLUDE_DIR, "GCC", 0, 0 },
+#endif
+#ifdef CROSS_INCLUDE_DIR
+ /* One place the target system's headers might be. */
+ { CROSS_INCLUDE_DIR, "GCC", 0, 0 },
+#endif
+#ifdef TOOL_INCLUDE_DIR
+ /* Another place the target system's headers might be. */
+ { TOOL_INCLUDE_DIR, "BINUTILS", 0, 1 },
+#endif
+#ifdef SYSTEM_INCLUDE_DIR
+ /* Some systems have an extra dir of include files. */
+ { SYSTEM_INCLUDE_DIR, 0, 0, 0 },
+#endif
+#ifdef STANDARD_INCLUDE_DIR
+ /* /usr/include comes dead last. */
+ { STANDARD_INCLUDE_DIR, STANDARD_INCLUDE_COMPONENT, 0, 0 },
+#endif
+ { 0, 0, 0, 0 }
+ };
+#endif /* no INCLUDE_DEFAULTS */
+
+#ifdef GCC_INCLUDE_DIR
+const char cpp_GCC_INCLUDE_DIR[] = GCC_INCLUDE_DIR;
+const size_t cpp_GCC_INCLUDE_DIR_len = sizeof GCC_INCLUDE_DIR - 8;
+#else
+const char cpp_GCC_INCLUDE_DIR[] = "";
+const size_t cpp_GCC_INCLUDE_DIR_len = 0;
+#endif
--- /dev/null
+/* CPP Library.
+ Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000 Free Software Foundation, Inc.
+ Contributed by Per Bothner, 1994-95.
+ Based on CCCP program by Paul Rubin, June 1986
+ Adapted to ANSI C, Richard Stallman, Jan 1987
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef GCC_CPPDEFAULT_H
+#define GCC_CPPDEFAULT_H
+
+/* This header contains declarations and/or #defines for all the
+ hard-wired defaults in cpp. Note it's used by both cpplib and
+ tradcpp. */
+
+#ifndef STANDARD_INCLUDE_DIR
+#define STANDARD_INCLUDE_DIR "/usr/include"
+#endif
+
+#ifndef STANDARD_INCLUDE_COMPONENT
+#define STANDARD_INCLUDE_COMPONENT 0
+#endif
+
+#ifdef CROSS_COMPILE
+#undef LOCAL_INCLUDE_DIR
+#undef SYSTEM_INCLUDE_DIR
+#undef STANDARD_INCLUDE_DIR
+#else
+#undef CROSS_INCLUDE_DIR
+#endif
+
+/* We let tm.h override the types used here, to handle trivial differences
+ such as the choice of unsigned int or long unsigned int for size_t.
+ When machines start needing nontrivial differences in the size type,
+ it would be best to do something here to figure out automatically
+ from other information what type to use. */
+
+/* The string value for __SIZE_TYPE__. */
+
+#ifndef SIZE_TYPE
+#define SIZE_TYPE "long unsigned int"
+#endif
+
+/* The string value for __PTRDIFF_TYPE__. */
+
+#ifndef PTRDIFF_TYPE
+#define PTRDIFF_TYPE "long int"
+#endif
+
+/* The string value for __WCHAR_TYPE__. */
+
+#ifndef WCHAR_TYPE
+#define WCHAR_TYPE "int"
+#endif
+
+/* The string value for __WINT_TYPE__. */
+
+#ifndef WINT_TYPE
+#define WINT_TYPE "unsigned int"
+#endif
+
+/* The string value for __USER_LABEL_PREFIX__ */
+
+#ifndef USER_LABEL_PREFIX
+#define USER_LABEL_PREFIX ""
+#endif
+
+/* The string value for __REGISTER_PREFIX__ */
+
+#ifndef REGISTER_PREFIX
+#define REGISTER_PREFIX ""
+#endif
+
+/* This is the default list of directories to search for include files.
+ It may be overridden by the various -I and -ixxx options.
+
+ #include "file" looks in the same directory as the current file,
+ then this list.
+ #include <file> just looks in this list.
+
+ All these directories are treated as `system' include directories
+ (they are not subject to pedantic warnings in some cases). */
+
+struct default_include
+{
+ const char *fname; /* The name of the directory. */
+ const char *component; /* The component containing the directory
+ (see update_path in prefix.c) */
+ int cplusplus; /* Only look here if we're compiling C++. */
+ int cxx_aware; /* Includes in this directory don't need to
+ be wrapped in extern "C" when compiling
+ C++. */
+};
+
+extern const struct default_include cpp_include_defaults[];
+extern const char cpp_GCC_INCLUDE_DIR[];
+extern const size_t cpp_GCC_INCLUDE_DIR_len;
+
+#endif /* ! GCC_CPPDEFAULT_H */
--- /dev/null
+/* Default error handlers for CPP Library.
+ Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1998, 1999, 2000
+ Free Software Foundation, Inc.
+ Written by Per Bothner, 1994.
+ Based on CCCP program by Paul Rubin, June 1986
+ Adapted to ANSI C, Richard Stallman, Jan 1987
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ In other words, you are welcome to use, share and improve this program.
+ You are forbidden to forbid anyone else to use, share and improve
+ what you give them. Help stamp out software-hoarding! */
+
+#include "config.h"
+#include "system.h"
+#include "cpplib.h"
+#include "cpphash.h"
+#include "intl.h"
+
+static void print_containing_files PARAMS ((cpp_buffer *));
+static void print_location PARAMS ((cpp_reader *,
+ const char *,
+ const cpp_lexer_pos *));
+
+/* Don't remove the blank before do, as otherwise the exgettext
+ script will mistake this as a function definition */
+#define v_message(msgid, ap) \
+ do { vfprintf (stderr, _(msgid), ap); putc ('\n', stderr); } while (0)
+
+/* Print the file names and line numbers of the #include
+ commands which led to the current file. */
+static void
+print_containing_files (ip)
+ cpp_buffer *ip;
+{
+ int first = 1;
+
+ /* Find the other, outer source files. */
+ for (ip = ip->prev; ip; ip = ip->prev)
+ {
+ if (first)
+ {
+ first = 0;
+ /* The current line in each outer source file is now the
+ same as the line of the #include. */
+ fprintf (stderr, _("In file included from %s:%u"),
+ ip->nominal_fname, CPP_BUF_LINE (ip));
+ }
+ else
+ /* Translators note: this message is used in conjunction
+ with "In file included from %s:%ld" and some other
+ tricks. We want something like this:
+
+ | In file included from sys/select.h:123,
+ | from sys/types.h:234,
+ | from userfile.c:31:
+ | bits/select.h:45: <error message here>
+
+ with all the "from"s lined up.
+ The trailing comma is at the beginning of this message,
+ and the trailing colon is not translated. */
+ fprintf (stderr, _(",\n from %s:%u"),
+ ip->nominal_fname, CPP_BUF_LINE (ip));
+ }
+ fputs (":\n", stderr);
+}
+
+static void
+print_location (pfile, filename, pos)
+ cpp_reader *pfile;
+ const char *filename;
+ const cpp_lexer_pos *pos;
+{
+ cpp_buffer *buffer = pfile->buffer;
+
+ if (!buffer)
+ fprintf (stderr, "%s: ", progname);
+ else
+ {
+ unsigned int line, col = 0;
+ enum cpp_buffer_type type = buffer->type;
+
+ /* For _Pragma buffers, we want to print the location as
+ "foo.c:5:8: _Pragma:", where foo.c is the containing buffer.
+ For diagnostics relating to command line options, we want to
+ print "<command line>:" with no line number. */
+ if (type == BUF_CL_OPTION || type == BUF_BUILTIN)
+ line = 0;
+ else
+ {
+ if (type == BUF_PRAGMA)
+ {
+ buffer = buffer->prev;
+ line = CPP_BUF_LINE (buffer);
+ col = CPP_BUF_COL (buffer);
+ }
+ else
+ {
+ if (pos == 0)
+ pos = cpp_get_line (pfile);
+ line = pos->line;
+ col = pos->col;
+ }
+
+ if (col == 0)
+ col = 1;
+
+ /* Don't repeat the include stack unnecessarily. */
+ if (buffer->prev && ! buffer->include_stack_listed)
+ {
+ buffer->include_stack_listed = 1;
+ print_containing_files (buffer);
+ }
+ }
+
+ if (filename == 0)
+ filename = buffer->nominal_fname;
+
+ if (line == 0)
+ fprintf (stderr, "%s: ", filename);
+ else if (CPP_OPTION (pfile, show_column) == 0)
+ fprintf (stderr, "%s:%u: ", filename, line);
+ else
+ fprintf (stderr, "%s:%u:%u: ", filename, line, col);
+
+ if (type == BUF_PRAGMA)
+ fprintf (stderr, "_Pragma: ");
+ }
+}
+
+/* Set up for an error message: print the file and line, bump the error
+ counter, etc.
+ If it returns 0, this error has been suppressed. */
+
+int
+_cpp_begin_message (pfile, code, file, pos)
+ cpp_reader *pfile;
+ enum error_type code;
+ const char *file;
+ const cpp_lexer_pos *pos;
+{
+ int is_warning = 0;
+
+ switch (code)
+ {
+ case PEDWARN:
+ case WARNING:
+ if (CPP_IN_SYSTEM_HEADER (pfile)
+ && ! CPP_OPTION (pfile, warn_system_headers))
+ return 0;
+ case WARNING_SYSHDR:
+ if (CPP_OPTION (pfile, warnings_are_errors)
+ || (code == PEDWARN && CPP_OPTION (pfile, pedantic_errors)))
+ {
+ if (CPP_OPTION (pfile, inhibit_errors))
+ return 0;
+ if (pfile->errors < CPP_FATAL_LIMIT)
+ pfile->errors++;
+ }
+ else
+ {
+ if (CPP_OPTION (pfile, inhibit_warnings))
+ return 0;
+ is_warning = 1;
+ }
+ break;
+
+ case ERROR:
+ if (CPP_OPTION (pfile, inhibit_errors))
+ return 0;
+ if (pfile->errors < CPP_FATAL_LIMIT)
+ pfile->errors++;
+ break;
+ /* Fatal errors cannot be inhibited. */
+ case FATAL:
+ pfile->errors = CPP_FATAL_LIMIT;
+ break;
+ case ICE:
+ fprintf (stderr, _("internal error: "));
+ pfile->errors = CPP_FATAL_LIMIT;
+ break;
+ }
+
+ print_location (pfile, file, pos);
+ if (is_warning)
+ fputs (_("warning: "), stderr);
+
+ return 1;
+}
+
+/* Exported interface. */
+
+/* For reporting internal errors. Prints "internal error: " for you,
+ otherwise identical to cpp_fatal. */
+
+void
+cpp_ice VPARAMS ((cpp_reader *pfile, const char *msgid, ...))
+{
+#ifndef ANSI_PROTOTYPES
+ cpp_reader *pfile;
+ const char *msgid;
+#endif
+ va_list ap;
+
+ VA_START (ap, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ pfile = va_arg (ap, cpp_reader *);
+ msgid = va_arg (ap, const char *);
+#endif
+
+ if (_cpp_begin_message (pfile, ICE, NULL, 0))
+ v_message (msgid, ap);
+ va_end(ap);
+}
+
+/* Same as cpp_error, except we consider the error to be "fatal",
+ such as inconsistent options. I.e. there is little point in continuing.
+ (We do not exit, to support use of cpplib as a library.
+ Instead, it is the caller's responsibility to check
+ CPP_FATAL_ERRORS. */
+
+void
+cpp_fatal VPARAMS ((cpp_reader *pfile, const char *msgid, ...))
+{
+#ifndef ANSI_PROTOTYPES
+ cpp_reader *pfile;
+ const char *msgid;
+#endif
+ va_list ap;
+
+ VA_START (ap, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ pfile = va_arg (ap, cpp_reader *);
+ msgid = va_arg (ap, const char *);
+#endif
+
+ if (_cpp_begin_message (pfile, FATAL, NULL, 0))
+ v_message (msgid, ap);
+ va_end(ap);
+}
+
+void
+cpp_error VPARAMS ((cpp_reader * pfile, const char *msgid, ...))
+{
+#ifndef ANSI_PROTOTYPES
+ cpp_reader *pfile;
+ const char *msgid;
+#endif
+ va_list ap;
+
+ VA_START(ap, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ pfile = va_arg (ap, cpp_reader *);
+ msgid = va_arg (ap, const char *);
+#endif
+
+ if (_cpp_begin_message (pfile, ERROR, NULL, 0))
+ v_message (msgid, ap);
+ va_end(ap);
+}
+
+void
+cpp_error_with_line VPARAMS ((cpp_reader *pfile, int line, int column,
+ const char *msgid, ...))
+{
+#ifndef ANSI_PROTOTYPES
+ cpp_reader *pfile;
+ int line;
+ int column;
+ const char *msgid;
+#endif
+ va_list ap;
+ cpp_lexer_pos pos;
+
+ VA_START (ap, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ pfile = va_arg (ap, cpp_reader *);
+ line = va_arg (ap, int);
+ column = va_arg (ap, int);
+ msgid = va_arg (ap, const char *);
+#endif
+
+ pos.line = line;
+ pos.col = column;
+ if (_cpp_begin_message (pfile, ERROR, NULL, &pos))
+ v_message (msgid, ap);
+ va_end(ap);
+}
+
+/* Error including a message from `errno'. */
+void
+cpp_error_from_errno (pfile, name)
+ cpp_reader *pfile;
+ const char *name;
+{
+ cpp_error (pfile, "%s: %s", name, xstrerror (errno));
+}
+
+void
+cpp_warning VPARAMS ((cpp_reader * pfile, const char *msgid, ...))
+{
+#ifndef ANSI_PROTOTYPES
+ cpp_reader *pfile;
+ const char *msgid;
+#endif
+ va_list ap;
+
+ VA_START (ap, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ pfile = va_arg (ap, cpp_reader *);
+ msgid = va_arg (ap, const char *);
+#endif
+
+ if (_cpp_begin_message (pfile, WARNING, NULL, 0))
+ v_message (msgid, ap);
+ va_end(ap);
+}
+
+void
+cpp_warning_with_line VPARAMS ((cpp_reader * pfile, int line, int column,
+ const char *msgid, ...))
+{
+#ifndef ANSI_PROTOTYPES
+ cpp_reader *pfile;
+ int line;
+ int column;
+ const char *msgid;
+#endif
+ va_list ap;
+ cpp_lexer_pos pos;
+
+ VA_START (ap, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ pfile = va_arg (ap, cpp_reader *);
+ line = va_arg (ap, int);
+ column = va_arg (ap, int);
+ msgid = va_arg (ap, const char *);
+#endif
+
+ pos.line = line;
+ pos.col = column;
+ if (_cpp_begin_message (pfile, WARNING, NULL, &pos))
+ v_message (msgid, ap);
+ va_end(ap);
+}
+
+void
+cpp_pedwarn VPARAMS ((cpp_reader * pfile, const char *msgid, ...))
+{
+#ifndef ANSI_PROTOTYPES
+ cpp_reader *pfile;
+ const char *msgid;
+#endif
+ va_list ap;
+
+ VA_START (ap, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ pfile = va_arg (ap, cpp_reader *);
+ msgid = va_arg (ap, const char *);
+#endif
+
+ if (_cpp_begin_message (pfile, PEDWARN, NULL, 0))
+ v_message (msgid, ap);
+ va_end(ap);
+}
+
+void
+cpp_pedwarn_with_line VPARAMS ((cpp_reader * pfile, int line, int column,
+ const char *msgid, ...))
+{
+#ifndef ANSI_PROTOTYPES
+ cpp_reader *pfile;
+ int line;
+ int column;
+ const char *msgid;
+#endif
+ va_list ap;
+ cpp_lexer_pos pos;
+
+ VA_START (ap, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ pfile = va_arg (ap, cpp_reader *);
+ line = va_arg (ap, int);
+ column = va_arg (ap, int);
+ msgid = va_arg (ap, const char *);
+#endif
+
+ pos.line = line;
+ pos.col = column;
+ if (_cpp_begin_message (pfile, PEDWARN, NULL, &pos))
+ v_message (msgid, ap);
+ va_end(ap);
+}
+
+/* Report a warning (or an error if pedantic_errors)
+ giving specified file name and line number, not current. */
+
+void
+cpp_pedwarn_with_file_and_line VPARAMS ((cpp_reader *pfile,
+ const char *file, int line, int col,
+ const char *msgid, ...))
+{
+#ifndef ANSI_PROTOTYPES
+ cpp_reader *pfile;
+ const char *file;
+ int line;
+ int col;
+ const char *msgid;
+#endif
+ va_list ap;
+ cpp_lexer_pos pos;
+
+ VA_START (ap, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ pfile = va_arg (ap, cpp_reader *);
+ file = va_arg (ap, const char *);
+ line = va_arg (ap, int);
+ col = va_arg (ap, int);
+ msgid = va_arg (ap, const char *);
+#endif
+
+ pos.line = line;
+ pos.col = col;
+ if (_cpp_begin_message (pfile, PEDWARN, file, &pos))
+ v_message (msgid, ap);
+ va_end(ap);
+}
+
+/* Print an error message not associated with a file. */
+void
+cpp_notice VPARAMS ((cpp_reader *pfile, const char *msgid, ...))
+{
+#ifndef ANSI_PROTOTYPES
+ cpp_reader *pfile;
+ const char *msgid;
+#endif
+ va_list ap;
+
+ VA_START (ap, msgid);
+
+#ifndef ANSI_PROTOTYPES
+ pfile = va_arg (ap, cpp_reader *);
+ msgid = va_arg (ap, const char *);
+#endif
+
+ if (pfile->errors < CPP_FATAL_LIMIT)
+ pfile->errors++;
+
+ vfprintf (stderr, _(msgid), ap);
+ putc('\n', stderr);
+
+ va_end(ap);
+}
+
+void
+cpp_notice_from_errno (pfile, name)
+ cpp_reader *pfile;
+ const char *name;
+{
+ if (name[0] == '\0')
+ name = "stdout";
+ cpp_notice (pfile, "%s: %s", name, xstrerror (errno));
+}
--- /dev/null
+/* Parse C expressions for cpplib.
+ Copyright (C) 1987, 1992, 1994, 1995, 1997, 1998, 1999, 2000, 2001
+ Free Software Foundation.
+ Contributed by Per Bothner, 1994.
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "cpplib.h"
+#include "cpphash.h"
+
+/* Yield nonzero if adding two numbers with A's and B's signs can yield a
+ number with SUM's sign, where A, B, and SUM are all C integers. */
+#define possible_sum_sign(a, b, sum) ((((a) ^ (b)) | ~ ((a) ^ (sum))) < 0)
+
+static void integer_overflow PARAMS ((cpp_reader *));
+static HOST_WIDEST_INT left_shift PARAMS ((cpp_reader *, HOST_WIDEST_INT,
+ unsigned int,
+ unsigned HOST_WIDEST_INT));
+static HOST_WIDEST_INT right_shift PARAMS ((cpp_reader *, HOST_WIDEST_INT,
+ unsigned int,
+ unsigned HOST_WIDEST_INT));
+static struct op parse_number PARAMS ((cpp_reader *, const cpp_token *));
+static struct op parse_defined PARAMS ((cpp_reader *));
+static struct op lex PARAMS ((cpp_reader *, int, cpp_token *));
+static const unsigned char *op_as_text PARAMS ((cpp_reader *, enum cpp_ttype));
+
+struct op
+{
+ enum cpp_ttype op;
+ U_CHAR prio; /* Priority of op. */
+ U_CHAR flags;
+ U_CHAR unsignedp; /* True if value should be treated as unsigned. */
+ HOST_WIDEST_INT value; /* The value logically "right" of op. */
+};
+
+/* There is no "error" token, but we can't get comments in #if, so we can
+ abuse that token type. */
+#define CPP_ERROR CPP_COMMENT
+
+/* With -O2, gcc appears to produce nice code, moving the error
+ message load and subsequent jump completely out of the main path. */
+#define CPP_ICE(msgid) \
+ do { cpp_ice (pfile, msgid); goto syntax_error; } while(0)
+#define SYNTAX_ERROR(msgid) \
+ do { cpp_error (pfile, msgid); goto syntax_error; } while(0)
+#define SYNTAX_ERROR2(msgid, arg) \
+ do { cpp_error (pfile, msgid, arg); goto syntax_error; } while(0)
+
+/* Parse and convert an integer for #if. Accepts decimal, hex, or octal
+ with or without size suffixes. */
+struct suffix
+{
+ unsigned char s[4];
+ unsigned char u;
+ unsigned char l;
+};
+
+const struct suffix vsuf_1[] = {
+ { "u", 1, 0 }, { "U", 1, 0 },
+ { "l", 0, 1 }, { "L", 0, 1 }
+};
+
+const struct suffix vsuf_2[] = {
+ { "ul", 1, 1 }, { "UL", 1, 1 }, { "uL", 1, 1 }, { "Ul", 1, 1 },
+ { "lu", 1, 1 }, { "LU", 1, 1 }, { "Lu", 1, 1 }, { "lU", 1, 1 },
+ { "ll", 0, 2 }, { "LL", 0, 2 }
+};
+
+const struct suffix vsuf_3[] = {
+ { "ull", 1, 2 }, { "ULL", 1, 2 }, { "uLL", 1, 2 }, { "Ull", 1, 2 },
+ { "llu", 1, 2 }, { "LLU", 1, 2 }, { "LLu", 1, 2 }, { "llU", 1, 2 }
+};
+#define Nsuff(tab) (sizeof tab / sizeof (struct suffix))
+
+static struct op
+parse_number (pfile, tok)
+ cpp_reader *pfile;
+ const cpp_token *tok;
+{
+ struct op op;
+ const U_CHAR *start = tok->val.str.text;
+ const U_CHAR *end = start + tok->val.str.len;
+ const U_CHAR *p = start;
+ int c = 0, i, nsuff;
+ unsigned HOST_WIDEST_INT n = 0, nd, MAX_over_base;
+ int base = 10;
+ int overflow = 0;
+ int digit, largest_digit = 0;
+ const struct suffix *sufftab;
+
+ op.unsignedp = 0;
+
+ if (p[0] == '0')
+ {
+ if (end - start >= 3 && (p[1] == 'x' || p[1] == 'X'))
+ {
+ p += 2;
+ base = 16;
+ }
+ else
+ {
+ p += 1;
+ base = 8;
+ }
+ }
+
+ /* Some buggy compilers (e.g. MPW C) seem to need both casts. */
+ MAX_over_base = (((unsigned HOST_WIDEST_INT) -1)
+ / ((unsigned HOST_WIDEST_INT) base));
+
+ for(; p < end; p++)
+ {
+ c = *p;
+
+ if (c >= '0' && c <= '9')
+ digit = c - '0';
+ /* We believe that in all live character sets, a-f are
+ consecutive, and so are A-F. */
+ else if (base == 16 && c >= 'a' && c <= 'f')
+ digit = c - 'a' + 10;
+ else if (base == 16 && c >= 'A' && c <= 'F')
+ digit = c - 'A' + 10;
+ else
+ break;
+
+ if (largest_digit < digit)
+ largest_digit = digit;
+ nd = n * base + digit;
+ overflow |= MAX_over_base < n || nd < n;
+ n = nd;
+ }
+
+ if (p < end)
+ {
+ /* Check for a floating point constant. Note that float constants
+ with an exponent or suffix but no decimal point are technically
+ invalid (C99 6.4.4.2) but accepted elsewhere. */
+ if ((c == '.' || c == 'F' || c == 'f')
+ || (base == 10 && (c == 'E' || c == 'e')
+ && p+1 < end && (p[1] == '+' || p[1] == '-'))
+ || (base == 16 && (c == 'P' || c == 'p')
+ && p+1 < end && (p[1] == '+' || p[1] == '-')))
+ SYNTAX_ERROR ("floating point numbers are not valid in #if");
+
+ /* Determine the suffix. l means long, and u means unsigned.
+ See the suffix tables, above. */
+ switch (end - p)
+ {
+ case 1: sufftab = vsuf_1; nsuff = Nsuff(vsuf_1); break;
+ case 2: sufftab = vsuf_2; nsuff = Nsuff(vsuf_2); break;
+ case 3: sufftab = vsuf_3; nsuff = Nsuff(vsuf_3); break;
+ default: goto invalid_suffix;
+ }
+
+ for (i = 0; i < nsuff; i++)
+ if (memcmp (p, sufftab[i].s, end - p) == 0)
+ break;
+ if (i == nsuff)
+ goto invalid_suffix;
+ op.unsignedp = sufftab[i].u;
+
+ if (CPP_WTRADITIONAL (pfile)
+ && sufftab[i].u
+ && ! cpp_sys_macro_p (pfile))
+ cpp_warning (pfile, "traditional C rejects the `U' suffix");
+ if (sufftab[i].l == 2 && CPP_OPTION (pfile, pedantic)
+ && ! CPP_OPTION (pfile, c99))
+ cpp_pedwarn (pfile, "too many 'l' suffixes in integer constant");
+ }
+
+ if (base <= largest_digit)
+ cpp_pedwarn (pfile, "integer constant contains digits beyond the radix");
+
+ if (overflow)
+ cpp_pedwarn (pfile, "integer constant out of range");
+
+ /* If too big to be signed, consider it unsigned. */
+ else if ((HOST_WIDEST_INT) n < 0 && ! op.unsignedp)
+ {
+ if (base == 10)
+ cpp_warning (pfile, "integer constant is so large that it is unsigned");
+ op.unsignedp = 1;
+ }
+
+ op.value = n;
+ op.op = CPP_INT;
+ return op;
+
+ invalid_suffix:
+ cpp_error (pfile, "invalid suffix '%.*s' on integer constant",
+ (int) (end - p), p);
+ syntax_error:
+ op.op = CPP_ERROR;
+ return op;
+}
+
+static struct op
+parse_defined (pfile)
+ cpp_reader *pfile;
+{
+ int paren = 0;
+ cpp_hashnode *node = 0;
+ cpp_token token;
+ struct op op;
+
+ /* Don't expand macros. */
+ pfile->state.prevent_expansion++;
+
+ cpp_get_token (pfile, &token);
+ if (token.type == CPP_OPEN_PAREN)
+ {
+ paren = 1;
+ cpp_get_token (pfile, &token);
+ }
+
+ if (token.type == CPP_NAME)
+ {
+ node = token.val.node;
+ if (paren)
+ {
+ cpp_get_token (pfile, &token);
+ if (token.type != CPP_CLOSE_PAREN)
+ {
+ cpp_error (pfile, "missing ')' after \"defined\"");
+ node = 0;
+ }
+ }
+ }
+ else
+ {
+ cpp_error (pfile, "operator \"defined\" requires an identifier");
+ if (token.flags & NAMED_OP)
+ {
+ cpp_token op;
+
+ op.flags = 0;
+ op.type = token.type;
+ cpp_error (pfile,
+ "(\"%s\" is an alternative token for \"%s\" in C++)",
+ cpp_token_as_text (pfile, &token),
+ cpp_token_as_text (pfile, &op));
+ }
+ }
+
+ if (!node)
+ op.op = CPP_ERROR;
+ else
+ {
+ op.value = node->type == NT_MACRO;
+ op.unsignedp = 0;
+ op.op = CPP_INT;
+
+ /* No macros? At top of file? */
+ if (pfile->mi_state == MI_OUTSIDE && pfile->mi_cmacro == 0
+ && pfile->mi_if_not_defined == MI_IND_NOT && pfile->mi_lexed == 1)
+ {
+ cpp_start_lookahead (pfile);
+ cpp_get_token (pfile, &token);
+ if (token.type == CPP_EOF)
+ pfile->mi_ind_cmacro = node;
+ cpp_stop_lookahead (pfile, 0);
+ }
+ }
+
+ pfile->state.prevent_expansion--;
+ return op;
+}
+
+/* Read one token. */
+
+static struct op
+lex (pfile, skip_evaluation, token)
+ cpp_reader *pfile;
+ int skip_evaluation;
+ cpp_token *token;
+{
+ struct op op;
+
+ cpp_get_token (pfile, token);
+
+ switch (token->type)
+ {
+ case CPP_INT:
+ case CPP_NUMBER:
+ return parse_number (pfile, token);
+
+ case CPP_CHAR:
+ case CPP_WCHAR:
+ {
+ unsigned int chars_seen;
+
+ /* This is always a signed type. */
+ op.unsignedp = 0;
+ op.op = CPP_INT;
+ op.value = cpp_interpret_charconst (pfile, token, 1, 0, &chars_seen);
+ return op;
+ }
+
+ case CPP_STRING:
+ case CPP_WSTRING:
+ SYNTAX_ERROR ("string constants are not valid in #if");
+
+ case CPP_FLOAT:
+ SYNTAX_ERROR ("floating point numbers are not valid in #if");
+
+ case CPP_OTHER:
+ if (ISGRAPH (token->val.c))
+ SYNTAX_ERROR2 ("invalid character '%c' in #if", token->val.c);
+ else
+ SYNTAX_ERROR2 ("invalid character '\\%03o' in #if", token->val.c);
+
+ case CPP_NAME:
+ if (token->val.node == pfile->spec_nodes.n_defined)
+ {
+ if (pfile->context->prev && CPP_PEDANTIC (pfile))
+ cpp_pedwarn (pfile, "\"defined\" operator appears during macro expansion");
+
+ return parse_defined (pfile);
+ }
+ else if (CPP_OPTION (pfile, cplusplus)
+ && (token->val.node == pfile->spec_nodes.n_true
+ || token->val.node == pfile->spec_nodes.n_false))
+ {
+ op.op = CPP_INT;
+ op.unsignedp = 0;
+ op.value = (token->val.node == pfile->spec_nodes.n_true);
+
+ /* Warn about use of true or false in #if when pedantic
+ and stdbool.h has not been included. */
+ if (CPP_PEDANTIC (pfile)
+ && ! cpp_defined (pfile, DSC("__bool_true_false_are_defined")))
+ cpp_pedwarn (pfile, "ISO C++ does not permit \"%s\" in #if",
+ NODE_NAME (token->val.node));
+ return op;
+ }
+ else
+ {
+ /* Controlling #if expressions cannot contain identifiers (they
+ could become macros in the future). */
+ pfile->mi_state = MI_FAILED;
+
+ op.op = CPP_INT;
+ op.unsignedp = 0;
+ op.value = 0;
+
+ if (CPP_OPTION (pfile, warn_undef) && !skip_evaluation)
+ cpp_warning (pfile, "\"%s\" is not defined",
+ NODE_NAME (token->val.node));
+ return op;
+ }
+
+ case CPP_HASH:
+ {
+ int temp;
+
+ op.op = CPP_INT;
+ if (_cpp_test_assertion (pfile, &temp))
+ op.op = CPP_ERROR;
+ op.unsignedp = 0;
+ op.value = temp;
+ return op;
+ }
+
+ case CPP_NOT:
+ /* We don't worry about its position here. */
+ pfile->mi_if_not_defined = MI_IND_NOT;
+ /* Fall through. */
+
+ default:
+ if (((int) token->type > (int) CPP_EQ
+ && (int) token->type < (int) CPP_PLUS_EQ)
+ || token->type == CPP_EOF)
+ {
+ op.op = token->type;
+ return op;
+ }
+
+ SYNTAX_ERROR2 ("\"%s\" is not valid in #if expressions",
+ cpp_token_as_text (pfile, token));
+ }
+
+ syntax_error:
+ op.op = CPP_ERROR;
+ return op;
+}
+
+static void
+integer_overflow (pfile)
+ cpp_reader *pfile;
+{
+ if (CPP_PEDANTIC (pfile))
+ cpp_pedwarn (pfile, "integer overflow in preprocessor expression");
+}
+
+static HOST_WIDEST_INT
+left_shift (pfile, a, unsignedp, b)
+ cpp_reader *pfile;
+ HOST_WIDEST_INT a;
+ unsigned int unsignedp;
+ unsigned HOST_WIDEST_INT b;
+{
+ if (b >= HOST_BITS_PER_WIDEST_INT)
+ {
+ if (! unsignedp && a != 0)
+ integer_overflow (pfile);
+ return 0;
+ }
+ else if (unsignedp)
+ return (unsigned HOST_WIDEST_INT) a << b;
+ else
+ {
+ HOST_WIDEST_INT l = a << b;
+ if (l >> b != a)
+ integer_overflow (pfile);
+ return l;
+ }
+}
+
+static HOST_WIDEST_INT
+right_shift (pfile, a, unsignedp, b)
+ cpp_reader *pfile ATTRIBUTE_UNUSED;
+ HOST_WIDEST_INT a;
+ unsigned int unsignedp;
+ unsigned HOST_WIDEST_INT b;
+{
+ if (b >= HOST_BITS_PER_WIDEST_INT)
+ return unsignedp ? 0 : a >> (HOST_BITS_PER_WIDEST_INT - 1);
+ else if (unsignedp)
+ return (unsigned HOST_WIDEST_INT) a >> b;
+ else
+ return a >> b;
+}
+\f
+/* Operator precedence and flags table.
+
+After an operator is returned from the lexer, if it has priority less
+than or equal to the operator on the top of the stack, we reduce the
+stack by one operator and repeat the test. Since equal priorities
+reduce, this is naturally left-associative.
+
+We handle right-associative operators by clearing the lower bit of all
+left-associative operators, and setting it for right-associative ones.
+After the reduction phase of a new operator, just before it is pushed
+onto the stack, its RIGHT_ASSOC bit is cleared. The effect is that
+during the reduction phase, the current right-associative operator has
+a priority one greater than any other operator of otherwise equal
+precedence that has been pushed on the top of the stack. This avoids
+a reduction pass, and effectively makes the logic right-associative.
+
+The remaining cases are '(' and ')'. We handle '(' by skipping the
+reduction phase completely. ')' is given lower priority than
+everything else, including '(', effectively forcing a reduction of the
+parenthesised expression. If there is no matching '(', the stack will
+be reduced all the way to the beginning, exiting the parser in the
+same way as the ultra-low priority end-of-expression dummy operator.
+The exit code checks to see if the operator that caused it is ')', and
+if so outputs an appropriate error message.
+
+The parser assumes all shifted operators require a right operand
+unless the flag NO_R_OPERAND is set, and similarly for NO_L_OPERAND.
+These semantics are automatically checked, any extra semantics need to
+be handled with operator-specific code. */
+
+#define FLAG_BITS 8
+#define FLAG_MASK ((1 << FLAG_BITS) - 1)
+#define PRIO_SHIFT (FLAG_BITS + 1)
+#define EXTRACT_PRIO(cnst) (cnst >> FLAG_BITS)
+#define EXTRACT_FLAGS(cnst) (cnst & FLAG_MASK)
+
+/* Flags. */
+#define HAVE_VALUE (1 << 0)
+#define NO_L_OPERAND (1 << 1)
+#define NO_R_OPERAND (1 << 2)
+#define SHORT_CIRCUIT (1 << 3)
+
+/* Priority and flag combinations. */
+#define RIGHT_ASSOC (1 << FLAG_BITS)
+#define FORCE_REDUCE_PRIO (0 << PRIO_SHIFT)
+#define CLOSE_PAREN_PRIO (1 << PRIO_SHIFT)
+#define OPEN_PAREN_PRIO ((2 << PRIO_SHIFT) | NO_L_OPERAND)
+#define COMMA_PRIO (3 << PRIO_SHIFT)
+#define COND_PRIO ((4 << PRIO_SHIFT) | RIGHT_ASSOC | SHORT_CIRCUIT)
+#define COLON_PRIO ((5 << PRIO_SHIFT) | SHORT_CIRCUIT)
+#define OROR_PRIO ((6 << PRIO_SHIFT) | SHORT_CIRCUIT)
+#define ANDAND_PRIO ((7 << PRIO_SHIFT) | SHORT_CIRCUIT)
+#define OR_PRIO (8 << PRIO_SHIFT)
+#define XOR_PRIO (9 << PRIO_SHIFT)
+#define AND_PRIO (10 << PRIO_SHIFT)
+#define MINMAX_PRIO (11 << PRIO_SHIFT)
+#define EQUAL_PRIO (12 << PRIO_SHIFT)
+#define LESS_PRIO (13 << PRIO_SHIFT)
+#define SHIFT_PRIO (14 << PRIO_SHIFT)
+#define PLUS_PRIO (15 << PRIO_SHIFT)
+#define MUL_PRIO (16 << PRIO_SHIFT)
+#define UNARY_PRIO ((17 << PRIO_SHIFT) | RIGHT_ASSOC | NO_L_OPERAND)
+
+/* Operator to priority map. Must be in the same order as the first
+ N entries of enum cpp_ttype. */
+static const short
+op_to_prio[] =
+{
+ /* EQ */ 0, /* dummy entry - can't happen */
+ /* NOT */ UNARY_PRIO,
+ /* GREATER */ LESS_PRIO,
+ /* LESS */ LESS_PRIO,
+ /* PLUS */ UNARY_PRIO, /* note these two can be unary */
+ /* MINUS */ UNARY_PRIO, /* or binary */
+ /* MULT */ MUL_PRIO,
+ /* DIV */ MUL_PRIO,
+ /* MOD */ MUL_PRIO,
+ /* AND */ AND_PRIO,
+ /* OR */ OR_PRIO,
+ /* XOR */ XOR_PRIO,
+ /* RSHIFT */ SHIFT_PRIO,
+ /* LSHIFT */ SHIFT_PRIO,
+ /* MIN */ MINMAX_PRIO, /* C++ specific */
+ /* MAX */ MINMAX_PRIO, /* extensions */
+
+ /* COMPL */ UNARY_PRIO,
+ /* AND_AND */ ANDAND_PRIO,
+ /* OR_OR */ OROR_PRIO,
+ /* QUERY */ COND_PRIO,
+ /* COLON */ COLON_PRIO,
+ /* COMMA */ COMMA_PRIO,
+ /* OPEN_PAREN */ OPEN_PAREN_PRIO,
+ /* CLOSE_PAREN */ CLOSE_PAREN_PRIO,
+ /* EQ_EQ */ EQUAL_PRIO,
+ /* NOT_EQ */ EQUAL_PRIO,
+ /* GREATER_EQ */ LESS_PRIO,
+ /* LESS_EQ */ LESS_PRIO
+};
+
+#define COMPARE(OP) \
+ top->unsignedp = 0; \
+ top->value = (unsigned1 | unsigned2) \
+ ? (unsigned HOST_WIDEST_INT) v1 OP (unsigned HOST_WIDEST_INT) v2 \
+ : (v1 OP v2)
+#define EQUALITY(OP) \
+ top->value = v1 OP v2; \
+ top->unsignedp = 0;
+#define BITWISE(OP) \
+ top->value = v1 OP v2; \
+ top->unsignedp = unsigned1 | unsigned2;
+#define MINMAX(OP) \
+ top->value = (v1 OP v2) ? v1 : v2; \
+ top->unsignedp = unsigned1 | unsigned2;
+#define UNARY(OP) \
+ top->value = OP v2; \
+ top->unsignedp = unsigned2; \
+ top->flags |= HAVE_VALUE;
+#define SHIFT(PSH, MSH) \
+ if (skip_evaluation) \
+ break; \
+ top->unsignedp = unsigned1; \
+ if (v2 < 0 && ! unsigned2) \
+ top->value = MSH (pfile, v1, unsigned1, -v2); \
+ else \
+ top->value = PSH (pfile, v1, unsigned1, v2);
+
+/* Parse and evaluate a C expression, reading from PFILE.
+ Returns the truth value of the expression. */
+
+int
+_cpp_parse_expr (pfile)
+ cpp_reader *pfile;
+{
+ /* The implementation is an operator precedence parser, i.e. a
+ bottom-up parser, using a stack for not-yet-reduced tokens.
+
+ The stack base is 'stack', and the current stack pointer is 'top'.
+ There is a stack element for each operator (only),
+ and the most recently pushed operator is 'top->op'.
+ An operand (value) is stored in the 'value' field of the stack
+ element of the operator that precedes it.
+ In that case the 'flags' field has the HAVE_VALUE flag set. */
+
+#define INIT_STACK_SIZE 20
+ struct op init_stack[INIT_STACK_SIZE];
+ struct op *stack = init_stack;
+ struct op *limit = stack + INIT_STACK_SIZE;
+ cpp_token token;
+ register struct op *top = stack + 1;
+ int skip_evaluation = 0;
+ int result;
+
+ /* Set up detection of #if ! defined(). */
+ pfile->mi_lexed = 0;
+ pfile->mi_if_not_defined = MI_IND_NONE;
+
+ /* We've finished when we try to reduce this. */
+ top->op = CPP_EOF;
+ /* Nifty way to catch missing '('. */
+ top->prio = EXTRACT_PRIO(CLOSE_PAREN_PRIO);
+ /* Avoid missing right operand checks. */
+ top->flags = NO_R_OPERAND;
+
+ for (;;)
+ {
+ unsigned int prio;
+ unsigned int flags;
+ struct op op;
+
+ /* Read a token */
+ op = lex (pfile, skip_evaluation, &token);
+ pfile->mi_lexed++;
+
+ /* If the token is an operand, push its value and get next
+ token. If it is an operator, get its priority and flags, and
+ try to reduce the expression on the stack. */
+ switch (op.op)
+ {
+ case CPP_ERROR:
+ goto syntax_error;
+ push_immediate:
+ case CPP_INT:
+ /* Push a value onto the stack. */
+ if (top->flags & HAVE_VALUE)
+ SYNTAX_ERROR ("missing binary operator");
+ top->value = op.value;
+ top->unsignedp = op.unsignedp;
+ top->flags |= HAVE_VALUE;
+ continue;
+
+ case CPP_EOF: prio = FORCE_REDUCE_PRIO; break;
+ case CPP_PLUS:
+ case CPP_MINUS: prio = PLUS_PRIO; if (top->flags & HAVE_VALUE) break;
+ /* else unary; fall through */
+ default: prio = op_to_prio[op.op]; break;
+ }
+
+ /* Separate the operator's code into priority and flags. */
+ flags = EXTRACT_FLAGS(prio);
+ prio = EXTRACT_PRIO(prio);
+ if (prio == EXTRACT_PRIO(OPEN_PAREN_PRIO))
+ goto skip_reduction;
+
+ /* Check for reductions. Then push the operator. */
+ while (prio <= top->prio)
+ {
+ HOST_WIDEST_INT v1, v2;
+ unsigned int unsigned1, unsigned2;
+
+ /* Most operators that can appear on the stack require a
+ right operand. Check this before trying to reduce. */
+ if ((top->flags & (HAVE_VALUE | NO_R_OPERAND)) == 0)
+ {
+ if (top->op == CPP_OPEN_PAREN)
+ SYNTAX_ERROR ("void expression between '(' and ')'");
+ else
+ SYNTAX_ERROR2 ("operator '%s' has no right operand",
+ op_as_text (pfile, top->op));
+ }
+
+ unsigned2 = top->unsignedp, v2 = top->value;
+ top--;
+ unsigned1 = top->unsignedp, v1 = top->value;
+
+ /* Now set top->value = (top[1].op)(v1, v2); */
+ switch (top[1].op)
+ {
+ default:
+ cpp_ice (pfile, "impossible operator '%s'",
+ op_as_text (pfile, top[1].op));
+ goto syntax_error;
+
+ case CPP_NOT: UNARY(!); break;
+ case CPP_COMPL: UNARY(~); break;
+ case CPP_LESS: COMPARE(<); break;
+ case CPP_GREATER: COMPARE(>); break;
+ case CPP_LESS_EQ: COMPARE(<=); break;
+ case CPP_GREATER_EQ: COMPARE(>=); break;
+ case CPP_EQ_EQ: EQUALITY(==); break;
+ case CPP_NOT_EQ: EQUALITY(!=); break;
+ case CPP_AND: BITWISE(&); break;
+ case CPP_XOR: BITWISE(^); break;
+ case CPP_OR: BITWISE(|); break;
+ case CPP_LSHIFT: SHIFT(left_shift, right_shift); break;
+ case CPP_RSHIFT: SHIFT(right_shift, left_shift); break;
+ case CPP_MIN: MINMAX(<); break;
+ case CPP_MAX: MINMAX(>); break;
+
+ case CPP_PLUS:
+ if (!(top->flags & HAVE_VALUE))
+ {
+ /* Can't use UNARY(+) because K+R C did not have unary
+ plus. Can't use UNARY() because some compilers object
+ to the empty argument. */
+ top->value = v2;
+ top->unsignedp = unsigned2;
+ top->flags |= HAVE_VALUE;
+
+ if (CPP_WTRADITIONAL (pfile))
+ cpp_warning (pfile,
+ "traditional C rejects the unary plus operator");
+ }
+ else
+ {
+ top->value = v1 + v2;
+ top->unsignedp = unsigned1 | unsigned2;
+ if (! top->unsignedp && ! skip_evaluation
+ && ! possible_sum_sign (v1, v2, top->value))
+ integer_overflow (pfile);
+ }
+ break;
+ case CPP_MINUS:
+ if (!(top->flags & HAVE_VALUE))
+ {
+ UNARY(-);
+ if (!skip_evaluation && (top->value & v2) < 0 && !unsigned2)
+ integer_overflow (pfile);
+ }
+ else
+ { /* Binary '-' */
+ top->value = v1 - v2;
+ top->unsignedp = unsigned1 | unsigned2;
+ if (! top->unsignedp && ! skip_evaluation
+ && ! possible_sum_sign (top->value, v2, v1))
+ integer_overflow (pfile);
+ }
+ break;
+ case CPP_MULT:
+ top->unsignedp = unsigned1 | unsigned2;
+ if (top->unsignedp)
+ top->value = (unsigned HOST_WIDEST_INT) v1 * v2;
+ else if (!skip_evaluation)
+ {
+ top->value = v1 * v2;
+ if (v1 && (top->value / v1 != v2
+ || (top->value & v1 & v2) < 0))
+ integer_overflow (pfile);
+ }
+ break;
+ case CPP_DIV:
+ case CPP_MOD:
+ if (skip_evaluation)
+ break;
+ if (v2 == 0)
+ SYNTAX_ERROR ("division by zero in #if");
+ top->unsignedp = unsigned1 | unsigned2;
+ if (top[1].op == CPP_DIV)
+ {
+ if (top->unsignedp)
+ top->value = (unsigned HOST_WIDEST_INT) v1 / v2;
+ else
+ {
+ top->value = v1 / v2;
+ if ((top->value & v1 & v2) < 0)
+ integer_overflow (pfile);
+ }
+ }
+ else
+ {
+ if (top->unsignedp)
+ top->value = (unsigned HOST_WIDEST_INT) v1 % v2;
+ else
+ top->value = v1 % v2;
+ }
+ break;
+
+ case CPP_OR_OR:
+ top->value = v1 || v2;
+ top->unsignedp = 0;
+ if (v1) skip_evaluation--;
+ break;
+ case CPP_AND_AND:
+ top->value = v1 && v2;
+ top->unsignedp = 0;
+ if (!v1) skip_evaluation--;
+ break;
+ case CPP_COMMA:
+ if (CPP_PEDANTIC (pfile))
+ cpp_pedwarn (pfile, "comma operator in operand of #if");
+ top->value = v2;
+ top->unsignedp = unsigned2;
+ break;
+ case CPP_QUERY:
+ SYNTAX_ERROR ("syntax error '?' without following ':'");
+ case CPP_COLON:
+ if (top[0].op != CPP_QUERY)
+ SYNTAX_ERROR ("syntax error ':' without preceding '?'");
+ top--;
+ if (top->value) skip_evaluation--;
+ top->value = top->value ? v1 : v2;
+ top->unsignedp = unsigned1 | unsigned2;
+ break;
+ case CPP_OPEN_PAREN:
+ if (op.op != CPP_CLOSE_PAREN)
+ SYNTAX_ERROR ("missing ')' in expression");
+ op.value = v2;
+ op.unsignedp = unsigned2;
+ goto push_immediate;
+ case CPP_EOF:
+ /* Reducing this dummy operator indicates we've finished. */
+ if (op.op == CPP_CLOSE_PAREN)
+ SYNTAX_ERROR ("missing '(' in expression");
+ goto done;
+ }
+ }
+
+ /* Handle short-circuit evaluations. */
+ if (flags & SHORT_CIRCUIT)
+ switch (op.op)
+ {
+ case CPP_OR_OR: if (top->value) skip_evaluation++; break;
+ case CPP_AND_AND:
+ case CPP_QUERY: if (!top->value) skip_evaluation++; break;
+ case CPP_COLON:
+ if (top[-1].value) /* Was '?' condition true? */
+ skip_evaluation++;
+ else
+ skip_evaluation--;
+ default:
+ break;
+ }
+
+ skip_reduction:
+ /* Check we have a left operand iff we need one. */
+ if (flags & NO_L_OPERAND)
+ {
+ if (top->flags & HAVE_VALUE)
+ SYNTAX_ERROR2 ("missing binary operator before '%s'",
+ op_as_text (pfile, top->op));
+ }
+ else
+ {
+ if (!(top->flags & HAVE_VALUE))
+ SYNTAX_ERROR2 ("operator '%s' has no left operand",
+ op_as_text (pfile, top->op));
+ }
+
+ /* Check for and handle stack overflow. */
+ top++;
+ if (top == limit)
+ {
+ struct op *new_stack;
+ int old_size = (char *) limit - (char *) stack;
+ int new_size = 2 * old_size;
+ if (stack != init_stack)
+ new_stack = (struct op *) xrealloc (stack, new_size);
+ else
+ {
+ new_stack = (struct op *) xmalloc (new_size);
+ memcpy (new_stack, stack, old_size);
+ }
+ stack = new_stack;
+ top = (struct op *) ((char *) new_stack + old_size);
+ limit = (struct op *) ((char *) new_stack + new_size);
+ }
+
+ top->flags = flags;
+ top->prio = prio & ~EXTRACT_PRIO(RIGHT_ASSOC);
+ top->op = op.op;
+ }
+
+ done:
+ result = (top[1].value != 0);
+ if (top != stack)
+ CPP_ICE ("unbalanced stack in #if");
+ else if (!(top[1].flags & HAVE_VALUE))
+ {
+ SYNTAX_ERROR ("#if with no expression");
+ syntax_error:
+ result = 0; /* Return 0 on syntax error. */
+ }
+
+ /* Free dynamic stack if we allocated one. */
+ if (stack != init_stack)
+ free (stack);
+ return result;
+}
+
+static const unsigned char *
+op_as_text (pfile, op)
+ cpp_reader *pfile;
+ enum cpp_ttype op;
+{
+ cpp_token token;
+
+ token.type = op;
+ token.flags = 0;
+ return cpp_token_as_text (pfile, &token);
+}
--- /dev/null
+/* Part of CPP library. (include file handling)
+ Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1998,
+ 1999, 2000, 2001 Free Software Foundation, Inc.
+ Written by Per Bothner, 1994.
+ Based on CCCP program by Paul Rubin, June 1986
+ Adapted to ANSI C, Richard Stallman, Jan 1987
+ Split out of cpplib.c, Zack Weinberg, Oct 1998
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "cpplib.h"
+#include "cpphash.h"
+#include "intl.h"
+#include "mkdeps.h"
+#include "splay-tree.h"
+
+#ifdef HAVE_MMAP_FILE
+# include <sys/mman.h>
+# ifndef MMAP_THRESHOLD
+# define MMAP_THRESHOLD 3 /* Minimum page count to mmap the file. */
+# endif
+
+#else /* No MMAP_FILE */
+# undef MMAP_THRESHOLD
+# define MMAP_THRESHOLD 0
+#endif
+
+#ifndef O_BINARY
+# define O_BINARY 0
+#endif
+
+/* If errno is inspected immediately after a system call fails, it will be
+ nonzero, and no error number will ever be zero. */
+#ifndef ENOENT
+# define ENOENT 0
+#endif
+#ifndef ENOTDIR
+# define ENOTDIR 0
+#endif
+
+/* Suppress warning about function macros used w/o arguments in traditional
+ C. It is unlikely that glibc's strcmp macro helps this file at all. */
+#undef strcmp
+
+/* This structure is used for the table of all includes. */
+struct include_file
+{
+ const char *name; /* actual path name of file */
+ const cpp_hashnode *cmacro; /* macro, if any, preventing reinclusion. */
+ const struct search_path *foundhere;
+ /* location in search path where file was
+ found, for #include_next and sysp. */
+ const unsigned char *buffer; /* pointer to cached file contents */
+ struct stat st; /* copy of stat(2) data for file */
+ int fd; /* fd open on file (short term storage only) */
+ int err_no; /* errno obtained if opening a file failed */
+ unsigned short include_count; /* number of times file has been read */
+ unsigned short refcnt; /* number of stacked buffers using this file */
+ unsigned char mapped; /* file buffer is mmapped */
+};
+
+/* The cmacro works like this: If it's NULL, the file is to be
+ included again. If it's NEVER_REREAD, the file is never to be
+ included again. Otherwise it is a macro hashnode, and the file is
+ to be included again if the macro is defined. */
+#define NEVER_REREAD ((const cpp_hashnode *)-1)
+#define DO_NOT_REREAD(inc) \
+((inc)->cmacro && ((inc)->cmacro == NEVER_REREAD \
+ || (inc)->cmacro->type == NT_MACRO))
+#define NO_INCLUDE_PATH ((struct include_file *) -1)
+
+static struct file_name_map *read_name_map
+ PARAMS ((cpp_reader *, const char *));
+static char *read_filename_string PARAMS ((int, FILE *));
+static char *remap_filename PARAMS ((cpp_reader *, char *,
+ struct search_path *));
+static struct search_path *search_from PARAMS ((cpp_reader *,
+ enum include_type));
+static struct include_file *
+ find_include_file PARAMS ((cpp_reader *, const cpp_token *,
+ enum include_type));
+static struct include_file *open_file PARAMS ((cpp_reader *, const char *));
+static int read_include_file PARAMS ((cpp_reader *, struct include_file *));
+static void stack_include_file PARAMS ((cpp_reader *, struct include_file *));
+static void purge_cache PARAMS ((struct include_file *));
+static void destroy_node PARAMS ((splay_tree_value));
+static int report_missing_guard PARAMS ((splay_tree_node, void *));
+static splay_tree_node find_or_create_entry PARAMS ((cpp_reader *,
+ const char *));
+static void handle_missing_header PARAMS ((cpp_reader *, const char *, int));
+static int remove_component_p PARAMS ((const char *));
+
+/* Set up the splay tree we use to store information about all the
+ file names seen in this compilation. We also have entries for each
+ file we tried to open but failed; this saves system calls since we
+ don't try to open it again in future.
+
+ The key of each node is the file name, after processing by
+ _cpp_simplify_pathname. The path name may or may not be absolute.
+ The path string has been malloced, as is automatically freed by
+ registering free () as the splay tree key deletion function.
+
+ A node's value is a pointer to a struct include_file, and is never
+ NULL. */
+void
+_cpp_init_includes (pfile)
+ cpp_reader *pfile;
+{
+ pfile->all_include_files
+ = splay_tree_new ((splay_tree_compare_fn) strcmp,
+ (splay_tree_delete_key_fn) free,
+ destroy_node);
+}
+
+/* Tear down the splay tree. */
+void
+_cpp_cleanup_includes (pfile)
+ cpp_reader *pfile;
+{
+ splay_tree_delete (pfile->all_include_files);
+}
+
+/* Free a node. The path string is automatically freed. */
+static void
+destroy_node (v)
+ splay_tree_value v;
+{
+ struct include_file *f = (struct include_file *)v;
+
+ if (f)
+ {
+ purge_cache (f);
+ free (f);
+ }
+}
+
+/* Mark a file to not be reread (e.g. #import, read failure). */
+void
+_cpp_never_reread (file)
+ struct include_file *file;
+{
+ file->cmacro = NEVER_REREAD;
+}
+
+/* Lookup a filename, which is simplified after making a copy, and
+ create an entry if none exists. errno is nonzero iff a (reported)
+ stat() error occurred during simplification. */
+static splay_tree_node
+find_or_create_entry (pfile, fname)
+ cpp_reader *pfile;
+ const char *fname;
+{
+ splay_tree_node node;
+ struct include_file *file;
+ char *name = xstrdup (fname);
+
+ _cpp_simplify_pathname (name);
+ node = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) name);
+ if (node)
+ free (name);
+ else
+ {
+ file = xcnew (struct include_file);
+ file->name = name;
+ file->err_no = errno;
+ node = splay_tree_insert (pfile->all_include_files,
+ (splay_tree_key) file->name,
+ (splay_tree_value) file);
+ }
+
+ return node;
+}
+
+/* Enter a file name in the splay tree, for the sake of cpp_included. */
+void
+_cpp_fake_include (pfile, fname)
+ cpp_reader *pfile;
+ const char *fname;
+{
+ find_or_create_entry (pfile, fname);
+}
+
+/* Given a file name, look it up in the cache; if there is no entry,
+ create one with a non-NULL value (regardless of success in opening
+ the file). If the file doesn't exist or is inaccessible, this
+ entry is flagged so we don't attempt to open it again in the
+ future. If the file isn't open, open it. The empty string is
+ interpreted as stdin.
+
+ Returns an include_file structure with an open file descriptor on
+ success, or NULL on failure. */
+
+static struct include_file *
+open_file (pfile, filename)
+ cpp_reader *pfile;
+ const char *filename;
+{
+ splay_tree_node nd = find_or_create_entry (pfile, filename);
+ struct include_file *file = (struct include_file *) nd->value;
+
+ if (file->err_no)
+ {
+ /* Ugh. handle_missing_header () needs errno to be set. */
+ errno = file->err_no;
+ return 0;
+ }
+
+ /* Don't reopen an idempotent file. */
+ if (DO_NOT_REREAD (file))
+ return file;
+
+ /* Don't reopen one which is already loaded. */
+ if (file->buffer != NULL)
+ return file;
+
+ /* We used to open files in nonblocking mode, but that caused more
+ problems than it solved. Do take care not to acquire a
+ controlling terminal by mistake (this can't happen on sane
+ systems, but paranoia is a virtue).
+
+ Use the three-argument form of open even though we aren't
+ specifying O_CREAT, to defend against broken system headers.
+
+ O_BINARY tells some runtime libraries (notably DJGPP) not to do
+ newline translation; we can handle DOS line breaks just fine
+ ourselves.
+
+ Special case: the empty string is translated to stdin. */
+
+ if (filename[0] == '\0')
+ file->fd = 0;
+ else
+ file->fd = open (file->name, O_RDONLY | O_NOCTTY | O_BINARY, 0666);
+
+ if (file->fd != -1 && fstat (file->fd, &file->st) == 0)
+ {
+ /* If it's a directory, we return null and continue the search
+ as the file we're looking for may appear elsewhere in the
+ search path. */
+ if (S_ISDIR (file->st.st_mode))
+ errno = ENOENT;
+ else
+ {
+ /* Mark a regular, zero-length file never-reread now. */
+ if (S_ISREG (file->st.st_mode) && file->st.st_size == 0)
+ {
+ _cpp_never_reread (file);
+ close (file->fd);
+ file->fd = -1;
+ }
+
+ return file;
+ }
+ }
+
+ /* Don't issue an error message if the file doesn't exist. */
+ file->err_no = errno;
+ if (errno != ENOENT && errno != ENOTDIR)
+ cpp_error_from_errno (pfile, file->name);
+
+ return 0;
+}
+
+/* Place the file referenced by INC into a new buffer on PFILE's
+ stack. If there are errors, or the file should not be re-included,
+ a null (zero-length) buffer is pushed. */
+
+static void
+stack_include_file (pfile, inc)
+ cpp_reader *pfile;
+ struct include_file *inc;
+{
+ size_t len = 0;
+ cpp_buffer *fp;
+ int sysp, deps_sysp;
+
+ /* We'll try removing deps_sysp after the release of 3.0. */
+ deps_sysp = pfile->system_include_depth != 0;
+ sysp = MAX ((pfile->buffer ? pfile->buffer->sysp : 0),
+ (inc->foundhere ? inc->foundhere->sysp : 0));
+
+ /* For -M, add the file to the dependencies on its first inclusion. */
+ if (CPP_OPTION (pfile, print_deps) > deps_sysp && !inc->include_count)
+ deps_add_dep (pfile->deps, inc->name);
+
+ /* Not in cache? */
+ if (! DO_NOT_REREAD (inc) && ! inc->buffer)
+ {
+ /* If an error occurs, do not try to read this file again. */
+ if (read_include_file (pfile, inc))
+ _cpp_never_reread (inc);
+ close (inc->fd);
+ inc->fd = -1;
+ }
+
+ if (! DO_NOT_REREAD (inc))
+ {
+ len = inc->st.st_size;
+ if (pfile->buffer)
+ {
+ /* We don't want MI guard advice for the main file. */
+ inc->include_count++;
+
+ /* Handle -H option. */
+ if (CPP_OPTION (pfile, print_include_names))
+ {
+ for (fp = pfile->buffer; fp; fp = fp->prev)
+ putc ('.', stderr);
+ fprintf (stderr, " %s\n", inc->name);
+ }
+ }
+ }
+
+ /* Push a buffer. */
+ fp = cpp_push_buffer (pfile, inc->buffer, len, BUF_FILE, inc->name);
+ fp->inc = inc;
+ fp->inc->refcnt++;
+ fp->sysp = sysp;
+
+ /* Initialise controlling macro state. */
+ pfile->mi_state = MI_OUTSIDE;
+ pfile->mi_cmacro = 0;
+ pfile->include_depth++;
+
+ /* Generate the call back. */
+ fp->lineno = 0;
+ _cpp_do_file_change (pfile, FC_ENTER, 0, 0);
+ fp->lineno = 1;
+}
+
+/* Read the file referenced by INC into the file cache.
+
+ If fd points to a plain file, we might be able to mmap it; we can
+ definitely allocate the buffer all at once. If fd is a pipe or
+ terminal, we can't do either. If fd is something weird, like a
+ block device, we don't want to read it at all.
+
+ Unfortunately, different systems use different st.st_mode values
+ for pipes: some have S_ISFIFO, some S_ISSOCK, some are buggy and
+ zero the entire struct stat except a couple fields. Hence we don't
+ even try to figure out what something is, except for plain files
+ and block devices.
+
+ FIXME: Flush file cache and try again if we run out of memory. */
+
+static int
+read_include_file (pfile, inc)
+ cpp_reader *pfile;
+ struct include_file *inc;
+{
+ ssize_t size, offset, count;
+ U_CHAR *buf;
+#if MMAP_THRESHOLD
+ static int pagesize = -1;
+#endif
+
+ if (S_ISREG (inc->st.st_mode))
+ {
+ /* off_t might have a wider range than ssize_t - in other words,
+ the max size of a file might be bigger than the address
+ space. We can't handle a file that large. (Anyone with
+ a single source file bigger than 2GB needs to rethink
+ their coding style.) Some systems (e.g. AIX 4.1) define
+ SSIZE_MAX to be much smaller than the actual range of the
+ type. Use INTTYPE_MAXIMUM unconditionally to ensure this
+ does not bite us. */
+ if (inc->st.st_size > INTTYPE_MAXIMUM (ssize_t))
+ {
+ cpp_error (pfile, "%s is too large", inc->name);
+ goto fail;
+ }
+ size = inc->st.st_size;
+
+ inc->mapped = 0;
+#if MMAP_THRESHOLD
+ if (pagesize == -1)
+ pagesize = getpagesize ();
+
+ if (size / pagesize >= MMAP_THRESHOLD)
+ {
+ buf = (U_CHAR *) mmap (0, size, PROT_READ, MAP_PRIVATE, inc->fd, 0);
+ if (buf == (U_CHAR *)-1)
+ goto perror_fail;
+ inc->mapped = 1;
+ }
+ else
+#endif
+ {
+ buf = (U_CHAR *) xmalloc (size);
+ offset = 0;
+ while (offset < size)
+ {
+ count = read (inc->fd, buf + offset, size - offset);
+ if (count < 0)
+ goto perror_fail;
+ if (count == 0)
+ {
+ cpp_warning (pfile, "%s is shorter than expected", inc->name);
+ break;
+ }
+ offset += count;
+ }
+ }
+ }
+ else if (S_ISBLK (inc->st.st_mode))
+ {
+ cpp_error (pfile, "%s is a block device", inc->name);
+ goto fail;
+ }
+ else
+ {
+ /* 8 kilobytes is a sensible starting size. It ought to be
+ bigger than the kernel pipe buffer, and it's definitely
+ bigger than the majority of C source files. */
+ size = 8 * 1024;
+
+ buf = (U_CHAR *) xmalloc (size);
+ offset = 0;
+ while ((count = read (inc->fd, buf + offset, size - offset)) > 0)
+ {
+ offset += count;
+ if (offset == size)
+ buf = xrealloc (buf, (size *= 2));
+ }
+ if (count < 0)
+ goto perror_fail;
+
+ if (offset < size)
+ buf = xrealloc (buf, offset);
+ inc->st.st_size = offset;
+ }
+
+ inc->buffer = buf;
+ return 0;
+
+ perror_fail:
+ cpp_error_from_errno (pfile, inc->name);
+ fail:
+ return 1;
+}
+
+static void
+purge_cache (inc)
+ struct include_file *inc;
+{
+ if (inc->buffer)
+ {
+#if MMAP_THRESHOLD
+ if (inc->mapped)
+ munmap ((PTR) inc->buffer, inc->st.st_size);
+ else
+#endif
+ free ((PTR) inc->buffer);
+ inc->buffer = NULL;
+ }
+}
+
+/* Return 1 if the file named by FNAME has been included before in
+ any context, 0 otherwise. */
+int
+cpp_included (pfile, fname)
+ cpp_reader *pfile;
+ const char *fname;
+{
+ struct search_path *path;
+ char *name, *n;
+ splay_tree_node nd;
+
+ if (IS_ABSOLUTE_PATHNAME (fname))
+ {
+ /* Just look it up. */
+ nd = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) fname);
+ return (nd && nd->value);
+ }
+
+ /* Search directory path for the file. */
+ name = (char *) alloca (strlen (fname) + pfile->max_include_len + 2);
+ for (path = CPP_OPTION (pfile, quote_include); path; path = path->next)
+ {
+ memcpy (name, path->name, path->len);
+ name[path->len] = '/';
+ strcpy (&name[path->len + 1], fname);
+ if (CPP_OPTION (pfile, remap))
+ n = remap_filename (pfile, name, path);
+ else
+ n = name;
+
+ nd = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) n);
+ if (nd && nd->value)
+ return 1;
+ }
+ return 0;
+}
+
+/* Search for HEADER. Return 0 if there is no such file (or it's
+ un-openable), in which case an error code will be in errno. If
+ there is no include path to use it returns NO_INCLUDE_PATH,
+ otherwise an include_file structure. If this request originates
+ from a #include_next directive, set INCLUDE_NEXT to true. */
+
+static struct include_file *
+find_include_file (pfile, header, type)
+ cpp_reader *pfile;
+ const cpp_token *header;
+ enum include_type type;
+{
+ const char *fname = (const char *) header->val.str.text;
+ struct search_path *path;
+ struct include_file *file;
+ char *name, *n;
+
+ if (IS_ABSOLUTE_PATHNAME (fname))
+ return open_file (pfile, fname);
+
+ /* For #include_next, skip in the search path past the dir in which
+ the current file was found, but if it was found via an absolute
+ path use the normal search logic. */
+ if (type == IT_INCLUDE_NEXT && pfile->buffer->inc->foundhere)
+ path = pfile->buffer->inc->foundhere->next;
+ else if (header->type == CPP_HEADER_NAME)
+ path = CPP_OPTION (pfile, bracket_include);
+ else
+ path = search_from (pfile, type);
+
+ if (path == NULL)
+ {
+ cpp_error (pfile, "No include path in which to find %s", fname);
+ return NO_INCLUDE_PATH;
+ }
+
+ /* Search directory path for the file. */
+ name = (char *) alloca (strlen (fname) + pfile->max_include_len + 2);
+ for (; path; path = path->next)
+ {
+ memcpy (name, path->name, path->len);
+ name[path->len] = '/';
+ strcpy (&name[path->len + 1], fname);
+ if (CPP_OPTION (pfile, remap))
+ n = remap_filename (pfile, name, path);
+ else
+ n = name;
+
+ file = open_file (pfile, n);
+ if (file)
+ {
+ file->foundhere = path;
+ return file;
+ }
+ }
+
+ return 0;
+}
+
+/* Not everyone who wants to set system-header-ness on a buffer can
+ see the details of a buffer. This is an exported interface because
+ fix-header needs it. */
+void
+cpp_make_system_header (pfile, syshdr, externc)
+ cpp_reader *pfile;
+ int syshdr, externc;
+{
+ int flags = 0;
+
+ /* 1 = system header, 2 = system header to be treated as C. */
+ if (syshdr)
+ flags = 1 + (externc != 0);
+ pfile->buffer->sysp = flags;
+ _cpp_do_file_change (pfile, FC_RENAME, pfile->buffer->nominal_fname,
+ pfile->buffer->lineno);
+}
+
+/* Report on all files that might benefit from a multiple include guard.
+ Triggered by -H. */
+void
+_cpp_report_missing_guards (pfile)
+ cpp_reader *pfile;
+{
+ int banner = 0;
+ splay_tree_foreach (pfile->all_include_files, report_missing_guard,
+ (PTR) &banner);
+}
+
+static int
+report_missing_guard (n, b)
+ splay_tree_node n;
+ void *b;
+{
+ struct include_file *f = (struct include_file *) n->value;
+ int *bannerp = (int *)b;
+
+ if (f && f->cmacro == 0 && f->include_count == 1)
+ {
+ if (*bannerp == 0)
+ {
+ fputs (_("Multiple include guards may be useful for:\n"), stderr);
+ *bannerp = 1;
+ }
+ fputs (f->name, stderr);
+ putc ('\n', stderr);
+ }
+ return 0;
+}
+
+/* Create a dependency, or issue an error message as appropriate. */
+static void
+handle_missing_header (pfile, fname, angle_brackets)
+ cpp_reader *pfile;
+ const char *fname;
+ int angle_brackets;
+{
+ /* We will try making the RHS pfile->buffer->sysp after 3.0. */
+ int print_dep = CPP_PRINT_DEPS(pfile) > (angle_brackets
+ || pfile->system_include_depth);
+
+ if (CPP_OPTION (pfile, print_deps_missing_files) && print_dep)
+ {
+ if (!angle_brackets || IS_ABSOLUTE_PATHNAME (fname))
+ deps_add_dep (pfile->deps, fname);
+ else
+ {
+ /* If requested as a system header, assume it belongs in
+ the first system header directory. */
+ struct search_path *ptr = CPP_OPTION (pfile, bracket_include);
+ char *p;
+ int len = 0, fname_len = strlen (fname);
+
+ if (ptr)
+ len = ptr->len;
+
+ p = (char *) alloca (len + fname_len + 2);
+ if (len)
+ {
+ memcpy (p, ptr->name, len);
+ p[len++] = '/';
+ }
+ memcpy (p + len, fname, fname_len + 1);
+ deps_add_dep (pfile->deps, p);
+ }
+ }
+ /* If -M was specified, then don't count this as an error, because
+ we can still produce correct output. Otherwise, we can't produce
+ correct output, because there may be dependencies we need inside
+ the missing file, and we don't know what directory this missing
+ file exists in. FIXME: Use a future cpp_diagnotic_with_errno ()
+ for both of these cases. */
+ else if (CPP_PRINT_DEPS (pfile) && ! print_dep)
+ cpp_warning (pfile, "%s: %s", fname, xstrerror (errno));
+ else
+ cpp_error_from_errno (pfile, fname);
+}
+
+/* Returns non-zero if a buffer was stacked. */
+int
+_cpp_execute_include (pfile, header, type)
+ cpp_reader *pfile;
+ const cpp_token *header;
+ enum include_type type;
+{
+ struct include_file *inc = find_include_file (pfile, header, type);
+
+ if (inc == 0)
+ handle_missing_header (pfile, (const char *) header->val.str.text,
+ header->type == CPP_HEADER_NAME);
+ else if (inc != NO_INCLUDE_PATH)
+ {
+ if (header->type == CPP_HEADER_NAME)
+ pfile->system_include_depth++;
+
+ stack_include_file (pfile, inc);
+
+ if (type == IT_IMPORT)
+ _cpp_never_reread (inc);
+
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Locate HEADER, and determine whether it is newer than the current
+ file. If it cannot be located or dated, return -1, if it is newer
+ newer, return 1, otherwise 0. */
+int
+_cpp_compare_file_date (pfile, header)
+ cpp_reader *pfile;
+ const cpp_token *header;
+{
+ struct include_file *inc = find_include_file (pfile, header, 0);
+
+ if (inc == NULL || inc == NO_INCLUDE_PATH)
+ return -1;
+
+ if (inc->fd > 0)
+ {
+ close (inc->fd);
+ inc->fd = -1;
+ }
+
+ return inc->st.st_mtime > pfile->buffer->inc->st.st_mtime;
+}
+
+
+/* Push an input buffer and load it up with the contents of FNAME.
+ If FNAME is "", read standard input. */
+int
+_cpp_read_file (pfile, fname)
+ cpp_reader *pfile;
+ const char *fname;
+{
+ struct include_file *f = open_file (pfile, fname);
+
+ if (f == NULL)
+ {
+ cpp_error_from_errno (pfile, fname);
+ return 0;
+ }
+
+ stack_include_file (pfile, f);
+ return 1;
+}
+
+/* Do appropriate cleanup when a file buffer is popped off the input
+ stack. */
+void
+_cpp_pop_file_buffer (pfile, buf)
+ cpp_reader *pfile;
+ cpp_buffer *buf;
+{
+ struct include_file *inc = buf->inc;
+
+ if (pfile->system_include_depth)
+ pfile->system_include_depth--;
+ if (pfile->include_depth)
+ pfile->include_depth--;
+
+ /* Record the inclusion-preventing macro, which could be NULL
+ meaning no controlling macro, if we haven't got it already. */
+ if (pfile->mi_state == MI_OUTSIDE && inc->cmacro == NULL)
+ inc->cmacro = pfile->mi_cmacro;
+
+ /* Invalidate control macros in the #including file. */
+ pfile->mi_state = MI_FAILED;
+
+ inc->refcnt--;
+ if (inc->refcnt == 0 && DO_NOT_REREAD (inc))
+ purge_cache (inc);
+}
+
+/* Returns the first place in the include chain to start searching for
+ "" includes. This involves stripping away the basename of the
+ current file, unless -I- was specified.
+
+ If we're handling -include or -imacros, use the "" chain, but with
+ the preprocessor's cwd prepended. */
+static struct search_path *
+search_from (pfile, type)
+ cpp_reader *pfile;
+ enum include_type type;
+{
+ cpp_buffer *buffer = pfile->buffer;
+ unsigned int dlen;
+
+ /* Command line uses the cwd, and does not cache the result. */
+ if (type == IT_CMDLINE)
+ goto use_cwd;
+
+ /* Ignore the current file's directory if -I- was given. */
+ if (CPP_OPTION (pfile, ignore_srcdir))
+ return CPP_OPTION (pfile, quote_include);
+
+ if (! buffer->search_cached)
+ {
+ buffer->search_cached = 1;
+
+ dlen = lbasename (buffer->inc->name) - buffer->inc->name;
+
+ if (dlen)
+ {
+ /* We don't guarantee NAME is null-terminated. This saves
+ allocating and freeing memory, and duplicating it when faking
+ buffers in cpp_push_buffer. Drop a trailing '/'. */
+ buffer->dir.name = buffer->inc->name;
+ if (dlen > 1)
+ dlen--;
+ }
+ else
+ {
+ use_cwd:
+ buffer->dir.name = ".";
+ dlen = 1;
+ }
+
+ if (dlen > pfile->max_include_len)
+ pfile->max_include_len = dlen;
+
+ buffer->dir.len = dlen;
+ buffer->dir.next = CPP_OPTION (pfile, quote_include);
+ buffer->dir.sysp = buffer->sysp;
+ }
+
+ return &buffer->dir;
+}
+
+/* The file_name_map structure holds a mapping of file names for a
+ particular directory. This mapping is read from the file named
+ FILE_NAME_MAP_FILE in that directory. Such a file can be used to
+ map filenames on a file system with severe filename restrictions,
+ such as DOS. The format of the file name map file is just a series
+ of lines with two tokens on each line. The first token is the name
+ to map, and the second token is the actual name to use. */
+
+struct file_name_map
+{
+ struct file_name_map *map_next;
+ char *map_from;
+ char *map_to;
+};
+
+#define FILE_NAME_MAP_FILE "header.gcc"
+
+/* Read a space delimited string of unlimited length from a stdio
+ file. */
+
+static char *
+read_filename_string (ch, f)
+ int ch;
+ FILE *f;
+{
+ char *alloc, *set;
+ int len;
+
+ len = 20;
+ set = alloc = xmalloc (len + 1);
+ if (! is_space(ch))
+ {
+ *set++ = ch;
+ while ((ch = getc (f)) != EOF && ! is_space(ch))
+ {
+ if (set - alloc == len)
+ {
+ len *= 2;
+ alloc = xrealloc (alloc, len + 1);
+ set = alloc + len / 2;
+ }
+ *set++ = ch;
+ }
+ }
+ *set = '\0';
+ ungetc (ch, f);
+ return alloc;
+}
+
+/* This structure holds a linked list of file name maps, one per directory. */
+
+struct file_name_map_list
+{
+ struct file_name_map_list *map_list_next;
+ char *map_list_name;
+ struct file_name_map *map_list_map;
+};
+
+/* Read the file name map file for DIRNAME. */
+
+static struct file_name_map *
+read_name_map (pfile, dirname)
+ cpp_reader *pfile;
+ const char *dirname;
+{
+ register struct file_name_map_list *map_list_ptr;
+ char *name;
+ FILE *f;
+
+ /* Check the cache of directories, and mappings in their remap file. */
+ for (map_list_ptr = CPP_OPTION (pfile, map_list); map_list_ptr;
+ map_list_ptr = map_list_ptr->map_list_next)
+ if (! strcmp (map_list_ptr->map_list_name, dirname))
+ return map_list_ptr->map_list_map;
+
+ map_list_ptr = ((struct file_name_map_list *)
+ xmalloc (sizeof (struct file_name_map_list)));
+ map_list_ptr->map_list_name = xstrdup (dirname);
+
+ /* The end of the list ends in NULL. */
+ map_list_ptr->map_list_map = NULL;
+
+ name = (char *) alloca (strlen (dirname) + strlen (FILE_NAME_MAP_FILE) + 2);
+ strcpy (name, dirname);
+ if (*dirname)
+ strcat (name, "/");
+ strcat (name, FILE_NAME_MAP_FILE);
+ f = fopen (name, "r");
+
+ /* Silently return NULL if we cannot open. */
+ if (f)
+ {
+ int ch;
+ int dirlen = strlen (dirname);
+
+ while ((ch = getc (f)) != EOF)
+ {
+ char *from, *to;
+ struct file_name_map *ptr;
+
+ if (is_space(ch))
+ continue;
+ from = read_filename_string (ch, f);
+ while ((ch = getc (f)) != EOF && is_hspace(ch))
+ ;
+ to = read_filename_string (ch, f);
+
+ ptr = ((struct file_name_map *)
+ xmalloc (sizeof (struct file_name_map)));
+ ptr->map_from = from;
+
+ /* Make the real filename absolute. */
+ if (IS_ABSOLUTE_PATHNAME (to))
+ ptr->map_to = to;
+ else
+ {
+ ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
+ strcpy (ptr->map_to, dirname);
+ ptr->map_to[dirlen] = '/';
+ strcpy (ptr->map_to + dirlen + 1, to);
+ free (to);
+ }
+
+ ptr->map_next = map_list_ptr->map_list_map;
+ map_list_ptr->map_list_map = ptr;
+
+ while ((ch = getc (f)) != '\n')
+ if (ch == EOF)
+ break;
+ }
+ fclose (f);
+ }
+
+ /* Add this information to the cache. */
+ map_list_ptr->map_list_next = CPP_OPTION (pfile, map_list);
+ CPP_OPTION (pfile, map_list) = map_list_ptr;
+
+ return map_list_ptr->map_list_map;
+}
+
+/* Remap an unsimplified path NAME based on the file_name_map (if any)
+ for LOC. */
+static char *
+remap_filename (pfile, name, loc)
+ cpp_reader *pfile;
+ char *name;
+ struct search_path *loc;
+{
+ struct file_name_map *map;
+ const char *from, *p;
+ char *dir;
+
+ if (! loc->name_map)
+ {
+ /* Get a null-terminated path. */
+ char *dname = alloca (loc->len + 1);
+ memcpy (dname, loc->name, loc->len);
+ dname[loc->len] = '\0';
+
+ loc->name_map = read_name_map (pfile, dname);
+ if (! loc->name_map)
+ return name;
+ }
+
+ /* This works since NAME has not been simplified yet. */
+ from = name + loc->len + 1;
+
+ for (map = loc->name_map; map; map = map->map_next)
+ if (!strcmp (map->map_from, from))
+ return map->map_to;
+
+ /* Try to find a mapping file for the particular directory we are
+ looking in. Thus #include <sys/types.h> will look up sys/types.h
+ in /usr/include/header.gcc and look up types.h in
+ /usr/include/sys/header.gcc. */
+ p = strrchr (name, '/');
+ if (!p)
+ return name;
+
+ /* We know p != name as absolute paths don't call remap_filename. */
+ if (p == name)
+ cpp_ice (pfile, "absolute file name in remap_filename");
+
+ dir = (char *) alloca (p - name + 1);
+ memcpy (dir, name, p - name);
+ dir[p - name] = '\0';
+ from = p + 1;
+
+ for (map = read_name_map (pfile, dir); map; map = map->map_next)
+ if (! strcmp (map->map_from, from))
+ return map->map_to;
+
+ return name;
+}
+
+/* Returns true if it is safe to remove the final component of path,
+ when it is followed by a ".." component. We use lstat to avoid
+ symlinks if we have it. If not, we can still catch errors with
+ stat (). */
+static int
+remove_component_p (path)
+ const char *path;
+{
+ struct stat s;
+ int result;
+
+#ifdef HAVE_LSTAT
+ result = lstat (path, &s);
+#else
+ result = stat (path, &s);
+#endif
+
+ /* There's no guarantee that errno will be unchanged, even on
+ success. Cygwin's lstat(), for example, will often set errno to
+ ENOSYS. In case of success, reset errno to zero. */
+ if (result == 0)
+ errno = 0;
+
+ return result == 0 && S_ISDIR (s.st_mode);
+}
+
+/* Simplify a path name in place, deleting redundant components. This
+ reduces OS overhead and guarantees that equivalent paths compare
+ the same (modulo symlinks).
+
+ Transforms made:
+ foo/bar/../quux foo/quux
+ foo/./bar foo/bar
+ foo//bar foo/bar
+ /../quux /quux
+ //quux //quux (POSIX allows leading // as a namespace escape)
+
+ Guarantees no trailing slashes. All transforms reduce the length
+ of the string. Returns PATH. errno is 0 if no error occurred;
+ nonzero if an error occurred when using stat () or lstat (). */
+
+char *
+_cpp_simplify_pathname (path)
+ char *path;
+{
+#ifndef VMS
+ char *from, *to;
+ char *base, *orig_base;
+ int absolute = 0;
+
+ errno = 0;
+ /* Don't overflow the empty path by putting a '.' in it below. */
+ if (*path == '\0')
+ return path;
+
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ /* Convert all backslashes to slashes. */
+ for (from = path; *from; from++)
+ if (*from == '\\') *from = '/';
+
+ /* Skip over leading drive letter if present. */
+ if (ISALPHA (path[0]) && path[1] == ':')
+ from = to = &path[2];
+ else
+ from = to = path;
+#else
+ from = to = path;
+#endif
+
+ /* Remove redundant leading /s. */
+ if (*from == '/')
+ {
+ absolute = 1;
+ to++;
+ from++;
+ if (*from == '/')
+ {
+ if (*++from == '/')
+ /* 3 or more initial /s are equivalent to 1 /. */
+ while (*++from == '/');
+ else
+ /* On some hosts // differs from /; Posix allows this. */
+ to++;
+ }
+ }
+
+ base = orig_base = to;
+ for (;;)
+ {
+ int move_base = 0;
+
+ while (*from == '/')
+ from++;
+
+ if (*from == '\0')
+ break;
+
+ if (*from == '.')
+ {
+ if (from[1] == '\0')
+ break;
+ if (from[1] == '/')
+ {
+ from += 2;
+ continue;
+ }
+ else if (from[1] == '.' && (from[2] == '/' || from[2] == '\0'))
+ {
+ /* Don't simplify if there was no previous component. */
+ if (absolute && orig_base == to)
+ {
+ from += 2;
+ continue;
+ }
+ /* Don't simplify if the previous component was "../",
+ or if an error has already occurred with (l)stat. */
+ if (base != to && errno == 0)
+ {
+ /* We don't back up if it's a symlink. */
+ *to = '\0';
+ if (remove_component_p (path))
+ {
+ while (to > base && *to != '/')
+ to--;
+ from += 2;
+ continue;
+ }
+ }
+ move_base = 1;
+ }
+ }
+
+ /* Add the component separator. */
+ if (to > orig_base)
+ *to++ = '/';
+
+ /* Copy this component until the trailing null or '/'. */
+ while (*from != '\0' && *from != '/')
+ *to++ = *from++;
+
+ if (move_base)
+ base = to;
+ }
+
+ /* Change the empty string to "." so that it is not treated as stdin.
+ Null terminate. */
+ if (to == path)
+ *to++ = '.';
+ *to = '\0';
+
+ return path;
+#else /* VMS */
+ errno = 0;
+ return path;
+#endif /* !VMS */
+}
--- /dev/null
+/* Hash tables for the CPP library.
+ Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1998,
+ 1999, 2000 Free Software Foundation, Inc.
+ Written by Per Bothner, 1994.
+ Based on CCCP program by Paul Rubin, June 1986
+ Adapted to ANSI C, Richard Stallman, Jan 1987
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ In other words, you are welcome to use, share and improve this program.
+ You are forbidden to forbid anyone else to use, share and improve
+ what you give them. Help stamp out software-hoarding! */
+
+#include "config.h"
+#include "system.h"
+#include "cpplib.h"
+#include "cpphash.h"
+
+static cpp_hashnode *alloc_node PARAMS ((hash_table *));
+
+/* Return an identifier node for hashtable.c. Used by cpplib except
+ when integrated with the C front ends. */
+
+static cpp_hashnode *
+alloc_node (table)
+ hash_table *table;
+{
+ cpp_hashnode *node;
+
+ node = (cpp_hashnode *) obstack_alloc (&table->pfile->hash_ob,
+ sizeof (cpp_hashnode));
+ memset ((PTR) node, 0, sizeof (cpp_hashnode));
+ return node;
+}
+
+/* Set up the identifier hash table. Use TABLE if non-null, otherwise
+ create our own. */
+
+void
+_cpp_init_hashtable (pfile, table)
+ cpp_reader *pfile;
+ hash_table *table;
+{
+ if (table == NULL)
+ {
+ pfile->our_hashtable = 1;
+ table = ht_create (13); /* 8K (=2^13) entries. */
+ table->alloc_node = (hashnode (*) PARAMS ((hash_table *))) alloc_node;
+ gcc_obstack_init (&pfile->hash_ob);
+ }
+
+ table->pfile = pfile;
+ pfile->hash_table = table;
+}
+
+/* Tear down the identifier hash table. */
+
+void
+_cpp_destroy_hashtable (pfile)
+ cpp_reader *pfile;
+{
+ if (pfile->our_hashtable)
+ {
+ free (pfile->hash_table);
+ obstack_free (&pfile->hash_ob, 0);
+ }
+}
+
+/* Returns the hash entry for the STR of length LEN, creating one
+ if necessary. */
+
+cpp_hashnode *
+cpp_lookup (pfile, str, len)
+ cpp_reader *pfile;
+ const unsigned char *str;
+ unsigned int len;
+{
+ /* ht_lookup cannot return NULL. */
+ return CPP_HASHNODE (ht_lookup (pfile->hash_table, str, len, HT_ALLOC));
+}
+
+/* Determine whether the str STR, of length LEN, is a defined macro. */
+
+int
+cpp_defined (pfile, str, len)
+ cpp_reader *pfile;
+ const unsigned char *str;
+ int len;
+{
+ cpp_hashnode *node;
+
+ node = CPP_HASHNODE (ht_lookup (pfile->hash_table, str, len, HT_NO_INSERT));
+
+ /* If it's of type NT_MACRO, it cannot be poisoned. */
+ return node && node->type == NT_MACRO;
+}
+
+/* For all nodes in the hashtable, callback CB with parameters PFILE,
+ the node, and V. */
+
+void
+cpp_forall_identifiers (pfile, cb, v)
+ cpp_reader *pfile;
+ cpp_cb cb;
+ PTR v;
+{
+ /* We don't need a proxy since the hash table's identifier comes
+ first in cpp_hashnode. */
+ ht_forall (pfile->hash_table, (ht_cb) cb, v);
+}
--- /dev/null
+/* Part of CPP library.
+ Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This header defines all the internal data structures and functions
+ that need to be visible across files. It's called cpphash.h for
+ historical reasons. */
+
+#ifndef GCC_CPPHASH_H
+#define GCC_CPPHASH_H
+
+#include "hashtable.h"
+
+struct directive; /* Deliberately incomplete. */
+
+/* Test if a sign is valid within a preprocessing number. */
+#define VALID_SIGN(c, prevc) \
+ (((c) == '+' || (c) == '-') && \
+ ((prevc) == 'e' || (prevc) == 'E' \
+ || (((prevc) == 'p' || (prevc) == 'P') \
+ && CPP_OPTION (pfile, extended_numbers))))
+
+#define CPP_OPTION(PFILE, OPTION) ((PFILE)->opts.OPTION)
+#define CPP_BUFFER(PFILE) ((PFILE)->buffer)
+#define CPP_BUF_LINE(BUF) ((BUF)->lineno)
+#define CPP_BUF_COLUMN(BUF, CUR) ((CUR) - (BUF)->line_base + (BUF)->col_adjust)
+#define CPP_BUF_COL(BUF) CPP_BUF_COLUMN(BUF, (BUF)->cur)
+
+/* Maximum nesting of cpp_buffers. We use a static limit, partly for
+ efficiency, and partly to limit runaway recursion. */
+#define CPP_STACK_MAX 200
+
+/* Memory pools. */
+#define POOL_ALIGN(size, align) (((size) + ((align) - 1)) & ~((align) - 1))
+#define POOL_FRONT(p) ((p)->cur->front)
+#define POOL_LIMIT(p) ((p)->cur->limit)
+#define POOL_BASE(p) ((p)->cur->base)
+#define POOL_SIZE(p) ((p)->cur->limit - (p)->cur->base)
+#define POOL_ROOM(p) ((p)->cur->limit - (p)->cur->front)
+#define POOL_USED(p) ((p)->cur->front - (p)->cur->base)
+#define POOL_COMMIT(p, len) do {\
+ ((p)->cur->front += POOL_ALIGN (len, (p)->align));\
+ if ((p)->cur->front > (p)->cur->limit) abort ();} while (0)
+
+typedef struct cpp_chunk cpp_chunk;
+struct cpp_chunk
+{
+ cpp_chunk *next;
+ unsigned char *front;
+ unsigned char *limit;
+ unsigned char *base;
+};
+
+typedef struct cpp_pool cpp_pool;
+struct cpp_pool
+{
+ struct cpp_chunk *cur, *locked;
+ unsigned char *pos; /* Current position. */
+ unsigned int align;
+ unsigned int locks;
+};
+
+/* List of directories to look for include files in. */
+struct search_path
+{
+ struct search_path *next;
+
+ /* NOTE: NAME may not be null terminated for the case of the current
+ file's directory! */
+ const char *name;
+ unsigned int len;
+ /* We use these to tell if the directory mentioned here is a duplicate
+ of an earlier directory on the search path. */
+ ino_t ino;
+ dev_t dev;
+ /* Non-zero if it is a system include directory. */
+ int sysp;
+ /* Mapping of file names for this directory. Only used on MS-DOS
+ and related platforms. */
+ struct file_name_map *name_map;
+};
+
+/* Multiple-include optimisation. */
+enum mi_state {MI_FAILED = 0, MI_OUTSIDE};
+enum mi_ind {MI_IND_NONE = 0, MI_IND_NOT};
+
+/* #include types. */
+enum include_type {IT_INCLUDE, IT_INCLUDE_NEXT, IT_IMPORT, IT_CMDLINE};
+
+typedef struct toklist toklist;
+struct toklist
+{
+ cpp_token *first;
+ cpp_token *limit;
+};
+
+typedef struct cpp_context cpp_context;
+struct cpp_context
+{
+ /* Doubly-linked list. */
+ cpp_context *next, *prev;
+
+ /* Contexts other than the base context are contiguous tokens.
+ e.g. macro expansions, expanded argument tokens. */
+ struct toklist list;
+
+ /* For a macro context, these are the macro and its arguments. */
+ cpp_macro *macro;
+};
+
+struct lexer_state
+{
+ /* Nonzero if first token on line is CPP_HASH. */
+ unsigned char in_directive;
+
+ /* Nonzero if in a directive that takes angle-bracketed headers. */
+ unsigned char angled_headers;
+
+ /* Nonzero to save comments. Turned off if discard_comments, and in
+ all directives apart from #define. */
+ unsigned char save_comments;
+
+ /* If nonzero the next token is at the beginning of the line. */
+ unsigned char next_bol;
+
+ /* Nonzero if we're mid-comment. */
+ unsigned char lexing_comment;
+
+ /* Nonzero if lexing __VA_ARGS__ is valid. */
+ unsigned char va_args_ok;
+
+ /* Nonzero if lexing poisoned identifiers is valid. */
+ unsigned char poisoned_ok;
+
+ /* Nonzero to prevent macro expansion. */
+ unsigned char prevent_expansion;
+
+ /* Nonzero when parsing arguments to a function-like macro. */
+ unsigned char parsing_args;
+
+ /* Nonzero when in a # NUMBER directive. */
+ unsigned char line_extension;
+};
+
+/* Special nodes - identifiers with predefined significance. */
+struct spec_nodes
+{
+ cpp_hashnode *n_L; /* L"str" */
+ cpp_hashnode *n_defined; /* defined operator */
+ cpp_hashnode *n_true; /* C++ keyword true */
+ cpp_hashnode *n_false; /* C++ keyword false */
+ cpp_hashnode *n__Pragma; /* _Pragma operator */
+ cpp_hashnode *n__STRICT_ANSI__; /* STDC_0_IN_SYSTEM_HEADERS */
+ cpp_hashnode *n__CHAR_UNSIGNED__; /* plain char is unsigned */
+ cpp_hashnode *n__VA_ARGS__; /* C99 vararg macros */
+};
+
+struct cpp_buffer
+{
+ const unsigned char *cur; /* current position */
+ const unsigned char *rlimit; /* end of valid data */
+ const unsigned char *line_base; /* start of current line */
+ cppchar_t read_ahead; /* read ahead character */
+ cppchar_t extra_char; /* extra read-ahead for long tokens. */
+
+ struct cpp_reader *pfile; /* Owns this buffer. */
+ struct cpp_buffer *prev;
+
+ const unsigned char *buf; /* entire buffer */
+
+ /* Filename specified with #line command. */
+ const char *nominal_fname;
+
+ /* Pointer into the include table. Used for include_next and
+ to record control macros. */
+ struct include_file *inc;
+
+ /* Value of if_stack at start of this file.
+ Used to prohibit unmatched #endif (etc) in an include file. */
+ struct if_stack *if_stack;
+
+ /* Token column position adjustment owing to tabs in whitespace. */
+ unsigned int col_adjust;
+
+ /* Line number at line_base (above). */
+ unsigned int lineno;
+
+ /* Contains PREV_WHITE and/or AVOID_LPASTE. */
+ unsigned char saved_flags;
+
+ /* Because of the way the lexer works, -Wtrigraphs can sometimes
+ warn twice for the same trigraph. This helps prevent that. */
+ const unsigned char *last_Wtrigraphs;
+
+ /* True if we have already warned about C++ comments in this file.
+ The warning happens only for C89 extended mode with -pedantic on,
+ or for -Wtraditional, and only once per file (otherwise it would
+ be far too noisy). */
+ unsigned char warned_cplusplus_comments;
+
+ /* True if we don't process trigraphs and escaped newlines. True
+ for preprocessed input, command line directives, and _Pragma
+ buffers. */
+ unsigned char from_stage3;
+
+ /* Temporary storage for pfile->skipping whilst in a directive. */
+ unsigned char was_skipping;
+
+ /* 1 = system header file, 2 = C system header file used for C++. */
+ unsigned char sysp;
+
+ /* Nonzero means we have printed (while error reporting) a list of
+ containing files that matches the current status. */
+ unsigned char include_stack_listed;
+
+ /* Nonzero means that the directory to start searching for ""
+ include files has been calculated and stored in "dir" below. */
+ unsigned char search_cached;
+
+ /* Buffer type. */
+ ENUM_BITFIELD (cpp_buffer_type) type : 8;
+
+ /* The directory of the this buffer's file. Its NAME member is not
+ allocated, so we don't need to worry about freeing it. */
+ struct search_path dir;
+};
+
+/* A cpp_reader encapsulates the "state" of a pre-processor run.
+ Applying cpp_get_token repeatedly yields a stream of pre-processor
+ tokens. Usually, there is only one cpp_reader object active. */
+
+struct cpp_reader
+{
+ /* Top of buffer stack. */
+ cpp_buffer *buffer;
+
+ /* Lexer state. */
+ struct lexer_state state;
+
+ /* The position of the last lexed token and last lexed directive. */
+ cpp_lexer_pos lexer_pos;
+ cpp_lexer_pos directive_pos;
+
+ /* Memory pools. */
+ cpp_pool ident_pool; /* For all identifiers, and permanent
+ numbers and strings. */
+ cpp_pool macro_pool; /* For macro definitions. Permanent. */
+ cpp_pool argument_pool; /* For macro arguments. Temporary. */
+
+ /* Context stack. */
+ struct cpp_context base_context;
+ struct cpp_context *context;
+
+ /* If in_directive, the directive if known. */
+ const struct directive *directive;
+
+ /* Multiple inlcude optimisation. */
+ enum mi_state mi_state;
+ enum mi_ind mi_if_not_defined;
+ unsigned int mi_lexed;
+ const cpp_hashnode *mi_cmacro;
+ const cpp_hashnode *mi_ind_cmacro;
+
+ /* Token lookahead. */
+ struct cpp_lookahead *la_read; /* Read from this lookahead. */
+ struct cpp_lookahead *la_write; /* Write to this lookahead. */
+ struct cpp_lookahead *la_unused; /* Free store. */
+ struct cpp_lookahead *la_saved; /* Backup when entering directive. */
+
+ /* Error counter for exit code. */
+ unsigned int errors;
+
+ /* Line and column where a newline was first seen in a string
+ constant (multi-line strings). */
+ cpp_lexer_pos mlstring_pos;
+
+ /* Buffer to hold macro definition string. */
+ unsigned char *macro_buffer;
+ unsigned int macro_buffer_len;
+
+ /* Current depth in #include directives that use <...>. */
+ unsigned int system_include_depth;
+
+ /* Current depth of buffer stack. */
+ unsigned int buffer_stack_depth;
+
+ /* Current depth in #include directives. */
+ unsigned int include_depth;
+
+ /* Tree of other included files. See cppfiles.c. */
+ struct splay_tree_s *all_include_files;
+
+ /* Current maximum length of directory names in the search path
+ for include files. (Altered as we get more of them.) */
+ unsigned int max_include_len;
+
+ /* Date and time tokens. Calculated together if either is requested. */
+ cpp_token date;
+ cpp_token time;
+
+ /* Opaque handle to the dependencies of mkdeps.c. Used by -M etc. */
+ struct deps *deps;
+
+ /* Obstack holding all macro hash nodes. This never shrinks.
+ See cpphash.c */
+ struct obstack hash_ob;
+
+ /* Obstack holding buffer and conditional structures. This is a
+ real stack. See cpplib.c. */
+ struct obstack buffer_ob;
+
+ /* Pragma table - dynamic, because a library user can add to the
+ list of recognized pragmas. */
+ struct pragma_entry *pragmas;
+
+ /* Call backs. */
+ struct cpp_callbacks cb;
+
+ /* Identifier hash table. */
+ struct ht *hash_table;
+
+ /* User visible options. */
+ struct cpp_options opts;
+
+ /* Special nodes - identifiers with predefined significance to the
+ preprocessor. */
+ struct spec_nodes spec_nodes;
+
+ /* We're printed a warning recommending against using #import. */
+ unsigned char import_warning;
+
+ /* True if we are skipping a failed conditional group. */
+ unsigned char skipping;
+
+ /* Whether to print our version number. Done this way so
+ we don't get it twice for -v -version. */
+ unsigned char print_version;
+
+ /* Whether cpplib owns the hashtable. */
+ unsigned char our_hashtable;
+};
+
+/* Character classes. Based on the more primitive macros in safe-ctype.h.
+ If the definition of `numchar' looks odd to you, please look up the
+ definition of a pp-number in the C standard [section 6.4.8 of C99].
+
+ In the unlikely event that characters other than \r and \n enter
+ the set is_vspace, the macro handle_newline() in cpplex.c must be
+ updated. */
+#define _dollar_ok(x) ((x) == '$' && CPP_OPTION (pfile, dollars_in_ident))
+
+#define is_idchar(x) (ISIDNUM(x) || _dollar_ok(x))
+#define is_numchar(x) ISIDNUM(x)
+#define is_idstart(x) (ISIDST(x) || _dollar_ok(x))
+#define is_numstart(x) ISDIGIT(x)
+#define is_hspace(x) ISBLANK(x)
+#define is_vspace(x) IS_VSPACE(x)
+#define is_nvspace(x) IS_NVSPACE(x)
+#define is_space(x) IS_SPACE_OR_NUL(x)
+
+/* This table is constant if it can be initialized at compile time,
+ which is the case if cpp was compiled with GCC >=2.7, or another
+ compiler that supports C99. */
+#if HAVE_DESIGNATED_INITIALIZERS
+extern const unsigned char _cpp_trigraph_map[UCHAR_MAX + 1];
+#else
+extern unsigned char _cpp_trigraph_map[UCHAR_MAX + 1];
+#endif
+
+/* Macros. */
+
+#define CPP_PRINT_DEPS(PFILE) CPP_OPTION (PFILE, print_deps)
+#define CPP_IN_SYSTEM_HEADER(PFILE) \
+ (CPP_BUFFER (PFILE) && CPP_BUFFER (PFILE)->sysp)
+#define CPP_PEDANTIC(PF) CPP_OPTION (PF, pedantic)
+#define CPP_WTRADITIONAL(PF) CPP_OPTION (PF, warn_traditional)
+
+/* In cpperror.c */
+enum error_type { WARNING = 0, WARNING_SYSHDR, PEDWARN, ERROR, FATAL, ICE };
+extern int _cpp_begin_message PARAMS ((cpp_reader *, enum error_type,
+ const char *, const cpp_lexer_pos *));
+
+/* In cppmacro.c */
+extern void _cpp_free_definition PARAMS ((cpp_hashnode *));
+extern int _cpp_create_definition PARAMS ((cpp_reader *, cpp_hashnode *));
+extern void _cpp_pop_context PARAMS ((cpp_reader *));
+extern void _cpp_free_lookaheads PARAMS ((cpp_reader *));
+extern void _cpp_release_lookahead PARAMS ((cpp_reader *));
+extern void _cpp_push_token PARAMS ((cpp_reader *, const cpp_token *,
+ const cpp_lexer_pos *));
+
+/* In cpphash.c */
+extern void _cpp_init_hashtable PARAMS ((cpp_reader *, hash_table *));
+extern void _cpp_destroy_hashtable PARAMS ((cpp_reader *));
+
+/* In cppfiles.c */
+extern void _cpp_fake_include PARAMS ((cpp_reader *, const char *));
+extern void _cpp_never_reread PARAMS ((struct include_file *));
+extern char *_cpp_simplify_pathname PARAMS ((char *));
+extern int _cpp_read_file PARAMS ((cpp_reader *, const char *));
+extern int _cpp_execute_include PARAMS ((cpp_reader *,
+ const cpp_token *,
+ enum include_type));
+extern int _cpp_compare_file_date PARAMS ((cpp_reader *,
+ const cpp_token *));
+extern void _cpp_report_missing_guards PARAMS ((cpp_reader *));
+extern void _cpp_init_includes PARAMS ((cpp_reader *));
+extern void _cpp_cleanup_includes PARAMS ((cpp_reader *));
+extern void _cpp_pop_file_buffer PARAMS ((cpp_reader *, cpp_buffer *));
+
+/* In cppexp.c */
+extern int _cpp_parse_expr PARAMS ((cpp_reader *));
+
+/* In cpplex.c */
+extern void _cpp_lex_token PARAMS ((cpp_reader *, cpp_token *));
+extern int _cpp_equiv_tokens PARAMS ((const cpp_token *,
+ const cpp_token *));
+extern void _cpp_init_pool PARAMS ((cpp_pool *, unsigned int,
+ unsigned int, unsigned int));
+extern void _cpp_free_pool PARAMS ((cpp_pool *));
+extern unsigned char *_cpp_pool_reserve PARAMS ((cpp_pool *, unsigned int));
+extern unsigned char *_cpp_pool_alloc PARAMS ((cpp_pool *, unsigned int));
+extern unsigned char *_cpp_next_chunk PARAMS ((cpp_pool *, unsigned int,
+ unsigned char **));
+extern void _cpp_lock_pool PARAMS ((cpp_pool *));
+extern void _cpp_unlock_pool PARAMS ((cpp_pool *));
+
+/* In cpplib.c */
+extern int _cpp_test_assertion PARAMS ((cpp_reader *, int *));
+extern int _cpp_handle_directive PARAMS ((cpp_reader *, int));
+extern void _cpp_define_builtin PARAMS ((cpp_reader *, const char *));
+extern void _cpp_do__Pragma PARAMS ((cpp_reader *));
+extern void _cpp_init_directives PARAMS ((cpp_reader *));
+extern void _cpp_init_internal_pragmas PARAMS ((cpp_reader *));
+extern void _cpp_do_file_change PARAMS ((cpp_reader *, enum cpp_fc_reason,
+ const char *, unsigned int));
+
+/* Utility routines and macros. */
+#define DSC(str) (const U_CHAR *)str, sizeof str - 1
+#define xnew(T) (T *) xmalloc (sizeof(T))
+#define xcnew(T) (T *) xcalloc (1, sizeof(T))
+#define xnewvec(T, N) (T *) xmalloc (sizeof(T) * (N))
+#define xcnewvec(T, N) (T *) xcalloc (N, sizeof(T))
+#define xobnew(O, T) (T *) obstack_alloc (O, sizeof(T))
+
+/* These are inline functions instead of macros so we can get type
+ checking. */
+typedef unsigned char U_CHAR;
+#define U (const U_CHAR *) /* Intended use: U"string" */
+
+static inline int ustrcmp PARAMS ((const U_CHAR *, const U_CHAR *));
+static inline int ustrncmp PARAMS ((const U_CHAR *, const U_CHAR *,
+ size_t));
+static inline size_t ustrlen PARAMS ((const U_CHAR *));
+static inline U_CHAR *uxstrdup PARAMS ((const U_CHAR *));
+static inline U_CHAR *ustrchr PARAMS ((const U_CHAR *, int));
+static inline int ufputs PARAMS ((const U_CHAR *, FILE *));
+
+static inline int
+ustrcmp (s1, s2)
+ const U_CHAR *s1, *s2;
+{
+ return strcmp ((const char *)s1, (const char *)s2);
+}
+
+static inline int
+ustrncmp (s1, s2, n)
+ const U_CHAR *s1, *s2;
+ size_t n;
+{
+ return strncmp ((const char *)s1, (const char *)s2, n);
+}
+
+static inline size_t
+ustrlen (s1)
+ const U_CHAR *s1;
+{
+ return strlen ((const char *)s1);
+}
+
+static inline U_CHAR *
+uxstrdup (s1)
+ const U_CHAR *s1;
+{
+ return (U_CHAR *) xstrdup ((const char *)s1);
+}
+
+static inline U_CHAR *
+ustrchr (s1, c)
+ const U_CHAR *s1;
+ int c;
+{
+ return (U_CHAR *) strchr ((const char *)s1, c);
+}
+
+static inline int
+ufputs (s, f)
+ const U_CHAR *s;
+ FILE *f;
+{
+ return fputs ((const char *)s, f);
+}
+
+#endif /* ! GCC_CPPHASH_H */
--- /dev/null
+/* CPP Library.
+ Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Per Bothner, 1994-95.
+ Based on CCCP program by Paul Rubin, June 1986
+ Adapted to ANSI C, Richard Stallman, Jan 1987
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "cpplib.h"
+#include "cpphash.h"
+#include "output.h"
+#include "prefix.h"
+#include "intl.h"
+#include "version.h"
+#include "mkdeps.h"
+#include "cppdefault.h"
+
+/* Predefined symbols, built-in macros, and the default include path. */
+
+#ifndef GET_ENV_PATH_LIST
+#define GET_ENV_PATH_LIST(VAR,NAME) do { (VAR) = getenv (NAME); } while (0)
+#endif
+
+/* Windows does not natively support inodes, and neither does MSDOS.
+ Cygwin's emulation can generate non-unique inodes, so don't use it.
+ VMS has non-numeric inodes. */
+#ifdef VMS
+# define INO_T_EQ(a, b) (!memcmp (&(a), &(b), sizeof (a)))
+#else
+# if (defined _WIN32 && ! defined (_UWIN)) || defined __MSDOS__
+# define INO_T_EQ(a, b) 0
+# else
+# define INO_T_EQ(a, b) ((a) == (b))
+# endif
+#endif
+
+/* Internal structures and prototypes. */
+
+/* A `struct pending_option' remembers one -D, -A, -U, -include, or
+ -imacros switch. */
+
+typedef void (* cl_directive_handler) PARAMS ((cpp_reader *, const char *));
+struct pending_option
+{
+ struct pending_option *next;
+ const char *arg;
+ cl_directive_handler handler;
+};
+
+/* The `pending' structure accumulates all the options that are not
+ actually processed until we hit cpp_start_read. It consists of
+ several lists, one for each type of option. We keep both head and
+ tail pointers for quick insertion. */
+struct cpp_pending
+{
+ struct pending_option *directive_head, *directive_tail;
+
+ struct search_path *quote_head, *quote_tail;
+ struct search_path *brack_head, *brack_tail;
+ struct search_path *systm_head, *systm_tail;
+ struct search_path *after_head, *after_tail;
+
+ struct pending_option *imacros_head, *imacros_tail;
+ struct pending_option *include_head, *include_tail;
+};
+
+#ifdef __STDC__
+#define APPEND(pend, list, elt) \
+ do { if (!(pend)->list##_head) (pend)->list##_head = (elt); \
+ else (pend)->list##_tail->next = (elt); \
+ (pend)->list##_tail = (elt); \
+ } while (0)
+#else
+#define APPEND(pend, list, elt) \
+ do { if (!(pend)->list/**/_head) (pend)->list/**/_head = (elt); \
+ else (pend)->list/**/_tail->next = (elt); \
+ (pend)->list/**/_tail = (elt); \
+ } while (0)
+#endif
+
+static void print_help PARAMS ((void));
+static void path_include PARAMS ((cpp_reader *,
+ char *, int));
+static void init_library PARAMS ((void));
+static void init_builtins PARAMS ((cpp_reader *));
+static void append_include_chain PARAMS ((cpp_reader *,
+ char *, int, int));
+struct search_path * remove_dup_dir PARAMS ((cpp_reader *,
+ struct search_path *));
+struct search_path * remove_dup_dirs PARAMS ((cpp_reader *,
+ struct search_path *));
+static void merge_include_chains PARAMS ((cpp_reader *));
+static void do_includes PARAMS ((cpp_reader *,
+ struct pending_option *,
+ int));
+static void set_lang PARAMS ((cpp_reader *, enum c_lang));
+static void init_dependency_output PARAMS ((cpp_reader *));
+static void init_standard_includes PARAMS ((cpp_reader *));
+static void new_pending_directive PARAMS ((struct cpp_pending *,
+ const char *,
+ cl_directive_handler));
+static void output_deps PARAMS ((cpp_reader *));
+static int parse_option PARAMS ((const char *));
+
+/* Fourth argument to append_include_chain: chain to use.
+ Note it's never asked to append to the quote chain. */
+enum { BRACKET = 0, SYSTEM, AFTER };
+
+/* If we have designated initializers (GCC >2.7) these tables can be
+ initialized, constant data. Otherwise, they have to be filled in at
+ runtime. */
+#if HAVE_DESIGNATED_INITIALIZERS
+
+#define init_trigraph_map() /* Nothing. */
+#define TRIGRAPH_MAP \
+__extension__ const U_CHAR _cpp_trigraph_map[UCHAR_MAX + 1] = {
+
+#define END };
+#define s(p, v) [p] = v,
+
+#else
+
+#define TRIGRAPH_MAP U_CHAR _cpp_trigraph_map[UCHAR_MAX + 1] = { 0 }; \
+ static void init_trigraph_map PARAMS ((void)) { \
+ unsigned char *x = _cpp_trigraph_map;
+
+#define END }
+#define s(p, v) x[p] = v;
+
+#endif
+
+TRIGRAPH_MAP
+ s('=', '#') s(')', ']') s('!', '|')
+ s('(', '[') s('\'', '^') s('>', '}')
+ s('/', '\\') s('<', '{') s('-', '~')
+END
+
+#undef s
+#undef END
+#undef TRIGRAPH_MAP
+
+/* Given a colon-separated list of file names PATH,
+ add all the names to the search path for include files. */
+
+static void
+path_include (pfile, list, path)
+ cpp_reader *pfile;
+ char *list;
+ int path;
+{
+ char *p, *q, *name;
+
+ p = list;
+
+ do
+ {
+ /* Find the end of this name. */
+ q = p;
+ while (*q != 0 && *q != PATH_SEPARATOR) q++;
+ if (q == p)
+ {
+ /* An empty name in the path stands for the current directory. */
+ name = (char *) xmalloc (2);
+ name[0] = '.';
+ name[1] = 0;
+ }
+ else
+ {
+ /* Otherwise use the directory that is named. */
+ name = (char *) xmalloc (q - p + 1);
+ memcpy (name, p, q - p);
+ name[q - p] = 0;
+ }
+
+ append_include_chain (pfile, name, path, 0);
+
+ /* Advance past this name. */
+ if (*q == 0)
+ break;
+ p = q + 1;
+ }
+ while (1);
+}
+
+/* Append DIR to include path PATH. DIR must be permanently allocated
+ and writable. */
+static void
+append_include_chain (pfile, dir, path, cxx_aware)
+ cpp_reader *pfile;
+ char *dir;
+ int path;
+ int cxx_aware ATTRIBUTE_UNUSED;
+{
+ struct cpp_pending *pend = CPP_OPTION (pfile, pending);
+ struct search_path *new;
+ struct stat st;
+ unsigned int len;
+
+ if (*dir == '\0')
+ dir = xstrdup (".");
+ _cpp_simplify_pathname (dir);
+ if (stat (dir, &st))
+ {
+ /* Dirs that don't exist are silently ignored. */
+ if (errno != ENOENT)
+ cpp_notice_from_errno (pfile, dir);
+ else if (CPP_OPTION (pfile, verbose))
+ fprintf (stderr, _("ignoring nonexistent directory \"%s\"\n"), dir);
+ return;
+ }
+
+ if (!S_ISDIR (st.st_mode))
+ {
+ cpp_notice (pfile, "%s: Not a directory", dir);
+ return;
+ }
+
+ len = strlen (dir);
+ if (len > pfile->max_include_len)
+ pfile->max_include_len = len;
+
+ new = (struct search_path *) xmalloc (sizeof (struct search_path));
+ new->name = dir;
+ new->len = len;
+ new->ino = st.st_ino;
+ new->dev = st.st_dev;
+ /* Both systm and after include file lists should be treated as system
+ include files since these two lists are really just a concatenation
+ of one "system" list. */
+ if (path == SYSTEM || path == AFTER)
+#ifdef NO_IMPLICIT_EXTERN_C
+ new->sysp = 1;
+#else
+ new->sysp = cxx_aware ? 1 : 2;
+#endif
+ else
+ new->sysp = 0;
+ new->name_map = NULL;
+ new->next = NULL;
+
+ switch (path)
+ {
+ case BRACKET: APPEND (pend, brack, new); break;
+ case SYSTEM: APPEND (pend, systm, new); break;
+ case AFTER: APPEND (pend, after, new); break;
+ }
+}
+
+/* Handle a duplicated include path. PREV is the link in the chain
+ before the duplicate. The duplicate is removed from the chain and
+ freed. Returns PREV. */
+struct search_path *
+remove_dup_dir (pfile, prev)
+ cpp_reader *pfile;
+ struct search_path *prev;
+{
+ struct search_path *cur = prev->next;
+
+ if (CPP_OPTION (pfile, verbose))
+ fprintf (stderr, _("ignoring duplicate directory \"%s\"\n"), cur->name);
+
+ prev->next = cur->next;
+ free ((PTR) cur->name);
+ free (cur);
+
+ return prev;
+}
+
+/* Remove duplicate directories from a chain. Returns the tail of the
+ chain, or NULL if the chain is empty. This algorithm is quadratic
+ in the number of -I switches, which is acceptable since there
+ aren't usually that many of them. */
+struct search_path *
+remove_dup_dirs (pfile, head)
+ cpp_reader *pfile;
+ struct search_path *head;
+{
+ struct search_path *prev = NULL, *cur, *other;
+
+ for (cur = head; cur; cur = cur->next)
+ {
+ for (other = head; other != cur; other = other->next)
+ if (INO_T_EQ (cur->ino, other->ino) && cur->dev == other->dev)
+ {
+ cur = remove_dup_dir (pfile, prev);
+ break;
+ }
+ prev = cur;
+ }
+
+ return prev;
+}
+
+/* Merge the four include chains together in the order quote, bracket,
+ system, after. Remove duplicate dirs (as determined by
+ INO_T_EQ()). The system_include and after_include chains are never
+ referred to again after this function; all access is through the
+ bracket_include path.
+
+ For the future: Check if the directory is empty (but
+ how?) and possibly preload the include hash. */
+
+static void
+merge_include_chains (pfile)
+ cpp_reader *pfile;
+{
+ struct search_path *quote, *brack, *systm, *qtail;
+
+ struct cpp_pending *pend = CPP_OPTION (pfile, pending);
+
+ quote = pend->quote_head;
+ brack = pend->brack_head;
+ systm = pend->systm_head;
+ qtail = pend->quote_tail;
+
+ /* Paste together bracket, system, and after include chains. */
+ if (systm)
+ pend->systm_tail->next = pend->after_head;
+ else
+ systm = pend->after_head;
+
+ if (brack)
+ pend->brack_tail->next = systm;
+ else
+ brack = systm;
+
+ /* This is a bit tricky. First we drop dupes from the quote-include
+ list. Then we drop dupes from the bracket-include list.
+ Finally, if qtail and brack are the same directory, we cut out
+ brack and move brack up to point to qtail.
+
+ We can't just merge the lists and then uniquify them because
+ then we may lose directories from the <> search path that should
+ be there; consider -Ifoo -Ibar -I- -Ifoo -Iquux. It is however
+ safe to treat -Ibar -Ifoo -I- -Ifoo -Iquux as if written
+ -Ibar -I- -Ifoo -Iquux. */
+
+ remove_dup_dirs (pfile, brack);
+ qtail = remove_dup_dirs (pfile, quote);
+
+ if (quote)
+ {
+ qtail->next = brack;
+
+ /* If brack == qtail, remove brack as it's simpler. */
+ if (INO_T_EQ (qtail->ino, brack->ino) && qtail->dev == brack->dev)
+ brack = remove_dup_dir (pfile, qtail);
+ }
+ else
+ quote = brack;
+
+ CPP_OPTION (pfile, quote_include) = quote;
+ CPP_OPTION (pfile, bracket_include) = brack;
+}
+
+/* Sets internal flags correctly for a given language, and defines
+ macros if necessary. */
+static void
+set_lang (pfile, lang)
+ cpp_reader *pfile;
+ enum c_lang lang;
+{
+ /* Defaults. */
+ CPP_OPTION (pfile, lang) = lang;
+ CPP_OPTION (pfile, objc) = 0;
+ CPP_OPTION (pfile, cplusplus) = 0;
+ CPP_OPTION (pfile, extended_numbers) = 1; /* Allowed in GNU C and C99. */
+
+ switch (lang)
+ {
+ /* GNU C. */
+ case CLK_GNUC99:
+ CPP_OPTION (pfile, trigraphs) = 0;
+ CPP_OPTION (pfile, dollars_in_ident) = 1;
+ CPP_OPTION (pfile, cplusplus_comments) = 1;
+ CPP_OPTION (pfile, digraphs) = 1;
+ CPP_OPTION (pfile, c99) = 1;
+ break;
+ case CLK_GNUC89:
+ CPP_OPTION (pfile, trigraphs) = 0;
+ CPP_OPTION (pfile, dollars_in_ident) = 1;
+ CPP_OPTION (pfile, cplusplus_comments) = 1;
+ CPP_OPTION (pfile, digraphs) = 1;
+ CPP_OPTION (pfile, c99) = 0;
+ break;
+
+ /* ISO C. */
+ case CLK_STDC94:
+ case CLK_STDC89:
+ CPP_OPTION (pfile, trigraphs) = 1;
+ CPP_OPTION (pfile, dollars_in_ident) = 0;
+ CPP_OPTION (pfile, cplusplus_comments) = 0;
+ CPP_OPTION (pfile, digraphs) = lang == CLK_STDC94;
+ CPP_OPTION (pfile, c99) = 0;
+ CPP_OPTION (pfile, extended_numbers) = 0;
+ break;
+ case CLK_STDC99:
+ CPP_OPTION (pfile, trigraphs) = 1;
+ CPP_OPTION (pfile, dollars_in_ident) = 0;
+ CPP_OPTION (pfile, cplusplus_comments) = 1;
+ CPP_OPTION (pfile, digraphs) = 1;
+ CPP_OPTION (pfile, c99) = 1;
+ break;
+
+ /* Objective C. */
+ case CLK_OBJCXX:
+ CPP_OPTION (pfile, cplusplus) = 1;
+ case CLK_OBJC:
+ CPP_OPTION (pfile, trigraphs) = 0;
+ CPP_OPTION (pfile, dollars_in_ident) = 1;
+ CPP_OPTION (pfile, cplusplus_comments) = 1;
+ CPP_OPTION (pfile, digraphs) = 1;
+ CPP_OPTION (pfile, c99) = 0;
+ CPP_OPTION (pfile, objc) = 1;
+ break;
+
+ /* C++. */
+ case CLK_GNUCXX:
+ case CLK_CXX98:
+ CPP_OPTION (pfile, cplusplus) = 1;
+ CPP_OPTION (pfile, trigraphs) = lang == CLK_CXX98;
+ CPP_OPTION (pfile, dollars_in_ident) = lang == CLK_GNUCXX;
+ CPP_OPTION (pfile, cplusplus_comments) = 1;
+ CPP_OPTION (pfile, digraphs) = 1;
+ CPP_OPTION (pfile, c99) = 0;
+ break;
+
+ /* Assembler. */
+ case CLK_ASM:
+ CPP_OPTION (pfile, trigraphs) = 0;
+ CPP_OPTION (pfile, dollars_in_ident) = 0; /* Maybe not? */
+ CPP_OPTION (pfile, cplusplus_comments) = 1;
+ CPP_OPTION (pfile, digraphs) = 0;
+ CPP_OPTION (pfile, c99) = 0;
+ break;
+ }
+}
+
+#ifdef HOST_EBCDIC
+static int opt_comp PARAMS ((const void *, const void *));
+
+/* Run-time sorting of options array. */
+static int
+opt_comp (p1, p2)
+ const void *p1, *p2;
+{
+ return strcmp (((struct cl_option *) p1)->opt_text,
+ ((struct cl_option *) p2)->opt_text);
+}
+#endif
+
+/* init initializes library global state. It might not need to
+ do anything depending on the platform and compiler. */
+
+static void
+init_library ()
+{
+ static int initialized = 0;
+
+ if (! initialized)
+ {
+ initialized = 1;
+
+#ifdef HOST_EBCDIC
+ /* For non-ASCII hosts, the cl_options array needs to be sorted at
+ runtime. */
+ qsort (cl_options, N_OPTS, sizeof (struct cl_option), opt_comp);
+#endif
+
+ /* Set up the trigraph map. This doesn't need to do anything if
+ we were compiled with a compiler that supports C99 designated
+ initializers. */
+ init_trigraph_map ();
+ }
+}
+
+/* Initialize a cpp_reader structure. */
+cpp_reader *
+cpp_create_reader (table, lang)
+ hash_table *table;
+ enum c_lang lang;
+{
+ struct spec_nodes *s;
+ cpp_reader *pfile;
+
+ /* Initialise this instance of the library if it hasn't been already. */
+ init_library ();
+
+ pfile = (cpp_reader *) xcalloc (1, sizeof (cpp_reader));
+
+ set_lang (pfile, lang);
+ CPP_OPTION (pfile, warn_import) = 1;
+ CPP_OPTION (pfile, discard_comments) = 1;
+ CPP_OPTION (pfile, show_column) = 1;
+ CPP_OPTION (pfile, tabstop) = 8;
+ CPP_OPTION (pfile, operator_names) = 1;
+
+ CPP_OPTION (pfile, pending) =
+ (struct cpp_pending *) xcalloc (1, sizeof (struct cpp_pending));
+
+ /* It's simplest to just create this struct whether or not it will
+ be needed. */
+ pfile->deps = deps_init ();
+
+ /* Initialize lexer state. */
+ pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
+
+ /* Indicate date and time not yet calculated. */
+ pfile->date.type = CPP_EOF;
+
+ /* Initialise the base context. */
+ pfile->context = &pfile->base_context;
+ pfile->base_context.macro = 0;
+ pfile->base_context.prev = pfile->base_context.next = 0;
+
+ /* Identifier pool initially 8K. Unaligned, permanent pool. */
+ _cpp_init_pool (&pfile->ident_pool, 8 * 1024, 1, 0);
+
+ /* Argument pool initially 8K. Aligned, temporary pool. */
+ _cpp_init_pool (&pfile->argument_pool, 8 * 1024, 0, 1);
+
+ /* Macro pool initially 8K. Aligned, permanent pool. */
+ _cpp_init_pool (&pfile->macro_pool, 8 * 1024, 0, 0);
+
+ /* Initialise the buffer obstack. */
+ gcc_obstack_init (&pfile->buffer_ob);
+
+ /* Initialise the hashtable. */
+ _cpp_init_hashtable (pfile, table);
+
+ _cpp_init_directives (pfile);
+ _cpp_init_includes (pfile);
+ _cpp_init_internal_pragmas (pfile);
+
+ /* Initialize the special nodes. */
+ s = &pfile->spec_nodes;
+ s->n_L = cpp_lookup (pfile, DSC("L"));
+ s->n_defined = cpp_lookup (pfile, DSC("defined"));
+ s->n_true = cpp_lookup (pfile, DSC("true"));
+ s->n_false = cpp_lookup (pfile, DSC("false"));
+ s->n__Pragma = cpp_lookup (pfile, DSC("_Pragma"));
+ s->n__STRICT_ANSI__ = cpp_lookup (pfile, DSC("__STRICT_ANSI__"));
+ s->n__CHAR_UNSIGNED__ = cpp_lookup (pfile, DSC("__CHAR_UNSIGNED__"));
+ s->n__VA_ARGS__ = cpp_lookup (pfile, DSC("__VA_ARGS__"));
+ s->n__VA_ARGS__->flags |= NODE_DIAGNOSTIC;
+
+ return pfile;
+}
+
+/* Free resources used by PFILE. Accessing PFILE after this function
+ returns leads to undefined behaviour. */
+int
+cpp_destroy (pfile)
+ cpp_reader *pfile;
+{
+ int result;
+ struct search_path *dir, *dirn;
+ cpp_context *context, *contextn;
+
+ while (CPP_BUFFER (pfile) != NULL)
+ cpp_pop_buffer (pfile);
+
+ if (pfile->macro_buffer)
+ {
+ free ((PTR) pfile->macro_buffer);
+ pfile->macro_buffer = NULL;
+ pfile->macro_buffer_len = 0;
+ }
+
+ deps_free (pfile->deps);
+ obstack_free (&pfile->buffer_ob, 0);
+
+ _cpp_destroy_hashtable (pfile);
+ _cpp_cleanup_includes (pfile);
+ _cpp_free_lookaheads (pfile);
+
+ _cpp_free_pool (&pfile->ident_pool);
+ _cpp_free_pool (&pfile->macro_pool);
+ _cpp_free_pool (&pfile->argument_pool);
+
+ for (dir = CPP_OPTION (pfile, quote_include); dir; dir = dirn)
+ {
+ dirn = dir->next;
+ free ((PTR) dir->name);
+ free (dir);
+ }
+
+ for (context = pfile->base_context.next; context; context = contextn)
+ {
+ contextn = context->next;
+ free (context);
+ }
+
+ result = pfile->errors;
+ free (pfile);
+
+ return result;
+}
+
+
+/* This structure defines one built-in identifier. A node will be
+ entered in the hash table under the name NAME, with value VALUE (if
+ any). If flags has OPERATOR, the node's operator field is used; if
+ flags has BUILTIN the node's builtin field is used. Macros that are
+ known at build time should not be flagged BUILTIN, as then they do
+ not appear in macro dumps with e.g. -dM or -dD.
+
+ Two values are not compile time constants, so we tag
+ them in the FLAGS field instead:
+ VERS value is the global version_string, quoted
+ ULP value is the global user_label_prefix
+
+ Also, macros with CPLUS set in the flags field are entered only for C++. */
+
+struct builtin
+{
+ const U_CHAR *name;
+ const char *value;
+ unsigned char builtin;
+ unsigned char operator;
+ unsigned short flags;
+ unsigned short len;
+};
+#define VERS 0x01
+#define ULP 0x02
+#define CPLUS 0x04
+#define BUILTIN 0x08
+#define OPERATOR 0x10
+
+#define B(n, t) { U n, 0, t, 0, BUILTIN, sizeof n - 1 }
+#define C(n, v) { U n, v, 0, 0, 0, sizeof n - 1 }
+#define X(n, f) { U n, 0, 0, 0, f, sizeof n - 1 }
+#define O(n, c, f) { U n, 0, 0, c, OPERATOR | f, sizeof n - 1 }
+static const struct builtin builtin_array[] =
+{
+ B("__TIME__", BT_TIME),
+ B("__DATE__", BT_DATE),
+ B("__FILE__", BT_FILE),
+ B("__BASE_FILE__", BT_BASE_FILE),
+ B("__LINE__", BT_SPECLINE),
+ B("__INCLUDE_LEVEL__", BT_INCLUDE_LEVEL),
+
+ X("__VERSION__", VERS),
+ X("__USER_LABEL_PREFIX__", ULP),
+ C("__REGISTER_PREFIX__", REGISTER_PREFIX),
+ C("__HAVE_BUILTIN_SETJMP__", "1"),
+#ifndef NO_BUILTIN_SIZE_TYPE
+ C("__SIZE_TYPE__", SIZE_TYPE),
+#endif
+#ifndef NO_BUILTIN_PTRDIFF_TYPE
+ C("__PTRDIFF_TYPE__", PTRDIFF_TYPE),
+#endif
+#ifndef NO_BUILTIN_WCHAR_TYPE
+ C("__WCHAR_TYPE__", WCHAR_TYPE),
+#endif
+#ifndef NO_BUILTIN_WINT_TYPE
+ C("__WINT_TYPE__", WINT_TYPE),
+#endif
+#ifdef STDC_0_IN_SYSTEM_HEADERS
+ B("__STDC__", BT_STDC),
+#else
+ C("__STDC__", "1"),
+#endif
+
+ /* Named operators known to the preprocessor. These cannot be #defined
+ and always have their stated meaning. They are treated like normal
+ identifiers except for the type code and the meaning. Most of them
+ are only for C++ (but see iso646.h). */
+ O("and", CPP_AND_AND, CPLUS),
+ O("and_eq", CPP_AND_EQ, CPLUS),
+ O("bitand", CPP_AND, CPLUS),
+ O("bitor", CPP_OR, CPLUS),
+ O("compl", CPP_COMPL, CPLUS),
+ O("not", CPP_NOT, CPLUS),
+ O("not_eq", CPP_NOT_EQ, CPLUS),
+ O("or", CPP_OR_OR, CPLUS),
+ O("or_eq", CPP_OR_EQ, CPLUS),
+ O("xor", CPP_XOR, CPLUS),
+ O("xor_eq", CPP_XOR_EQ, CPLUS)
+};
+#undef B
+#undef C
+#undef X
+#undef O
+#define builtin_array_end \
+ builtin_array + sizeof(builtin_array)/sizeof(struct builtin)
+
+/* Subroutine of cpp_start_read; reads the builtins table above and
+ enters the macros into the hash table. */
+static void
+init_builtins (pfile)
+ cpp_reader *pfile;
+{
+ const struct builtin *b;
+
+ for(b = builtin_array; b < builtin_array_end; b++)
+ {
+ if ((b->flags & CPLUS) && ! CPP_OPTION (pfile, cplusplus))
+ continue;
+
+ if ((b->flags & OPERATOR) && ! CPP_OPTION (pfile, operator_names))
+ continue;
+
+ if (b->flags & (OPERATOR | BUILTIN))
+ {
+ cpp_hashnode *hp = cpp_lookup (pfile, b->name, b->len);
+ if (b->flags & OPERATOR)
+ {
+ hp->flags |= NODE_OPERATOR;
+ hp->value.operator = b->operator;
+ }
+ else
+ {
+ hp->type = NT_MACRO;
+ hp->flags |= NODE_BUILTIN | NODE_WARN;
+ hp->value.builtin = b->builtin;
+ }
+ }
+ else /* A standard macro of some kind. */
+ {
+ const char *val;
+ char *str;
+
+ if (b->flags & VERS)
+ {
+ /* Allocate enough space for 'name "value"\n\0'. */
+ str = alloca (b->len + strlen (version_string) + 5);
+ sprintf (str, "%s \"%s\"\n", b->name, version_string);
+ }
+ else
+ {
+ if (b->flags & ULP)
+ val = CPP_OPTION (pfile, user_label_prefix);
+ else
+ val = b->value;
+
+ /* Allocate enough space for "name value\n\0". */
+ str = alloca (b->len + strlen (val) + 3);
+ sprintf(str, "%s %s\n", b->name, val);
+ }
+
+ _cpp_define_builtin (pfile, str);
+ }
+ }
+
+ if (CPP_OPTION (pfile, cplusplus))
+ {
+ _cpp_define_builtin (pfile, "__cplusplus 1");
+ if (SUPPORTS_ONE_ONLY)
+ _cpp_define_builtin (pfile, "__GXX_WEAK__ 1");
+ else
+ _cpp_define_builtin (pfile, "__GXX_WEAK__ 0");
+ }
+ if (CPP_OPTION (pfile, objc))
+ _cpp_define_builtin (pfile, "__OBJC__ 1");
+
+ if (CPP_OPTION (pfile, lang) == CLK_STDC94)
+ _cpp_define_builtin (pfile, "__STDC_VERSION__ 199409L");
+ else if (CPP_OPTION (pfile, c99))
+ _cpp_define_builtin (pfile, "__STDC_VERSION__ 199901L");
+
+ if (CPP_OPTION (pfile, lang) == CLK_STDC89
+ || CPP_OPTION (pfile, lang) == CLK_STDC94
+ || CPP_OPTION (pfile, lang) == CLK_STDC99)
+ _cpp_define_builtin (pfile, "__STRICT_ANSI__ 1");
+ else if (CPP_OPTION (pfile, lang) == CLK_ASM)
+ _cpp_define_builtin (pfile, "__ASSEMBLER__ 1");
+}
+#undef BUILTIN
+#undef OPERATOR
+#undef VERS
+#undef ULP
+#undef CPLUS
+#undef builtin_array_end
+
+/* And another subroutine. This one sets up the standard include path. */
+static void
+init_standard_includes (pfile)
+ cpp_reader *pfile;
+{
+ char *path;
+ const struct default_include *p;
+ const char *specd_prefix = CPP_OPTION (pfile, include_prefix);
+
+ /* Several environment variables may add to the include search path.
+ CPATH specifies an additional list of directories to be searched
+ as if specified with -I, while C_INCLUDE_PATH, CPLUS_INCLUDE_PATH,
+ etc. specify an additional list of directories to be searched as
+ if specified with -isystem, for the language indicated. */
+
+ GET_ENV_PATH_LIST (path, "CPATH");
+ if (path != 0 && *path != 0)
+ path_include (pfile, path, BRACKET);
+
+ switch ((CPP_OPTION (pfile, objc) << 1) + CPP_OPTION (pfile, cplusplus))
+ {
+ case 0:
+ GET_ENV_PATH_LIST (path, "C_INCLUDE_PATH");
+ break;
+ case 1:
+ GET_ENV_PATH_LIST (path, "CPLUS_INCLUDE_PATH");
+ break;
+ case 2:
+ GET_ENV_PATH_LIST (path, "OBJC_INCLUDE_PATH");
+ break;
+ case 3:
+ GET_ENV_PATH_LIST (path, "OBJCPLUS_INCLUDE_PATH");
+ break;
+ }
+ if (path != 0 && *path != 0)
+ path_include (pfile, path, SYSTEM);
+
+ /* Search "translated" versions of GNU directories.
+ These have /usr/local/lib/gcc... replaced by specd_prefix. */
+ if (specd_prefix != 0 && cpp_GCC_INCLUDE_DIR_len)
+ {
+ /* Remove the `include' from /usr/local/lib/gcc.../include.
+ GCC_INCLUDE_DIR will always end in /include. */
+ int default_len = cpp_GCC_INCLUDE_DIR_len;
+ char *default_prefix = (char *) alloca (default_len + 1);
+ int specd_len = strlen (specd_prefix);
+
+ memcpy (default_prefix, cpp_GCC_INCLUDE_DIR, default_len);
+ default_prefix[default_len] = '\0';
+
+ for (p = cpp_include_defaults; p->fname; p++)
+ {
+ /* Some standard dirs are only for C++. */
+ if (!p->cplusplus
+ || (CPP_OPTION (pfile, cplusplus)
+ && !CPP_OPTION (pfile, no_standard_cplusplus_includes)))
+ {
+ /* Does this dir start with the prefix? */
+ if (!memcmp (p->fname, default_prefix, default_len))
+ {
+ /* Yes; change prefix and add to search list. */
+ int flen = strlen (p->fname);
+ int this_len = specd_len + flen - default_len;
+ char *str = (char *) xmalloc (this_len + 1);
+ memcpy (str, specd_prefix, specd_len);
+ memcpy (str + specd_len,
+ p->fname + default_len,
+ flen - default_len + 1);
+
+ append_include_chain (pfile, str, SYSTEM, p->cxx_aware);
+ }
+ }
+ }
+ }
+
+ /* Search ordinary names for GNU include directories. */
+ for (p = cpp_include_defaults; p->fname; p++)
+ {
+ /* Some standard dirs are only for C++. */
+ if (!p->cplusplus
+ || (CPP_OPTION (pfile, cplusplus)
+ && !CPP_OPTION (pfile, no_standard_cplusplus_includes)))
+ {
+ char *str = xstrdup (update_path (p->fname, p->component));
+ append_include_chain (pfile, str, SYSTEM, p->cxx_aware);
+ }
+ }
+}
+
+/* Handles -imacro and -include from the command line. */
+static void
+do_includes (pfile, p, scan)
+ cpp_reader *pfile;
+ struct pending_option *p;
+ int scan;
+{
+ while (p)
+ {
+ struct pending_option *q;
+
+ /* Don't handle if -fpreprocessed. Later: maybe update this to
+ use the #include "" search path if cpp_read_file fails. */
+ if (CPP_OPTION (pfile, preprocessed))
+ cpp_error (pfile, "-include and -imacros cannot be used with -fpreprocessed");
+ else
+ {
+ cpp_token header;
+ header.type = CPP_STRING;
+ header.val.str.text = (const unsigned char *) p->arg;
+ header.val.str.len = strlen (p->arg);
+ if (_cpp_execute_include (pfile, &header, IT_CMDLINE) && scan)
+ cpp_scan_buffer_nooutput (pfile, 0);
+ }
+ q = p->next;
+ free (p);
+ p = q;
+ }
+}
+
+/* This is called after options have been processed. Setup for
+ processing input from the file named FNAME, or stdin if it is the
+ empty string. Return 1 on success, 0 on failure. */
+int
+cpp_start_read (pfile, fname)
+ cpp_reader *pfile;
+ const char *fname;
+{
+ struct pending_option *p, *q;
+
+ /* Set up the include search path now. */
+ if (! CPP_OPTION (pfile, no_standard_includes))
+ init_standard_includes (pfile);
+
+ merge_include_chains (pfile);
+
+ /* With -v, print the list of dirs to search. */
+ if (CPP_OPTION (pfile, verbose))
+ {
+ struct search_path *l;
+ fprintf (stderr, _("#include \"...\" search starts here:\n"));
+ for (l = CPP_OPTION (pfile, quote_include); l; l = l->next)
+ {
+ if (l == CPP_OPTION (pfile, bracket_include))
+ fprintf (stderr, _("#include <...> search starts here:\n"));
+ fprintf (stderr, " %s\n", l->name);
+ }
+ fprintf (stderr, _("End of search list.\n"));
+ }
+
+ if (CPP_OPTION (pfile, print_deps))
+ /* Set the default target (if there is none already). */
+ deps_add_default_target (pfile->deps, fname);
+
+ /* Open the main input file. This must be done early, so we have a
+ buffer to stand on. */
+ if (!_cpp_read_file (pfile, fname))
+ return 0;
+
+ /* If already preprocessed, don't install __LINE__, etc., and ignore
+ command line definitions and assertions. Handle -U's, -D's and
+ -A's in the order they were seen. */
+ if (! CPP_OPTION (pfile, preprocessed))
+ init_builtins (pfile);
+
+ p = CPP_OPTION (pfile, pending)->directive_head;
+ while (p)
+ {
+ if (! CPP_OPTION (pfile, preprocessed))
+ (*p->handler) (pfile, p->arg);
+ q = p->next;
+ free (p);
+ p = q;
+ }
+
+ /* The -imacros files can be scanned now, but the -include files
+ have to be pushed onto the buffer stack and processed later,
+ otherwise cppmain.c won't see the tokens. include_head was built
+ up as a stack, and popping this stack onto the buffer stack means
+ we preserve the order of the command line. */
+ do_includes (pfile, CPP_OPTION (pfile, pending)->imacros_head, 1);
+ do_includes (pfile, CPP_OPTION (pfile, pending)->include_head, 0);
+
+ free (CPP_OPTION (pfile, pending));
+ CPP_OPTION (pfile, pending) = NULL;
+
+ return 1;
+}
+
+/* Use mkdeps.c to output dependency information. */
+static void
+output_deps (pfile)
+ cpp_reader *pfile;
+{
+ /* Stream on which to print the dependency information. */
+ FILE *deps_stream = 0;
+ const char *deps_mode = CPP_OPTION (pfile, print_deps_append) ? "a" : "w";
+
+ if (CPP_OPTION (pfile, deps_file) == 0)
+ deps_stream = stdout;
+ else
+ {
+ deps_stream = fopen (CPP_OPTION (pfile, deps_file), deps_mode);
+ if (deps_stream == 0)
+ {
+ cpp_notice_from_errno (pfile, CPP_OPTION (pfile, deps_file));
+ return;
+ }
+ }
+
+ deps_write (pfile->deps, deps_stream, 72);
+
+ if (CPP_OPTION (pfile, deps_phony_targets))
+ deps_phony_targets (pfile->deps, deps_stream);
+
+ /* Don't close stdout. */
+ if (CPP_OPTION (pfile, deps_file))
+ {
+ if (ferror (deps_stream) || fclose (deps_stream) != 0)
+ cpp_fatal (pfile, "I/O error on output");
+ }
+}
+
+/* This is called at the end of preprocessing. It pops the
+ last buffer and writes dependency output. It should also
+ clear macro definitions, such that you could call cpp_start_read
+ with a new filename to restart processing. */
+void
+cpp_finish (pfile)
+ cpp_reader *pfile;
+{
+ if (CPP_BUFFER (pfile))
+ {
+ cpp_ice (pfile, "buffers still stacked in cpp_finish");
+ while (CPP_BUFFER (pfile))
+ cpp_pop_buffer (pfile);
+ }
+
+ /* Don't write the deps file if preprocessing has failed. */
+ if (CPP_OPTION (pfile, print_deps) && pfile->errors == 0)
+ output_deps (pfile);
+
+ /* Report on headers that could use multiple include guards. */
+ if (CPP_OPTION (pfile, print_include_names))
+ _cpp_report_missing_guards (pfile);
+}
+
+static void
+new_pending_directive (pend, text, handler)
+ struct cpp_pending *pend;
+ const char *text;
+ cl_directive_handler handler;
+{
+ struct pending_option *o = (struct pending_option *)
+ xmalloc (sizeof (struct pending_option));
+
+ o->arg = text;
+ o->next = NULL;
+ o->handler = handler;
+ APPEND (pend, directive, o);
+}
+
+/* Irix6 "cc -n32" and OSF4 cc have problems with char foo[] = ("string");
+ I.e. a const string initializer with parens around it. That is
+ what N_("string") resolves to, so we make no_* be macros instead. */
+#define no_arg N_("Argument missing after %s")
+#define no_ass N_("Assertion missing after %s")
+#define no_dir N_("Directory name missing after %s")
+#define no_fil N_("File name missing after %s")
+#define no_mac N_("Macro name missing after %s")
+#define no_pth N_("Path name missing after %s")
+#define no_num N_("Number missing after %s")
+#define no_tgt N_("Target missing after %s")
+
+/* This is the list of all command line options, with the leading
+ "-" removed. It must be sorted in ASCII collating order. */
+#define COMMAND_LINE_OPTIONS \
+ DEF_OPT("$", 0, OPT_dollar) \
+ DEF_OPT("+", 0, OPT_plus) \
+ DEF_OPT("-help", 0, OPT__help) \
+ DEF_OPT("-target-help", 0, OPT_target__help) \
+ DEF_OPT("-version", 0, OPT__version) \
+ DEF_OPT("A", no_ass, OPT_A) \
+ DEF_OPT("C", 0, OPT_C) \
+ DEF_OPT("D", no_mac, OPT_D) \
+ DEF_OPT("H", 0, OPT_H) \
+ DEF_OPT("I", no_dir, OPT_I) \
+ DEF_OPT("M", 0, OPT_M) \
+ DEF_OPT("MD", no_fil, OPT_MD) \
+ DEF_OPT("MF", no_fil, OPT_MF) \
+ DEF_OPT("MG", 0, OPT_MG) \
+ DEF_OPT("MM", 0, OPT_MM) \
+ DEF_OPT("MMD", no_fil, OPT_MMD) \
+ DEF_OPT("MP", 0, OPT_MP) \
+ DEF_OPT("MQ", no_tgt, OPT_MQ) \
+ DEF_OPT("MT", no_tgt, OPT_MT) \
+ DEF_OPT("P", 0, OPT_P) \
+ DEF_OPT("U", no_mac, OPT_U) \
+ DEF_OPT("W", no_arg, OPT_W) /* arg optional */ \
+ DEF_OPT("d", no_arg, OPT_d) \
+ DEF_OPT("fleading-underscore", 0, OPT_fleading_underscore) \
+ DEF_OPT("fno-leading-underscore", 0, OPT_fno_leading_underscore) \
+ DEF_OPT("fno-operator-names", 0, OPT_fno_operator_names) \
+ DEF_OPT("fno-preprocessed", 0, OPT_fno_preprocessed) \
+ DEF_OPT("fno-show-column", 0, OPT_fno_show_column) \
+ DEF_OPT("fpreprocessed", 0, OPT_fpreprocessed) \
+ DEF_OPT("fshow-column", 0, OPT_fshow_column) \
+ DEF_OPT("ftabstop=", no_num, OPT_ftabstop) \
+ DEF_OPT("h", 0, OPT_h) \
+ DEF_OPT("idirafter", no_dir, OPT_idirafter) \
+ DEF_OPT("imacros", no_fil, OPT_imacros) \
+ DEF_OPT("include", no_fil, OPT_include) \
+ DEF_OPT("iprefix", no_pth, OPT_iprefix) \
+ DEF_OPT("isystem", no_dir, OPT_isystem) \
+ DEF_OPT("iwithprefix", no_dir, OPT_iwithprefix) \
+ DEF_OPT("iwithprefixbefore", no_dir, OPT_iwithprefixbefore) \
+ DEF_OPT("lang-asm", 0, OPT_lang_asm) \
+ DEF_OPT("lang-c", 0, OPT_lang_c) \
+ DEF_OPT("lang-c++", 0, OPT_lang_cplusplus) \
+ DEF_OPT("lang-c89", 0, OPT_lang_c89) \
+ DEF_OPT("lang-objc", 0, OPT_lang_objc) \
+ DEF_OPT("lang-objc++", 0, OPT_lang_objcplusplus) \
+ DEF_OPT("nostdinc", 0, OPT_nostdinc) \
+ DEF_OPT("nostdinc++", 0, OPT_nostdincplusplus) \
+ DEF_OPT("o", no_fil, OPT_o) \
+ DEF_OPT("pedantic", 0, OPT_pedantic) \
+ DEF_OPT("pedantic-errors", 0, OPT_pedantic_errors) \
+ DEF_OPT("remap", 0, OPT_remap) \
+ DEF_OPT("std=c++98", 0, OPT_std_cplusplus98) \
+ DEF_OPT("std=c89", 0, OPT_std_c89) \
+ DEF_OPT("std=c99", 0, OPT_std_c99) \
+ DEF_OPT("std=c9x", 0, OPT_std_c9x) \
+ DEF_OPT("std=gnu89", 0, OPT_std_gnu89) \
+ DEF_OPT("std=gnu99", 0, OPT_std_gnu99) \
+ DEF_OPT("std=gnu9x", 0, OPT_std_gnu9x) \
+ DEF_OPT("std=iso9899:1990", 0, OPT_std_iso9899_1990) \
+ DEF_OPT("std=iso9899:199409", 0, OPT_std_iso9899_199409) \
+ DEF_OPT("std=iso9899:1999", 0, OPT_std_iso9899_1999) \
+ DEF_OPT("std=iso9899:199x", 0, OPT_std_iso9899_199x) \
+ DEF_OPT("trigraphs", 0, OPT_trigraphs) \
+ DEF_OPT("v", 0, OPT_v) \
+ DEF_OPT("version", 0, OPT_version) \
+ DEF_OPT("w", 0, OPT_w)
+
+#define DEF_OPT(text, msg, code) code,
+enum opt_code
+{
+ COMMAND_LINE_OPTIONS
+ N_OPTS
+};
+#undef DEF_OPT
+
+struct cl_option
+{
+ const char *opt_text;
+ const char *msg;
+ size_t opt_len;
+ enum opt_code opt_code;
+};
+
+#define DEF_OPT(text, msg, code) { text, msg, sizeof(text) - 1, code },
+#ifdef HOST_EBCDIC
+static struct cl_option cl_options[] =
+#else
+static const struct cl_option cl_options[] =
+#endif
+{
+ COMMAND_LINE_OPTIONS
+};
+#undef DEF_OPT
+#undef COMMAND_LINE_OPTIONS
+
+/* Perform a binary search to find which, if any, option the given
+ command-line matches. Returns its index in the option array,
+ negative on failure. Complications arise since some options can be
+ suffixed with an argument, and multiple complete matches can occur,
+ e.g. -iwithprefix and -iwithprefixbefore. Moreover, we need to
+ accept options beginning with -W that we do not recognise, but not
+ to swallow any subsequent command line argument; this is handled as
+ special cases in cpp_handle_option. */
+static int
+parse_option (input)
+ const char *input;
+{
+ unsigned int md, mn, mx;
+ size_t opt_len;
+ int comp;
+
+ mn = 0;
+ mx = N_OPTS;
+
+ while (mx > mn)
+ {
+ md = (mn + mx) / 2;
+
+ opt_len = cl_options[md].opt_len;
+ comp = memcmp (input, cl_options[md].opt_text, opt_len);
+
+ if (comp > 0)
+ mn = md + 1;
+ else if (comp < 0)
+ mx = md;
+ else
+ {
+ if (input[opt_len] == '\0')
+ return md;
+ /* We were passed more text. If the option takes an argument,
+ we may match a later option or we may have been passed the
+ argument. The longest possible option match succeeds.
+ If the option takes no arguments we have not matched and
+ continue the search (e.g. input="stdc++" match was "stdc"). */
+ mn = md + 1;
+ if (cl_options[md].msg)
+ {
+ /* Scan forwards. If we get an exact match, return it.
+ Otherwise, return the longest option-accepting match.
+ This loops no more than twice with current options. */
+ mx = md;
+ for (; mn < (unsigned int) N_OPTS; mn++)
+ {
+ opt_len = cl_options[mn].opt_len;
+ if (memcmp (input, cl_options[mn].opt_text, opt_len))
+ break;
+ if (input[opt_len] == '\0')
+ return mn;
+ if (cl_options[mn].msg)
+ mx = mn;
+ }
+ return mx;
+ }
+ }
+ }
+
+ return -1;
+}
+
+/* Handle one command-line option in (argc, argv).
+ Can be called multiple times, to handle multiple sets of options.
+ Returns number of strings consumed. */
+
+int
+cpp_handle_option (pfile, argc, argv)
+ cpp_reader *pfile;
+ int argc;
+ char **argv;
+{
+ int i = 0;
+ struct cpp_pending *pend = CPP_OPTION (pfile, pending);
+
+ /* Interpret "-" or a non-option as a file name. */
+ if (argv[i][0] != '-' || argv[i][1] == '\0')
+ {
+ if (CPP_OPTION (pfile, in_fname) == NULL)
+ CPP_OPTION (pfile, in_fname) = argv[i];
+ else if (CPP_OPTION (pfile, out_fname) == NULL)
+ CPP_OPTION (pfile, out_fname) = argv[i];
+ else
+ cpp_fatal (pfile, "Too many filenames. Type %s --help for usage info",
+ progname);
+ }
+ else
+ {
+ enum opt_code opt_code;
+ int opt_index;
+ const char *arg = 0;
+
+ /* Skip over '-'. */
+ opt_index = parse_option (&argv[i][1]);
+ if (opt_index < 0)
+ return i;
+
+ opt_code = cl_options[opt_index].opt_code;
+ if (cl_options[opt_index].msg)
+ {
+ arg = &argv[i][cl_options[opt_index].opt_len + 1];
+
+ /* Yuk. Special case for -W as it must not swallow
+ up any following argument. If this becomes common, add
+ another field to the cl_options table. */
+ if (arg[0] == '\0' && opt_code != OPT_W)
+ {
+ arg = argv[++i];
+ if (!arg)
+ {
+ cpp_fatal (pfile, cl_options[opt_index].msg, argv[i - 1]);
+ return argc;
+ }
+ }
+ }
+
+ switch (opt_code)
+ {
+ case N_OPTS: /* Shut GCC up. */
+ break;
+ case OPT_fleading_underscore:
+ CPP_OPTION (pfile, user_label_prefix) = "_";
+ break;
+ case OPT_fno_leading_underscore:
+ CPP_OPTION (pfile, user_label_prefix) = "";
+ break;
+ case OPT_fno_operator_names:
+ CPP_OPTION (pfile, operator_names) = 0;
+ break;
+ case OPT_fpreprocessed:
+ CPP_OPTION (pfile, preprocessed) = 1;
+ break;
+ case OPT_fno_preprocessed:
+ CPP_OPTION (pfile, preprocessed) = 0;
+ break;
+ case OPT_fshow_column:
+ CPP_OPTION (pfile, show_column) = 1;
+ break;
+ case OPT_fno_show_column:
+ CPP_OPTION (pfile, show_column) = 0;
+ break;
+ case OPT_ftabstop:
+ /* Silently ignore empty string, non-longs and silly values. */
+ if (arg[0] != '\0')
+ {
+ char *endptr;
+ long tabstop = strtol (arg, &endptr, 10);
+ if (*endptr == '\0' && tabstop >= 1 && tabstop <= 100)
+ CPP_OPTION (pfile, tabstop) = tabstop;
+ }
+ break;
+ case OPT_w:
+ CPP_OPTION (pfile, inhibit_warnings) = 1;
+ break;
+ case OPT_h:
+ case OPT__help:
+ print_help ();
+ CPP_OPTION (pfile, help_only) = 1;
+ break;
+ case OPT_target__help:
+ /* Print if any target specific options. cpplib has none, but
+ make sure help_only gets set. */
+ CPP_OPTION (pfile, help_only) = 1;
+ break;
+
+ /* --version inhibits compilation, -version doesn't. -v means
+ verbose and -version. Historical reasons, don't ask. */
+ case OPT__version:
+ CPP_OPTION (pfile, help_only) = 1;
+ pfile->print_version = 1;
+ break;
+ case OPT_v:
+ CPP_OPTION (pfile, verbose) = 1;
+ pfile->print_version = 1;
+ break;
+ case OPT_version:
+ pfile->print_version = 1;
+ break;
+
+ case OPT_C:
+ CPP_OPTION (pfile, discard_comments) = 0;
+ break;
+ case OPT_P:
+ CPP_OPTION (pfile, no_line_commands) = 1;
+ break;
+ case OPT_dollar: /* Don't include $ in identifiers. */
+ CPP_OPTION (pfile, dollars_in_ident) = 0;
+ break;
+ case OPT_H:
+ CPP_OPTION (pfile, print_include_names) = 1;
+ break;
+ case OPT_D:
+ new_pending_directive (pend, arg, cpp_define);
+ break;
+ case OPT_pedantic_errors:
+ CPP_OPTION (pfile, pedantic_errors) = 1;
+ /* fall through */
+ case OPT_pedantic:
+ CPP_OPTION (pfile, pedantic) = 1;
+ break;
+ case OPT_trigraphs:
+ CPP_OPTION (pfile, trigraphs) = 1;
+ break;
+ case OPT_plus:
+ CPP_OPTION (pfile, cplusplus) = 1;
+ CPP_OPTION (pfile, cplusplus_comments) = 1;
+ break;
+ case OPT_remap:
+ CPP_OPTION (pfile, remap) = 1;
+ break;
+ case OPT_iprefix:
+ CPP_OPTION (pfile, include_prefix) = arg;
+ CPP_OPTION (pfile, include_prefix_len) = strlen (arg);
+ break;
+ case OPT_lang_c:
+ set_lang (pfile, CLK_GNUC89);
+ break;
+ case OPT_lang_cplusplus:
+ set_lang (pfile, CLK_GNUCXX);
+ break;
+ case OPT_lang_objc:
+ set_lang (pfile, CLK_OBJC);
+ break;
+ case OPT_lang_objcplusplus:
+ set_lang (pfile, CLK_OBJCXX);
+ break;
+ case OPT_lang_asm:
+ set_lang (pfile, CLK_ASM);
+ break;
+ case OPT_std_cplusplus98:
+ set_lang (pfile, CLK_CXX98);
+ break;
+ case OPT_std_gnu89:
+ set_lang (pfile, CLK_GNUC89);
+ break;
+ case OPT_std_gnu9x:
+ case OPT_std_gnu99:
+ set_lang (pfile, CLK_GNUC99);
+ break;
+ case OPT_std_iso9899_199409:
+ set_lang (pfile, CLK_STDC94);
+ break;
+ case OPT_std_iso9899_1990:
+ case OPT_std_c89:
+ case OPT_lang_c89:
+ set_lang (pfile, CLK_STDC89);
+ break;
+ case OPT_std_iso9899_199x:
+ case OPT_std_iso9899_1999:
+ case OPT_std_c9x:
+ case OPT_std_c99:
+ set_lang (pfile, CLK_STDC99);
+ break;
+ case OPT_nostdinc:
+ /* -nostdinc causes no default include directories.
+ You must specify all include-file directories with -I. */
+ CPP_OPTION (pfile, no_standard_includes) = 1;
+ break;
+ case OPT_nostdincplusplus:
+ /* -nostdinc++ causes no default C++-specific include directories. */
+ CPP_OPTION (pfile, no_standard_cplusplus_includes) = 1;
+ break;
+ case OPT_o:
+ if (CPP_OPTION (pfile, out_fname) == NULL)
+ CPP_OPTION (pfile, out_fname) = arg;
+ else
+ {
+ cpp_fatal (pfile, "Output filename specified twice");
+ return argc;
+ }
+ break;
+ case OPT_d:
+ /* Args to -d specify what parts of macros to dump.
+ Silently ignore unrecognised options; they may
+ be aimed at the compiler proper. */
+ {
+ char c;
+
+ while ((c = *arg++) != '\0')
+ switch (c)
+ {
+ case 'M':
+ CPP_OPTION (pfile, dump_macros) = dump_only;
+ CPP_OPTION (pfile, no_output) = 1;
+ break;
+ case 'N':
+ CPP_OPTION (pfile, dump_macros) = dump_names;
+ break;
+ case 'D':
+ CPP_OPTION (pfile, dump_macros) = dump_definitions;
+ break;
+ case 'I':
+ CPP_OPTION (pfile, dump_includes) = 1;
+ break;
+ }
+ }
+ break;
+
+ case OPT_MG:
+ CPP_OPTION (pfile, print_deps_missing_files) = 1;
+ break;
+ case OPT_M:
+ CPP_OPTION (pfile, print_deps) = 2;
+ break;
+ case OPT_MM:
+ CPP_OPTION (pfile, print_deps) = 1;
+ break;
+ case OPT_MF:
+ CPP_OPTION (pfile, deps_file) = arg;
+ break;
+ case OPT_MP:
+ CPP_OPTION (pfile, deps_phony_targets) = 1;
+ break;
+ case OPT_MQ:
+ case OPT_MT:
+ /* Add a target. -MQ quotes for Make. */
+ deps_add_target (pfile->deps, arg, opt_code == OPT_MQ);
+ break;
+
+ /* -MD and -MMD for cpp0 are deprecated and undocumented
+ (use -M or -MM with -MF instead), and probably should be
+ removed with the next major GCC version. For the moment
+ we allow these for the benefit of Automake 1.4, which
+ uses these when dependency tracking is enabled. Automake
+ 1.5 will fix this. */
+ case OPT_MD:
+ CPP_OPTION (pfile, print_deps) = 2;
+ CPP_OPTION (pfile, deps_file) = arg;
+ break;
+ case OPT_MMD:
+ CPP_OPTION (pfile, print_deps) = 1;
+ CPP_OPTION (pfile, deps_file) = arg;
+ break;
+
+ case OPT_A:
+ if (arg[0] == '-')
+ {
+ /* -A with an argument beginning with '-' acts as
+ #unassert on whatever immediately follows the '-'.
+ If "-" is the whole argument, we eliminate all
+ predefined macros and assertions, including those
+ that were specified earlier on the command line.
+ That way we can get rid of any that were passed
+ automatically in from GCC. */
+
+ if (arg[1] == '\0')
+ {
+ struct pending_option *o1, *o2;
+
+ o1 = pend->directive_head;
+ while (o1)
+ {
+ o2 = o1->next;
+ free (o1);
+ o1 = o2;
+ }
+ pend->directive_head = NULL;
+ pend->directive_tail = NULL;
+ }
+ else
+ new_pending_directive (pend, arg + 1, cpp_unassert);
+ }
+ else
+ new_pending_directive (pend, arg, cpp_assert);
+ break;
+ case OPT_U:
+ new_pending_directive (pend, arg, cpp_undef);
+ break;
+ case OPT_I: /* Add directory to path for includes. */
+ if (!strcmp (arg, "-"))
+ {
+ /* -I- means:
+ Use the preceding -I directories for #include "..."
+ but not #include <...>.
+ Don't search the directory of the present file
+ for #include "...". (Note that -I. -I- is not the same as
+ the default setup; -I. uses the compiler's working dir.) */
+ if (! CPP_OPTION (pfile, ignore_srcdir))
+ {
+ pend->quote_head = pend->brack_head;
+ pend->quote_tail = pend->brack_tail;
+ pend->brack_head = 0;
+ pend->brack_tail = 0;
+ CPP_OPTION (pfile, ignore_srcdir) = 1;
+ }
+ else
+ {
+ cpp_fatal (pfile, "-I- specified twice");
+ return argc;
+ }
+ }
+ else
+ append_include_chain (pfile, xstrdup (arg), BRACKET, 0);
+ break;
+ case OPT_isystem:
+ /* Add directory to beginning of system include path, as a system
+ include directory. */
+ append_include_chain (pfile, xstrdup (arg), SYSTEM, 0);
+ break;
+ case OPT_include:
+ {
+ struct pending_option *o = (struct pending_option *)
+ xmalloc (sizeof (struct pending_option));
+ o->arg = arg;
+
+ /* This list has to be built in reverse order so that
+ when cpp_start_read pushes all the -include files onto
+ the buffer stack, they will be scanned in forward order. */
+ o->next = pend->include_head;
+ pend->include_head = o;
+ }
+ break;
+ case OPT_imacros:
+ {
+ struct pending_option *o = (struct pending_option *)
+ xmalloc (sizeof (struct pending_option));
+ o->arg = arg;
+ o->next = NULL;
+
+ APPEND (pend, imacros, o);
+ }
+ break;
+ case OPT_iwithprefix:
+ /* Add directory to end of path for includes,
+ with the default prefix at the front of its name. */
+ /* fall through */
+ case OPT_iwithprefixbefore:
+ /* Add directory to main path for includes,
+ with the default prefix at the front of its name. */
+ {
+ char *fname;
+ int len;
+
+ len = strlen (arg);
+
+ if (CPP_OPTION (pfile, include_prefix) != 0)
+ {
+ size_t ipl = CPP_OPTION (pfile, include_prefix_len);
+ fname = xmalloc (ipl + len + 1);
+ memcpy (fname, CPP_OPTION (pfile, include_prefix), ipl);
+ memcpy (fname + ipl, arg, len + 1);
+ }
+ else if (cpp_GCC_INCLUDE_DIR_len)
+ {
+ fname = xmalloc (cpp_GCC_INCLUDE_DIR_len + len + 1);
+ memcpy (fname, cpp_GCC_INCLUDE_DIR, cpp_GCC_INCLUDE_DIR_len);
+ memcpy (fname + cpp_GCC_INCLUDE_DIR_len, arg, len + 1);
+ }
+ else
+ fname = xstrdup (arg);
+
+ append_include_chain (pfile, fname,
+ opt_code == OPT_iwithprefix ? SYSTEM: BRACKET, 0);
+ }
+ break;
+ case OPT_idirafter:
+ /* Add directory to end of path for includes. */
+ append_include_chain (pfile, xstrdup (arg), AFTER, 0);
+ break;
+ case OPT_W:
+ /* Silently ignore unrecognised options. */
+ if (!strcmp (argv[i], "-Wall"))
+ {
+ CPP_OPTION (pfile, warn_trigraphs) = 1;
+ CPP_OPTION (pfile, warn_comments) = 1;
+ }
+ else if (!strcmp (argv[i], "-Wtraditional"))
+ CPP_OPTION (pfile, warn_traditional) = 1;
+ else if (!strcmp (argv[i], "-Wtrigraphs"))
+ CPP_OPTION (pfile, warn_trigraphs) = 1;
+ else if (!strcmp (argv[i], "-Wcomment"))
+ CPP_OPTION (pfile, warn_comments) = 1;
+ else if (!strcmp (argv[i], "-Wcomments"))
+ CPP_OPTION (pfile, warn_comments) = 1;
+ else if (!strcmp (argv[i], "-Wundef"))
+ CPP_OPTION (pfile, warn_undef) = 1;
+ else if (!strcmp (argv[i], "-Wimport"))
+ CPP_OPTION (pfile, warn_import) = 1;
+ else if (!strcmp (argv[i], "-Werror"))
+ CPP_OPTION (pfile, warnings_are_errors) = 1;
+ else if (!strcmp (argv[i], "-Wsystem-headers"))
+ CPP_OPTION (pfile, warn_system_headers) = 1;
+ else if (!strcmp (argv[i], "-Wno-traditional"))
+ CPP_OPTION (pfile, warn_traditional) = 0;
+ else if (!strcmp (argv[i], "-Wno-trigraphs"))
+ CPP_OPTION (pfile, warn_trigraphs) = 0;
+ else if (!strcmp (argv[i], "-Wno-comment"))
+ CPP_OPTION (pfile, warn_comments) = 0;
+ else if (!strcmp (argv[i], "-Wno-comments"))
+ CPP_OPTION (pfile, warn_comments) = 0;
+ else if (!strcmp (argv[i], "-Wno-undef"))
+ CPP_OPTION (pfile, warn_undef) = 0;
+ else if (!strcmp (argv[i], "-Wno-import"))
+ CPP_OPTION (pfile, warn_import) = 0;
+ else if (!strcmp (argv[i], "-Wno-error"))
+ CPP_OPTION (pfile, warnings_are_errors) = 0;
+ else if (!strcmp (argv[i], "-Wno-system-headers"))
+ CPP_OPTION (pfile, warn_system_headers) = 0;
+ break;
+ }
+ }
+ return i + 1;
+}
+
+/* Handle command-line options in (argc, argv).
+ Can be called multiple times, to handle multiple sets of options.
+ Returns if an unrecognized option is seen.
+ Returns number of strings consumed. */
+int
+cpp_handle_options (pfile, argc, argv)
+ cpp_reader *pfile;
+ int argc;
+ char **argv;
+{
+ int i;
+ int strings_processed;
+
+ for (i = 0; i < argc; i += strings_processed)
+ {
+ strings_processed = cpp_handle_option (pfile, argc - i, argv + i);
+ if (strings_processed == 0)
+ break;
+ }
+
+ return i;
+}
+
+/* Extra processing when all options are parsed, after all calls to
+ cpp_handle_option[s]. Consistency checks etc. */
+void
+cpp_post_options (pfile)
+ cpp_reader *pfile;
+{
+ if (pfile->print_version)
+ {
+ fprintf (stderr, _("GNU CPP version %s (cpplib)"), version_string);
+#ifdef TARGET_VERSION
+ TARGET_VERSION;
+#endif
+ fputc ('\n', stderr);
+ }
+
+ /* Canonicalize in_fname and out_fname. We guarantee they are not
+ NULL, and that the empty string represents stdin / stdout. */
+ if (CPP_OPTION (pfile, in_fname) == NULL
+ || !strcmp (CPP_OPTION (pfile, in_fname), "-"))
+ CPP_OPTION (pfile, in_fname) = "";
+
+ if (CPP_OPTION (pfile, out_fname) == NULL
+ || !strcmp (CPP_OPTION (pfile, out_fname), "-"))
+ CPP_OPTION (pfile, out_fname) = "";
+
+ /* -Wtraditional is not useful in C++ mode. */
+ if (CPP_OPTION (pfile, cplusplus))
+ CPP_OPTION (pfile, warn_traditional) = 0;
+
+ /* Set this if it hasn't been set already. */
+ if (CPP_OPTION (pfile, user_label_prefix) == NULL)
+ CPP_OPTION (pfile, user_label_prefix) = USER_LABEL_PREFIX;
+
+ /* Permanently disable macro expansion if we are rescanning
+ preprocessed text. */
+ if (CPP_OPTION (pfile, preprocessed))
+ pfile->state.prevent_expansion = 1;
+
+ /* We need to do this after option processing and before
+ cpp_start_read, as cppmain.c relies on the options->no_output to
+ set its callbacks correctly before calling cpp_start_read. */
+ init_dependency_output (pfile);
+
+ /* After checking the environment variables, check if -M or -MM has
+ not been specified, but other -M options have. */
+ if (CPP_OPTION (pfile, print_deps) == 0 &&
+ (CPP_OPTION (pfile, print_deps_missing_files)
+ || CPP_OPTION (pfile, deps_file)
+ || CPP_OPTION (pfile, deps_phony_targets)))
+ cpp_fatal (pfile, "you must additionally specify either -M or -MM");
+}
+
+/* Set up dependency-file output. */
+static void
+init_dependency_output (pfile)
+ cpp_reader *pfile;
+{
+ char *spec, *s, *output_file;
+
+ /* Either of two environment variables can specify output of deps.
+ Its value is either "OUTPUT_FILE" or "OUTPUT_FILE DEPS_TARGET",
+ where OUTPUT_FILE is the file to write deps info to
+ and DEPS_TARGET is the target to mention in the deps. */
+
+ if (CPP_OPTION (pfile, print_deps) == 0)
+ {
+ spec = getenv ("DEPENDENCIES_OUTPUT");
+ if (spec)
+ CPP_OPTION (pfile, print_deps) = 1;
+ else
+ {
+ spec = getenv ("SUNPRO_DEPENDENCIES");
+ if (spec)
+ CPP_OPTION (pfile, print_deps) = 2;
+ else
+ return;
+ }
+
+ /* Find the space before the DEPS_TARGET, if there is one. */
+ s = strchr (spec, ' ');
+ if (s)
+ {
+ /* Let the caller perform MAKE quoting. */
+ deps_add_target (pfile->deps, s + 1, 0);
+ output_file = (char *) xmalloc (s - spec + 1);
+ memcpy (output_file, spec, s - spec);
+ output_file[s - spec] = 0;
+ }
+ else
+ output_file = spec;
+
+ /* Command line overrides environment variables. */
+ if (CPP_OPTION (pfile, deps_file) == 0)
+ CPP_OPTION (pfile, deps_file) = output_file;
+ CPP_OPTION (pfile, print_deps_append) = 1;
+ }
+
+ /* If dependencies go to standard output, or -MG is used, we should
+ suppress output. The user may be requesting other stuff to
+ stdout, with -dM, -v etc. We let them shoot themselves in the
+ foot. */
+ if (CPP_OPTION (pfile, deps_file) == 0
+ || CPP_OPTION (pfile, print_deps_missing_files))
+ CPP_OPTION (pfile, no_output) = 1;
+}
+
+static void
+print_help ()
+{
+ fprintf (stderr, _("Usage: %s [switches] input output\n"), progname);
+ /* To keep the lines from getting too long for some compilers, limit
+ to about 500 characters (6 lines) per chunk. */
+ fputs (_("\
+Switches:\n\
+ -include <file> Include the contents of <file> before other files\n\
+ -imacros <file> Accept definition of macros in <file>\n\
+ -iprefix <path> Specify <path> as a prefix for next two options\n\
+ -iwithprefix <dir> Add <dir> to the end of the system include path\n\
+ -iwithprefixbefore <dir> Add <dir> to the end of the main include path\n\
+ -isystem <dir> Add <dir> to the start of the system include path\n\
+"), stdout);
+ fputs (_("\
+ -idirafter <dir> Add <dir> to the end of the system include path\n\
+ -I <dir> Add <dir> to the end of the main include path\n\
+ -I- Fine-grained include path control; see info docs\n\
+ -nostdinc Do not search system include directories\n\
+ (dirs specified with -isystem will still be used)\n\
+ -nostdinc++ Do not search system include directories for C++\n\
+ -o <file> Put output into <file>\n\
+"), stdout);
+ fputs (_("\
+ -pedantic Issue all warnings demanded by strict ISO C\n\
+ -pedantic-errors Issue -pedantic warnings as errors instead\n\
+ -trigraphs Support ISO C trigraphs\n\
+ -lang-c Assume that the input sources are in C\n\
+ -lang-c89 Assume that the input sources are in C89\n\
+"), stdout);
+ fputs (_("\
+ -lang-c++ Assume that the input sources are in C++\n\
+ -lang-objc Assume that the input sources are in ObjectiveC\n\
+ -lang-objc++ Assume that the input sources are in ObjectiveC++\n\
+ -lang-asm Assume that the input sources are in assembler\n\
+"), stdout);
+ fputs (_("\
+ -std=<std name> Specify the conformance standard; one of:\n\
+ gnu89, gnu99, c89, c99, iso9899:1990,\n\
+ iso9899:199409, iso9899:1999\n\
+ -+ Allow parsing of C++ style features\n\
+ -w Inhibit warning messages\n\
+ -Wtrigraphs Warn if trigraphs are encountered\n\
+ -Wno-trigraphs Do not warn about trigraphs\n\
+ -Wcomment{s} Warn if one comment starts inside another\n\
+"), stdout);
+ fputs (_("\
+ -Wno-comment{s} Do not warn about comments\n\
+ -Wtraditional Warn about features not present in traditional C\n\
+ -Wno-traditional Do not warn about traditional C\n\
+ -Wundef Warn if an undefined macro is used by #if\n\
+ -Wno-undef Do not warn about testing undefined macros\n\
+ -Wimport Warn about the use of the #import directive\n\
+"), stdout);
+ fputs (_("\
+ -Wno-import Do not warn about the use of #import\n\
+ -Werror Treat all warnings as errors\n\
+ -Wno-error Do not treat warnings as errors\n\
+ -Wsystem-headers Do not suppress warnings from system headers\n\
+ -Wno-system-headers Suppress warnings from system headers\n\
+ -Wall Enable all preprocessor warnings\n\
+"), stdout);
+ fputs (_("\
+ -M Generate make dependencies\n\
+ -MM As -M, but ignore system header files\n\
+ -MF <file> Write dependency output to the given file\n\
+ -MG Treat missing header file as generated files\n\
+"), stdout);
+ fputs (_("\
+ -MP Generate phony targets for all headers\n\
+ -MQ <target> Add a MAKE-quoted target\n\
+ -MT <target> Add an unquoted target\n\
+"), stdout);
+ fputs (_("\
+ -D<macro> Define a <macro> with string '1' as its value\n\
+ -D<macro>=<val> Define a <macro> with <val> as its value\n\
+ -A<question> (<answer>) Assert the <answer> to <question>\n\
+ -A-<question> (<answer>) Disable the <answer> to <question>\n\
+ -U<macro> Undefine <macro> \n\
+ -v Display the version number\n\
+"), stdout);
+ fputs (_("\
+ -H Print the name of header files as they are used\n\
+ -C Do not discard comments\n\
+ -dM Display a list of macro definitions active at end\n\
+ -dD Preserve macro definitions in output\n\
+ -dN As -dD except that only the names are preserved\n\
+ -dI Include #include directives in the output\n\
+"), stdout);
+ fputs (_("\
+ -fpreprocessed Treat the input file as already preprocessed\n\
+ -ftabstop=<number> Distance between tab stops for column reporting\n\
+ -P Do not generate #line directives\n\
+ -$ Do not allow '$' in identifiers\n\
+ -remap Remap file names when including files.\n\
+ --version Display version information\n\
+ -h or --help Display this information\n\
+"), stdout);
+}
--- /dev/null
+/* CPP Library - lexical analysis.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ Contributed by Per Bothner, 1994-95.
+ Based on CCCP program by Paul Rubin, June 1986
+ Adapted to ANSI C, Richard Stallman, Jan 1987
+ Broken out to separate file, Zack Weinberg, Mar 2000
+ Single-pass line tokenization by Neil Booth, April 2000
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This lexer works with a single pass of the file. Recently I
+ re-wrote it to minimize the places where we step backwards in the
+ input stream, to make future changes to support multi-byte
+ character sets fairly straight-forward.
+
+ There is now only one routine where we do step backwards:
+ skip_escaped_newlines. This routine could probably also be changed
+ so that it doesn't need to step back. One possibility is to use a
+ trick similar to that used in lex_period and lex_percent. Two
+ extra characters might be needed, but skip_escaped_newlines itself
+ would probably be the only place that needs to be aware of that,
+ and changes to the remaining routines would probably only be needed
+ if they process a backslash. */
+
+#include "config.h"
+#include "system.h"
+#include "cpplib.h"
+#include "cpphash.h"
+
+/* MULTIBYTE_CHARS support only works for native compilers.
+ ??? Ideally what we want is to model widechar support after
+ the current floating point support. */
+#ifdef CROSS_COMPILE
+#undef MULTIBYTE_CHARS
+#endif
+
+#ifdef MULTIBYTE_CHARS
+#include "mbchar.h"
+#include <locale.h>
+#endif
+
+/* Tokens with SPELL_STRING store their spelling in the token list,
+ and it's length in the token->val.name.len. */
+enum spell_type
+{
+ SPELL_OPERATOR = 0,
+ SPELL_CHAR,
+ SPELL_IDENT,
+ SPELL_STRING,
+ SPELL_NONE
+};
+
+struct token_spelling
+{
+ enum spell_type category;
+ const unsigned char *name;
+};
+
+const unsigned char *digraph_spellings [] = {U"%:", U"%:%:", U"<:",
+ U":>", U"<%", U"%>"};
+
+#define OP(e, s) { SPELL_OPERATOR, U s },
+#define TK(e, s) { s, U STRINGX (e) },
+const struct token_spelling token_spellings [N_TTYPES] = {TTYPE_TABLE };
+#undef OP
+#undef TK
+
+#define TOKEN_SPELL(token) (token_spellings[(token)->type].category)
+#define TOKEN_NAME(token) (token_spellings[(token)->type].name)
+
+static cppchar_t handle_newline PARAMS ((cpp_buffer *, cppchar_t));
+static cppchar_t skip_escaped_newlines PARAMS ((cpp_buffer *, cppchar_t));
+static cppchar_t get_effective_char PARAMS ((cpp_buffer *));
+
+static int skip_block_comment PARAMS ((cpp_reader *));
+static int skip_line_comment PARAMS ((cpp_reader *));
+static void adjust_column PARAMS ((cpp_reader *));
+static void skip_whitespace PARAMS ((cpp_reader *, cppchar_t));
+static cpp_hashnode *parse_identifier PARAMS ((cpp_reader *, cppchar_t));
+static void parse_number PARAMS ((cpp_reader *, cpp_string *, cppchar_t, int));
+static int unescaped_terminator_p PARAMS ((cpp_reader *, const U_CHAR *));
+static void parse_string PARAMS ((cpp_reader *, cpp_token *, cppchar_t));
+static void unterminated PARAMS ((cpp_reader *, int));
+static int trigraph_ok PARAMS ((cpp_reader *, cppchar_t));
+static void save_comment PARAMS ((cpp_reader *, cpp_token *, const U_CHAR *));
+static void lex_percent PARAMS ((cpp_buffer *, cpp_token *));
+static void lex_dot PARAMS ((cpp_reader *, cpp_token *));
+static int name_p PARAMS ((cpp_reader *, const cpp_string *));
+static int maybe_read_ucs PARAMS ((cpp_reader *, const unsigned char **,
+ const unsigned char *, unsigned int *));
+
+static cpp_chunk *new_chunk PARAMS ((unsigned int));
+static int chunk_suitable PARAMS ((cpp_pool *, cpp_chunk *, unsigned int));
+static unsigned int hex_digit_value PARAMS ((unsigned int));
+
+/* Utility routine:
+
+ Compares, the token TOKEN to the NUL-terminated string STRING.
+ TOKEN must be a CPP_NAME. Returns 1 for equal, 0 for unequal. */
+
+int
+cpp_ideq (token, string)
+ const cpp_token *token;
+ const char *string;
+{
+ if (token->type != CPP_NAME)
+ return 0;
+
+ return !ustrcmp (NODE_NAME (token->val.node), (const U_CHAR *) string);
+}
+
+/* Call when meeting a newline. Returns the character after the newline
+ (or carriage-return newline combination), or EOF. */
+static cppchar_t
+handle_newline (buffer, newline_char)
+ cpp_buffer *buffer;
+ cppchar_t newline_char;
+{
+ cppchar_t next = EOF;
+
+ buffer->col_adjust = 0;
+ buffer->lineno++;
+ buffer->line_base = buffer->cur;
+
+ /* Handle CR-LF and LF-CR combinations, get the next character. */
+ if (buffer->cur < buffer->rlimit)
+ {
+ next = *buffer->cur++;
+ if (next + newline_char == '\r' + '\n')
+ {
+ buffer->line_base = buffer->cur;
+ if (buffer->cur < buffer->rlimit)
+ next = *buffer->cur++;
+ else
+ next = EOF;
+ }
+ }
+
+ buffer->read_ahead = next;
+ return next;
+}
+
+/* Subroutine of skip_escaped_newlines; called when a trigraph is
+ encountered. It warns if necessary, and returns true if the
+ trigraph should be honoured. FROM_CHAR is the third character of a
+ trigraph, and presumed to be the previous character for position
+ reporting. */
+static int
+trigraph_ok (pfile, from_char)
+ cpp_reader *pfile;
+ cppchar_t from_char;
+{
+ int accept = CPP_OPTION (pfile, trigraphs);
+
+ /* Don't warn about trigraphs in comments. */
+ if (CPP_OPTION (pfile, warn_trigraphs) && !pfile->state.lexing_comment)
+ {
+ cpp_buffer *buffer = pfile->buffer;
+ if (accept)
+ cpp_warning_with_line (pfile, buffer->lineno, CPP_BUF_COL (buffer) - 2,
+ "trigraph ??%c converted to %c",
+ (int) from_char,
+ (int) _cpp_trigraph_map[from_char]);
+ else if (buffer->cur != buffer->last_Wtrigraphs)
+ {
+ buffer->last_Wtrigraphs = buffer->cur;
+ cpp_warning_with_line (pfile, buffer->lineno,
+ CPP_BUF_COL (buffer) - 2,
+ "trigraph ??%c ignored", (int) from_char);
+ }
+ }
+
+ return accept;
+}
+
+/* Assumes local variables buffer and result. */
+#define ACCEPT_CHAR(t) \
+ do { result->type = t; buffer->read_ahead = EOF; } while (0)
+
+/* When we move to multibyte character sets, add to these something
+ that saves and restores the state of the multibyte conversion
+ library. This probably involves saving and restoring a "cookie".
+ In the case of glibc it is an 8-byte structure, so is not a high
+ overhead operation. In any case, it's out of the fast path. */
+#define SAVE_STATE() do { saved_cur = buffer->cur; } while (0)
+#define RESTORE_STATE() do { buffer->cur = saved_cur; } while (0)
+
+/* Skips any escaped newlines introduced by NEXT, which is either a
+ '?' or a '\\'. Returns the next character, which will also have
+ been placed in buffer->read_ahead. This routine performs
+ preprocessing stages 1 and 2 of the ISO C standard. */
+static cppchar_t
+skip_escaped_newlines (buffer, next)
+ cpp_buffer *buffer;
+ cppchar_t next;
+{
+ /* Only do this if we apply stages 1 and 2. */
+ if (!buffer->from_stage3)
+ {
+ cppchar_t next1;
+ const unsigned char *saved_cur;
+ int space;
+
+ do
+ {
+ if (buffer->cur == buffer->rlimit)
+ break;
+
+ SAVE_STATE ();
+ if (next == '?')
+ {
+ next1 = *buffer->cur++;
+ if (next1 != '?' || buffer->cur == buffer->rlimit)
+ {
+ RESTORE_STATE ();
+ break;
+ }
+
+ next1 = *buffer->cur++;
+ if (!_cpp_trigraph_map[next1]
+ || !trigraph_ok (buffer->pfile, next1))
+ {
+ RESTORE_STATE ();
+ break;
+ }
+
+ /* We have a full trigraph here. */
+ next = _cpp_trigraph_map[next1];
+ if (next != '\\' || buffer->cur == buffer->rlimit)
+ break;
+ SAVE_STATE ();
+ }
+
+ /* We have a backslash, and room for at least one more character. */
+ space = 0;
+ do
+ {
+ next1 = *buffer->cur++;
+ if (!is_nvspace (next1))
+ break;
+ space = 1;
+ }
+ while (buffer->cur < buffer->rlimit);
+
+ if (!is_vspace (next1))
+ {
+ RESTORE_STATE ();
+ break;
+ }
+
+ if (space && !buffer->pfile->state.lexing_comment)
+ cpp_warning (buffer->pfile,
+ "backslash and newline separated by space");
+
+ next = handle_newline (buffer, next1);
+ if (next == EOF)
+ cpp_pedwarn (buffer->pfile, "backslash-newline at end of file");
+ }
+ while (next == '\\' || next == '?');
+ }
+
+ buffer->read_ahead = next;
+ return next;
+}
+
+/* Obtain the next character, after trigraph conversion and skipping
+ an arbitrary string of escaped newlines. The common case of no
+ trigraphs or escaped newlines falls through quickly. */
+static cppchar_t
+get_effective_char (buffer)
+ cpp_buffer *buffer;
+{
+ cppchar_t next = EOF;
+
+ if (buffer->cur < buffer->rlimit)
+ {
+ next = *buffer->cur++;
+
+ /* '?' can introduce trigraphs (and therefore backslash); '\\'
+ can introduce escaped newlines, which we want to skip, or
+ UCNs, which, depending upon lexer state, we will handle in
+ the future. */
+ if (next == '?' || next == '\\')
+ next = skip_escaped_newlines (buffer, next);
+ }
+
+ buffer->read_ahead = next;
+ return next;
+}
+
+/* Skip a C-style block comment. We find the end of the comment by
+ seeing if an asterisk is before every '/' we encounter. Returns
+ non-zero if comment terminated by EOF, zero otherwise. */
+static int
+skip_block_comment (pfile)
+ cpp_reader *pfile;
+{
+ cpp_buffer *buffer = pfile->buffer;
+ cppchar_t c = EOF, prevc = EOF;
+
+ pfile->state.lexing_comment = 1;
+ while (buffer->cur != buffer->rlimit)
+ {
+ prevc = c, c = *buffer->cur++;
+
+ next_char:
+ /* FIXME: For speed, create a new character class of characters
+ of interest inside block comments. */
+ if (c == '?' || c == '\\')
+ c = skip_escaped_newlines (buffer, c);
+
+ /* People like decorating comments with '*', so check for '/'
+ instead for efficiency. */
+ if (c == '/')
+ {
+ if (prevc == '*')
+ break;
+
+ /* Warn about potential nested comments, but not if the '/'
+ comes immediately before the true comment delimeter.
+ Don't bother to get it right across escaped newlines. */
+ if (CPP_OPTION (pfile, warn_comments)
+ && buffer->cur != buffer->rlimit)
+ {
+ prevc = c, c = *buffer->cur++;
+ if (c == '*' && buffer->cur != buffer->rlimit)
+ {
+ prevc = c, c = *buffer->cur++;
+ if (c != '/')
+ cpp_warning_with_line (pfile, CPP_BUF_LINE (buffer),
+ CPP_BUF_COL (buffer),
+ "\"/*\" within comment");
+ }
+ goto next_char;
+ }
+ }
+ else if (is_vspace (c))
+ {
+ prevc = c, c = handle_newline (buffer, c);
+ goto next_char;
+ }
+ else if (c == '\t')
+ adjust_column (pfile);
+ }
+
+ pfile->state.lexing_comment = 0;
+ buffer->read_ahead = EOF;
+ return c != '/' || prevc != '*';
+}
+
+/* Skip a C++ line comment. Handles escaped newlines. Returns
+ non-zero if a multiline comment. The following new line, if any,
+ is left in buffer->read_ahead. */
+static int
+skip_line_comment (pfile)
+ cpp_reader *pfile;
+{
+ cpp_buffer *buffer = pfile->buffer;
+ unsigned int orig_lineno = buffer->lineno;
+ cppchar_t c;
+
+ pfile->state.lexing_comment = 1;
+ do
+ {
+ c = EOF;
+ if (buffer->cur == buffer->rlimit)
+ break;
+
+ c = *buffer->cur++;
+ if (c == '?' || c == '\\')
+ c = skip_escaped_newlines (buffer, c);
+ }
+ while (!is_vspace (c));
+
+ pfile->state.lexing_comment = 0;
+ buffer->read_ahead = c; /* Leave any newline for caller. */
+ return orig_lineno != buffer->lineno;
+}
+
+/* pfile->buffer->cur is one beyond the \t character. Update
+ col_adjust so we track the column correctly. */
+static void
+adjust_column (pfile)
+ cpp_reader *pfile;
+{
+ cpp_buffer *buffer = pfile->buffer;
+ unsigned int col = CPP_BUF_COL (buffer) - 1; /* Zero-based column. */
+
+ /* Round it up to multiple of the tabstop, but subtract 1 since the
+ tab itself occupies a character position. */
+ buffer->col_adjust += (CPP_OPTION (pfile, tabstop)
+ - col % CPP_OPTION (pfile, tabstop)) - 1;
+}
+
+/* Skips whitespace, saving the next non-whitespace character.
+ Adjusts pfile->col_adjust to account for tabs. Without this,
+ tokens might be assigned an incorrect column. */
+static void
+skip_whitespace (pfile, c)
+ cpp_reader *pfile;
+ cppchar_t c;
+{
+ cpp_buffer *buffer = pfile->buffer;
+ unsigned int warned = 0;
+
+ do
+ {
+ /* Horizontal space always OK. */
+ if (c == ' ')
+ ;
+ else if (c == '\t')
+ adjust_column (pfile);
+ /* Just \f \v or \0 left. */
+ else if (c == '\0')
+ {
+ if (!warned)
+ {
+ cpp_warning (pfile, "null character(s) ignored");
+ warned = 1;
+ }
+ }
+ else if (pfile->state.in_directive && CPP_PEDANTIC (pfile))
+ cpp_pedwarn_with_line (pfile, CPP_BUF_LINE (buffer),
+ CPP_BUF_COL (buffer),
+ "%s in preprocessing directive",
+ c == '\f' ? "form feed" : "vertical tab");
+
+ c = EOF;
+ if (buffer->cur == buffer->rlimit)
+ break;
+ c = *buffer->cur++;
+ }
+ /* We only want non-vertical space, i.e. ' ' \t \f \v \0. */
+ while (is_nvspace (c));
+
+ /* Remember the next character. */
+ buffer->read_ahead = c;
+}
+
+/* See if the characters of a number token are valid in a name (no
+ '.', '+' or '-'). */
+static int
+name_p (pfile, string)
+ cpp_reader *pfile;
+ const cpp_string *string;
+{
+ unsigned int i;
+
+ for (i = 0; i < string->len; i++)
+ if (!is_idchar (string->text[i]))
+ return 0;
+
+ return 1;
+}
+
+/* Parse an identifier, skipping embedded backslash-newlines.
+ Calculate the hash value of the token while parsing, for improved
+ performance. The hashing algorithm *must* match cpp_lookup(). */
+
+static cpp_hashnode *
+parse_identifier (pfile, c)
+ cpp_reader *pfile;
+ cppchar_t c;
+{
+ cpp_hashnode *result;
+ cpp_buffer *buffer = pfile->buffer;
+ unsigned int saw_dollar = 0, len;
+ struct obstack *stack = &pfile->hash_table->stack;
+
+ do
+ {
+ do
+ {
+ obstack_1grow (stack, c);
+
+ if (c == '$')
+ saw_dollar++;
+
+ c = EOF;
+ if (buffer->cur == buffer->rlimit)
+ break;
+
+ c = *buffer->cur++;
+ }
+ while (is_idchar (c));
+
+ /* Potential escaped newline? */
+ if (c != '?' && c != '\\')
+ break;
+ c = skip_escaped_newlines (buffer, c);
+ }
+ while (is_idchar (c));
+
+ /* Remember the next character. */
+ buffer->read_ahead = c;
+
+ /* $ is not a identifier character in the standard, but is commonly
+ accepted as an extension. Don't warn about it in skipped
+ conditional blocks. */
+ if (saw_dollar && CPP_PEDANTIC (pfile) && ! pfile->skipping)
+ cpp_pedwarn (pfile, "'$' character(s) in identifier");
+
+ /* Identifiers are null-terminated. */
+ len = obstack_object_size (stack);
+ obstack_1grow (stack, '\0');
+
+ /* This routine commits the memory if necessary. */
+ result = (cpp_hashnode *)
+ ht_lookup (pfile->hash_table, obstack_finish (stack), len, HT_ALLOCED);
+
+ /* Some identifiers require diagnostics when lexed. */
+ if (result->flags & NODE_DIAGNOSTIC && !pfile->skipping)
+ {
+ /* It is allowed to poison the same identifier twice. */
+ if ((result->flags & NODE_POISONED) && !pfile->state.poisoned_ok)
+ cpp_error (pfile, "attempt to use poisoned \"%s\"",
+ NODE_NAME (result));
+
+ /* Constraint 6.10.3.5: __VA_ARGS__ should only appear in the
+ replacement list of a variadic macro. */
+ if (result == pfile->spec_nodes.n__VA_ARGS__
+ && !pfile->state.va_args_ok)
+ cpp_pedwarn (pfile, "__VA_ARGS__ can only appear in the expansion of a C99 variadic macro");
+ }
+
+ return result;
+}
+
+/* Parse a number, skipping embedded backslash-newlines. */
+static void
+parse_number (pfile, number, c, leading_period)
+ cpp_reader *pfile;
+ cpp_string *number;
+ cppchar_t c;
+ int leading_period;
+{
+ cpp_buffer *buffer = pfile->buffer;
+ cpp_pool *pool = &pfile->ident_pool;
+ unsigned char *dest, *limit;
+
+ dest = POOL_FRONT (pool);
+ limit = POOL_LIMIT (pool);
+
+ /* Place a leading period. */
+ if (leading_period)
+ {
+ if (dest >= limit)
+ limit = _cpp_next_chunk (pool, 0, &dest);
+ *dest++ = '.';
+ }
+
+ do
+ {
+ do
+ {
+ /* Need room for terminating null. */
+ if (dest + 1 >= limit)
+ limit = _cpp_next_chunk (pool, 0, &dest);
+ *dest++ = c;
+
+ c = EOF;
+ if (buffer->cur == buffer->rlimit)
+ break;
+
+ c = *buffer->cur++;
+ }
+ while (is_numchar (c) || c == '.' || VALID_SIGN (c, dest[-1]));
+
+ /* Potential escaped newline? */
+ if (c != '?' && c != '\\')
+ break;
+ c = skip_escaped_newlines (buffer, c);
+ }
+ while (is_numchar (c) || c == '.' || VALID_SIGN (c, dest[-1]));
+
+ /* Remember the next character. */
+ buffer->read_ahead = c;
+
+ /* Null-terminate the number. */
+ *dest = '\0';
+
+ number->text = POOL_FRONT (pool);
+ number->len = dest - number->text;
+ POOL_COMMIT (pool, number->len + 1);
+}
+
+/* Subroutine of parse_string. Emits error for unterminated strings. */
+static void
+unterminated (pfile, term)
+ cpp_reader *pfile;
+ int term;
+{
+ cpp_error (pfile, "missing terminating %c character", term);
+
+ if (term == '\"' && pfile->mlstring_pos.line
+ && pfile->mlstring_pos.line != pfile->lexer_pos.line)
+ {
+ cpp_error_with_line (pfile, pfile->mlstring_pos.line,
+ pfile->mlstring_pos.col,
+ "possible start of unterminated string literal");
+ pfile->mlstring_pos.line = 0;
+ }
+}
+
+/* Subroutine of parse_string. */
+static int
+unescaped_terminator_p (pfile, dest)
+ cpp_reader *pfile;
+ const unsigned char *dest;
+{
+ const unsigned char *start, *temp;
+
+ /* In #include-style directives, terminators are not escapeable. */
+ if (pfile->state.angled_headers)
+ return 1;
+
+ start = POOL_FRONT (&pfile->ident_pool);
+
+ /* An odd number of consecutive backslashes represents an escaped
+ terminator. */
+ for (temp = dest; temp > start && temp[-1] == '\\'; temp--)
+ ;
+
+ return ((dest - temp) & 1) == 0;
+}
+
+/* Parses a string, character constant, or angle-bracketed header file
+ name. Handles embedded trigraphs and escaped newlines. The stored
+ string is guaranteed NUL-terminated, but it is not guaranteed that
+ this is the first NUL since embedded NULs are preserved.
+
+ Multi-line strings are allowed, but they are deprecated. */
+static void
+parse_string (pfile, token, terminator)
+ cpp_reader *pfile;
+ cpp_token *token;
+ cppchar_t terminator;
+{
+ cpp_buffer *buffer = pfile->buffer;
+ cpp_pool *pool = &pfile->ident_pool;
+ unsigned char *dest, *limit;
+ cppchar_t c;
+ unsigned int nulls = 0;
+
+ dest = POOL_FRONT (pool);
+ limit = POOL_LIMIT (pool);
+
+ for (;;)
+ {
+ if (buffer->cur == buffer->rlimit)
+ c = EOF;
+ else
+ c = *buffer->cur++;
+
+ have_char:
+ /* We need space for the terminating NUL. */
+ if (dest >= limit)
+ limit = _cpp_next_chunk (pool, 0, &dest);
+
+ if (c == EOF)
+ {
+ unterminated (pfile, terminator);
+ break;
+ }
+
+ /* Handle trigraphs, escaped newlines etc. */
+ if (c == '?' || c == '\\')
+ c = skip_escaped_newlines (buffer, c);
+
+ if (c == terminator && unescaped_terminator_p (pfile, dest))
+ {
+ c = EOF;
+ break;
+ }
+ else if (is_vspace (c))
+ {
+ /* In assembly language, silently terminate string and
+ character literals at end of line. This is a kludge
+ around not knowing where comments are. */
+ if (CPP_OPTION (pfile, lang) == CLK_ASM && terminator != '>')
+ break;
+
+ /* Character constants and header names may not extend over
+ multiple lines. In Standard C, neither may strings.
+ Unfortunately, we accept multiline strings as an
+ extension, except in #include family directives. */
+ if (terminator != '"' || pfile->state.angled_headers)
+ {
+ unterminated (pfile, terminator);
+ break;
+ }
+
+ cpp_pedwarn (pfile, "multi-line string literals are deprecated");
+ if (pfile->mlstring_pos.line == 0)
+ pfile->mlstring_pos = pfile->lexer_pos;
+
+ c = handle_newline (buffer, c);
+ *dest++ = '\n';
+ goto have_char;
+ }
+ else if (c == '\0')
+ {
+ if (nulls++ == 0)
+ cpp_warning (pfile, "null character(s) preserved in literal");
+ }
+
+ *dest++ = c;
+ }
+
+ /* Remember the next character. */
+ buffer->read_ahead = c;
+ *dest = '\0';
+
+ token->val.str.text = POOL_FRONT (pool);
+ token->val.str.len = dest - token->val.str.text;
+ POOL_COMMIT (pool, token->val.str.len + 1);
+}
+
+/* The stored comment includes the comment start and any terminator. */
+static void
+save_comment (pfile, token, from)
+ cpp_reader *pfile;
+ cpp_token *token;
+ const unsigned char *from;
+{
+ unsigned char *buffer;
+ unsigned int len;
+
+ len = pfile->buffer->cur - from + 1; /* + 1 for the initial '/'. */
+ /* C++ comments probably (not definitely) have moved past a new
+ line, which we don't want to save in the comment. */
+ if (pfile->buffer->read_ahead != EOF)
+ len--;
+ buffer = _cpp_pool_alloc (&pfile->ident_pool, len);
+
+ token->type = CPP_COMMENT;
+ token->val.str.len = len;
+ token->val.str.text = buffer;
+
+ buffer[0] = '/';
+ memcpy (buffer + 1, from, len - 1);
+}
+
+/* Subroutine of lex_token to handle '%'. A little tricky, since we
+ want to avoid stepping back when lexing %:%X. */
+static void
+lex_percent (buffer, result)
+ cpp_buffer *buffer;
+ cpp_token *result;
+{
+ cppchar_t c;
+
+ result->type = CPP_MOD;
+ /* Parsing %:%X could leave an extra character. */
+ if (buffer->extra_char == EOF)
+ c = get_effective_char (buffer);
+ else
+ {
+ c = buffer->read_ahead = buffer->extra_char;
+ buffer->extra_char = EOF;
+ }
+
+ if (c == '=')
+ ACCEPT_CHAR (CPP_MOD_EQ);
+ else if (CPP_OPTION (buffer->pfile, digraphs))
+ {
+ if (c == ':')
+ {
+ result->flags |= DIGRAPH;
+ ACCEPT_CHAR (CPP_HASH);
+ if (get_effective_char (buffer) == '%')
+ {
+ buffer->extra_char = get_effective_char (buffer);
+ if (buffer->extra_char == ':')
+ {
+ buffer->extra_char = EOF;
+ ACCEPT_CHAR (CPP_PASTE);
+ }
+ else
+ /* We'll catch the extra_char when we're called back. */
+ buffer->read_ahead = '%';
+ }
+ }
+ else if (c == '>')
+ {
+ result->flags |= DIGRAPH;
+ ACCEPT_CHAR (CPP_CLOSE_BRACE);
+ }
+ }
+}
+
+/* Subroutine of lex_token to handle '.'. This is tricky, since we
+ want to avoid stepping back when lexing '...' or '.123'. In the
+ latter case we should also set a flag for parse_number. */
+static void
+lex_dot (pfile, result)
+ cpp_reader *pfile;
+ cpp_token *result;
+{
+ cpp_buffer *buffer = pfile->buffer;
+ cppchar_t c;
+
+ /* Parsing ..X could leave an extra character. */
+ if (buffer->extra_char == EOF)
+ c = get_effective_char (buffer);
+ else
+ {
+ c = buffer->read_ahead = buffer->extra_char;
+ buffer->extra_char = EOF;
+ }
+
+ /* All known character sets have 0...9 contiguous. */
+ if (c >= '0' && c <= '9')
+ {
+ result->type = CPP_NUMBER;
+ parse_number (pfile, &result->val.str, c, 1);
+ }
+ else
+ {
+ result->type = CPP_DOT;
+ if (c == '.')
+ {
+ buffer->extra_char = get_effective_char (buffer);
+ if (buffer->extra_char == '.')
+ {
+ buffer->extra_char = EOF;
+ ACCEPT_CHAR (CPP_ELLIPSIS);
+ }
+ else
+ /* We'll catch the extra_char when we're called back. */
+ buffer->read_ahead = '.';
+ }
+ else if (c == '*' && CPP_OPTION (pfile, cplusplus))
+ ACCEPT_CHAR (CPP_DOT_STAR);
+ }
+}
+
+void
+_cpp_lex_token (pfile, result)
+ cpp_reader *pfile;
+ cpp_token *result;
+{
+ cppchar_t c;
+ cpp_buffer *buffer;
+ const unsigned char *comment_start;
+ unsigned char bol;
+
+ skip:
+ bol = pfile->state.next_bol;
+ done_directive:
+ buffer = pfile->buffer;
+ pfile->state.next_bol = 0;
+ result->flags = buffer->saved_flags;
+ buffer->saved_flags = 0;
+ next_char:
+ pfile->lexer_pos.line = buffer->lineno;
+ next_char2:
+ pfile->lexer_pos.col = CPP_BUF_COLUMN (buffer, buffer->cur);
+
+ c = buffer->read_ahead;
+ if (c == EOF && buffer->cur < buffer->rlimit)
+ {
+ c = *buffer->cur++;
+ pfile->lexer_pos.col++;
+ }
+
+ do_switch:
+ buffer->read_ahead = EOF;
+ switch (c)
+ {
+ case EOF:
+ /* Non-empty files should end in a newline. Checking "bol" too
+ prevents multiple warnings when hitting the EOF more than
+ once, like in a directive. Don't warn for command line and
+ _Pragma buffers. */
+ if (pfile->lexer_pos.col != 0 && !bol && !buffer->from_stage3)
+ cpp_pedwarn (pfile, "no newline at end of file");
+ pfile->state.next_bol = 1;
+ pfile->skipping = 0; /* In case missing #endif. */
+ result->type = CPP_EOF;
+ /* Don't do MI optimisation. */
+ return;
+
+ case ' ': case '\t': case '\f': case '\v': case '\0':
+ skip_whitespace (pfile, c);
+ result->flags |= PREV_WHITE;
+ goto next_char2;
+
+ case '\n': case '\r':
+ if (!pfile->state.in_directive)
+ {
+ handle_newline (buffer, c);
+ bol = 1;
+ pfile->lexer_pos.output_line = buffer->lineno;
+ /* This is a new line, so clear any white space flag.
+ Newlines in arguments are white space (6.10.3.10);
+ parse_arg takes care of that. */
+ result->flags &= ~(PREV_WHITE | AVOID_LPASTE);
+ goto next_char;
+ }
+
+ /* Don't let directives spill over to the next line. */
+ buffer->read_ahead = c;
+ pfile->state.next_bol = 1;
+ result->type = CPP_EOF;
+ /* Don't break; pfile->skipping might be true. */
+ return;
+
+ case '?':
+ case '\\':
+ /* These could start an escaped newline, or '?' a trigraph. Let
+ skip_escaped_newlines do all the work. */
+ {
+ unsigned int lineno = buffer->lineno;
+
+ c = skip_escaped_newlines (buffer, c);
+ if (lineno != buffer->lineno)
+ /* We had at least one escaped newline of some sort, and the
+ next character is in buffer->read_ahead. Update the
+ token's line and column. */
+ goto next_char;
+
+ /* We are either the original '?' or '\\', or a trigraph. */
+ result->type = CPP_QUERY;
+ buffer->read_ahead = EOF;
+ if (c == '\\')
+ goto random_char;
+ else if (c != '?')
+ goto do_switch;
+ }
+ break;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ result->type = CPP_NUMBER;
+ parse_number (pfile, &result->val.str, c, 0);
+ break;
+
+ case '$':
+ if (!CPP_OPTION (pfile, dollars_in_ident))
+ goto random_char;
+ /* Fall through... */
+
+ case '_':
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
+ case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
+ case 's': case 't': case 'u': case 'v': case 'w': case 'x':
+ case 'y': case 'z':
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
+ case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
+ case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
+ case 'Y': case 'Z':
+ result->type = CPP_NAME;
+ result->val.node = parse_identifier (pfile, c);
+
+ /* 'L' may introduce wide characters or strings. */
+ if (result->val.node == pfile->spec_nodes.n_L)
+ {
+ c = buffer->read_ahead; /* For make_string. */
+ if (c == '\'' || c == '"')
+ {
+ ACCEPT_CHAR (c == '"' ? CPP_WSTRING: CPP_WCHAR);
+ goto make_string;
+ }
+ }
+ /* Convert named operators to their proper types. */
+ else if (result->val.node->flags & NODE_OPERATOR)
+ {
+ result->flags |= NAMED_OP;
+ result->type = result->val.node->value.operator;
+ }
+ break;
+
+ case '\'':
+ case '"':
+ result->type = c == '"' ? CPP_STRING: CPP_CHAR;
+ make_string:
+ parse_string (pfile, result, c);
+ break;
+
+ case '/':
+ /* A potential block or line comment. */
+ comment_start = buffer->cur;
+ result->type = CPP_DIV;
+ c = get_effective_char (buffer);
+ if (c == '=')
+ ACCEPT_CHAR (CPP_DIV_EQ);
+ if (c != '/' && c != '*')
+ break;
+
+ if (c == '*')
+ {
+ if (skip_block_comment (pfile))
+ cpp_error_with_line (pfile, pfile->lexer_pos.line,
+ pfile->lexer_pos.col,
+ "unterminated comment");
+ }
+ else
+ {
+ if (!CPP_OPTION (pfile, cplusplus_comments)
+ && !CPP_IN_SYSTEM_HEADER (pfile))
+ break;
+
+ /* Warn about comments only if pedantically GNUC89, and not
+ in system headers. */
+ if (CPP_OPTION (pfile, lang) == CLK_GNUC89 && CPP_PEDANTIC (pfile)
+ && ! buffer->warned_cplusplus_comments)
+ {
+ cpp_pedwarn (pfile,
+ "C++ style comments are not allowed in ISO C89");
+ cpp_pedwarn (pfile,
+ "(this will be reported only once per input file)");
+ buffer->warned_cplusplus_comments = 1;
+ }
+
+ /* Skip_line_comment updates buffer->read_ahead. */
+ if (skip_line_comment (pfile) && CPP_OPTION (pfile, warn_comments))
+ cpp_warning_with_line (pfile, pfile->lexer_pos.line,
+ pfile->lexer_pos.col,
+ "multi-line comment");
+ }
+
+ /* Skipping the comment has updated buffer->read_ahead. */
+ if (!pfile->state.save_comments)
+ {
+ result->flags |= PREV_WHITE;
+ goto next_char;
+ }
+
+ /* Save the comment as a token in its own right. */
+ save_comment (pfile, result, comment_start);
+ /* Don't do MI optimisation. */
+ return;
+
+ case '<':
+ if (pfile->state.angled_headers)
+ {
+ result->type = CPP_HEADER_NAME;
+ c = '>'; /* terminator. */
+ goto make_string;
+ }
+
+ result->type = CPP_LESS;
+ c = get_effective_char (buffer);
+ if (c == '=')
+ ACCEPT_CHAR (CPP_LESS_EQ);
+ else if (c == '<')
+ {
+ ACCEPT_CHAR (CPP_LSHIFT);
+ if (get_effective_char (buffer) == '=')
+ ACCEPT_CHAR (CPP_LSHIFT_EQ);
+ }
+ else if (c == '?' && CPP_OPTION (pfile, cplusplus))
+ {
+ ACCEPT_CHAR (CPP_MIN);
+ if (get_effective_char (buffer) == '=')
+ ACCEPT_CHAR (CPP_MIN_EQ);
+ }
+ else if (c == ':' && CPP_OPTION (pfile, digraphs))
+ {
+ ACCEPT_CHAR (CPP_OPEN_SQUARE);
+ result->flags |= DIGRAPH;
+ }
+ else if (c == '%' && CPP_OPTION (pfile, digraphs))
+ {
+ ACCEPT_CHAR (CPP_OPEN_BRACE);
+ result->flags |= DIGRAPH;
+ }
+ break;
+
+ case '>':
+ result->type = CPP_GREATER;
+ c = get_effective_char (buffer);
+ if (c == '=')
+ ACCEPT_CHAR (CPP_GREATER_EQ);
+ else if (c == '>')
+ {
+ ACCEPT_CHAR (CPP_RSHIFT);
+ if (get_effective_char (buffer) == '=')
+ ACCEPT_CHAR (CPP_RSHIFT_EQ);
+ }
+ else if (c == '?' && CPP_OPTION (pfile, cplusplus))
+ {
+ ACCEPT_CHAR (CPP_MAX);
+ if (get_effective_char (buffer) == '=')
+ ACCEPT_CHAR (CPP_MAX_EQ);
+ }
+ break;
+
+ case '%':
+ lex_percent (buffer, result);
+ if (result->type == CPP_HASH)
+ goto do_hash;
+ break;
+
+ case '.':
+ lex_dot (pfile, result);
+ break;
+
+ case '+':
+ result->type = CPP_PLUS;
+ c = get_effective_char (buffer);
+ if (c == '=')
+ ACCEPT_CHAR (CPP_PLUS_EQ);
+ else if (c == '+')
+ ACCEPT_CHAR (CPP_PLUS_PLUS);
+ break;
+
+ case '-':
+ result->type = CPP_MINUS;
+ c = get_effective_char (buffer);
+ if (c == '>')
+ {
+ ACCEPT_CHAR (CPP_DEREF);
+ if (CPP_OPTION (pfile, cplusplus)
+ && get_effective_char (buffer) == '*')
+ ACCEPT_CHAR (CPP_DEREF_STAR);
+ }
+ else if (c == '=')
+ ACCEPT_CHAR (CPP_MINUS_EQ);
+ else if (c == '-')
+ ACCEPT_CHAR (CPP_MINUS_MINUS);
+ break;
+
+ case '*':
+ result->type = CPP_MULT;
+ if (get_effective_char (buffer) == '=')
+ ACCEPT_CHAR (CPP_MULT_EQ);
+ break;
+
+ case '=':
+ result->type = CPP_EQ;
+ if (get_effective_char (buffer) == '=')
+ ACCEPT_CHAR (CPP_EQ_EQ);
+ break;
+
+ case '!':
+ result->type = CPP_NOT;
+ if (get_effective_char (buffer) == '=')
+ ACCEPT_CHAR (CPP_NOT_EQ);
+ break;
+
+ case '&':
+ result->type = CPP_AND;
+ c = get_effective_char (buffer);
+ if (c == '=')
+ ACCEPT_CHAR (CPP_AND_EQ);
+ else if (c == '&')
+ ACCEPT_CHAR (CPP_AND_AND);
+ break;
+
+ case '#':
+ c = buffer->extra_char; /* Can be set by error condition below. */
+ if (c != EOF)
+ {
+ buffer->read_ahead = c;
+ buffer->extra_char = EOF;
+ }
+ else
+ c = get_effective_char (buffer);
+
+ if (c == '#')
+ {
+ ACCEPT_CHAR (CPP_PASTE);
+ break;
+ }
+
+ result->type = CPP_HASH;
+ do_hash:
+ if (!bol)
+ break;
+ /* 6.10.3 paragraph 11: If there are sequences of preprocessing
+ tokens within the list of arguments that would otherwise act
+ as preprocessing directives, the behavior is undefined.
+
+ This implementation will report a hard error, terminate the
+ macro invocation, and proceed to process the directive. */
+ if (pfile->state.parsing_args)
+ {
+ if (pfile->state.parsing_args == 2)
+ cpp_error (pfile,
+ "directives may not be used inside a macro argument");
+
+ /* Put a '#' in lookahead, return CPP_EOF for parse_arg. */
+ buffer->extra_char = buffer->read_ahead;
+ buffer->read_ahead = '#';
+ pfile->state.next_bol = 1;
+ result->type = CPP_EOF;
+
+ /* Get whitespace right - newline_in_args sets it. */
+ if (pfile->lexer_pos.col == 1)
+ result->flags &= ~(PREV_WHITE | AVOID_LPASTE);
+ }
+ else
+ {
+ /* This is the hash introducing a directive. */
+ if (_cpp_handle_directive (pfile, result->flags & PREV_WHITE))
+ goto done_directive; /* bol still 1. */
+ /* This is in fact an assembler #. */
+ }
+ break;
+
+ case '|':
+ result->type = CPP_OR;
+ c = get_effective_char (buffer);
+ if (c == '=')
+ ACCEPT_CHAR (CPP_OR_EQ);
+ else if (c == '|')
+ ACCEPT_CHAR (CPP_OR_OR);
+ break;
+
+ case '^':
+ result->type = CPP_XOR;
+ if (get_effective_char (buffer) == '=')
+ ACCEPT_CHAR (CPP_XOR_EQ);
+ break;
+
+ case ':':
+ result->type = CPP_COLON;
+ c = get_effective_char (buffer);
+ if (c == ':' && CPP_OPTION (pfile, cplusplus))
+ ACCEPT_CHAR (CPP_SCOPE);
+ else if (c == '>' && CPP_OPTION (pfile, digraphs))
+ {
+ result->flags |= DIGRAPH;
+ ACCEPT_CHAR (CPP_CLOSE_SQUARE);
+ }
+ break;
+
+ case '~': result->type = CPP_COMPL; break;
+ case ',': result->type = CPP_COMMA; break;
+ case '(': result->type = CPP_OPEN_PAREN; break;
+ case ')': result->type = CPP_CLOSE_PAREN; break;
+ case '[': result->type = CPP_OPEN_SQUARE; break;
+ case ']': result->type = CPP_CLOSE_SQUARE; break;
+ case '{': result->type = CPP_OPEN_BRACE; break;
+ case '}': result->type = CPP_CLOSE_BRACE; break;
+ case ';': result->type = CPP_SEMICOLON; break;
+
+ /* @ is a punctuator in Objective C. */
+ case '@': result->type = CPP_ATSIGN; break;
+
+ random_char:
+ default:
+ result->type = CPP_OTHER;
+ result->val.c = c;
+ break;
+ }
+
+ if (pfile->skipping)
+ goto skip;
+
+ /* If not in a directive, this token invalidates controlling macros. */
+ if (!pfile->state.in_directive)
+ pfile->mi_state = MI_FAILED;
+}
+
+/* An upper bound on the number of bytes needed to spell a token,
+ including preceding whitespace. */
+unsigned int
+cpp_token_len (token)
+ const cpp_token *token;
+{
+ unsigned int len;
+
+ switch (TOKEN_SPELL (token))
+ {
+ default: len = 0; break;
+ case SPELL_STRING: len = token->val.str.len; break;
+ case SPELL_IDENT: len = NODE_LEN (token->val.node); break;
+ }
+ /* 1 for whitespace, 4 for comment delimeters. */
+ return len + 5;
+}
+
+/* Write the spelling of a token TOKEN to BUFFER. The buffer must
+ already contain the enough space to hold the token's spelling.
+ Returns a pointer to the character after the last character
+ written. */
+unsigned char *
+cpp_spell_token (pfile, token, buffer)
+ cpp_reader *pfile; /* Would be nice to be rid of this... */
+ const cpp_token *token;
+ unsigned char *buffer;
+{
+ switch (TOKEN_SPELL (token))
+ {
+ case SPELL_OPERATOR:
+ {
+ const unsigned char *spelling;
+ unsigned char c;
+
+ if (token->flags & DIGRAPH)
+ spelling
+ = digraph_spellings[(int) token->type - (int) CPP_FIRST_DIGRAPH];
+ else if (token->flags & NAMED_OP)
+ goto spell_ident;
+ else
+ spelling = TOKEN_NAME (token);
+
+ while ((c = *spelling++) != '\0')
+ *buffer++ = c;
+ }
+ break;
+
+ case SPELL_IDENT:
+ spell_ident:
+ memcpy (buffer, NODE_NAME (token->val.node), NODE_LEN (token->val.node));
+ buffer += NODE_LEN (token->val.node);
+ break;
+
+ case SPELL_STRING:
+ {
+ int left, right, tag;
+ switch (token->type)
+ {
+ case CPP_STRING: left = '"'; right = '"'; tag = '\0'; break;
+ case CPP_WSTRING: left = '"'; right = '"'; tag = 'L'; break;
+ case CPP_CHAR: left = '\''; right = '\''; tag = '\0'; break;
+ case CPP_WCHAR: left = '\''; right = '\''; tag = 'L'; break;
+ case CPP_HEADER_NAME: left = '<'; right = '>'; tag = '\0'; break;
+ default: left = '\0'; right = '\0'; tag = '\0'; break;
+ }
+ if (tag) *buffer++ = tag;
+ if (left) *buffer++ = left;
+ memcpy (buffer, token->val.str.text, token->val.str.len);
+ buffer += token->val.str.len;
+ if (right) *buffer++ = right;
+ }
+ break;
+
+ case SPELL_CHAR:
+ *buffer++ = token->val.c;
+ break;
+
+ case SPELL_NONE:
+ cpp_ice (pfile, "Unspellable token %s", TOKEN_NAME (token));
+ break;
+ }
+
+ return buffer;
+}
+
+/* Returns a token as a null-terminated string. The string is
+ temporary, and automatically freed later. Useful for diagnostics. */
+unsigned char *
+cpp_token_as_text (pfile, token)
+ cpp_reader *pfile;
+ const cpp_token *token;
+{
+ unsigned int len = cpp_token_len (token);
+ unsigned char *start = _cpp_pool_alloc (&pfile->ident_pool, len), *end;
+
+ end = cpp_spell_token (pfile, token, start);
+ end[0] = '\0';
+
+ return start;
+}
+
+/* Used by C front ends. Should really move to using cpp_token_as_text. */
+const char *
+cpp_type2name (type)
+ enum cpp_ttype type;
+{
+ return (const char *) token_spellings[type].name;
+}
+
+/* Writes the spelling of token to FP. Separate from cpp_spell_token
+ for efficiency - to avoid double-buffering. Also, outputs a space
+ if PREV_WHITE is flagged. */
+void
+cpp_output_token (token, fp)
+ const cpp_token *token;
+ FILE *fp;
+{
+ if (token->flags & PREV_WHITE)
+ putc (' ', fp);
+
+ switch (TOKEN_SPELL (token))
+ {
+ case SPELL_OPERATOR:
+ {
+ const unsigned char *spelling;
+
+ if (token->flags & DIGRAPH)
+ spelling
+ = digraph_spellings[(int) token->type - (int) CPP_FIRST_DIGRAPH];
+ else if (token->flags & NAMED_OP)
+ goto spell_ident;
+ else
+ spelling = TOKEN_NAME (token);
+
+ ufputs (spelling, fp);
+ }
+ break;
+
+ spell_ident:
+ case SPELL_IDENT:
+ ufputs (NODE_NAME (token->val.node), fp);
+ break;
+
+ case SPELL_STRING:
+ {
+ int left, right, tag;
+ switch (token->type)
+ {
+ case CPP_STRING: left = '"'; right = '"'; tag = '\0'; break;
+ case CPP_WSTRING: left = '"'; right = '"'; tag = 'L'; break;
+ case CPP_CHAR: left = '\''; right = '\''; tag = '\0'; break;
+ case CPP_WCHAR: left = '\''; right = '\''; tag = 'L'; break;
+ case CPP_HEADER_NAME: left = '<'; right = '>'; tag = '\0'; break;
+ default: left = '\0'; right = '\0'; tag = '\0'; break;
+ }
+ if (tag) putc (tag, fp);
+ if (left) putc (left, fp);
+ fwrite (token->val.str.text, 1, token->val.str.len, fp);
+ if (right) putc (right, fp);
+ }
+ break;
+
+ case SPELL_CHAR:
+ putc (token->val.c, fp);
+ break;
+
+ case SPELL_NONE:
+ /* An error, most probably. */
+ break;
+ }
+}
+
+/* Compare two tokens. */
+int
+_cpp_equiv_tokens (a, b)
+ const cpp_token *a, *b;
+{
+ if (a->type == b->type && a->flags == b->flags)
+ switch (TOKEN_SPELL (a))
+ {
+ default: /* Keep compiler happy. */
+ case SPELL_OPERATOR:
+ return 1;
+ case SPELL_CHAR:
+ return a->val.c == b->val.c; /* Character. */
+ case SPELL_NONE:
+ return (a->type != CPP_MACRO_ARG || a->val.arg_no == b->val.arg_no);
+ case SPELL_IDENT:
+ return a->val.node == b->val.node;
+ case SPELL_STRING:
+ return (a->val.str.len == b->val.str.len
+ && !memcmp (a->val.str.text, b->val.str.text,
+ a->val.str.len));
+ }
+
+ return 0;
+}
+
+/* Determine whether two tokens can be pasted together, and if so,
+ what the resulting token is. Returns CPP_EOF if the tokens cannot
+ be pasted, or the appropriate type for the merged token if they
+ can. */
+enum cpp_ttype
+cpp_can_paste (pfile, token1, token2, digraph)
+ cpp_reader * pfile;
+ const cpp_token *token1, *token2;
+ int* digraph;
+{
+ enum cpp_ttype a = token1->type, b = token2->type;
+ int cxx = CPP_OPTION (pfile, cplusplus);
+
+ /* Treat named operators as if they were ordinary NAMEs. */
+ if (token1->flags & NAMED_OP)
+ a = CPP_NAME;
+ if (token2->flags & NAMED_OP)
+ b = CPP_NAME;
+
+ if ((int) a <= (int) CPP_LAST_EQ && b == CPP_EQ)
+ return (enum cpp_ttype) ((int) a + ((int) CPP_EQ_EQ - (int) CPP_EQ));
+
+ switch (a)
+ {
+ case CPP_GREATER:
+ if (b == a) return CPP_RSHIFT;
+ if (b == CPP_QUERY && cxx) return CPP_MAX;
+ if (b == CPP_GREATER_EQ) return CPP_RSHIFT_EQ;
+ break;
+ case CPP_LESS:
+ if (b == a) return CPP_LSHIFT;
+ if (b == CPP_QUERY && cxx) return CPP_MIN;
+ if (b == CPP_LESS_EQ) return CPP_LSHIFT_EQ;
+ if (CPP_OPTION (pfile, digraphs))
+ {
+ if (b == CPP_COLON)
+ {*digraph = 1; return CPP_OPEN_SQUARE;} /* <: digraph */
+ if (b == CPP_MOD)
+ {*digraph = 1; return CPP_OPEN_BRACE;} /* <% digraph */
+ }
+ break;
+
+ case CPP_PLUS: if (b == a) return CPP_PLUS_PLUS; break;
+ case CPP_AND: if (b == a) return CPP_AND_AND; break;
+ case CPP_OR: if (b == a) return CPP_OR_OR; break;
+
+ case CPP_MINUS:
+ if (b == a) return CPP_MINUS_MINUS;
+ if (b == CPP_GREATER) return CPP_DEREF;
+ break;
+ case CPP_COLON:
+ if (b == a && cxx) return CPP_SCOPE;
+ if (b == CPP_GREATER && CPP_OPTION (pfile, digraphs))
+ {*digraph = 1; return CPP_CLOSE_SQUARE;} /* :> digraph */
+ break;
+
+ case CPP_MOD:
+ if (CPP_OPTION (pfile, digraphs))
+ {
+ if (b == CPP_GREATER)
+ {*digraph = 1; return CPP_CLOSE_BRACE;} /* %> digraph */
+ if (b == CPP_COLON)
+ {*digraph = 1; return CPP_HASH;} /* %: digraph */
+ }
+ break;
+ case CPP_DEREF:
+ if (b == CPP_MULT && cxx) return CPP_DEREF_STAR;
+ break;
+ case CPP_DOT:
+ if (b == CPP_MULT && cxx) return CPP_DOT_STAR;
+ if (b == CPP_NUMBER) return CPP_NUMBER;
+ break;
+
+ case CPP_HASH:
+ if (b == a && (token1->flags & DIGRAPH) == (token2->flags & DIGRAPH))
+ /* %:%: digraph */
+ {*digraph = (token1->flags & DIGRAPH); return CPP_PASTE;}
+ break;
+
+ case CPP_NAME:
+ if (b == CPP_NAME) return CPP_NAME;
+ if (b == CPP_NUMBER
+ && name_p (pfile, &token2->val.str)) return CPP_NAME;
+ if (b == CPP_CHAR
+ && token1->val.node == pfile->spec_nodes.n_L) return CPP_WCHAR;
+ if (b == CPP_STRING
+ && token1->val.node == pfile->spec_nodes.n_L) return CPP_WSTRING;
+ break;
+
+ case CPP_NUMBER:
+ if (b == CPP_NUMBER) return CPP_NUMBER;
+ if (b == CPP_NAME) return CPP_NUMBER;
+ if (b == CPP_DOT) return CPP_NUMBER;
+ /* Numbers cannot have length zero, so this is safe. */
+ if ((b == CPP_PLUS || b == CPP_MINUS)
+ && VALID_SIGN ('+', token1->val.str.text[token1->val.str.len - 1]))
+ return CPP_NUMBER;
+ break;
+
+ default:
+ break;
+ }
+
+ return CPP_EOF;
+}
+
+/* Returns nonzero if a space should be inserted to avoid an
+ accidental token paste for output. For simplicity, it is
+ conservative, and occasionally advises a space where one is not
+ needed, e.g. "." and ".2". */
+
+int
+cpp_avoid_paste (pfile, token1, token2)
+ cpp_reader *pfile;
+ const cpp_token *token1, *token2;
+{
+ enum cpp_ttype a = token1->type, b = token2->type;
+ cppchar_t c;
+
+ if (token1->flags & NAMED_OP)
+ a = CPP_NAME;
+ if (token2->flags & NAMED_OP)
+ b = CPP_NAME;
+
+ c = EOF;
+ if (token2->flags & DIGRAPH)
+ c = digraph_spellings[(int) b - (int) CPP_FIRST_DIGRAPH][0];
+ else if (token_spellings[b].category == SPELL_OPERATOR)
+ c = token_spellings[b].name[0];
+
+ /* Quickly get everything that can paste with an '='. */
+ if ((int) a <= (int) CPP_LAST_EQ && c == '=')
+ return 1;
+
+ switch (a)
+ {
+ case CPP_GREATER: return c == '>' || c == '?';
+ case CPP_LESS: return c == '<' || c == '?' || c == '%' || c == ':';
+ case CPP_PLUS: return c == '+';
+ case CPP_MINUS: return c == '-' || c == '>';
+ case CPP_DIV: return c == '/' || c == '*'; /* Comments. */
+ case CPP_MOD: return c == ':' || c == '>';
+ case CPP_AND: return c == '&';
+ case CPP_OR: return c == '|';
+ case CPP_COLON: return c == ':' || c == '>';
+ case CPP_DEREF: return c == '*';
+ case CPP_DOT: return c == '.' || c == '%' || b == CPP_NUMBER;
+ case CPP_HASH: return c == '#' || c == '%'; /* Digraph form. */
+ case CPP_NAME: return ((b == CPP_NUMBER
+ && name_p (pfile, &token2->val.str))
+ || b == CPP_NAME
+ || b == CPP_CHAR || b == CPP_STRING); /* L */
+ case CPP_NUMBER: return (b == CPP_NUMBER || b == CPP_NAME
+ || c == '.' || c == '+' || c == '-');
+ case CPP_OTHER: return (CPP_OPTION (pfile, objc)
+ && token1->val.c == '@'
+ && (b == CPP_NAME || b == CPP_STRING));
+ default: break;
+ }
+
+ return 0;
+}
+
+/* Output all the remaining tokens on the current line, and a newline
+ character, to FP. Leading whitespace is removed. */
+void
+cpp_output_line (pfile, fp)
+ cpp_reader *pfile;
+ FILE *fp;
+{
+ cpp_token token;
+
+ cpp_get_token (pfile, &token);
+ token.flags &= ~PREV_WHITE;
+ while (token.type != CPP_EOF)
+ {
+ cpp_output_token (&token, fp);
+ cpp_get_token (pfile, &token);
+ }
+
+ putc ('\n', fp);
+}
+
+/* Returns the value of a hexadecimal digit. */
+static unsigned int
+hex_digit_value (c)
+ unsigned int c;
+{
+ if (c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ if (c >= 'A' && c <= 'F')
+ return c - 'A' + 10;
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ abort ();
+}
+
+/* Parse a '\uNNNN' or '\UNNNNNNNN' sequence. Returns 1 to indicate
+ failure if cpplib is not parsing C++ or C99. Such failure is
+ silent, and no variables are updated. Otherwise returns 0, and
+ warns if -Wtraditional.
+
+ [lex.charset]: The character designated by the universal character
+ name \UNNNNNNNN is that character whose character short name in
+ ISO/IEC 10646 is NNNNNNNN; the character designated by the
+ universal character name \uNNNN is that character whose character
+ short name in ISO/IEC 10646 is 0000NNNN. If the hexadecimal value
+ for a universal character name is less than 0x20 or in the range
+ 0x7F-0x9F (inclusive), or if the universal character name
+ designates a character in the basic source character set, then the
+ program is ill-formed.
+
+ We assume that wchar_t is Unicode, so we don't need to do any
+ mapping. Is this ever wrong?
+
+ PC points to the 'u' or 'U', PSTR is points to the byte after PC,
+ LIMIT is the end of the string or charconst. PSTR is updated to
+ point after the UCS on return, and the UCS is written into PC. */
+
+static int
+maybe_read_ucs (pfile, pstr, limit, pc)
+ cpp_reader *pfile;
+ const unsigned char **pstr;
+ const unsigned char *limit;
+ unsigned int *pc;
+{
+ const unsigned char *p = *pstr;
+ unsigned int code = 0;
+ unsigned int c = *pc, length;
+
+ /* Only attempt to interpret a UCS for C++ and C99. */
+ if (! (CPP_OPTION (pfile, cplusplus) || CPP_OPTION (pfile, c99)))
+ return 1;
+
+ if (CPP_WTRADITIONAL (pfile))
+ cpp_warning (pfile, "the meaning of '\\%c' varies with -traditional", c);
+
+ length = (c == 'u' ? 4: 8);
+
+ if ((size_t) (limit - p) < length)
+ {
+ cpp_error (pfile, "incomplete universal-character-name");
+ /* Skip to the end to avoid more diagnostics. */
+ p = limit;
+ }
+ else
+ {
+ for (; length; length--, p++)
+ {
+ c = *p;
+ if (ISXDIGIT (c))
+ code = (code << 4) + hex_digit_value (c);
+ else
+ {
+ cpp_error (pfile,
+ "non-hex digit '%c' in universal-character-name", c);
+ /* We shouldn't skip in case there are multibyte chars. */
+ break;
+ }
+ }
+ }
+
+#ifdef TARGET_EBCDIC
+ cpp_error (pfile, "universal-character-name on EBCDIC target");
+ code = 0x3f; /* EBCDIC invalid character */
+#else
+ /* True extended characters are OK. */
+ if (code >= 0xa0
+ && !(code & 0x80000000)
+ && !(code >= 0xD800 && code <= 0xDFFF))
+ ;
+ /* The standard permits $, @ and ` to be specified as UCNs. We use
+ hex escapes so that this also works with EBCDIC hosts. */
+ else if (code == 0x24 || code == 0x40 || code == 0x60)
+ ;
+ /* Don't give another error if one occurred above. */
+ else if (length == 0)
+ cpp_error (pfile, "universal-character-name out of range");
+#endif
+
+ *pstr = p;
+ *pc = code;
+ return 0;
+}
+
+/* Interpret an escape sequence, and return its value. PSTR points to
+ the input pointer, which is just after the backslash. LIMIT is how
+ much text we have. MASK is a bitmask for the precision for the
+ destination type (char or wchar_t). TRADITIONAL, if true, does not
+ interpret escapes that did not exist in traditional C.
+
+ Handles all relevant diagnostics. */
+
+unsigned int
+cpp_parse_escape (pfile, pstr, limit, mask, traditional)
+ cpp_reader *pfile;
+ const unsigned char **pstr;
+ const unsigned char *limit;
+ unsigned HOST_WIDE_INT mask;
+ int traditional;
+{
+ int unknown = 0;
+ const unsigned char *str = *pstr;
+ unsigned int c = *str++;
+
+ switch (c)
+ {
+ case '\\': case '\'': case '"': case '?': break;
+ case 'b': c = TARGET_BS; break;
+ case 'f': c = TARGET_FF; break;
+ case 'n': c = TARGET_NEWLINE; break;
+ case 'r': c = TARGET_CR; break;
+ case 't': c = TARGET_TAB; break;
+ case 'v': c = TARGET_VT; break;
+
+ case '(': case '{': case '[': case '%':
+ /* '\(', etc, are used at beginning of line to avoid confusing Emacs.
+ '\%' is used to prevent SCCS from getting confused. */
+ unknown = CPP_PEDANTIC (pfile);
+ break;
+
+ case 'a':
+ if (CPP_WTRADITIONAL (pfile))
+ cpp_warning (pfile, "the meaning of '\\a' varies with -traditional");
+ if (!traditional)
+ c = TARGET_BELL;
+ break;
+
+ case 'e': case 'E':
+ if (CPP_PEDANTIC (pfile))
+ cpp_pedwarn (pfile, "non-ISO-standard escape sequence, '\\%c'", c);
+ c = TARGET_ESC;
+ break;
+
+ case 'u': case 'U':
+ unknown = maybe_read_ucs (pfile, &str, limit, &c);
+ break;
+
+ case 'x':
+ if (CPP_WTRADITIONAL (pfile))
+ cpp_warning (pfile, "the meaning of '\\x' varies with -traditional");
+
+ if (!traditional)
+ {
+ unsigned int i = 0, overflow = 0;
+ int digits_found = 0;
+
+ while (str < limit)
+ {
+ c = *str;
+ if (! ISXDIGIT (c))
+ break;
+ str++;
+ overflow |= i ^ (i << 4 >> 4);
+ i = (i << 4) + hex_digit_value (c);
+ digits_found = 1;
+ }
+
+ if (!digits_found)
+ cpp_error (pfile, "\\x used with no following hex digits");
+
+ if (overflow | (i != (i & mask)))
+ {
+ cpp_pedwarn (pfile, "hex escape sequence out of range");
+ i &= mask;
+ }
+ c = i;
+ }
+ break;
+
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ {
+ unsigned int i = c - '0';
+ int count = 0;
+
+ while (str < limit && ++count < 3)
+ {
+ c = *str;
+ if (c < '0' || c > '7')
+ break;
+ str++;
+ i = (i << 3) + c - '0';
+ }
+
+ if (i != (i & mask))
+ {
+ cpp_pedwarn (pfile, "octal escape sequence out of range");
+ i &= mask;
+ }
+ c = i;
+ }
+ break;
+
+ default:
+ unknown = 1;
+ break;
+ }
+
+ if (unknown)
+ {
+ if (ISGRAPH (c))
+ cpp_pedwarn (pfile, "unknown escape sequence '\\%c'", c);
+ else
+ cpp_pedwarn (pfile, "unknown escape sequence: '\\%03o'", c);
+ }
+
+ if (c > mask)
+ cpp_pedwarn (pfile, "escape sequence out of range for character");
+
+ *pstr = str;
+ return c;
+}
+
+#ifndef MAX_CHAR_TYPE_SIZE
+#define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE
+#endif
+
+#ifndef MAX_WCHAR_TYPE_SIZE
+#define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
+#endif
+
+/* Interpret a (possibly wide) character constant in TOKEN.
+ WARN_MULTI warns about multi-character charconsts, if not
+ TRADITIONAL. TRADITIONAL also indicates not to interpret escapes
+ that did not exist in traditional C. PCHARS_SEEN points to a
+ variable that is filled in with the number of characters seen. */
+HOST_WIDE_INT
+cpp_interpret_charconst (pfile, token, warn_multi, traditional, pchars_seen)
+ cpp_reader *pfile;
+ const cpp_token *token;
+ int warn_multi;
+ int traditional;
+ unsigned int *pchars_seen;
+{
+ const unsigned char *str = token->val.str.text;
+ const unsigned char *limit = str + token->val.str.len;
+ unsigned int chars_seen = 0;
+ unsigned int width, max_chars, c;
+ unsigned HOST_WIDE_INT mask;
+ HOST_WIDE_INT result = 0;
+
+#ifdef MULTIBYTE_CHARS
+ (void) local_mbtowc (NULL, NULL, 0);
+#endif
+
+ /* Width in bits. */
+ if (token->type == CPP_CHAR)
+ width = MAX_CHAR_TYPE_SIZE;
+ else
+ width = MAX_WCHAR_TYPE_SIZE;
+
+ if (width < HOST_BITS_PER_WIDE_INT)
+ mask = ((unsigned HOST_WIDE_INT) 1 << width) - 1;
+ else
+ mask = ~0;
+ max_chars = HOST_BITS_PER_WIDE_INT / width;
+
+ while (str < limit)
+ {
+#ifdef MULTIBYTE_CHARS
+ wchar_t wc;
+ int char_len;
+
+ char_len = local_mbtowc (&wc, str, limit - str);
+ if (char_len == -1)
+ {
+ cpp_warning (pfile, "ignoring invalid multibyte character");
+ c = *str++;
+ }
+ else
+ {
+ str += char_len;
+ c = wc;
+ }
+#else
+ c = *str++;
+#endif
+
+ if (c == '\\')
+ c = cpp_parse_escape (pfile, &str, limit, mask, traditional);
+
+#ifdef MAP_CHARACTER
+ if (ISPRINT (c))
+ c = MAP_CHARACTER (c);
+#endif
+
+ /* Merge character into result; ignore excess chars. */
+ if (++chars_seen <= max_chars)
+ {
+ if (width < HOST_BITS_PER_WIDE_INT)
+ result = (result << width) | (c & mask);
+ else
+ result = c;
+ }
+ }
+
+ if (chars_seen == 0)
+ cpp_error (pfile, "empty character constant");
+ else if (chars_seen > max_chars)
+ {
+ chars_seen = max_chars;
+ cpp_warning (pfile, "character constant too long");
+ }
+ else if (chars_seen > 1 && !traditional && warn_multi)
+ cpp_warning (pfile, "multi-character character constant");
+
+ /* If char type is signed, sign-extend the constant. The
+ __CHAR_UNSIGNED__ macro is set by the driver if appropriate. */
+ if (token->type == CPP_CHAR && chars_seen)
+ {
+ unsigned int nbits = chars_seen * width;
+ unsigned int mask = (unsigned int) ~0 >> (HOST_BITS_PER_INT - nbits);
+
+ if (pfile->spec_nodes.n__CHAR_UNSIGNED__->type == NT_MACRO
+ || ((result >> (nbits - 1)) & 1) == 0)
+ result &= mask;
+ else
+ result |= ~mask;
+ }
+
+ *pchars_seen = chars_seen;
+ return result;
+}
+
+/* Memory pools. */
+
+struct dummy
+{
+ char c;
+ union
+ {
+ double d;
+ int *p;
+ } u;
+};
+
+#define DEFAULT_ALIGNMENT (offsetof (struct dummy, u))
+
+static int
+chunk_suitable (pool, chunk, size)
+ cpp_pool *pool;
+ cpp_chunk *chunk;
+ unsigned int size;
+{
+ /* Being at least twice SIZE means we can use memcpy in
+ _cpp_next_chunk rather than memmove. Besides, it's a good idea
+ anyway. */
+ return (chunk && pool->locked != chunk
+ && (unsigned int) (chunk->limit - chunk->base) >= size * 2);
+}
+
+/* Returns the end of the new pool. PTR points to a char in the old
+ pool, and is updated to point to the same char in the new pool. */
+unsigned char *
+_cpp_next_chunk (pool, len, ptr)
+ cpp_pool *pool;
+ unsigned int len;
+ unsigned char **ptr;
+{
+ cpp_chunk *chunk = pool->cur->next;
+
+ /* LEN is the minimum size we want in the new pool. */
+ len += POOL_ROOM (pool);
+ if (! chunk_suitable (pool, chunk, len))
+ {
+ chunk = new_chunk (POOL_SIZE (pool) * 2 + len);
+
+ chunk->next = pool->cur->next;
+ pool->cur->next = chunk;
+ }
+
+ /* Update the pointer before changing chunk's front. */
+ if (ptr)
+ *ptr += chunk->base - POOL_FRONT (pool);
+
+ memcpy (chunk->base, POOL_FRONT (pool), POOL_ROOM (pool));
+ chunk->front = chunk->base;
+
+ pool->cur = chunk;
+ return POOL_LIMIT (pool);
+}
+
+static cpp_chunk *
+new_chunk (size)
+ unsigned int size;
+{
+ unsigned char *base;
+ cpp_chunk *result;
+
+ size = POOL_ALIGN (size, DEFAULT_ALIGNMENT);
+ base = (unsigned char *) xmalloc (size + sizeof (cpp_chunk));
+ /* Put the chunk descriptor at the end. Then chunk overruns will
+ cause obvious chaos. */
+ result = (cpp_chunk *) (base + size);
+ result->base = base;
+ result->front = base;
+ result->limit = base + size;
+ result->next = 0;
+
+ return result;
+}
+
+void
+_cpp_init_pool (pool, size, align, temp)
+ cpp_pool *pool;
+ unsigned int size, align, temp;
+{
+ if (align == 0)
+ align = DEFAULT_ALIGNMENT;
+ if (align & (align - 1))
+ abort ();
+ pool->align = align;
+ pool->cur = new_chunk (size);
+ pool->locked = 0;
+ pool->locks = 0;
+ if (temp)
+ pool->cur->next = pool->cur;
+}
+
+void
+_cpp_lock_pool (pool)
+ cpp_pool *pool;
+{
+ if (pool->locks++ == 0)
+ pool->locked = pool->cur;
+}
+
+void
+_cpp_unlock_pool (pool)
+ cpp_pool *pool;
+{
+ if (--pool->locks == 0)
+ pool->locked = 0;
+}
+
+void
+_cpp_free_pool (pool)
+ cpp_pool *pool;
+{
+ cpp_chunk *chunk = pool->cur, *next;
+
+ do
+ {
+ next = chunk->next;
+ free (chunk->base);
+ chunk = next;
+ }
+ while (chunk && chunk != pool->cur);
+}
+
+/* Reserve LEN bytes from a memory pool. */
+unsigned char *
+_cpp_pool_reserve (pool, len)
+ cpp_pool *pool;
+ unsigned int len;
+{
+ len = POOL_ALIGN (len, pool->align);
+ if (len > (unsigned int) POOL_ROOM (pool))
+ _cpp_next_chunk (pool, len, 0);
+
+ return POOL_FRONT (pool);
+}
+
+/* Allocate LEN bytes from a memory pool. */
+unsigned char *
+_cpp_pool_alloc (pool, len)
+ cpp_pool *pool;
+ unsigned int len;
+{
+ unsigned char *result = _cpp_pool_reserve (pool, len);
+
+ POOL_COMMIT (pool, len);
+ return result;
+}
--- /dev/null
+/* CPP Library. (Directive handling.)
+ Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Per Bothner, 1994-95.
+ Based on CCCP program by Paul Rubin, June 1986
+ Adapted to ANSI C, Richard Stallman, Jan 1987
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+
+#include "cpplib.h"
+#include "cpphash.h"
+#include "intl.h"
+#include "obstack.h"
+
+/* Chained list of answers to an assertion. */
+struct answer
+{
+ struct answer *next;
+ unsigned int count;
+ cpp_token first[1];
+};
+
+/* Stack of conditionals currently in progress
+ (including both successful and failing conditionals). */
+
+struct if_stack
+{
+ struct if_stack *next;
+ cpp_lexer_pos pos; /* line and column where condition started */
+ const cpp_hashnode *mi_cmacro;/* macro name for #ifndef around entire file */
+ unsigned char was_skipping; /* Value of pfile->skipping before this if. */
+ int type; /* type of last directive seen in this group */
+};
+
+/* Values for the origin field of struct directive. KANDR directives
+ come from traditional (K&R) C. STDC89 directives come from the
+ 1989 C standard. EXTENSION directives are extensions. */
+#define KANDR 0
+#define STDC89 1
+#define EXTENSION 2
+
+/* Values for the flags field of struct directive. COND indicates a
+ conditional; IF_COND an opening conditional. INCL means to treat
+ "..." and <...> as q-char and h-char sequences respectively. IN_I
+ means this directive should be handled even if -fpreprocessed is in
+ effect (these are the directives with callback hooks). */
+#define COND (1 << 0)
+#define IF_COND (1 << 1)
+#define INCL (1 << 2)
+#define IN_I (1 << 3)
+
+/* Defines one #-directive, including how to handle it. */
+typedef void (*directive_handler) PARAMS ((cpp_reader *));
+typedef struct directive directive;
+struct directive
+{
+ directive_handler handler; /* Function to handle directive. */
+ const U_CHAR *name; /* Name of directive. */
+ unsigned short length; /* Length of name. */
+ unsigned char origin; /* Origin of directive. */
+ unsigned char flags; /* Flags describing this directive. */
+};
+
+/* Forward declarations. */
+
+static void skip_rest_of_line PARAMS ((cpp_reader *));
+static void check_eol PARAMS ((cpp_reader *));
+static void start_directive PARAMS ((cpp_reader *));
+static void end_directive PARAMS ((cpp_reader *, int));
+static void run_directive PARAMS ((cpp_reader *, int,
+ enum cpp_buffer_type,
+ const char *, size_t));
+static int glue_header_name PARAMS ((cpp_reader *, cpp_token *));
+static int parse_include PARAMS ((cpp_reader *, cpp_token *));
+static void push_conditional PARAMS ((cpp_reader *, int, int,
+ const cpp_hashnode *));
+static unsigned int read_flag PARAMS ((cpp_reader *, unsigned int));
+static int strtoul_for_line PARAMS ((const U_CHAR *, unsigned int,
+ unsigned long *));
+static void do_diagnostic PARAMS ((cpp_reader *, enum error_type, int));
+static cpp_hashnode *lex_macro_node PARAMS ((cpp_reader *));
+static void do_include_common PARAMS ((cpp_reader *, enum include_type));
+static void do_pragma_once PARAMS ((cpp_reader *));
+static void do_pragma_poison PARAMS ((cpp_reader *));
+static void do_pragma_system_header PARAMS ((cpp_reader *));
+static void do_pragma_dependency PARAMS ((cpp_reader *));
+static int get__Pragma_string PARAMS ((cpp_reader *, cpp_token *));
+static unsigned char *destringize PARAMS ((const cpp_string *,
+ unsigned int *));
+static int parse_answer PARAMS ((cpp_reader *, struct answer **, int));
+static cpp_hashnode *parse_assertion PARAMS ((cpp_reader *, struct answer **,
+ int));
+static struct answer ** find_answer PARAMS ((cpp_hashnode *,
+ const struct answer *));
+static void handle_assertion PARAMS ((cpp_reader *, const char *, int));
+
+/* This is the table of directive handlers. It is ordered by
+ frequency of occurrence; the numbers at the end are directive
+ counts from all the source code I have lying around (egcs and libc
+ CVS as of 1999-05-18, plus grub-0.5.91, linux-2.2.9, and
+ pcmcia-cs-3.0.9). This is no longer important as directive lookup
+ is now O(1). All extensions other than #warning and #include_next
+ are deprecated. The name is where the extension appears to have
+ come from. */
+
+#define DIRECTIVE_TABLE \
+D(define, T_DEFINE = 0, KANDR, IN_I) /* 270554 */ \
+D(include, T_INCLUDE, KANDR, INCL) /* 52262 */ \
+D(endif, T_ENDIF, KANDR, COND) /* 45855 */ \
+D(ifdef, T_IFDEF, KANDR, COND | IF_COND) /* 22000 */ \
+D(if, T_IF, KANDR, COND | IF_COND) /* 18162 */ \
+D(else, T_ELSE, KANDR, COND) /* 9863 */ \
+D(ifndef, T_IFNDEF, KANDR, COND | IF_COND) /* 9675 */ \
+D(undef, T_UNDEF, KANDR, IN_I) /* 4837 */ \
+D(line, T_LINE, KANDR, IN_I) /* 2465 */ \
+D(elif, T_ELIF, STDC89, COND) /* 610 */ \
+D(error, T_ERROR, STDC89, 0) /* 475 */ \
+D(pragma, T_PRAGMA, STDC89, IN_I) /* 195 */ \
+D(warning, T_WARNING, EXTENSION, 0) /* 22 */ \
+D(include_next, T_INCLUDE_NEXT, EXTENSION, INCL) /* 19 */ \
+D(ident, T_IDENT, EXTENSION, IN_I) /* 11 */ \
+D(import, T_IMPORT, EXTENSION, INCL) /* 0 ObjC */ \
+D(assert, T_ASSERT, EXTENSION, 0) /* 0 SVR4 */ \
+D(unassert, T_UNASSERT, EXTENSION, 0) /* 0 SVR4 */ \
+SCCS_ENTRY /* 0 SVR4? */
+
+/* #sccs is not always recognized. */
+#ifdef SCCS_DIRECTIVE
+# define SCCS_ENTRY D(sccs, T_SCCS, EXTENSION, 0)
+#else
+# define SCCS_ENTRY /* nothing */
+#endif
+
+/* Use the table to generate a series of prototypes, an enum for the
+ directive names, and an array of directive handlers. */
+
+/* The directive-processing functions are declared to return int
+ instead of void, because some old compilers have trouble with
+ pointers to functions returning void. */
+
+/* Don't invoke CONCAT2 with any whitespace or K&R cc will fail. */
+#define D(name, t, o, f) static void CONCAT2(do_,name) PARAMS ((cpp_reader *));
+DIRECTIVE_TABLE
+#undef D
+
+#define D(n, tag, o, f) tag,
+enum
+{
+ DIRECTIVE_TABLE
+ N_DIRECTIVES
+};
+#undef D
+
+/* Don't invoke CONCAT2 with any whitespace or K&R cc will fail. */
+#define D(name, t, origin, flags) \
+{ CONCAT2(do_,name), (const U_CHAR *) STRINGX(name), \
+ sizeof STRINGX(name) - 1, origin, flags },
+static const directive dtable[] =
+{
+DIRECTIVE_TABLE
+};
+#undef D
+#undef DIRECTIVE_TABLE
+
+/* Skip any remaining tokens in a directive. */
+static void
+skip_rest_of_line (pfile)
+ cpp_reader *pfile;
+{
+ cpp_token token;
+
+ /* Discard all input lookaheads. */
+ while (pfile->la_read)
+ _cpp_release_lookahead (pfile);
+
+ /* Discard all stacked contexts. */
+ while (pfile->context != &pfile->base_context)
+ _cpp_pop_context (pfile);
+
+ /* Sweep up all tokens remaining on the line. */
+ pfile->state.prevent_expansion++;
+ while (!pfile->state.next_bol)
+ _cpp_lex_token (pfile, &token);
+ pfile->state.prevent_expansion--;
+}
+
+/* Ensure there are no stray tokens at the end of a directive. */
+static void
+check_eol (pfile)
+ cpp_reader *pfile;
+{
+ if (!pfile->state.next_bol)
+ {
+ cpp_token token;
+
+ _cpp_lex_token (pfile, &token);
+ if (token.type != CPP_EOF)
+ cpp_pedwarn (pfile, "extra tokens at end of #%s directive",
+ pfile->directive->name);
+ }
+}
+
+/* Called when entering a directive, _Pragma or command-line directive. */
+static void
+start_directive (pfile)
+ cpp_reader *pfile;
+{
+ cpp_buffer *buffer = pfile->buffer;
+
+ /* Setup in-directive state. */
+ pfile->state.in_directive = 1;
+ pfile->state.save_comments = 0;
+
+ /* Some handlers need the position of the # for diagnostics. */
+ pfile->directive_pos = pfile->lexer_pos;
+
+ /* Don't save directive tokens for external clients. */
+ pfile->la_saved = pfile->la_write;
+ pfile->la_write = 0;
+
+ /* Turn off skipping. */
+ buffer->was_skipping = pfile->skipping;
+ pfile->skipping = 0;
+}
+
+/* Called when leaving a directive, _Pragma or command-line directive. */
+static void
+end_directive (pfile, skip_line)
+ cpp_reader *pfile;
+ int skip_line;
+{
+ cpp_buffer *buffer = pfile->buffer;
+
+ /* Restore pfile->skipping before skip_rest_of_line, so that e.g.
+ __VA_ARGS__ in the rest of the directive doesn't warn. */
+ pfile->skipping = buffer->was_skipping;
+
+ /* We don't skip for an assembler #. */
+ if (skip_line)
+ skip_rest_of_line (pfile);
+
+ /* Restore state. */
+ pfile->la_write = pfile->la_saved;
+ pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
+ pfile->state.in_directive = 0;
+ pfile->state.angled_headers = 0;
+ pfile->state.line_extension = 0;
+ pfile->directive = 0;
+}
+
+/* Check if a token's name matches that of a known directive. Put in
+ this file to save exporting dtable and other unneeded information. */
+int
+_cpp_handle_directive (pfile, indented)
+ cpp_reader *pfile;
+ int indented;
+{
+ cpp_buffer *buffer = pfile->buffer;
+ const directive *dir = 0;
+ cpp_token dname;
+ int skip = 1;
+
+ start_directive (pfile);
+
+ /* Lex the directive name directly. */
+ _cpp_lex_token (pfile, &dname);
+
+ if (dname.type == CPP_NAME)
+ {
+ unsigned int index = dname.val.node->directive_index;
+ if (index)
+ dir = &dtable[index - 1];
+ }
+ else if (dname.type == CPP_NUMBER)
+ {
+ /* # followed by a number is equivalent to #line. Do not
+ recognize this form in assembly language source files or
+ skipped conditional groups. Complain about this form if
+ we're being pedantic, but not if this is regurgitated input
+ (preprocessed or fed back in by the C++ frontend). */
+ if (! buffer->was_skipping && CPP_OPTION (pfile, lang) != CLK_ASM)
+ {
+ dir = &dtable[T_LINE];
+ pfile->state.line_extension = 1;
+ _cpp_push_token (pfile, &dname, &pfile->directive_pos);
+ if (CPP_PEDANTIC (pfile) && ! CPP_OPTION (pfile, preprocessed))
+ cpp_pedwarn (pfile, "# followed by integer");
+ }
+ }
+
+ pfile->directive = dir;
+ if (dir)
+ {
+ /* Make sure we lex headers correctly, whether skipping or not. */
+ pfile->state.angled_headers = dir->flags & INCL;
+
+ /* If we are rescanning preprocessed input, only directives tagged
+ with IN_I are honored, and the warnings below are suppressed. */
+ if (CPP_OPTION (pfile, preprocessed))
+ {
+ /* Kluge alert. In order to be sure that code like this
+ #define HASH #
+ HASH define foo bar
+ does not cause '#define foo bar' to get executed when
+ compiled with -save-temps, we recognize directives in
+ -fpreprocessed mode only if the # is in column 1 and the
+ directive name starts in column 2. This output can only
+ be generated by the directive callbacks in cppmain.c (see
+ also the special case in scan_buffer). */
+ if (dir->flags & IN_I && !indented && !(dname.flags & PREV_WHITE))
+ (*dir->handler) (pfile);
+ /* That check misses '# 123' linemarkers. Let them through too. */
+ else if (dname.type == CPP_NUMBER)
+ (*dir->handler) (pfile);
+ else
+ {
+ /* We don't want to process this directive. Put back the
+ tokens so caller will see them (and issue an error,
+ probably). */
+ _cpp_push_token (pfile, &dname, &pfile->directive_pos);
+ skip = 0;
+ }
+ }
+ else
+ {
+ /* Traditionally, a directive is ignored unless its # is in
+ column 1. Therefore in code intended to work with K+R
+ compilers, directives added by C89 must have their #
+ indented, and directives present in traditional C must
+ not. This is true even of directives in skipped
+ conditional blocks. */
+ if (CPP_WTRADITIONAL (pfile))
+ {
+ if (dir == &dtable[T_ELIF])
+ cpp_warning (pfile,
+ "suggest not using #elif in traditional C");
+ else if (indented && dir->origin == KANDR)
+ cpp_warning (pfile,
+ "traditional C ignores #%s with the # indented",
+ dir->name);
+ else if (!indented && dir->origin != KANDR)
+ cpp_warning (pfile,
+ "suggest hiding #%s from traditional C with an indented #",
+ dir->name);
+ }
+
+ /* If we are skipping a failed conditional group, all
+ non-conditional directives are ignored. */
+ if (! buffer->was_skipping || (dir->flags & COND))
+ {
+ /* Issue -pedantic warnings for extensions. */
+ if (CPP_PEDANTIC (pfile) && dir->origin == EXTENSION)
+ cpp_pedwarn (pfile, "#%s is a GCC extension", dir->name);
+
+ /* If we have a directive that is not an opening
+ conditional, invalidate any control macro. */
+ if (! (dir->flags & IF_COND))
+ pfile->mi_state = MI_FAILED;
+
+ (*dir->handler) (pfile);
+ }
+ }
+ }
+ else if (dname.type != CPP_EOF && ! buffer->was_skipping)
+ {
+ /* An unknown directive. Don't complain about it in assembly
+ source: we don't know where the comments are, and # may
+ introduce assembler pseudo-ops. Don't complain about invalid
+ directives in skipped conditional groups (6.10 p4). */
+ if (CPP_OPTION (pfile, lang) == CLK_ASM)
+ {
+ /* Output the # and lookahead token for the assembler. */
+ _cpp_push_token (pfile, &dname, &pfile->directive_pos);
+ skip = 0;
+ }
+ else
+ cpp_error (pfile, "invalid preprocessing directive #%s",
+ cpp_token_as_text (pfile, &dname));
+ }
+
+ end_directive (pfile, skip);
+ return skip;
+}
+
+/* Directive handler wrapper used by the command line option
+ processor. */
+static void
+run_directive (pfile, dir_no, type, buf, count)
+ cpp_reader *pfile;
+ int dir_no;
+ enum cpp_buffer_type type;
+ const char *buf;
+ size_t count;
+{
+ unsigned int output_line = pfile->lexer_pos.output_line;
+ cpp_buffer *buffer;
+
+ buffer = cpp_push_buffer (pfile, (const U_CHAR *) buf, count, type, 0);
+
+ if (dir_no == T_PRAGMA)
+ {
+ /* A kludge to avoid line markers for _Pragma. */
+ pfile->lexer_pos.output_line = output_line;
+ /* Avoid interpretation of directives in a _Pragma string. */
+ pfile->state.next_bol = 0;
+ }
+
+ start_directive (pfile);
+ pfile->state.prevent_expansion++;
+ pfile->directive = &dtable[dir_no];
+ (void) (*pfile->directive->handler) (pfile);
+ pfile->state.prevent_expansion--;
+ check_eol (pfile);
+ end_directive (pfile, 1);
+
+ cpp_pop_buffer (pfile);
+}
+
+/* Checks for validity the macro name in #define, #undef, #ifdef and
+ #ifndef directives. */
+static cpp_hashnode *
+lex_macro_node (pfile)
+ cpp_reader *pfile;
+{
+ cpp_token token;
+
+ /* Lex the macro name directly. */
+ _cpp_lex_token (pfile, &token);
+
+ /* The token immediately after #define must be an identifier. That
+ identifier is not allowed to be "defined". See predefined macro
+ names (6.10.8.4). In C++, it is not allowed to be any of the
+ <iso646.h> macro names (which are keywords in C++) either. */
+
+ if (token.type != CPP_NAME)
+ {
+ if (token.type == CPP_EOF)
+ cpp_error (pfile, "no macro name given in #%s directive",
+ pfile->directive->name);
+ else if (token.flags & NAMED_OP)
+ cpp_error (pfile,
+ "\"%s\" cannot be used as a macro name as it is an operator in C++",
+ NODE_NAME (token.val.node));
+ else
+ cpp_error (pfile, "macro names must be identifiers");
+ }
+ else
+ {
+ cpp_hashnode *node = token.val.node;
+
+ /* In Objective C, some keywords begin with '@', but general
+ identifiers do not, and you're not allowed to #define them. */
+ if (node == pfile->spec_nodes.n_defined || NODE_NAME (node)[0] == '@')
+ cpp_error (pfile, "\"%s\" cannot be used as a macro name",
+ NODE_NAME (node));
+ else if (!(node->flags & NODE_POISONED))
+ return node;
+ }
+
+ return 0;
+}
+
+/* Process a #define directive. Most work is done in cppmacro.c. */
+static void
+do_define (pfile)
+ cpp_reader *pfile;
+{
+ cpp_hashnode *node = lex_macro_node (pfile);
+
+ if (node)
+ {
+ if (_cpp_create_definition (pfile, node))
+ if (pfile->cb.define)
+ (*pfile->cb.define) (pfile, node);
+ }
+}
+
+/* Handle #undef. Marks the identifier NT_VOID in the hash table. */
+static void
+do_undef (pfile)
+ cpp_reader *pfile;
+{
+ cpp_hashnode *node = lex_macro_node (pfile);
+
+ /* 6.10.3.5 paragraph 2: [#undef] is ignored if the specified identifier
+ is not currently defined as a macro name. */
+ if (node && node->type == NT_MACRO)
+ {
+ if (pfile->cb.undef)
+ (*pfile->cb.undef) (pfile, node);
+
+ if (node->flags & NODE_WARN)
+ cpp_warning (pfile, "undefining \"%s\"", NODE_NAME (node));
+
+ _cpp_free_definition (node);
+ }
+ check_eol (pfile);
+}
+
+/* Helper routine used by parse_include. Reinterpret the current line
+ as an h-char-sequence (< ... >); we are looking at the first token
+ after the <. Returns zero on success. */
+static int
+glue_header_name (pfile, header)
+ cpp_reader *pfile;
+ cpp_token *header;
+{
+ cpp_token token;
+ unsigned char *buffer, *token_mem;
+ size_t len, total_len = 0, capacity = 1024;
+
+ /* To avoid lexed tokens overwriting our glued name, we can only
+ allocate from the string pool once we've lexed everything. */
+
+ buffer = (unsigned char *) xmalloc (capacity);
+ for (;;)
+ {
+ cpp_get_token (pfile, &token);
+
+ if (token.type == CPP_GREATER || token.type == CPP_EOF)
+ break;
+
+ len = cpp_token_len (&token);
+ if (total_len + len > capacity)
+ {
+ capacity = (capacity + len) * 2;
+ buffer = (unsigned char *) xrealloc (buffer, capacity);
+ }
+
+ if (token.flags & PREV_WHITE)
+ buffer[total_len++] = ' ';
+
+ total_len = cpp_spell_token (pfile, &token, &buffer[total_len]) - buffer;
+ }
+
+ if (token.type == CPP_EOF)
+ cpp_error (pfile, "missing terminating > character");
+ else
+ {
+ token_mem = _cpp_pool_alloc (&pfile->ident_pool, total_len + 1);
+ memcpy (token_mem, buffer, total_len);
+ token_mem[total_len] = '\0';
+
+ header->type = CPP_HEADER_NAME;
+ header->flags &= ~PREV_WHITE;
+ header->val.str.len = total_len;
+ header->val.str.text = token_mem;
+ }
+
+ free ((PTR) buffer);
+ return token.type == CPP_EOF;
+}
+
+/* Parse the header name of #include, #include_next, #import and
+ #pragma dependency. Returns zero on success. */
+static int
+parse_include (pfile, header)
+ cpp_reader *pfile;
+ cpp_token *header;
+{
+ int is_pragma = pfile->directive == &dtable[T_PRAGMA];
+ const unsigned char *dir;
+
+ if (is_pragma)
+ dir = U"pragma dependency";
+ else
+ dir = pfile->directive->name;
+
+ /* Allow macro expansion. */
+ cpp_get_token (pfile, header);
+ if (header->type != CPP_STRING && header->type != CPP_HEADER_NAME)
+ {
+ if (header->type != CPP_LESS)
+ {
+ cpp_error (pfile, "#%s expects \"FILENAME\" or <FILENAME>", dir);
+ return 1;
+ }
+ if (glue_header_name (pfile, header))
+ return 1;
+ }
+
+ if (header->val.str.len == 0)
+ {
+ cpp_error (pfile, "empty file name in #%s", dir);
+ return 1;
+ }
+
+ if (!is_pragma)
+ {
+ check_eol (pfile);
+ /* Get out of macro context, if we are. */
+ skip_rest_of_line (pfile);
+ if (pfile->cb.include)
+ (*pfile->cb.include) (pfile, dir, header);
+ }
+
+ return 0;
+}
+
+/* Handle #include, #include_next and #import. */
+static void
+do_include_common (pfile, type)
+ cpp_reader *pfile;
+ enum include_type type;
+{
+ cpp_token header;
+
+ if (!parse_include (pfile, &header))
+ {
+ /* Prevent #include recursion. */
+ if (pfile->buffer_stack_depth >= CPP_STACK_MAX)
+ cpp_fatal (pfile, "#include nested too deeply");
+ else if (pfile->context->prev)
+ cpp_ice (pfile, "attempt to push file buffer with contexts stacked");
+ else
+ {
+ /* For #include_next, if this is the primary source file,
+ warn and use the normal search logic. */
+ if (type == IT_INCLUDE_NEXT && ! pfile->buffer->prev)
+ {
+ cpp_warning (pfile, "#include_next in primary source file");
+ type = IT_INCLUDE;
+ }
+
+ _cpp_execute_include (pfile, &header, type);
+ }
+ }
+}
+
+static void
+do_include (pfile)
+ cpp_reader *pfile;
+{
+ do_include_common (pfile, IT_INCLUDE);
+}
+
+static void
+do_import (pfile)
+ cpp_reader *pfile;
+{
+ if (!pfile->import_warning && CPP_OPTION (pfile, warn_import))
+ {
+ pfile->import_warning = 1;
+ cpp_warning (pfile,
+ "#import is obsolete, use an #ifndef wrapper in the header file");
+ }
+
+ do_include_common (pfile, IT_IMPORT);
+}
+
+static void
+do_include_next (pfile)
+ cpp_reader *pfile;
+{
+ do_include_common (pfile, IT_INCLUDE_NEXT);
+}
+
+/* Subroutine of do_line. Read possible flags after file name. LAST
+ is the last flag seen; 0 if this is the first flag. Return the flag
+ if it is valid, 0 at the end of the directive. Otherwise complain. */
+
+static unsigned int
+read_flag (pfile, last)
+ cpp_reader *pfile;
+ unsigned int last;
+{
+ cpp_token token;
+
+ _cpp_lex_token (pfile, &token);
+ if (token.type == CPP_NUMBER && token.val.str.len == 1)
+ {
+ unsigned int flag = token.val.str.text[0] - '0';
+
+ if (flag > last && flag <= 4
+ && (flag != 4 || last == 3)
+ && (flag != 2 || last == 0))
+ return flag;
+ }
+
+ if (token.type != CPP_EOF)
+ cpp_error (pfile, "invalid flag \"%s\" in line directive",
+ cpp_token_as_text (pfile, &token));
+ return 0;
+}
+
+/* Another subroutine of do_line. Convert a number in STR, of length
+ LEN, to binary; store it in NUMP, and return 0 if the number was
+ well-formed, 1 if not. Temporary, hopefully. */
+static int
+strtoul_for_line (str, len, nump)
+ const U_CHAR *str;
+ unsigned int len;
+ unsigned long *nump;
+{
+ unsigned long reg = 0;
+ U_CHAR c;
+ while (len--)
+ {
+ c = *str++;
+ if (!ISDIGIT (c))
+ return 1;
+ reg *= 10;
+ reg += c - '0';
+ }
+ *nump = reg;
+ return 0;
+}
+
+/* Interpret #line command.
+ Note that the filename string (if any) is treated as if it were an
+ include filename. That means no escape handling. */
+
+static void
+do_line (pfile)
+ cpp_reader *pfile;
+{
+ cpp_buffer *buffer = pfile->buffer;
+ const char *filename = buffer->nominal_fname;
+ unsigned int lineno = buffer->lineno;
+ enum cpp_fc_reason reason = FC_RENAME;
+ unsigned long new_lineno;
+ unsigned int cap;
+ cpp_token token;
+
+ /* C99 raised the minimum limit on #line numbers. */
+ cap = CPP_OPTION (pfile, c99) ? 2147483647 : 32767;
+
+ /* #line commands expand macros. */
+ cpp_get_token (pfile, &token);
+ if (token.type != CPP_NUMBER
+ || strtoul_for_line (token.val.str.text, token.val.str.len, &new_lineno))
+ {
+ cpp_error (pfile, "\"%s\" after #line is not a positive integer",
+ cpp_token_as_text (pfile, &token));
+ return;
+ }
+
+ if (CPP_PEDANTIC (pfile) && (new_lineno == 0 || new_lineno > cap))
+ cpp_pedwarn (pfile, "line number out of range");
+
+ cpp_get_token (pfile, &token);
+ if (token.type == CPP_STRING)
+ {
+ const char *fname = (const char *) token.val.str.text;
+
+ /* Only accept flags for the # 55 form. */
+ if (! pfile->state.line_extension)
+ check_eol (pfile);
+ else
+ {
+ int flag = 0, sysp = 0;
+
+ flag = read_flag (pfile, flag);
+ if (flag == 1)
+ {
+ reason = FC_ENTER;
+ flag = read_flag (pfile, flag);
+ }
+ else if (flag == 2)
+ {
+ reason = FC_LEAVE;
+ flag = read_flag (pfile, flag);
+ }
+ if (flag == 3)
+ {
+ sysp = 1;
+ flag = read_flag (pfile, flag);
+ if (flag == 4)
+ sysp = 2, read_flag (pfile, flag);
+ }
+
+ if (reason == FC_ENTER)
+ {
+ /* Fake a buffer stack for diagnostics. */
+ cpp_push_buffer (pfile, 0, 0, BUF_FAKE, fname);
+ /* Fake an include for cpp_included. */
+ _cpp_fake_include (pfile, fname);
+ buffer = pfile->buffer;
+ }
+ else if (reason == FC_LEAVE)
+ {
+ if (buffer->type != BUF_FAKE)
+ cpp_warning (pfile, "file \"%s\" left but not entered",
+ buffer->nominal_fname);
+ else
+ {
+ cpp_pop_buffer (pfile);
+ buffer = pfile->buffer;
+#ifdef ENABLE_CHECKING
+ if (strcmp (buffer->nominal_fname, fname))
+ cpp_warning (pfile, "expected to return to file \"%s\"",
+ buffer->nominal_fname);
+ if (buffer->lineno + 1 != new_lineno)
+ cpp_warning (pfile, "expected to return to line number %u",
+ buffer->lineno + 1);
+ if (buffer->sysp != sysp)
+ cpp_warning (pfile, "header flags for \"%s\" have changed",
+ buffer->nominal_fname);
+#endif
+ }
+ }
+ buffer->sysp = sysp;
+ }
+ buffer->nominal_fname = fname;
+ }
+ else if (token.type != CPP_EOF)
+ {
+ cpp_error (pfile, "\"%s\" is not a valid filename",
+ cpp_token_as_text (pfile, &token));
+ return;
+ }
+
+ /* Our line number is incremented after the directive is processed. */
+ buffer->lineno = new_lineno - 1;
+ _cpp_do_file_change (pfile, reason, filename, lineno);
+}
+
+/* Arrange the file_change callback. */
+void
+_cpp_do_file_change (pfile, reason, from_file, from_lineno)
+ cpp_reader *pfile;
+ enum cpp_fc_reason reason;
+ const char *from_file;
+ unsigned int from_lineno;
+{
+ if (pfile->cb.file_change)
+ {
+ cpp_file_change fc;
+ cpp_buffer *buffer = pfile->buffer;
+
+ fc.reason = reason;
+ fc.to.filename = buffer->nominal_fname;
+ fc.to.lineno = buffer->lineno + 1;
+ fc.sysp = buffer->sysp;
+ fc.externc = CPP_OPTION (pfile, cplusplus) && buffer->sysp == 2;
+
+ /* Caller doesn't need to handle FC_ENTER. */
+ if (reason == FC_ENTER)
+ {
+ if (buffer->prev)
+ {
+ from_file = buffer->prev->nominal_fname;
+ from_lineno = buffer->prev->lineno;
+ }
+ else
+ from_file = 0;
+ }
+ /* Special case for file "foo.i" with "# 1 foo.c" on first line. */
+ else if (reason == FC_RENAME && ! buffer->prev
+ && pfile->directive_pos.line == 1)
+ from_file = 0;
+
+ fc.from.filename = from_file;
+ fc.from.lineno = from_lineno;
+ pfile->cb.file_change (pfile, &fc);
+ }
+}
+
+/*
+ * Report a warning or error detected by the program we are
+ * processing. Use the directive's tokens in the error message.
+ */
+
+static void
+do_diagnostic (pfile, code, print_dir)
+ cpp_reader *pfile;
+ enum error_type code;
+ int print_dir;
+{
+ if (_cpp_begin_message (pfile, code, NULL, 0))
+ {
+ if (print_dir)
+ fprintf (stderr, "#%s ", pfile->directive->name);
+ pfile->state.prevent_expansion++;
+ cpp_output_line (pfile, stderr);
+ pfile->state.prevent_expansion--;
+ }
+}
+
+static void
+do_error (pfile)
+ cpp_reader *pfile;
+{
+ do_diagnostic (pfile, ERROR, 1);
+}
+
+static void
+do_warning (pfile)
+ cpp_reader *pfile;
+{
+ /* We want #warning diagnostics to be emitted in system headers too. */
+ do_diagnostic (pfile, WARNING_SYSHDR, 1);
+}
+
+/* Report program identification. */
+
+static void
+do_ident (pfile)
+ cpp_reader *pfile;
+{
+ cpp_token str;
+
+ cpp_get_token (pfile, &str);
+ if (str.type != CPP_STRING)
+ cpp_error (pfile, "invalid #ident");
+ else if (pfile->cb.ident)
+ (*pfile->cb.ident) (pfile, &str.val.str);
+
+ check_eol (pfile);
+}
+
+/* Pragmata handling. We handle some of these, and pass the rest on
+ to the front end. C99 defines three pragmas and says that no macro
+ expansion is to be performed on them; whether or not macro
+ expansion happens for other pragmas is implementation defined.
+ This implementation never macro-expands the text after #pragma. */
+
+/* Sub-handlers for the pragmas needing treatment here.
+ They return 1 if the token buffer is to be popped, 0 if not. */
+struct pragma_entry
+{
+ struct pragma_entry *next;
+ const char *name;
+ size_t len;
+ int isnspace;
+ union {
+ void (*handler) PARAMS ((cpp_reader *));
+ struct pragma_entry *space;
+ } u;
+};
+
+void
+cpp_register_pragma (pfile, space, name, handler)
+ cpp_reader *pfile;
+ const char *space;
+ const char *name;
+ void (*handler) PARAMS ((cpp_reader *));
+{
+ struct pragma_entry **x, *new;
+ size_t len;
+
+ x = &pfile->pragmas;
+ if (space)
+ {
+ struct pragma_entry *p = pfile->pragmas;
+ len = strlen (space);
+ while (p)
+ {
+ if (p->isnspace && p->len == len && !memcmp (p->name, space, len))
+ {
+ x = &p->u.space;
+ goto found;
+ }
+ p = p->next;
+ }
+ cpp_ice (pfile, "unknown #pragma namespace %s", space);
+ return;
+ }
+
+ found:
+ new = xnew (struct pragma_entry);
+ new->name = name;
+ new->len = strlen (name);
+ new->isnspace = 0;
+ new->u.handler = handler;
+
+ new->next = *x;
+ *x = new;
+}
+
+void
+cpp_register_pragma_space (pfile, space)
+ cpp_reader *pfile;
+ const char *space;
+{
+ struct pragma_entry *new;
+ const struct pragma_entry *p = pfile->pragmas;
+ size_t len = strlen (space);
+
+ while (p)
+ {
+ if (p->isnspace && p->len == len && !memcmp (p->name, space, len))
+ /* Multiple different callers are allowed to register the same
+ namespace. */
+ return;
+ p = p->next;
+ }
+
+ new = xnew (struct pragma_entry);
+ new->name = space;
+ new->len = len;
+ new->isnspace = 1;
+ new->u.space = 0;
+
+ new->next = pfile->pragmas;
+ pfile->pragmas = new;
+}
+
+void
+_cpp_init_internal_pragmas (pfile)
+ cpp_reader *pfile;
+{
+ /* top level */
+ cpp_register_pragma (pfile, 0, "poison", do_pragma_poison);
+ cpp_register_pragma (pfile, 0, "once", do_pragma_once);
+
+ /* GCC namespace */
+ cpp_register_pragma_space (pfile, "GCC");
+
+ cpp_register_pragma (pfile, "GCC", "poison", do_pragma_poison);
+ cpp_register_pragma (pfile, "GCC", "system_header", do_pragma_system_header);
+ cpp_register_pragma (pfile, "GCC", "dependency", do_pragma_dependency);
+}
+
+static void
+do_pragma (pfile)
+ cpp_reader *pfile;
+{
+ const struct pragma_entry *p;
+ cpp_token tok;
+ int drop = 0;
+
+ p = pfile->pragmas;
+ pfile->state.prevent_expansion++;
+ cpp_start_lookahead (pfile);
+
+ new_space:
+ cpp_get_token (pfile, &tok);
+ if (tok.type == CPP_NAME)
+ {
+ const cpp_hashnode *node = tok.val.node;
+ size_t len = NODE_LEN (node);
+
+ while (p)
+ {
+ if (strlen (p->name) == len
+ && !memcmp (p->name, NODE_NAME (node), len))
+ {
+ if (p->isnspace)
+ {
+ p = p->u.space;
+ goto new_space;
+ }
+ else
+ {
+ (*p->u.handler) (pfile);
+ drop = 1;
+ break;
+ }
+ }
+ p = p->next;
+ }
+ }
+
+ cpp_stop_lookahead (pfile, drop);
+ pfile->state.prevent_expansion--;
+
+ if (!drop && pfile->cb.def_pragma)
+ (*pfile->cb.def_pragma) (pfile);
+}
+
+static void
+do_pragma_once (pfile)
+ cpp_reader *pfile;
+{
+ cpp_warning (pfile, "#pragma once is obsolete");
+
+ if (pfile->buffer->prev == NULL)
+ cpp_warning (pfile, "#pragma once in main file");
+ else
+ _cpp_never_reread (pfile->buffer->inc);
+
+ check_eol (pfile);
+}
+
+static void
+do_pragma_poison (pfile)
+ cpp_reader *pfile;
+{
+ /* Poison these symbols so that all subsequent usage produces an
+ error message. */
+ cpp_token tok;
+ cpp_hashnode *hp;
+
+ pfile->state.poisoned_ok = 1;
+ for (;;)
+ {
+ _cpp_lex_token (pfile, &tok);
+ if (tok.type == CPP_EOF)
+ break;
+ if (tok.type != CPP_NAME)
+ {
+ cpp_error (pfile, "invalid #pragma GCC poison directive");
+ break;
+ }
+
+ hp = tok.val.node;
+ if (hp->flags & NODE_POISONED)
+ continue;
+
+ if (hp->type == NT_MACRO)
+ cpp_warning (pfile, "poisoning existing macro \"%s\"", NODE_NAME (hp));
+ _cpp_free_definition (hp);
+ hp->flags |= NODE_POISONED | NODE_DIAGNOSTIC;
+ }
+ pfile->state.poisoned_ok = 0;
+
+#if 0 /* Doesn't quite work yet. */
+ if (tok.type == CPP_EOF && pfile->cb.poison)
+ (*pfile->cb.poison) (pfile);
+#endif
+}
+
+/* Mark the current header as a system header. This will suppress
+ some categories of warnings (notably those from -pedantic). It is
+ intended for use in system libraries that cannot be implemented in
+ conforming C, but cannot be certain that their headers appear in a
+ system include directory. To prevent abuse, it is rejected in the
+ primary source file. */
+static void
+do_pragma_system_header (pfile)
+ cpp_reader *pfile;
+{
+ cpp_buffer *buffer = pfile->buffer;
+
+ if (buffer->prev == 0)
+ cpp_warning (pfile, "#pragma system_header ignored outside include file");
+ else
+ cpp_make_system_header (pfile, 1, 0);
+
+ check_eol (pfile);
+}
+
+/* Check the modified date of the current include file against a specified
+ file. Issue a diagnostic, if the specified file is newer. We use this to
+ determine if a fixed header should be refixed. */
+static void
+do_pragma_dependency (pfile)
+ cpp_reader *pfile;
+{
+ cpp_token header, msg;
+ int ordering;
+
+ if (parse_include (pfile, &header))
+ return;
+
+ ordering = _cpp_compare_file_date (pfile, &header);
+ if (ordering < 0)
+ cpp_warning (pfile, "cannot find source %s",
+ cpp_token_as_text (pfile, &header));
+ else if (ordering > 0)
+ {
+ cpp_warning (pfile, "current file is older than %s",
+ cpp_token_as_text (pfile, &header));
+ cpp_start_lookahead (pfile);
+ cpp_get_token (pfile, &msg);
+ cpp_stop_lookahead (pfile, msg.type == CPP_EOF);
+ if (msg.type != CPP_EOF)
+ do_diagnostic (pfile, WARNING, 0);
+ }
+}
+
+/* Check syntax is "(string-literal)". Returns 0 on success. */
+static int
+get__Pragma_string (pfile, string)
+ cpp_reader *pfile;
+ cpp_token *string;
+{
+ cpp_token paren;
+
+ cpp_get_token (pfile, &paren);
+ if (paren.type != CPP_OPEN_PAREN)
+ return 1;
+
+ cpp_get_token (pfile, string);
+ if (string->type != CPP_STRING && string->type != CPP_WSTRING)
+ return 1;
+
+ cpp_get_token (pfile, &paren);
+ return paren.type != CPP_CLOSE_PAREN;
+}
+
+/* Returns a malloced buffer containing a destringized cpp_string by
+ removing the first \ of \" and \\ sequences. */
+static unsigned char *
+destringize (in, len)
+ const cpp_string *in;
+ unsigned int *len;
+{
+ const unsigned char *src, *limit;
+ unsigned char *dest, *result;
+
+ dest = result = (unsigned char *) xmalloc (in->len);
+ for (src = in->text, limit = src + in->len; src < limit;)
+ {
+ /* We know there is a character following the backslash. */
+ if (*src == '\\' && (src[1] == '\\' || src[1] == '"'))
+ src++;
+ *dest++ = *src++;
+ }
+
+ *len = dest - result;
+ return result;
+}
+
+void
+_cpp_do__Pragma (pfile)
+ cpp_reader *pfile;
+{
+ cpp_token string;
+ unsigned char *buffer;
+ unsigned int len;
+
+ if (get__Pragma_string (pfile, &string))
+ {
+ cpp_error (pfile, "_Pragma takes a parenthesized string literal");
+ return;
+ }
+
+ buffer = destringize (&string.val.str, &len);
+ run_directive (pfile, T_PRAGMA, BUF_PRAGMA, (char *) buffer, len);
+ free ((PTR) buffer);
+}
+
+/* Just ignore #sccs, on systems where we define it at all. */
+#ifdef SCCS_DIRECTIVE
+static void
+do_sccs (pfile)
+ cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+}
+#endif
+
+static void
+do_ifdef (pfile)
+ cpp_reader *pfile;
+{
+ int skip = 1;
+
+ if (! pfile->buffer->was_skipping)
+ {
+ const cpp_hashnode *node = lex_macro_node (pfile);
+
+ if (node)
+ skip = node->type != NT_MACRO;
+
+ if (node)
+ check_eol (pfile);
+ }
+
+ push_conditional (pfile, skip, T_IFDEF, 0);
+}
+
+static void
+do_ifndef (pfile)
+ cpp_reader *pfile;
+{
+ int skip = 1;
+ const cpp_hashnode *node = 0;
+
+ if (! pfile->buffer->was_skipping)
+ {
+ node = lex_macro_node (pfile);
+ if (node)
+ skip = node->type == NT_MACRO;
+
+ if (node)
+ check_eol (pfile);
+ }
+
+ push_conditional (pfile, skip, T_IFNDEF, node);
+}
+
+/* #if cooperates with parse_defined to handle multiple-include
+ optimisations. If macro expansions or identifiers appear in the
+ expression, we cannot treat it as a controlling conditional, since
+ their values could change in the future. */
+
+static void
+do_if (pfile)
+ cpp_reader *pfile;
+{
+ int skip = 1;
+ const cpp_hashnode *cmacro = 0;
+
+ if (! pfile->buffer->was_skipping)
+ {
+ /* Controlling macro of #if ! defined () */
+ pfile->mi_ind_cmacro = 0;
+ skip = _cpp_parse_expr (pfile) == 0;
+ cmacro = pfile->mi_ind_cmacro;
+ }
+
+ push_conditional (pfile, skip, T_IF, cmacro);
+}
+
+/* Flip skipping state if appropriate and continue without changing
+ if_stack; this is so that the error message for missing #endif's
+ etc. will point to the original #if. */
+
+static void
+do_else (pfile)
+ cpp_reader *pfile;
+{
+ cpp_buffer *buffer = pfile->buffer;
+ struct if_stack *ifs = buffer->if_stack;
+
+ if (ifs == NULL)
+ cpp_error (pfile, "#else without #if");
+ else
+ {
+ if (ifs->type == T_ELSE)
+ {
+ cpp_error (pfile, "#else after #else");
+ cpp_error_with_line (pfile, ifs->pos.line, ifs->pos.col,
+ "the conditional began here");
+ }
+ ifs->type = T_ELSE;
+
+ /* Buffer->was_skipping is 1 if all conditionals in this chain
+ have been false, 2 if a conditional has been true. */
+ if (! ifs->was_skipping && buffer->was_skipping != 2)
+ buffer->was_skipping = ! buffer->was_skipping;
+
+ /* Invalidate any controlling macro. */
+ ifs->mi_cmacro = 0;
+ }
+
+ check_eol (pfile);
+}
+
+/* handle a #elif directive by not changing if_stack either. see the
+ comment above do_else. */
+
+static void
+do_elif (pfile)
+ cpp_reader *pfile;
+{
+ cpp_buffer *buffer = pfile->buffer;
+ struct if_stack *ifs = buffer->if_stack;
+
+ if (ifs == NULL)
+ cpp_error (pfile, "#elif without #if");
+ else
+ {
+ if (ifs->type == T_ELSE)
+ {
+ cpp_error (pfile, "#elif after #else");
+ cpp_error_with_line (pfile, ifs->pos.line, ifs->pos.col,
+ "the conditional began here");
+ }
+ ifs->type = T_ELIF;
+
+ /* Don't evaluate #elif if our higher level is skipping. */
+ if (! ifs->was_skipping)
+ {
+ /* Buffer->was_skipping is 1 if all conditionals in this
+ chain have been false, 2 if a conditional has been true. */
+ if (buffer->was_skipping == 1)
+ buffer->was_skipping = ! _cpp_parse_expr (pfile);
+ else
+ buffer->was_skipping = 2;
+
+ /* Invalidate any controlling macro. */
+ ifs->mi_cmacro = 0;
+ }
+ }
+}
+
+/* #endif pops the if stack and resets pfile->skipping. */
+
+static void
+do_endif (pfile)
+ cpp_reader *pfile;
+{
+ cpp_buffer *buffer = pfile->buffer;
+ struct if_stack *ifs = buffer->if_stack;
+
+ if (ifs == NULL)
+ cpp_error (pfile, "#endif without #if");
+ else
+ {
+ /* If potential control macro, we go back outside again. */
+ if (ifs->next == 0 && ifs->mi_cmacro)
+ {
+ pfile->mi_state = MI_OUTSIDE;
+ pfile->mi_cmacro = ifs->mi_cmacro;
+ }
+
+ buffer->if_stack = ifs->next;
+ buffer->was_skipping = ifs->was_skipping;
+ obstack_free (&pfile->buffer_ob, ifs);
+ }
+
+ check_eol (pfile);
+}
+
+/* Push an if_stack entry and set pfile->skipping accordingly.
+ If this is a #ifndef starting at the beginning of a file,
+ CMACRO is the macro name tested by the #ifndef. */
+
+static void
+push_conditional (pfile, skip, type, cmacro)
+ cpp_reader *pfile;
+ int skip;
+ int type;
+ const cpp_hashnode *cmacro;
+{
+ struct if_stack *ifs;
+ cpp_buffer *buffer = pfile->buffer;
+
+ ifs = xobnew (&pfile->buffer_ob, struct if_stack);
+ ifs->pos = pfile->directive_pos;
+ ifs->next = buffer->if_stack;
+ ifs->was_skipping = buffer->was_skipping;
+ ifs->type = type;
+ if (pfile->mi_state == MI_OUTSIDE && pfile->mi_cmacro == 0)
+ ifs->mi_cmacro = cmacro;
+ else
+ ifs->mi_cmacro = 0;
+
+ buffer->was_skipping = skip;
+ buffer->if_stack = ifs;
+}
+
+/* Read the tokens of the answer into the macro pool. Only commit the
+ memory if we intend it as permanent storage, i.e. the #assert case.
+ Returns 0 on success. */
+
+static int
+parse_answer (pfile, answerp, type)
+ cpp_reader *pfile;
+ struct answer **answerp;
+ int type;
+{
+ cpp_token paren, *token;
+ struct answer *answer;
+
+ if (POOL_FRONT (&pfile->macro_pool) + sizeof (struct answer) >
+ POOL_LIMIT (&pfile->macro_pool))
+ _cpp_next_chunk (&pfile->macro_pool, sizeof (struct answer), 0);
+ answer = (struct answer *) POOL_FRONT (&pfile->macro_pool);
+ answer->count = 0;
+
+ /* In a conditional, it is legal to not have an open paren. We
+ should save the following token in this case. */
+ if (type == T_IF)
+ cpp_start_lookahead (pfile);
+ cpp_get_token (pfile, &paren);
+ if (type == T_IF)
+ cpp_stop_lookahead (pfile, paren.type == CPP_OPEN_PAREN);
+
+ /* If not a paren, see if we're OK. */
+ if (paren.type != CPP_OPEN_PAREN)
+ {
+ /* In a conditional no answer is a test for any answer. It
+ could be followed by any token. */
+ if (type == T_IF)
+ return 0;
+
+ /* #unassert with no answer is valid - it removes all answers. */
+ if (type == T_UNASSERT && paren.type == CPP_EOF)
+ return 0;
+
+ cpp_error (pfile, "missing '(' after predicate");
+ return 1;
+ }
+
+ for (;;)
+ {
+ token = &answer->first[answer->count];
+ /* Check we have room for the token. */
+ if ((unsigned char *) (token + 1) >= POOL_LIMIT (&pfile->macro_pool))
+ {
+ _cpp_next_chunk (&pfile->macro_pool, sizeof (cpp_token),
+ (unsigned char **) &answer);
+ token = &answer->first[answer->count];
+ }
+
+ cpp_get_token (pfile, token);
+ if (token->type == CPP_CLOSE_PAREN)
+ break;
+
+ if (token->type == CPP_EOF)
+ {
+ cpp_error (pfile, "missing ')' to complete answer");
+ return 1;
+ }
+ answer->count++;
+ }
+
+ if (answer->count == 0)
+ {
+ cpp_error (pfile, "predicate's answer is empty");
+ return 1;
+ }
+
+ /* Drop whitespace at start. */
+ answer->first->flags &= ~PREV_WHITE;
+ *answerp = answer;
+
+ if (type == T_ASSERT || type == T_UNASSERT)
+ check_eol (pfile);
+ return 0;
+}
+
+/* Parses an assertion, returning a pointer to the hash node of the
+ predicate, or 0 on error. If an answer was supplied, it is placed
+ in ANSWERP, otherwise it is set to 0. */
+static cpp_hashnode *
+parse_assertion (pfile, answerp, type)
+ cpp_reader *pfile;
+ struct answer **answerp;
+ int type;
+{
+ cpp_hashnode *result = 0;
+ cpp_token predicate;
+
+ /* We don't expand predicates or answers. */
+ pfile->state.prevent_expansion++;
+
+ *answerp = 0;
+ cpp_get_token (pfile, &predicate);
+ if (predicate.type == CPP_EOF)
+ cpp_error (pfile, "assertion without predicate");
+ else if (predicate.type != CPP_NAME)
+ cpp_error (pfile, "predicate must be an identifier");
+ else if (parse_answer (pfile, answerp, type) == 0)
+ {
+ unsigned int len = NODE_LEN (predicate.val.node);
+ unsigned char *sym = alloca (len + 1);
+
+ /* Prefix '#' to get it out of macro namespace. */
+ sym[0] = '#';
+ memcpy (sym + 1, NODE_NAME (predicate.val.node), len);
+ result = cpp_lookup (pfile, sym, len + 1);
+ }
+
+ pfile->state.prevent_expansion--;
+ return result;
+}
+
+/* Returns a pointer to the pointer to the answer in the answer chain,
+ or a pointer to NULL if the answer is not in the chain. */
+static struct answer **
+find_answer (node, candidate)
+ cpp_hashnode *node;
+ const struct answer *candidate;
+{
+ unsigned int i;
+ struct answer **result;
+
+ for (result = &node->value.answers; *result; result = &(*result)->next)
+ {
+ struct answer *answer = *result;
+
+ if (answer->count == candidate->count)
+ {
+ for (i = 0; i < answer->count; i++)
+ if (! _cpp_equiv_tokens (&answer->first[i], &candidate->first[i]))
+ break;
+
+ if (i == answer->count)
+ break;
+ }
+ }
+
+ return result;
+}
+
+/* Test an assertion within a preprocessor conditional. Returns
+ non-zero on failure, zero on success. On success, the result of
+ the test is written into VALUE. */
+int
+_cpp_test_assertion (pfile, value)
+ cpp_reader *pfile;
+ int *value;
+{
+ struct answer *answer;
+ cpp_hashnode *node;
+
+ node = parse_assertion (pfile, &answer, T_IF);
+ if (node)
+ *value = (node->type == NT_ASSERTION &&
+ (answer == 0 || *find_answer (node, answer) != 0));
+
+ /* We don't commit the memory for the answer - it's temporary only. */
+ return node == 0;
+}
+
+static void
+do_assert (pfile)
+ cpp_reader *pfile;
+{
+ struct answer *new_answer;
+ cpp_hashnode *node;
+
+ node = parse_assertion (pfile, &new_answer, T_ASSERT);
+ if (node)
+ {
+ /* Place the new answer in the answer list. First check there
+ is not a duplicate. */
+ new_answer->next = 0;
+ if (node->type == NT_ASSERTION)
+ {
+ if (*find_answer (node, new_answer))
+ {
+ cpp_warning (pfile, "\"%s\" re-asserted", NODE_NAME (node) + 1);
+ return;
+ }
+ new_answer->next = node->value.answers;
+ }
+ node->type = NT_ASSERTION;
+ node->value.answers = new_answer;
+ POOL_COMMIT (&pfile->macro_pool, (sizeof (struct answer)
+ + (new_answer->count - 1)
+ * sizeof (cpp_token)));
+ }
+}
+
+static void
+do_unassert (pfile)
+ cpp_reader *pfile;
+{
+ cpp_hashnode *node;
+ struct answer *answer;
+
+ node = parse_assertion (pfile, &answer, T_UNASSERT);
+ /* It isn't an error to #unassert something that isn't asserted. */
+ if (node && node->type == NT_ASSERTION)
+ {
+ if (answer)
+ {
+ struct answer **p = find_answer (node, answer), *temp;
+
+ /* Remove the answer from the list. */
+ temp = *p;
+ if (temp)
+ *p = temp->next;
+
+ /* Did we free the last answer? */
+ if (node->value.answers == 0)
+ node->type = NT_VOID;
+ }
+ else
+ _cpp_free_definition (node);
+ }
+
+ /* We don't commit the memory for the answer - it's temporary only. */
+}
+
+/* These are for -D, -U, -A. */
+
+/* Process the string STR as if it appeared as the body of a #define.
+ If STR is just an identifier, define it with value 1.
+ If STR has anything after the identifier, then it should
+ be identifier=definition. */
+
+void
+cpp_define (pfile, str)
+ cpp_reader *pfile;
+ const char *str;
+{
+ char *buf, *p;
+ size_t count;
+
+ /* Copy the entire option so we can modify it.
+ Change the first "=" in the string to a space. If there is none,
+ tack " 1" on the end. */
+
+ /* Length including the null. */
+ count = strlen (str);
+ buf = (char *) alloca (count + 2);
+ memcpy (buf, str, count);
+
+ p = strchr (str, '=');
+ if (p)
+ buf[p - str] = ' ';
+ else
+ {
+ buf[count++] = ' ';
+ buf[count++] = '1';
+ }
+
+ run_directive (pfile, T_DEFINE, BUF_CL_OPTION, buf, count);
+}
+
+/* Slight variant of the above for use by initialize_builtins. */
+void
+_cpp_define_builtin (pfile, str)
+ cpp_reader *pfile;
+ const char *str;
+{
+ run_directive (pfile, T_DEFINE, BUF_BUILTIN, str, strlen (str));
+}
+
+/* Process MACRO as if it appeared as the body of an #undef. */
+void
+cpp_undef (pfile, macro)
+ cpp_reader *pfile;
+ const char *macro;
+{
+ run_directive (pfile, T_UNDEF, BUF_CL_OPTION, macro, strlen (macro));
+}
+
+/* Process the string STR as if it appeared as the body of a #assert. */
+void
+cpp_assert (pfile, str)
+ cpp_reader *pfile;
+ const char *str;
+{
+ handle_assertion (pfile, str, T_ASSERT);
+}
+
+/* Process STR as if it appeared as the body of an #unassert. */
+void
+cpp_unassert (pfile, str)
+ cpp_reader *pfile;
+ const char *str;
+{
+ handle_assertion (pfile, str, T_UNASSERT);
+}
+
+/* Common code for cpp_assert (-A) and cpp_unassert (-A-). */
+static void
+handle_assertion (pfile, str, type)
+ cpp_reader *pfile;
+ const char *str;
+ int type;
+{
+ size_t count = strlen (str);
+ const char *p = strchr (str, '=');
+
+ if (p)
+ {
+ /* Copy the entire option so we can modify it. Change the first
+ "=" in the string to a '(', and tack a ')' on the end. */
+ char *buf = (char *) alloca (count + 1);
+
+ memcpy (buf, str, count);
+ buf[p - str] = '(';
+ buf[count++] = ')';
+ str = buf;
+ }
+
+ run_directive (pfile, type, BUF_CL_OPTION, str, count);
+}
+
+/* The number of errors for a given reader. */
+unsigned int
+cpp_errors (pfile)
+ cpp_reader *pfile;
+{
+ return pfile->errors;
+}
+
+/* The options structure. */
+cpp_options *
+cpp_get_options (pfile)
+ cpp_reader *pfile;
+{
+ return &pfile->opts;
+}
+
+/* The callbacks structure. */
+cpp_callbacks *
+cpp_get_callbacks (pfile)
+ cpp_reader *pfile;
+{
+ return &pfile->cb;
+}
+
+/* Copy the given callbacks structure to our own. */
+void
+cpp_set_callbacks (pfile, cb)
+ cpp_reader *pfile;
+ cpp_callbacks *cb;
+{
+ pfile->cb = *cb;
+}
+
+/* Push a new buffer on the buffer stack. Returns the new buffer; it
+ doesn't fail. It does not generate a file change call back; that
+ is the responsibility of the caller. */
+cpp_buffer *
+cpp_push_buffer (pfile, buffer, len, type, filename)
+ cpp_reader *pfile;
+ const U_CHAR *buffer;
+ size_t len;
+ enum cpp_buffer_type type;
+ const char *filename;
+{
+ cpp_buffer *new = xobnew (&pfile->buffer_ob, cpp_buffer);
+
+ if (type == BUF_FAKE)
+ {
+ /* A copy of the current buffer, just with a new name and type. */
+ memcpy (new, pfile->buffer, sizeof (cpp_buffer));
+ new->type = BUF_FAKE;
+ }
+ else
+ {
+ if (type == BUF_BUILTIN)
+ filename = _("<builtin>");
+ else if (type == BUF_CL_OPTION)
+ filename = _("<command line>");
+ else if (type == BUF_PRAGMA)
+ filename = "<_Pragma>";
+
+ /* Clears, amongst other things, if_stack and mi_cmacro. */
+ memset (new, 0, sizeof (cpp_buffer));
+
+ new->line_base = new->buf = new->cur = buffer;
+ new->rlimit = buffer + len;
+ new->sysp = 0;
+
+ /* No read ahead or extra char initially. */
+ new->read_ahead = EOF;
+ new->extra_char = EOF;
+
+ /* Preprocessed files, builtins, _Pragma and command line
+ options don't do trigraph and escaped newline processing. */
+ new->from_stage3 = type != BUF_FILE || CPP_OPTION (pfile, preprocessed);
+
+ pfile->lexer_pos.output_line = 1;
+ }
+
+ if (*filename == '\0')
+ new->nominal_fname = _("<stdin>");
+ else
+ new->nominal_fname = filename;
+ new->type = type;
+ new->prev = pfile->buffer;
+ new->pfile = pfile;
+ new->include_stack_listed = 0;
+ new->lineno = 1;
+
+ pfile->state.next_bol = 1;
+ pfile->buffer_stack_depth++;
+ pfile->buffer = new;
+
+ return new;
+}
+
+/* If called from do_line, pops a single buffer. Otherwise pops all
+ buffers until a real file is reached. Generates appropriate
+ call-backs. */
+cpp_buffer *
+cpp_pop_buffer (pfile)
+ cpp_reader *pfile;
+{
+ cpp_buffer *buffer;
+ struct if_stack *ifs;
+
+ for (;;)
+ {
+ buffer = pfile->buffer;
+ /* Walk back up the conditional stack till we reach its level at
+ entry to this file, issuing error messages. */
+ for (ifs = buffer->if_stack; ifs; ifs = ifs->next)
+ cpp_error_with_line (pfile, ifs->pos.line, ifs->pos.col,
+ "unterminated #%s", dtable[ifs->type].name);
+
+ if (buffer->type == BUF_FAKE)
+ buffer->prev->cur = buffer->cur;
+ else if (buffer->type == BUF_FILE)
+ _cpp_pop_file_buffer (pfile, buffer);
+
+ pfile->buffer = buffer->prev;
+ pfile->buffer_stack_depth--;
+
+ /* Callbacks only generated for faked or real files. */
+ if (buffer->type != BUF_FILE && buffer->type != BUF_FAKE)
+ break;
+
+ /* No callback for EOF of last file. */
+ if (!pfile->buffer)
+ break;
+
+ /* do_line does its own call backs. */
+ pfile->buffer->include_stack_listed = 0;
+ if (pfile->directive == &dtable[T_LINE])
+ break;
+
+ _cpp_do_file_change (pfile, FC_LEAVE, buffer->nominal_fname,
+ buffer->lineno);
+ if (pfile->buffer->type == BUF_FILE)
+ break;
+
+ cpp_warning (pfile, "file \"%s\" entered but not left",
+ buffer->nominal_fname);
+ }
+
+ obstack_free (&pfile->buffer_ob, buffer);
+ return pfile->buffer;
+}
+
+void
+_cpp_init_directives (pfile)
+ cpp_reader *pfile;
+{
+ unsigned int i;
+ cpp_hashnode *node;
+
+ /* Register the directives. */
+ for (i = 0; i < (unsigned int) N_DIRECTIVES; i++)
+ {
+ node = cpp_lookup (pfile, dtable[i].name, dtable[i].length);
+ node->directive_index = i + 1;
+ }
+}
--- /dev/null
+/* Definitions for CPP library.
+ Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001
+ Free Software Foundation, Inc.
+ Written by Per Bothner, 1994-95.
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ In other words, you are welcome to use, share and improve this program.
+ You are forbidden to forbid anyone else to use, share and improve
+ what you give them. Help stamp out software-hoarding! */
+#ifndef GCC_CPPLIB_H
+#define GCC_CPPLIB_H
+
+#include <sys/types.h>
+#include "hashtable.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For complex reasons, cpp_reader is also typedefed in c-pragma.h. */
+#ifndef GCC_C_PRAGMA_H
+typedef struct cpp_reader cpp_reader;
+#endif
+typedef struct cpp_buffer cpp_buffer;
+typedef struct cpp_options cpp_options;
+typedef struct cpp_token cpp_token;
+typedef struct cpp_string cpp_string;
+typedef struct cpp_hashnode cpp_hashnode;
+typedef struct cpp_macro cpp_macro;
+typedef struct cpp_lexer_pos cpp_lexer_pos;
+typedef struct cpp_lookahead cpp_lookahead;
+typedef struct cpp_callbacks cpp_callbacks;
+
+struct answer;
+struct file_name_map_list;
+struct ht;
+
+/* The first two groups, apart from '=', can appear in preprocessor
+ expressions. This allows a lookup table to be implemented in
+ _cpp_parse_expr.
+
+ The first group, to CPP_LAST_EQ, can be immediately followed by an
+ '='. The lexer needs operators ending in '=', like ">>=", to be in
+ the same order as their counterparts without the '=', like ">>". */
+
+/* Positions in the table. */
+#define CPP_LAST_EQ CPP_MAX
+#define CPP_FIRST_DIGRAPH CPP_HASH
+#define CPP_LAST_PUNCTUATOR CPP_DOT_STAR
+
+#define TTYPE_TABLE \
+ OP(CPP_EQ = 0, "=") \
+ OP(CPP_NOT, "!") \
+ OP(CPP_GREATER, ">") /* compare */ \
+ OP(CPP_LESS, "<") \
+ OP(CPP_PLUS, "+") /* math */ \
+ OP(CPP_MINUS, "-") \
+ OP(CPP_MULT, "*") \
+ OP(CPP_DIV, "/") \
+ OP(CPP_MOD, "%") \
+ OP(CPP_AND, "&") /* bit ops */ \
+ OP(CPP_OR, "|") \
+ OP(CPP_XOR, "^") \
+ OP(CPP_RSHIFT, ">>") \
+ OP(CPP_LSHIFT, "<<") \
+ OP(CPP_MIN, "<?") /* extension */ \
+ OP(CPP_MAX, ">?") \
+\
+ OP(CPP_COMPL, "~") \
+ OP(CPP_AND_AND, "&&") /* logical */ \
+ OP(CPP_OR_OR, "||") \
+ OP(CPP_QUERY, "?") \
+ OP(CPP_COLON, ":") \
+ OP(CPP_COMMA, ",") /* grouping */ \
+ OP(CPP_OPEN_PAREN, "(") \
+ OP(CPP_CLOSE_PAREN, ")") \
+ OP(CPP_EQ_EQ, "==") /* compare */ \
+ OP(CPP_NOT_EQ, "!=") \
+ OP(CPP_GREATER_EQ, ">=") \
+ OP(CPP_LESS_EQ, "<=") \
+\
+ OP(CPP_PLUS_EQ, "+=") /* math */ \
+ OP(CPP_MINUS_EQ, "-=") \
+ OP(CPP_MULT_EQ, "*=") \
+ OP(CPP_DIV_EQ, "/=") \
+ OP(CPP_MOD_EQ, "%=") \
+ OP(CPP_AND_EQ, "&=") /* bit ops */ \
+ OP(CPP_OR_EQ, "|=") \
+ OP(CPP_XOR_EQ, "^=") \
+ OP(CPP_RSHIFT_EQ, ">>=") \
+ OP(CPP_LSHIFT_EQ, "<<=") \
+ OP(CPP_MIN_EQ, "<?=") /* extension */ \
+ OP(CPP_MAX_EQ, ">?=") \
+ /* Digraphs together, beginning with CPP_FIRST_DIGRAPH. */ \
+ OP(CPP_HASH, "#") /* digraphs */ \
+ OP(CPP_PASTE, "##") \
+ OP(CPP_OPEN_SQUARE, "[") \
+ OP(CPP_CLOSE_SQUARE, "]") \
+ OP(CPP_OPEN_BRACE, "{") \
+ OP(CPP_CLOSE_BRACE, "}") \
+ /* The remainder of the punctuation. Order is not significant. */ \
+ OP(CPP_SEMICOLON, ";") /* structure */ \
+ OP(CPP_ELLIPSIS, "...") \
+ OP(CPP_PLUS_PLUS, "++") /* increment */ \
+ OP(CPP_MINUS_MINUS, "--") \
+ OP(CPP_DEREF, "->") /* accessors */ \
+ OP(CPP_DOT, ".") \
+ OP(CPP_SCOPE, "::") \
+ OP(CPP_DEREF_STAR, "->*") \
+ OP(CPP_DOT_STAR, ".*") \
+ OP(CPP_ATSIGN, "@") /* used in Objective C */ \
+\
+ TK(CPP_NAME, SPELL_IDENT) /* word */ \
+ TK(CPP_INT, SPELL_STRING) /* 23 */ \
+ TK(CPP_FLOAT, SPELL_STRING) /* 3.14159 */ \
+ TK(CPP_NUMBER, SPELL_STRING) /* 34_be+ta */ \
+\
+ TK(CPP_CHAR, SPELL_STRING) /* 'char' */ \
+ TK(CPP_WCHAR, SPELL_STRING) /* L'char' */ \
+ TK(CPP_OTHER, SPELL_CHAR) /* stray punctuation */ \
+\
+ TK(CPP_STRING, SPELL_STRING) /* "string" */ \
+ TK(CPP_WSTRING, SPELL_STRING) /* L"string" */ \
+ TK(CPP_HEADER_NAME, SPELL_STRING) /* <stdio.h> in #include */ \
+\
+ TK(CPP_COMMENT, SPELL_STRING) /* Only if output comments. */ \
+ TK(CPP_MACRO_ARG, SPELL_NONE) /* Macro argument. */ \
+ OP(CPP_EOF, "EOL") /* End of line or file. */
+
+#define OP(e, s) e,
+#define TK(e, s) e,
+enum cpp_ttype
+{
+ TTYPE_TABLE
+ N_TTYPES
+};
+#undef OP
+#undef TK
+
+/* C language kind, used when calling cpp_reader_init. */
+enum c_lang {CLK_GNUC89 = 0, CLK_GNUC99, CLK_STDC89, CLK_STDC94, CLK_STDC99,
+ CLK_GNUCXX, CLK_CXX98, CLK_OBJC, CLK_OBJCXX, CLK_ASM};
+
+/* Payload of a NUMBER, FLOAT, STRING, or COMMENT token. */
+struct cpp_string
+{
+ unsigned int len;
+ const unsigned char *text;
+};
+
+/* Flags for the cpp_token structure. */
+#define PREV_WHITE (1 << 0) /* If whitespace before this token. */
+#define DIGRAPH (1 << 1) /* If it was a digraph. */
+#define STRINGIFY_ARG (1 << 2) /* If macro argument to be stringified. */
+#define PASTE_LEFT (1 << 3) /* If on LHS of a ## operator. */
+#define NAMED_OP (1 << 4) /* C++ named operators. */
+#define NO_EXPAND (1 << 5) /* Do not macro-expand this token. */
+#define AVOID_LPASTE (1 << 6) /* Check left for accidental pastes. */
+
+/* A preprocessing token. This has been carefully packed and should
+ occupy 12 bytes on 32-bit hosts and 16 bytes on 64-bit hosts. */
+struct cpp_token
+{
+ ENUM_BITFIELD(cpp_ttype) type : CHAR_BIT; /* token type */
+ unsigned char flags; /* flags - see above */
+
+ union
+ {
+ cpp_hashnode *node; /* An identifier. */
+ struct cpp_string str; /* A string, or number. */
+ unsigned int arg_no; /* Argument no. for a CPP_MACRO_ARG. */
+ unsigned char c; /* Character represented by CPP_OTHER. */
+ } val;
+};
+
+/* The position of a token in the current file. */
+struct cpp_lexer_pos
+{
+ unsigned int line;
+ unsigned int output_line;
+ unsigned short col;
+};
+
+typedef struct cpp_token_with_pos cpp_token_with_pos;
+struct cpp_token_with_pos
+{
+ cpp_token token;
+ cpp_lexer_pos pos;
+};
+
+/* Token lookahead. */
+struct cpp_lookahead
+{
+ struct cpp_lookahead *next;
+ cpp_token_with_pos *tokens;
+ cpp_lexer_pos pos;
+ unsigned int cur, count, cap;
+};
+
+/* A standalone character. We may want to make it unsigned for the
+ same reason we use unsigned char - to avoid signedness issues. */
+typedef int cppchar_t;
+
+/* Values for opts.dump_macros.
+ dump_only means inhibit output of the preprocessed text
+ and instead output the definitions of all user-defined
+ macros in a form suitable for use as input to cpp.
+ dump_names means pass #define and the macro name through to output.
+ dump_definitions means pass the whole definition (plus #define) through
+*/
+enum { dump_none = 0, dump_only, dump_names, dump_definitions };
+
+/* This structure is nested inside struct cpp_reader, and
+ carries all the options visible to the command line. */
+struct cpp_options
+{
+ /* Name of input and output files. */
+ const char *in_fname;
+ const char *out_fname;
+
+ /* Characters between tab stops. */
+ unsigned int tabstop;
+
+ /* Pending options - -D, -U, -A, -I, -ixxx. */
+ struct cpp_pending *pending;
+
+ /* File name which deps are being written to. This is 0 if deps are
+ being written to stdout. */
+ const char *deps_file;
+
+ /* Search paths for include files. */
+ struct search_path *quote_include; /* "" */
+ struct search_path *bracket_include; /* <> */
+
+ /* Map between header names and file names, used only on DOS where
+ file names are limited in length. */
+ struct file_name_map_list *map_list;
+
+ /* Directory prefix that should replace `/usr/lib/gcc-lib/TARGET/VERSION'
+ in the standard include file directories. */
+ const char *include_prefix;
+ unsigned int include_prefix_len;
+
+ /* -fleading_underscore sets this to "_". */
+ const char *user_label_prefix;
+
+ /* The language we're preprocessing. */
+ enum c_lang lang;
+
+ /* Non-0 means -v, so print the full set of include dirs. */
+ unsigned char verbose;
+
+ /* Nonzero means use extra default include directories for C++. */
+ unsigned char cplusplus;
+
+ /* Nonzero means handle cplusplus style comments */
+ unsigned char cplusplus_comments;
+
+ /* Nonzero means handle #import, for objective C. */
+ unsigned char objc;
+
+ /* Nonzero means don't copy comments into the output file. */
+ unsigned char discard_comments;
+
+ /* Nonzero means process the ISO trigraph sequences. */
+ unsigned char trigraphs;
+
+ /* Nonzero means process the ISO digraph sequences. */
+ unsigned char digraphs;
+
+ /* Nonzero means to allow hexadecimal floats and LL suffixes. */
+ unsigned char extended_numbers;
+
+ /* Nonzero means print the names of included files rather than the
+ preprocessed output. 1 means just the #include "...", 2 means
+ #include <...> as well. */
+ unsigned char print_deps;
+
+ /* Nonzero if phony targets are created for each header. */
+ unsigned char deps_phony_targets;
+
+ /* Nonzero if missing .h files in -M output are assumed to be
+ generated files and not errors. */
+ unsigned char print_deps_missing_files;
+
+ /* If true, fopen (deps_file, "a") else fopen (deps_file, "w"). */
+ unsigned char print_deps_append;
+
+ /* Nonzero means print names of header files (-H). */
+ unsigned char print_include_names;
+
+ /* Nonzero means cpp_pedwarn causes a hard error. */
+ unsigned char pedantic_errors;
+
+ /* Nonzero means don't print warning messages. */
+ unsigned char inhibit_warnings;
+
+ /* Nonzero means don't suppress warnings from system headers. */
+ unsigned char warn_system_headers;
+
+ /* Nonzero means don't print error messages. Has no option to
+ select it, but can be set by a user of cpplib (e.g. fix-header). */
+ unsigned char inhibit_errors;
+
+ /* Nonzero means warn if slash-star appears in a comment. */
+ unsigned char warn_comments;
+
+ /* Nonzero means warn if there are any trigraphs. */
+ unsigned char warn_trigraphs;
+
+ /* Nonzero means warn if #import is used. */
+ unsigned char warn_import;
+
+ /* Nonzero means warn about various incompatibilities with
+ traditional C. */
+ unsigned char warn_traditional;
+
+ /* Nonzero means turn warnings into errors. */
+ unsigned char warnings_are_errors;
+
+ /* Nonzero causes output not to be done, but directives such as
+ #define that have side effects are still obeyed. */
+ unsigned char no_output;
+
+ /* Nonzero means we should look for header.gcc files that remap file
+ names. */
+ unsigned char remap;
+
+ /* Nonzero means don't output line number information. */
+ unsigned char no_line_commands;
+
+ /* Nonzero means -I- has been seen, so don't look for #include "foo"
+ the source-file directory. */
+ unsigned char ignore_srcdir;
+
+ /* Zero means dollar signs are punctuation. */
+ unsigned char dollars_in_ident;
+
+ /* Nonzero means warn if undefined identifiers are evaluated in an #if. */
+ unsigned char warn_undef;
+
+ /* Nonzero for the 1999 C Standard, including corrigenda and amendments. */
+ unsigned char c99;
+
+ /* Nonzero means give all the error messages the ANSI standard requires. */
+ unsigned char pedantic;
+
+ /* Nonzero means we're looking at already preprocessed code, so don't
+ bother trying to do macro expansion and whatnot. */
+ unsigned char preprocessed;
+
+ /* Nonzero disables all the standard directories for headers. */
+ unsigned char no_standard_includes;
+
+ /* Nonzero disables the C++-specific standard directories for headers. */
+ unsigned char no_standard_cplusplus_includes;
+
+ /* Nonzero means dump macros in some fashion - see above. */
+ unsigned char dump_macros;
+
+ /* Nonzero means pass #include lines through to the output. */
+ unsigned char dump_includes;
+
+ /* Print column number in error messages. */
+ unsigned char show_column;
+
+ /* Treat C++ alternate operator names special. */
+ unsigned char operator_names;
+
+ /* True if --help, --version or --target-help appeared in the
+ options. Stand-alone CPP should then bail out after option
+ parsing; drivers might want to continue printing help. */
+ unsigned char help_only;
+};
+
+/* This structure is passed to the call back when changing file. */
+enum cpp_fc_reason {FC_ENTER = 0, FC_LEAVE, FC_RENAME};
+
+struct cpp_file_loc
+{
+ const char *filename;
+ unsigned int lineno;
+};
+
+typedef struct cpp_file_change cpp_file_change;
+struct cpp_file_change
+{
+ struct cpp_file_loc from; /* Line of #include or #line. */
+ struct cpp_file_loc to; /* Line after #include or #line, or start. */
+ enum cpp_fc_reason reason; /* Reason for change. */
+ unsigned char sysp; /* Nonzero if system header. */
+ unsigned char externc; /* Nonzero if wrapper needed. */
+};
+
+/* Call backs. */
+struct cpp_callbacks
+{
+ void (*file_change) PARAMS ((cpp_reader *, const cpp_file_change *));
+ void (*include) PARAMS ((cpp_reader *, const unsigned char *,
+ const cpp_token *));
+ void (*define) PARAMS ((cpp_reader *, cpp_hashnode *));
+ void (*undef) PARAMS ((cpp_reader *, cpp_hashnode *));
+ void (*poison) PARAMS ((cpp_reader *));
+ void (*ident) PARAMS ((cpp_reader *, const cpp_string *));
+ void (*def_pragma) PARAMS ((cpp_reader *));
+};
+
+#define CPP_FATAL_LIMIT 1000
+/* True if we have seen a "fatal" error. */
+#define CPP_FATAL_ERRORS(PFILE) (cpp_errors (PFILE) >= CPP_FATAL_LIMIT)
+
+/* Name under which this program was invoked. */
+extern const char *progname;
+
+/* Where does this buffer come from? A faked include, a source file,
+ a builtin macro, a command-line option, or a _Pragma operator. */
+enum cpp_buffer_type {BUF_FAKE, BUF_FILE, BUF_BUILTIN,
+ BUF_CL_OPTION, BUF_PRAGMA};
+
+/* The structure of a node in the hash table. The hash table has
+ entries for all identifiers: either macros defined by #define
+ commands (type NT_MACRO), assertions created with #assert
+ (NT_ASSERTION), or neither of the above (NT_VOID). Builtin macros
+ like __LINE__ are flagged NODE_BUILTIN. Poisioned identifiers are
+ flagged NODE_POISONED. NODE_OPERATOR (C++ only) indicates an
+ identifier that behaves like an operator such as "xor".
+ NODE_DIAGNOSTIC is for speed in lex_token: it indicates a
+ diagnostic may be required for this node. Currently this only
+ applies to __VA_ARGS__ and poisoned identifiers. */
+
+/* Hash node flags. */
+#define NODE_OPERATOR (1 << 0) /* C++ named operator. */
+#define NODE_POISONED (1 << 1) /* Poisoned identifier. */
+#define NODE_BUILTIN (1 << 2) /* Builtin macro. */
+#define NODE_DIAGNOSTIC (1 << 3) /* Possible diagnostic when lexed. */
+#define NODE_WARN (1 << 4) /* Warn if redefined or undefined. */
+
+/* Different flavors of hash node. */
+enum node_type
+{
+ NT_VOID = 0, /* No definition yet. */
+ NT_MACRO, /* A macro of some form. */
+ NT_ASSERTION /* Predicate for #assert. */
+};
+
+/* Different flavors of builtin macro. */
+enum builtin_type
+{
+ BT_SPECLINE = 0, /* `__LINE__' */
+ BT_DATE, /* `__DATE__' */
+ BT_FILE, /* `__FILE__' */
+ BT_BASE_FILE, /* `__BASE_FILE__' */
+ BT_INCLUDE_LEVEL, /* `__INCLUDE_LEVEL__' */
+ BT_TIME, /* `__TIME__' */
+ BT_STDC /* `__STDC__' */
+};
+
+#define CPP_HASHNODE(HNODE) ((cpp_hashnode *) (HNODE))
+#define HT_NODE(NODE) ((ht_identifier *) (NODE))
+#define NODE_LEN(NODE) HT_LEN (&(NODE)->ident)
+#define NODE_NAME(NODE) HT_STR (&(NODE)->ident)
+
+/* The common part of an identifier node shared amongst all 3 C front
+ ends. Also used to store CPP identifiers, which are a superset of
+ identifiers in the grammatical sense. */
+struct cpp_hashnode
+{
+ struct ht_identifier ident;
+ unsigned short arg_index; /* Macro argument index. */
+ unsigned char directive_index; /* Index into directive table. */
+ unsigned char rid_code; /* Rid code - for front ends. */
+ ENUM_BITFIELD(node_type) type : 8; /* CPP node type. */
+ unsigned char flags; /* CPP flags. */
+
+ union
+ {
+ cpp_macro *macro; /* If a macro. */
+ struct answer *answers; /* Answers to an assertion. */
+ enum cpp_ttype operator; /* Code for a named operator. */
+ enum builtin_type builtin; /* Code for a builtin macro. */
+ } value;
+};
+
+/* Call this first to get a handle to pass to other functions. If you
+ want cpplib to manage its own hashtable, pass in a NULL pointer.
+ Or you can pass in an initialised hash table that cpplib will use;
+ this technique is used by the C front ends. */
+extern cpp_reader *cpp_create_reader PARAMS ((struct ht *,
+ enum c_lang));
+
+/* Call this to release the handle. Any use of the handle after this
+ function returns is invalid. Returns cpp_errors (pfile). */
+extern int cpp_destroy PARAMS ((cpp_reader *));
+
+/* Call these to get pointers to the options and callback structures
+ for a given reader. These pointers are good until you call
+ cpp_finish on that reader. You can either edit the callbacks
+ through the pointer returned from cpp_get_callbacks, or set them
+ with cpp_set_callbacks. */
+extern cpp_options *cpp_get_options PARAMS ((cpp_reader *));
+extern cpp_callbacks *cpp_get_callbacks PARAMS ((cpp_reader *));
+extern void cpp_set_callbacks PARAMS ((cpp_reader *, cpp_callbacks *));
+
+/* Now call cpp_handle_option[s] to handle 1[or more] switches. The
+ return value is the number of arguments used. If
+ cpp_handle_options returns without using all arguments, it couldn't
+ understand the next switch. When there are no switches left, you
+ must call cpp_post_options before calling cpp_start_read. Only
+ after cpp_post_options are the contents of the cpp_options
+ structure reliable. */
+extern int cpp_handle_options PARAMS ((cpp_reader *, int, char **));
+extern int cpp_handle_option PARAMS ((cpp_reader *, int, char **));
+extern void cpp_post_options PARAMS ((cpp_reader *));
+
+/* Error count. */
+extern unsigned int cpp_errors PARAMS ((cpp_reader *));
+
+extern unsigned int cpp_token_len PARAMS ((const cpp_token *));
+extern unsigned char *cpp_token_as_text PARAMS ((cpp_reader *,
+ const cpp_token *));
+extern unsigned char *cpp_spell_token PARAMS ((cpp_reader *, const cpp_token *,
+ unsigned char *));
+extern void cpp_register_pragma PARAMS ((cpp_reader *,
+ const char *, const char *,
+ void (*) PARAMS ((cpp_reader *))));
+extern void cpp_register_pragma_space PARAMS ((cpp_reader *, const char *));
+
+extern int cpp_start_read PARAMS ((cpp_reader *, const char *));
+extern void cpp_finish PARAMS ((cpp_reader *));
+extern int cpp_avoid_paste PARAMS ((cpp_reader *, const cpp_token *,
+ const cpp_token *));
+extern enum cpp_ttype cpp_can_paste PARAMS ((cpp_reader *, const cpp_token *,
+ const cpp_token *, int *));
+extern void cpp_get_token PARAMS ((cpp_reader *, cpp_token *));
+extern const cpp_lexer_pos *cpp_get_line PARAMS ((cpp_reader *));
+extern const unsigned char *cpp_macro_definition PARAMS ((cpp_reader *,
+ const cpp_hashnode *));
+
+/* Evaluate a CPP_CHAR or CPP_WCHAR token. */
+extern HOST_WIDE_INT
+cpp_interpret_charconst PARAMS ((cpp_reader *, const cpp_token *,
+ int, int, unsigned int *));
+
+extern void cpp_define PARAMS ((cpp_reader *, const char *));
+extern void cpp_assert PARAMS ((cpp_reader *, const char *));
+extern void cpp_undef PARAMS ((cpp_reader *, const char *));
+extern void cpp_unassert PARAMS ((cpp_reader *, const char *));
+
+extern cpp_buffer *cpp_push_buffer PARAMS ((cpp_reader *,
+ const unsigned char *, size_t,
+ enum cpp_buffer_type,
+ const char *));
+extern cpp_buffer *cpp_pop_buffer PARAMS ((cpp_reader *));
+extern int cpp_defined PARAMS ((cpp_reader *, const unsigned char *, int));
+
+/* N.B. The error-message-printer prototypes have not been nicely
+ formatted because exgettext needs to see 'msgid' on the same line
+ as the name of the function in order to work properly. Only the
+ string argument gets a name in an effort to keep the lines from
+ getting ridiculously oversized. */
+
+extern void cpp_ice PARAMS ((cpp_reader *, const char *msgid, ...))
+ ATTRIBUTE_PRINTF_2;
+extern void cpp_fatal PARAMS ((cpp_reader *, const char *msgid, ...))
+ ATTRIBUTE_PRINTF_2;
+extern void cpp_error PARAMS ((cpp_reader *, const char *msgid, ...))
+ ATTRIBUTE_PRINTF_2;
+extern void cpp_warning PARAMS ((cpp_reader *, const char *msgid, ...))
+ ATTRIBUTE_PRINTF_2;
+extern void cpp_pedwarn PARAMS ((cpp_reader *, const char *msgid, ...))
+ ATTRIBUTE_PRINTF_2;
+extern void cpp_notice PARAMS ((cpp_reader *, const char *msgid, ...))
+ ATTRIBUTE_PRINTF_2;
+extern void cpp_error_with_line PARAMS ((cpp_reader *, int, int, const char *msgid, ...))
+ ATTRIBUTE_PRINTF_4;
+extern void cpp_warning_with_line PARAMS ((cpp_reader *, int, int, const char *msgid, ...))
+ ATTRIBUTE_PRINTF_4;
+extern void cpp_pedwarn_with_line PARAMS ((cpp_reader *, int, int, const char *msgid, ...))
+ ATTRIBUTE_PRINTF_4;
+extern void cpp_pedwarn_with_file_and_line PARAMS ((cpp_reader *, const char *, int, int, const char *msgid, ...))
+ ATTRIBUTE_PRINTF_5;
+extern void cpp_error_from_errno PARAMS ((cpp_reader *, const char *));
+extern void cpp_notice_from_errno PARAMS ((cpp_reader *, const char *));
+
+/* In cpplex.c */
+extern int cpp_ideq PARAMS ((const cpp_token *,
+ const char *));
+extern void cpp_output_line PARAMS ((cpp_reader *, FILE *));
+extern void cpp_output_token PARAMS ((const cpp_token *, FILE *));
+extern const char *cpp_type2name PARAMS ((enum cpp_ttype));
+extern unsigned int cpp_parse_escape PARAMS ((cpp_reader *,
+ const unsigned char **,
+ const unsigned char *,
+ unsigned HOST_WIDE_INT, int));
+
+/* In cpphash.c */
+
+/* Lookup an identifier in the hashtable. Puts the identifier in the
+ table if it is not already there. */
+extern cpp_hashnode *cpp_lookup PARAMS ((cpp_reader *,
+ const unsigned char *,
+ unsigned int));
+
+typedef int (*cpp_cb) PARAMS ((cpp_reader *, cpp_hashnode *, void *));
+extern void cpp_forall_identifiers PARAMS ((cpp_reader *,
+ cpp_cb, void *));
+
+/* In cppmacro.c */
+extern void cpp_scan_buffer_nooutput PARAMS ((cpp_reader *, int));
+extern void cpp_start_lookahead PARAMS ((cpp_reader *));
+extern void cpp_stop_lookahead PARAMS ((cpp_reader *, int));
+extern int cpp_sys_macro_p PARAMS ((cpp_reader *));
+
+/* In cppfiles.c */
+extern int cpp_included PARAMS ((cpp_reader *, const char *));
+extern void cpp_make_system_header PARAMS ((cpp_reader *, int, int));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! GCC_CPPLIB_H */
--- /dev/null
+/* Part of CPP library. (Macro and #define handling.)
+ Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1998,
+ 1999, 2000, 2001 Free Software Foundation, Inc.
+ Written by Per Bothner, 1994.
+ Based on CCCP program by Paul Rubin, June 1986
+ Adapted to ANSI C, Richard Stallman, Jan 1987
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ In other words, you are welcome to use, share and improve this program.
+ You are forbidden to forbid anyone else to use, share and improve
+ what you give them. Help stamp out software-hoarding! */
+
+#include "config.h"
+#include "system.h"
+#include "intl.h" /* for _("<command line>") below. */
+#include "cpplib.h"
+#include "cpphash.h"
+
+struct cpp_macro
+{
+ cpp_hashnode **params; /* Parameters, if any. */
+ cpp_token *expansion; /* First token of replacement list. */
+ const char *file; /* Defined in file name. */
+ unsigned int line; /* Starting line number. */
+ unsigned int count; /* Number of tokens in expansion. */
+ unsigned short paramc; /* Number of parameters. */
+ unsigned int fun_like : 1; /* If a function-like macro. */
+ unsigned int variadic : 1; /* If a variadic macro. */
+ unsigned int disabled : 1; /* If macro is disabled. */
+ unsigned int syshdr : 1; /* If macro defined in system header. */
+};
+
+typedef struct macro_arg macro_arg;
+struct macro_arg
+{
+ cpp_token *first; /* First token in unexpanded argument. */
+ cpp_token *expanded; /* Macro-expanded argument. */
+ cpp_token *stringified; /* Stringified argument. */
+ unsigned int count; /* # of tokens in argument. */
+ unsigned int expanded_count; /* # of tokens in expanded argument. */
+};
+
+/* Macro expansion. */
+
+static void lock_pools PARAMS ((cpp_reader *));
+static void unlock_pools PARAMS ((cpp_reader *));
+static int enter_macro_context PARAMS ((cpp_reader *, cpp_hashnode *));
+static void builtin_macro PARAMS ((cpp_reader *, cpp_token *));
+static cpp_context *push_arg_context PARAMS ((cpp_reader *, macro_arg *));
+static enum cpp_ttype parse_arg PARAMS ((cpp_reader *, macro_arg *, int));
+static macro_arg *parse_args PARAMS ((cpp_reader *, const cpp_hashnode *));
+static cpp_context *next_context PARAMS ((cpp_reader *));
+static void expand_arg PARAMS ((cpp_reader *, macro_arg *));
+static unsigned char *quote_string PARAMS ((unsigned char *,
+ const unsigned char *,
+ unsigned int));
+static void make_string_token PARAMS ((cpp_pool *, cpp_token *,
+ const U_CHAR *, unsigned int));
+static void make_number_token PARAMS ((cpp_reader *, cpp_token *, int));
+static void stringify_arg PARAMS ((cpp_reader *, macro_arg *));
+static void paste_all_tokens PARAMS ((cpp_reader *, cpp_token *));
+static int paste_tokens PARAMS ((cpp_reader *, cpp_token *, cpp_token *));
+static int funlike_invocation_p PARAMS ((cpp_reader *, const cpp_hashnode *,
+ struct toklist *));
+static void replace_args PARAMS ((cpp_reader *, cpp_macro *, macro_arg *,
+ struct toklist *));
+
+/* Lookaheads. */
+
+static void save_lookahead_token PARAMS ((cpp_reader *, const cpp_token *));
+static void take_lookahead_token PARAMS ((cpp_reader *, cpp_token *));
+static cpp_lookahead *alloc_lookahead PARAMS ((cpp_reader *));
+static void free_lookahead PARAMS ((cpp_lookahead *));
+
+/* #define directive parsing and handling. */
+
+static cpp_token *lex_expansion_token PARAMS ((cpp_reader *, cpp_macro *));
+static int warn_of_redefinition PARAMS ((cpp_reader *, const cpp_hashnode *,
+ const cpp_macro *));
+static int save_parameter PARAMS ((cpp_reader *, cpp_macro *, cpp_hashnode *));
+static int parse_params PARAMS ((cpp_reader *, cpp_macro *));
+static void check_trad_stringification PARAMS ((cpp_reader *,
+ const cpp_macro *,
+ const cpp_string *));
+
+/* Allocates a buffer to hold a token's TEXT, and converts TOKEN to a
+ CPP_STRING token containing TEXT in quoted form. */
+static void
+make_string_token (pool, token, text, len)
+ cpp_pool *pool;
+ cpp_token *token;
+ const U_CHAR *text;
+ unsigned int len;
+{
+ U_CHAR *buf = _cpp_pool_alloc (pool, len * 4 + 1);
+
+ token->type = CPP_STRING;
+ token->val.str.text = buf;
+ token->val.str.len = quote_string (buf, text, len) - buf;
+ buf[token->val.str.len] = '\0';
+ token->flags = 0;
+}
+
+/* Allocates and converts a temporary token to a CPP_NUMBER token,
+ evaluating to NUMBER. */
+static void
+make_number_token (pfile, token, number)
+ cpp_reader *pfile;
+ cpp_token *token;
+ int number;
+{
+ unsigned char *buf = _cpp_pool_alloc (&pfile->ident_pool, 20);
+
+ sprintf ((char *) buf, "%d", number);
+ token->type = CPP_NUMBER;
+ token->val.str.text = buf;
+ token->val.str.len = ustrlen (buf);
+ token->flags = 0;
+}
+
+static const char * const monthnames[] =
+{
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+
+/* Handle builtin macros like __FILE__. */
+static void
+builtin_macro (pfile, token)
+ cpp_reader *pfile;
+ cpp_token *token;
+{
+ unsigned char flags = ((token->flags & PREV_WHITE) | AVOID_LPASTE);
+ cpp_hashnode *node = token->val.node;
+
+ switch (node->value.builtin)
+ {
+ case BT_FILE:
+ case BT_BASE_FILE:
+ {
+ const char *name;
+ cpp_buffer *buffer = pfile->buffer;
+
+ if (node->value.builtin == BT_BASE_FILE)
+ while (buffer->prev)
+ buffer = buffer->prev;
+
+ name = buffer->nominal_fname;
+ make_string_token (&pfile->ident_pool, token,
+ (const unsigned char *) name, strlen (name));
+ }
+ break;
+
+ case BT_INCLUDE_LEVEL:
+ /* pfile->include_depth counts the primary source as level 1,
+ but historically __INCLUDE_DEPTH__ has called the primary
+ source level 0. */
+ make_number_token (pfile, token, pfile->include_depth - 1);
+ break;
+
+ case BT_SPECLINE:
+ /* If __LINE__ is embedded in a macro, it must expand to the
+ line of the macro's invocation, not its definition.
+ Otherwise things like assert() will not work properly. */
+ make_number_token (pfile, token, cpp_get_line (pfile)->line);
+ break;
+
+ case BT_STDC:
+ {
+ int stdc = (!CPP_IN_SYSTEM_HEADER (pfile)
+ || pfile->spec_nodes.n__STRICT_ANSI__->type != NT_VOID);
+ make_number_token (pfile, token, stdc);
+ }
+ break;
+
+ case BT_DATE:
+ case BT_TIME:
+ if (pfile->date.type == CPP_EOF)
+ {
+ /* Allocate __DATE__ and __TIME__ from permanent storage,
+ and save them in pfile so we don't have to do this again.
+ We don't generate these strings at init time because
+ time() and localtime() are very slow on some systems. */
+ time_t tt = time (NULL);
+ struct tm *tb = localtime (&tt);
+
+ make_string_token (&pfile->ident_pool, &pfile->date,
+ DSC("Oct 11 1347"));
+ make_string_token (&pfile->ident_pool, &pfile->time,
+ DSC("12:34:56"));
+
+ sprintf ((char *) pfile->date.val.str.text, "%s %2d %4d",
+ monthnames[tb->tm_mon], tb->tm_mday, tb->tm_year + 1900);
+ sprintf ((char *) pfile->time.val.str.text, "%02d:%02d:%02d",
+ tb->tm_hour, tb->tm_min, tb->tm_sec);
+ }
+ *token = node->value.builtin == BT_DATE ? pfile->date: pfile->time;
+ break;
+
+ default:
+ cpp_ice (pfile, "invalid builtin macro \"%s\"", NODE_NAME (node));
+ break;
+ }
+
+ token->flags = flags;
+}
+
+/* Used by cpperror.c to obtain the correct line and column to report
+ in a diagnostic. */
+const cpp_lexer_pos *
+cpp_get_line (pfile)
+ cpp_reader *pfile;
+{
+ return &pfile->lexer_pos;
+}
+
+static void
+lock_pools (pfile)
+ cpp_reader *pfile;
+{
+ _cpp_lock_pool (&pfile->argument_pool);
+}
+
+static void
+unlock_pools (pfile)
+ cpp_reader *pfile;
+{
+ _cpp_unlock_pool (&pfile->argument_pool);
+}
+
+/* Adds backslashes before all backslashes and double quotes appearing
+ in strings. Non-printable characters are converted to octal. */
+static U_CHAR *
+quote_string (dest, src, len)
+ U_CHAR *dest;
+ const U_CHAR *src;
+ unsigned int len;
+{
+ while (len--)
+ {
+ U_CHAR c = *src++;
+
+ if (c == '\\' || c == '"')
+ {
+ *dest++ = '\\';
+ *dest++ = c;
+ }
+ else
+ {
+ if (ISPRINT (c))
+ *dest++ = c;
+ else
+ {
+ sprintf ((char *) dest, "\\%03o", c);
+ dest += 4;
+ }
+ }
+ }
+
+ return dest;
+}
+
+/* Convert a token sequence to a single string token according to the
+ rules of the ISO C #-operator. */
+static void
+stringify_arg (pfile, arg)
+ cpp_reader *pfile;
+ macro_arg *arg;
+{
+ cpp_pool *pool = &pfile->ident_pool;
+ unsigned char *start = POOL_FRONT (pool);
+ unsigned int i, escape_it, total_len = 0, backslash_count = 0;
+
+ /* Loop, reading in the argument's tokens. */
+ for (i = 0; i < arg->count; i++)
+ {
+ unsigned char *dest;
+ const cpp_token *token = &arg->first[i];
+ unsigned int len = cpp_token_len (token);
+
+ escape_it = (token->type == CPP_STRING || token->type == CPP_WSTRING
+ || token->type == CPP_CHAR || token->type == CPP_WCHAR);
+
+ if (escape_it)
+ /* Worst case is each char is octal. */
+ len *= 4;
+ len += 2; /* Room for initial space and final NUL. */
+
+ dest = &start[total_len];
+ if (dest + len > POOL_LIMIT (pool))
+ {
+ _cpp_next_chunk (pool, len, (unsigned char **) &start);
+ dest = &start[total_len];
+ }
+
+ /* No leading white space. */
+ if (token->flags & PREV_WHITE && total_len > 0)
+ *dest++ = ' ';
+
+ if (escape_it)
+ {
+ unsigned char *buf = (unsigned char *) xmalloc (len);
+
+ len = cpp_spell_token (pfile, token, buf) - buf;
+ dest = quote_string (dest, buf, len);
+ free (buf);
+ }
+ else
+ dest = cpp_spell_token (pfile, token, dest);
+ total_len = dest - start;
+
+ if (token->type == CPP_OTHER && token->val.c == '\\')
+ backslash_count++;
+ else
+ backslash_count = 0;
+ }
+
+ /* Ignore the final \ of invalid string literals. */
+ if (backslash_count & 1)
+ {
+ cpp_warning (pfile, "invalid string literal, ignoring final '\\'");
+ total_len--;
+ }
+
+ /* Null terminate, and commit the memory. */
+ start[total_len] = '\0';
+ POOL_COMMIT (pool, total_len + 1);
+
+ arg->stringified = xnew (cpp_token);
+ arg->stringified->flags = 0;
+ arg->stringified->type = CPP_STRING;
+ arg->stringified->val.str.text = start;
+ arg->stringified->val.str.len = total_len;
+}
+
+/* Try to paste two tokens. On success, the LHS becomes the pasted
+ token, and 0 is returned. For failure, we update the flags of the
+ RHS appropriately and return non-zero. */
+static int
+paste_tokens (pfile, lhs, rhs)
+ cpp_reader *pfile;
+ cpp_token *lhs, *rhs;
+{
+ unsigned char flags;
+ int digraph = 0;
+ enum cpp_ttype type;
+
+ type = cpp_can_paste (pfile, lhs, rhs, &digraph);
+
+ if (type == CPP_EOF)
+ {
+ /* Mandatory warning for all apart from assembler. */
+ if (CPP_OPTION (pfile, lang) != CLK_ASM)
+ cpp_warning (pfile,
+ "pasting \"%s\" and \"%s\" does not give a valid preprocessing token",
+ cpp_token_as_text (pfile, lhs),
+ cpp_token_as_text (pfile, rhs));
+
+ /* The standard states that behaviour is undefined. By the
+ principle of least surpise, we step back before the RHS, and
+ mark it to prevent macro expansion. Tests in the testsuite
+ rely on clearing PREV_WHITE here, though you could argue we
+ should actually set it. Assembler can have '.' in labels and
+ so requires that we don't insert spaces there. Maybe we should
+ change this to put out a space unless it's assembler. */
+ rhs->flags &= ~PREV_WHITE;
+ rhs->flags |= NO_EXPAND;
+ return 1;
+ }
+
+ flags = lhs->flags & ~DIGRAPH;
+ if (digraph)
+ flags |= DIGRAPH;
+
+ /* Identifiers and numbers need spellings to be pasted. */
+ if (type == CPP_NAME || type == CPP_NUMBER)
+ {
+ unsigned int total_len = cpp_token_len (lhs) + cpp_token_len (rhs);
+ unsigned char *result, *end;
+
+ result = _cpp_pool_alloc (&pfile->ident_pool, total_len + 1);
+
+ /* Paste the spellings and null terminate. */
+ end = cpp_spell_token (pfile, rhs, cpp_spell_token (pfile, lhs, result));
+ *end = '\0';
+ total_len = end - result;
+
+ if (type == CPP_NAME)
+ {
+ lhs->val.node = cpp_lookup (pfile, result, total_len);
+ if (lhs->val.node->flags & NODE_OPERATOR)
+ {
+ flags |= NAMED_OP;
+ lhs->type = lhs->val.node->value.operator;
+ }
+ }
+ else
+ {
+ lhs->val.str.text = result;
+ lhs->val.str.len = total_len;
+ }
+ }
+ else if (type == CPP_WCHAR || type == CPP_WSTRING)
+ lhs->val.str = rhs->val.str;
+
+ /* Set type and flags after pasting spellings. */
+ lhs->type = type;
+ lhs->flags = flags;
+
+ return 0;
+}
+
+/* Handles an arbitrarily long sequence of ## operators. This
+ implementation is left-associative, non-recursive, and finishes a
+ paste before handling succeeding ones. If the paste fails, we back
+ up a token to just after the ## operator, with the effect that it
+ appears in the output stream normally. */
+static void
+paste_all_tokens (pfile, lhs)
+ cpp_reader *pfile;
+ cpp_token *lhs;
+{
+ cpp_token *rhs;
+ unsigned char orig_flags = lhs->flags;
+
+ do
+ {
+ /* Take the token directly from the current context. We can do
+ this, because we are in the replacement list of either an
+ object-like macro, or a function-like macro with arguments
+ inserted. In either case, the constraints to #define
+ guarantee we have at least one more token. */
+ rhs = pfile->context->list.first++;
+ if (paste_tokens (pfile, lhs, rhs))
+ {
+ /* We failed. Step back so we read the RHS in next. */
+ pfile->context->list.first--;
+ break;
+ }
+ }
+ while (rhs->flags & PASTE_LEFT);
+
+ /* The pasted token has the PREV_WHITE flag of the LHS, is no longer
+ PASTE_LEFT, and is subject to macro expansion. */
+ lhs->flags &= ~(PREV_WHITE | PASTE_LEFT | NO_EXPAND);
+ lhs->flags |= orig_flags & (PREV_WHITE | AVOID_LPASTE);
+}
+
+/* Reads the unexpanded tokens of a macro argument into ARG. VAR_ARGS
+ is non-zero if this is a variadic macro. Returns the type of the
+ token that caused reading to finish. */
+static enum cpp_ttype
+parse_arg (pfile, arg, variadic)
+ cpp_reader *pfile;
+ struct macro_arg *arg;
+ int variadic;
+{
+ enum cpp_ttype result;
+ unsigned int paren = 0;
+ unsigned int line;
+
+ arg->first = (cpp_token *) POOL_FRONT (&pfile->argument_pool);
+ for (;; arg->count++)
+ {
+ cpp_token *token = &arg->first[arg->count];
+ if ((unsigned char *) (token + 1) >= POOL_LIMIT (&pfile->argument_pool))
+ {
+ _cpp_next_chunk (&pfile->argument_pool, sizeof (cpp_token),
+ (unsigned char **) &arg->first);
+ token = &arg->first[arg->count];
+ }
+
+ /* Newlines in arguments are white space (6.10.3.10). */
+ line = pfile->lexer_pos.output_line;
+ cpp_get_token (pfile, token);
+ if (line != pfile->lexer_pos.output_line)
+ token->flags |= PREV_WHITE;
+
+ result = token->type;
+ if (result == CPP_OPEN_PAREN)
+ paren++;
+ else if (result == CPP_CLOSE_PAREN && paren-- == 0)
+ break;
+ /* Commas are not terminators within parantheses or variadic. */
+ else if (result == CPP_COMMA && paren == 0 && !variadic)
+ break;
+ else if (result == CPP_EOF)
+ break; /* Error reported by caller. */
+ }
+
+ /* Commit the memory used to store the arguments. */
+ POOL_COMMIT (&pfile->argument_pool, arg->count * sizeof (cpp_token));
+
+ return result;
+}
+
+/* Parse the arguments making up a macro invocation. */
+static macro_arg *
+parse_args (pfile, node)
+ cpp_reader *pfile;
+ const cpp_hashnode *node;
+{
+ cpp_macro *macro = node->value.macro;
+ macro_arg *args, *cur;
+ enum cpp_ttype type;
+ int argc, error = 0;
+
+ /* Allocate room for at least one argument, and zero it out. */
+ argc = macro->paramc ? macro->paramc: 1;
+ args = xcnewvec (macro_arg, argc);
+
+ for (cur = args, argc = 0; ;)
+ {
+ argc++;
+
+ type = parse_arg (pfile, cur, argc == macro->paramc && macro->variadic);
+ if (type == CPP_CLOSE_PAREN || type == CPP_EOF)
+ break;
+
+ /* Re-use the last argument for excess arguments. */
+ if (argc < macro->paramc)
+ cur++;
+ }
+
+ if (type == CPP_EOF)
+ {
+ cpp_error (pfile, "unterminated argument list invoking macro \"%s\"",
+ NODE_NAME (node));
+ error = 1;
+ }
+ else if (argc < macro->paramc)
+ {
+ /* As an extension, a rest argument is allowed to not appear in
+ the invocation at all.
+ e.g. #define debug(format, args...) something
+ debug("string");
+
+ This is exactly the same as if there had been an empty rest
+ argument - debug("string", ). */
+
+ if (argc + 1 == macro->paramc && macro->variadic)
+ {
+ if (CPP_PEDANTIC (pfile) && ! macro->syshdr)
+ cpp_pedwarn (pfile, "ISO C99 requires rest arguments to be used");
+ }
+ else
+ {
+ cpp_error (pfile,
+ "macro \"%s\" requires %u arguments, but only %u given",
+ NODE_NAME (node), macro->paramc, argc);
+ error = 1;
+ }
+ }
+ else if (argc > macro->paramc)
+ {
+ /* Empty argument to a macro taking no arguments is OK. */
+ if (argc != 1 || cur->count)
+ {
+ cpp_error (pfile,
+ "macro \"%s\" passed %u arguments, but takes just %u",
+ NODE_NAME (node), argc, macro->paramc);
+ error = 1;
+ }
+ }
+
+ if (error)
+ {
+ free (args);
+ args = 0;
+ }
+
+ return args;
+}
+
+static int
+funlike_invocation_p (pfile, node, list)
+ cpp_reader *pfile;
+ const cpp_hashnode *node;
+ struct toklist *list;
+{
+ cpp_context *orig;
+ cpp_token maybe_paren;
+ macro_arg *args = 0;
+ cpp_lexer_pos macro_pos;
+
+ macro_pos = pfile->lexer_pos;
+ pfile->state.parsing_args = 1;
+ pfile->state.prevent_expansion++;
+ orig = pfile->context;
+
+ cpp_start_lookahead (pfile);
+ cpp_get_token (pfile, &maybe_paren);
+ cpp_stop_lookahead (pfile, maybe_paren.type == CPP_OPEN_PAREN);
+ pfile->state.parsing_args = 2;
+
+ if (maybe_paren.type == CPP_OPEN_PAREN)
+ args = parse_args (pfile, node);
+ else if (CPP_WTRADITIONAL (pfile) && ! node->value.macro->syshdr)
+ cpp_warning (pfile,
+ "function-like macro \"%s\" must be used with arguments in traditional C",
+ NODE_NAME (node));
+
+ /* Restore original context. */
+ pfile->context = orig;
+ pfile->state.prevent_expansion--;
+ pfile->state.parsing_args = 0;
+
+ /* Reset the position in case of failure. If success, the macro's
+ expansion appears where the name would have. */
+ pfile->lexer_pos = macro_pos;
+
+ if (args)
+ {
+ if (node->value.macro->paramc > 0)
+ {
+ /* Don't save tokens during pre-expansion. */
+ struct cpp_lookahead *la_saved = pfile->la_write;
+ pfile->la_write = 0;
+ replace_args (pfile, node->value.macro, args, list);
+ pfile->la_write = la_saved;
+ }
+ free (args);
+ }
+
+ return args != 0;
+}
+
+/* Push the context of a macro onto the context stack. TOKEN is the
+ macro name. If we can successfully start expanding the macro,
+ TOKEN is replaced with the first token of the expansion, and we
+ return non-zero. */
+static int
+enter_macro_context (pfile, node)
+ cpp_reader *pfile;
+ cpp_hashnode *node;
+{
+ cpp_context *context;
+ cpp_macro *macro = node->value.macro;
+ struct toklist list;
+
+ /* Save the position of the outermost macro invocation. */
+ if (!pfile->context->prev)
+ lock_pools (pfile);
+
+ if (macro->fun_like && !funlike_invocation_p (pfile, node, &list))
+ {
+ if (!pfile->context->prev)
+ unlock_pools (pfile);
+ return 0;
+ }
+
+ if (macro->paramc == 0)
+ {
+ list.first = macro->expansion;
+ list.limit = macro->expansion + macro->count;
+ }
+
+ /* Only push a macro context for non-empty replacement lists. */
+ if (list.first != list.limit)
+ {
+ context = next_context (pfile);
+ context->list = list;
+ context->macro = macro;
+
+ /* Disable the macro within its expansion. */
+ macro->disabled = 1;
+ }
+
+ return 1;
+}
+
+/* Move to the next context. Create one if there is none. */
+static cpp_context *
+next_context (pfile)
+ cpp_reader *pfile;
+{
+ cpp_context *prev = pfile->context;
+ cpp_context *result = prev->next;
+
+ if (result == 0)
+ {
+ result = xnew (cpp_context);
+ prev->next = result;
+ result->prev = prev;
+ result->next = 0;
+ }
+
+ pfile->context = result;
+ return result;
+}
+
+static void
+replace_args (pfile, macro, args, list)
+ cpp_reader *pfile;
+ cpp_macro *macro;
+ macro_arg *args;
+ struct toklist *list;
+{
+ unsigned char flags = 0;
+ unsigned int i, total;
+ const cpp_token *src, *limit;
+ cpp_token *dest;
+ macro_arg *arg;
+
+ src = macro->expansion;
+ limit = src + macro->count;
+
+ /* First, fully macro-expand arguments, calculating the number of
+ tokens in the final expansion as we go. This ensures that the
+ possible recursive use of argument_pool is fine. */
+ total = limit - src;
+ for (; src < limit; src++)
+ if (src->type == CPP_MACRO_ARG)
+ {
+ /* We have an argument. If it is not being stringified or
+ pasted it is macro-replaced before insertion. */
+ arg = &args[src->val.arg_no - 1];
+
+ if (src->flags & STRINGIFY_ARG)
+ {
+ if (!arg->stringified)
+ stringify_arg (pfile, arg);
+ }
+ else if ((src->flags & PASTE_LEFT)
+ || (src > macro->expansion && (src[-1].flags & PASTE_LEFT)))
+ total += arg->count - 1;
+ else
+ {
+ if (!arg->expanded)
+ {
+ arg->expanded_count = 0;
+ if (arg->count)
+ expand_arg (pfile, arg);
+ }
+ total += arg->expanded_count - 1;
+ }
+ }
+
+ dest = (cpp_token *) _cpp_pool_alloc (&pfile->argument_pool,
+ total * sizeof (cpp_token));
+ list->first = dest;
+
+ for (src = macro->expansion; src < limit; src++)
+ if (src->type == CPP_MACRO_ARG)
+ {
+ unsigned int count;
+ const cpp_token *from;
+
+ arg = &args[src->val.arg_no - 1];
+ if (src->flags & STRINGIFY_ARG)
+ from = arg->stringified, count = 1;
+ else if (src->flags & PASTE_LEFT)
+ count = arg->count, from = arg->first;
+ else if (src > macro->expansion && (src[-1].flags & PASTE_LEFT))
+ {
+ count = arg->count, from = arg->first;
+ if (dest != list->first)
+ {
+ /* GCC has special semantics for , ## b where b is a
+ varargs parameter: the comma disappears if b was
+ given no actual arguments (not merely if b is an
+ empty argument); otherwise pasting is turned off. */
+ if (dest[-1].type == CPP_COMMA
+ && macro->variadic
+ && src->val.arg_no == macro->paramc)
+ {
+ if (count == 0)
+ dest--;
+ else
+ dest[-1].flags &= ~PASTE_LEFT;
+ }
+ /* Count == 0 is the RHS a placemarker case. */
+ else if (count == 0)
+ dest[-1].flags &= ~PASTE_LEFT;
+ }
+ }
+ else
+ count = arg->expanded_count, from = arg->expanded;
+
+ /* Count == 0 is the LHS a placemarker case. */
+ if (count)
+ {
+ memcpy (dest, from, count * sizeof (cpp_token));
+
+ /* The first token gets PREV_WHITE of the CPP_MACRO_ARG. */
+ dest->flags &= ~PREV_WHITE;
+ dest->flags |= src->flags & PREV_WHITE;
+ dest->flags |= AVOID_LPASTE;
+
+ /* The last token gets the PASTE_LEFT of the CPP_MACRO_ARG. */
+ dest[count - 1].flags |= src->flags & PASTE_LEFT;
+
+ dest += count;
+ }
+
+ /* The token after the argument must avoid an accidental paste. */
+ flags = AVOID_LPASTE;
+ }
+ else
+ {
+ *dest = *src;
+ dest->flags |= flags;
+ dest++;
+ flags = 0;
+ }
+
+ list->limit = dest;
+
+ /* Free the expanded arguments. */
+ for (i = 0; i < macro->paramc; i++)
+ {
+ if (args[i].expanded)
+ free (args[i].expanded);
+ if (args[i].stringified)
+ free (args[i].stringified);
+ }
+}
+
+/* Subroutine of expand_arg to put the unexpanded tokens on the
+ context stack. */
+static cpp_context *
+push_arg_context (pfile, arg)
+ cpp_reader *pfile;
+ macro_arg *arg;
+{
+ cpp_context *context = next_context (pfile);
+ context->macro = 0;
+ context->list.first = arg->first;
+ context->list.limit = arg->first + arg->count;
+
+ return context;
+}
+
+static void
+expand_arg (pfile, arg)
+ cpp_reader *pfile;
+ macro_arg *arg;
+{
+ cpp_token *token;
+ unsigned int capacity = 256;
+
+ /* Loop, reading in the arguments. */
+ arg->expanded = (cpp_token *) xmalloc (capacity * sizeof (cpp_token));
+
+ push_arg_context (pfile, arg);
+ do
+ {
+ if (arg->expanded_count >= capacity)
+ {
+ capacity *= 2;
+ arg->expanded = (cpp_token *)
+ xrealloc (arg->expanded, capacity * sizeof (cpp_token));
+ }
+ token = &arg->expanded[arg->expanded_count++];
+ cpp_get_token (pfile, token);
+ }
+ while (token->type != CPP_EOF);
+
+ arg->expanded_count--;
+
+ /* Pop the context we pushed. */
+ pfile->context = pfile->context->prev;
+}
+
+void
+_cpp_pop_context (pfile)
+ cpp_reader *pfile;
+{
+ cpp_context *context = pfile->context;
+
+ pfile->context = context->prev;
+ if (!pfile->context->prev && !pfile->state.parsing_args)
+ unlock_pools (pfile);
+
+ /* Re-enable a macro, temporarily if parsing_args, when leaving its
+ expansion. */
+ context->macro->disabled = 0;
+}
+
+/* Eternal routine to get a token. Also used nearly everywhere
+ internally, except for places where we know we can safely call
+ the lexer directly, such as lexing a directive name.
+
+ Macro expansions and directives are transparently handled,
+ including entering included files. Thus tokens are post-macro
+ expansion, and after any intervening directives. External callers
+ see CPP_EOF only at EOF. Internal callers also see it when meeting
+ a directive inside a macro call, when at the end of a directive and
+ state.in_directive is still 1, and at the end of argument
+ pre-expansion. */
+void
+cpp_get_token (pfile, token)
+ cpp_reader *pfile;
+ cpp_token *token;
+{
+ for (;;)
+ {
+ cpp_context *context = pfile->context;
+
+ if (pfile->la_read)
+ take_lookahead_token (pfile, token);
+ /* Context->prev == 0 <=> base context. */
+ else if (!context->prev)
+ _cpp_lex_token (pfile, token);
+ else if (context->list.first != context->list.limit)
+ {
+ *token = *context->list.first++;
+ token->flags |= pfile->buffer->saved_flags;
+ pfile->buffer->saved_flags = 0;
+ /* PASTE_LEFT tokens can only appear in macro expansions. */
+ if (token->flags & PASTE_LEFT)
+ {
+ paste_all_tokens (pfile, token);
+ pfile->buffer->saved_flags = AVOID_LPASTE;
+ }
+ }
+ else
+ {
+ if (context->macro)
+ {
+ /* Avoid accidental paste at the end of a macro. */
+ pfile->buffer->saved_flags |= AVOID_LPASTE;
+ _cpp_pop_context (pfile);
+ continue;
+ }
+ /* End of argument pre-expansion. */
+ token->type = CPP_EOF;
+ token->flags = 0;
+ return;
+ }
+
+ if (token->type != CPP_NAME)
+ break;
+
+ /* Handle macros and the _Pragma operator. */
+ if (token->val.node->type == NT_MACRO
+ && !pfile->state.prevent_expansion
+ && !(token->flags & NO_EXPAND))
+ {
+ cpp_hashnode *node = token->val.node;
+
+ /* Macros invalidate controlling macros. */
+ pfile->mi_state = MI_FAILED;
+
+ if (node->flags & NODE_BUILTIN)
+ {
+ builtin_macro (pfile, token);
+ pfile->buffer->saved_flags = AVOID_LPASTE;
+ break;
+ }
+
+ if (node->value.macro->disabled)
+ token->flags |= NO_EXPAND;
+ else if (enter_macro_context (pfile, node))
+ {
+ /* Pass AVOID_LPASTE and our PREV_WHITE to next token. */
+ pfile->buffer->saved_flags = ((token->flags & PREV_WHITE)
+ | AVOID_LPASTE);
+ continue;
+ }
+ }
+
+ /* Don't interpret _Pragma within directives. The standard is
+ not clear on this, but to me this makes most sense. */
+ if (token->val.node != pfile->spec_nodes.n__Pragma
+ || pfile->state.in_directive)
+ break;
+
+ /* Handle it, and loop back for another token. MI is cleared
+ since this token came from either the lexer or a macro. */
+ _cpp_do__Pragma (pfile);
+ }
+
+ if (pfile->la_write)
+ save_lookahead_token (pfile, token);
+}
+
+/* Returns true if we're expanding an object-like macro that was
+ defined in a system header. Just checks the macro at the top of
+ the stack. Used for diagnostic suppression. */
+int
+cpp_sys_macro_p (pfile)
+ cpp_reader *pfile;
+{
+ cpp_macro *macro = pfile->context->macro;
+
+ return macro && macro->syshdr;
+}
+
+/* Read each token in, until EOF. Directives are transparently
+ processed. */
+void
+cpp_scan_buffer_nooutput (pfile, all_buffers)
+ cpp_reader *pfile;
+ int all_buffers;
+{
+ cpp_token token;
+ cpp_buffer *buffer = all_buffers ? 0: pfile->buffer->prev;
+
+ do
+ do
+ cpp_get_token (pfile, &token);
+ while (token.type != CPP_EOF);
+ while (cpp_pop_buffer (pfile) != buffer);
+}
+
+/* Lookahead handling. */
+
+static void
+save_lookahead_token (pfile, token)
+ cpp_reader *pfile;
+ const cpp_token *token;
+{
+ if (token->type != CPP_EOF)
+ {
+ cpp_lookahead *la = pfile->la_write;
+ cpp_token_with_pos *twp;
+
+ if (la->count == la->cap)
+ {
+ la->cap += la->cap + 8;
+ la->tokens = (cpp_token_with_pos *)
+ xrealloc (la->tokens, la->cap * sizeof (cpp_token_with_pos));
+ }
+
+ twp = &la->tokens[la->count++];
+ twp->token = *token;
+ twp->pos = *cpp_get_line (pfile);
+ }
+}
+
+static void
+take_lookahead_token (pfile, token)
+ cpp_reader *pfile;
+ cpp_token *token;
+{
+ cpp_lookahead *la = pfile->la_read;
+ cpp_token_with_pos *twp = &la->tokens[la->cur];
+
+ *token = twp->token;
+ pfile->lexer_pos = twp->pos;
+
+ if (++la->cur == la->count)
+ _cpp_release_lookahead (pfile);
+}
+
+/* Moves the lookahead at the front of the read list to the free store. */
+void
+_cpp_release_lookahead (pfile)
+ cpp_reader *pfile;
+{
+ cpp_lookahead *la = pfile->la_read;
+
+ pfile->la_read = la->next;
+ la->next = pfile->la_unused;
+ pfile->la_unused = la;
+ unlock_pools (pfile);
+}
+
+/* Take a new lookahead from the free store, or allocate one if none. */
+static cpp_lookahead *
+alloc_lookahead (pfile)
+ cpp_reader *pfile;
+{
+ cpp_lookahead *la = pfile->la_unused;
+
+ if (la)
+ pfile->la_unused = la->next;
+ else
+ {
+ la = xnew (cpp_lookahead);
+ la->tokens = 0;
+ la->cap = 0;
+ }
+
+ la->cur = la->count = 0;
+ return la;
+}
+
+/* Free memory associated with a lookahead list. */
+static void
+free_lookahead (la)
+ cpp_lookahead *la;
+{
+ if (la->tokens)
+ free ((PTR) la->tokens);
+ free ((PTR) la);
+}
+
+/* Free all the lookaheads of a cpp_reader. */
+void
+_cpp_free_lookaheads (pfile)
+ cpp_reader *pfile;
+{
+ cpp_lookahead *la, *lan;
+
+ if (pfile->la_read)
+ free_lookahead (pfile->la_read);
+ if (pfile->la_write)
+ free_lookahead (pfile->la_write);
+
+ for (la = pfile->la_unused; la; la = lan)
+ {
+ lan = la->next;
+ free_lookahead (la);
+ }
+}
+
+/* Allocate a lookahead and move it to the front of the write list. */
+void
+cpp_start_lookahead (pfile)
+ cpp_reader *pfile;
+{
+ cpp_lookahead *la = alloc_lookahead (pfile);
+
+ la->next = pfile->la_write;
+ pfile->la_write = la;
+
+ la->pos = *cpp_get_line (pfile);
+
+ /* Don't allow memory pools to be re-used whilst we're reading ahead. */
+ lock_pools (pfile);
+}
+
+/* Stop reading ahead - either step back, or drop the read ahead. */
+void
+cpp_stop_lookahead (pfile, drop)
+ cpp_reader *pfile;
+ int drop;
+{
+ cpp_lookahead *la = pfile->la_write;
+
+ pfile->la_write = la->next;
+ la->next = pfile->la_read;
+ pfile->la_read = la;
+
+ if (drop || la->count == 0)
+ _cpp_release_lookahead (pfile);
+ else
+ pfile->lexer_pos = la->pos;
+}
+
+/* Push a single token back to the front of the queue. Only to be
+ used by cpplib, and only then when necessary. POS is the position
+ to report for the preceding token. */
+void
+_cpp_push_token (pfile, token, pos)
+ cpp_reader *pfile;
+ const cpp_token *token;
+ const cpp_lexer_pos *pos;
+{
+ cpp_start_lookahead (pfile);
+ save_lookahead_token (pfile, token);
+ cpp_stop_lookahead (pfile, 0);
+ pfile->lexer_pos = *pos;
+}
+
+/* #define directive parsing and handling. */
+
+/* Returns non-zero if a macro redefinition warning is required. */
+static int
+warn_of_redefinition (pfile, node, macro2)
+ cpp_reader *pfile;
+ const cpp_hashnode *node;
+ const cpp_macro *macro2;
+{
+ const cpp_macro *macro1;
+ unsigned int i;
+
+ /* Some redefinitions need to be warned about regardless. */
+ if (node->flags & NODE_WARN)
+ return 1;
+
+ if (! CPP_PEDANTIC (pfile))
+ return 0;
+
+ /* Redefinition of a macro is allowed if and only if the old and new
+ definitions are the same. (6.10.3 paragraph 2). */
+ macro1 = node->value.macro;
+
+ /* The quick failures. */
+ if (macro1->count != macro2->count
+ || macro1->paramc != macro2->paramc
+ || macro1->fun_like != macro2->fun_like
+ || macro1->variadic != macro2->variadic)
+ return 1;
+
+ /* Check each token. */
+ for (i = 0; i < macro1->count; i++)
+ if (! _cpp_equiv_tokens (¯o1->expansion[i], ¯o2->expansion[i]))
+ return 1;
+
+ /* Check parameter spellings. */
+ for (i = 0; i < macro1->paramc; i++)
+ if (macro1->params[i] != macro2->params[i])
+ return 1;
+
+ return 0;
+}
+
+/* Free the definition of hashnode H. */
+
+void
+_cpp_free_definition (h)
+ cpp_hashnode *h;
+{
+ /* Macros and assertions no longer have anything to free. */
+ h->type = NT_VOID;
+ /* Clear builtin flag in case of redefinition. */
+ h->flags &= ~NODE_BUILTIN;
+}
+
+static int
+save_parameter (pfile, macro, node)
+ cpp_reader *pfile;
+ cpp_macro *macro;
+ cpp_hashnode *node;
+{
+ cpp_hashnode **dest;
+
+ /* Constraint 6.10.3.6 - duplicate parameter names. */
+ if (node->arg_index)
+ {
+ cpp_error (pfile, "duplicate macro parameter \"%s\"", NODE_NAME (node));
+ return 1;
+ }
+
+ dest = ¯o->params[macro->paramc];
+
+ /* Check we have room for the parameters. */
+ if ((unsigned char *) (dest + 1) >= POOL_LIMIT (&pfile->macro_pool))
+ {
+ _cpp_next_chunk (&pfile->macro_pool, sizeof (cpp_hashnode *),
+ (unsigned char **) ¯o->params);
+ dest = ¯o->params[macro->paramc];
+ }
+
+ *dest = node;
+ node->arg_index = ++macro->paramc;
+ return 0;
+}
+
+static int
+parse_params (pfile, macro)
+ cpp_reader *pfile;
+ cpp_macro *macro;
+{
+ cpp_token token;
+ unsigned int prev_ident = 0;
+
+ macro->params = (cpp_hashnode **) POOL_FRONT (&pfile->macro_pool);
+ for (;;)
+ {
+ _cpp_lex_token (pfile, &token);
+
+ switch (token.type)
+ {
+ default:
+ cpp_error (pfile, "\"%s\" may not appear in macro parameter list",
+ cpp_token_as_text (pfile, &token));
+ return 0;
+
+ case CPP_NAME:
+ if (prev_ident)
+ {
+ cpp_error (pfile, "macro parameters must be comma-separated");
+ return 0;
+ }
+ prev_ident = 1;
+
+ if (save_parameter (pfile, macro, token.val.node))
+ return 0;
+ continue;
+
+ case CPP_CLOSE_PAREN:
+ if (prev_ident || macro->paramc == 0)
+ break;
+
+ /* Fall through to pick up the error. */
+ case CPP_COMMA:
+ if (!prev_ident)
+ {
+ cpp_error (pfile, "parameter name missing");
+ return 0;
+ }
+ prev_ident = 0;
+ continue;
+
+ case CPP_ELLIPSIS:
+ macro->variadic = 1;
+ if (!prev_ident)
+ {
+ save_parameter (pfile, macro, pfile->spec_nodes.n__VA_ARGS__);
+ pfile->state.va_args_ok = 1;
+ if (! CPP_OPTION (pfile, c99) && CPP_OPTION (pfile, pedantic))
+ cpp_pedwarn (pfile,
+ "anonymous variadic macros were introduced in C99");
+ }
+ else if (CPP_OPTION (pfile, pedantic))
+ cpp_pedwarn (pfile, "ISO C does not permit named variadic macros");
+
+ /* We're at the end, and just expect a closing parenthesis. */
+ _cpp_lex_token (pfile, &token);
+ if (token.type == CPP_CLOSE_PAREN)
+ break;
+ /* Fall through. */
+
+ case CPP_EOF:
+ cpp_error (pfile, "missing ')' in macro parameter list");
+ return 0;
+ }
+
+ /* Success. Commit the parameter array. */
+ POOL_COMMIT (&pfile->macro_pool,
+ macro->paramc * sizeof (cpp_hashnode *));
+ return 1;
+ }
+}
+
+/* Lex a token from a macro's replacement list. Translate it to a
+ CPP_MACRO_ARG if appropriate. */
+static cpp_token *
+lex_expansion_token (pfile, macro)
+ cpp_reader *pfile;
+ cpp_macro *macro;
+{
+ cpp_token *token = ¯o->expansion[macro->count];
+
+ /* Check we have room for the token. */
+ if ((unsigned char *) (token + 1) >= POOL_LIMIT (&pfile->macro_pool))
+ {
+ _cpp_next_chunk (&pfile->macro_pool, sizeof (cpp_token),
+ (unsigned char **) ¯o->expansion);
+ token = ¯o->expansion[macro->count];
+ }
+
+ macro->count++;
+ _cpp_lex_token (pfile, token);
+
+ /* Is this an argument? */
+ if (token->type == CPP_NAME && token->val.node->arg_index)
+ {
+ token->type = CPP_MACRO_ARG;
+ token->val.arg_no = token->val.node->arg_index;
+ }
+ else if (CPP_WTRADITIONAL (pfile) && macro->paramc > 0
+ && (token->type == CPP_STRING || token->type == CPP_CHAR))
+ check_trad_stringification (pfile, macro, &token->val.str);
+
+ return token;
+}
+
+/* Parse a macro and save its expansion. Returns non-zero on success. */
+int
+_cpp_create_definition (pfile, node)
+ cpp_reader *pfile;
+ cpp_hashnode *node;
+{
+ cpp_macro *macro;
+ cpp_token *token;
+ unsigned int i, ok = 1;
+
+ macro = (cpp_macro *) _cpp_pool_alloc (&pfile->macro_pool,
+ sizeof (cpp_macro));
+ macro->file = pfile->buffer->nominal_fname;
+ macro->line = pfile->directive_pos.line;
+ macro->params = 0;
+ macro->paramc = 0;
+ macro->fun_like = 0;
+ macro->variadic = 0;
+ macro->count = 0;
+ macro->expansion = (cpp_token *) POOL_FRONT (&pfile->macro_pool);
+
+ /* Get the first token of the expansion (or the '(' of a
+ function-like macro). */
+ token = lex_expansion_token (pfile, macro);
+ if (token->type == CPP_OPEN_PAREN && !(token->flags & PREV_WHITE))
+ {
+ if (!(ok = parse_params (pfile, macro)))
+ goto cleanup;
+ macro->count = 0;
+ macro->fun_like = 1;
+ /* Some of the pool may have been used for the parameter store. */
+ macro->expansion = (cpp_token *) POOL_FRONT (&pfile->macro_pool);
+ token = lex_expansion_token (pfile, macro);
+ }
+ else if (token->type != CPP_EOF && !(token->flags & PREV_WHITE))
+ cpp_pedwarn (pfile, "ISO C requires whitespace after the macro name");
+
+ /* Setting it here means we don't catch leading comments. */
+ pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
+
+ for (;;)
+ {
+ /* Check the stringifying # constraint 6.10.3.2.1 of
+ function-like macros when lexing the subsequent token. */
+ if (macro->count > 1 && token[-1].type == CPP_HASH && macro->fun_like)
+ {
+ if (token->type == CPP_MACRO_ARG)
+ {
+ token->flags &= ~PREV_WHITE;
+ token->flags |= STRINGIFY_ARG;
+ token->flags |= token[-1].flags & PREV_WHITE;
+ token[-1] = token[0];
+ macro->count--;
+ }
+ /* Let assembler get away with murder. */
+ else if (CPP_OPTION (pfile, lang) != CLK_ASM)
+ {
+ ok = 0;
+ cpp_error (pfile, "'#' is not followed by a macro parameter");
+ goto cleanup;
+ }
+ }
+
+ if (token->type == CPP_EOF)
+ break;
+
+ /* Paste operator constraint 6.10.3.3.1. */
+ if (token->type == CPP_PASTE)
+ {
+ /* Token-paste ##, can appear in both object-like and
+ function-like macros, but not at the ends. */
+ if (--macro->count > 0)
+ token = lex_expansion_token (pfile, macro);
+
+ if (macro->count == 0 || token->type == CPP_EOF)
+ {
+ ok = 0;
+ cpp_error (pfile,
+ "'##' cannot appear at either end of a macro expansion");
+ goto cleanup;
+ }
+
+ token[-1].flags |= PASTE_LEFT;
+ /* Give it a PREV_WHITE for -dM etc. */
+ token->flags |= PREV_WHITE;
+ }
+
+ token = lex_expansion_token (pfile, macro);
+ }
+
+ /* Don't count the CPP_EOF. */
+ macro->count--;
+
+ /* Clear the whitespace flag from the leading token. */
+ macro->expansion[0].flags &= ~PREV_WHITE;
+
+ /* Implement the macro-defined-to-itself optimisation. */
+ macro->disabled = (macro->count == 1 && !macro->fun_like
+ && macro->expansion[0].type == CPP_NAME
+ && macro->expansion[0].val.node == node);
+
+ /* To suppress some diagnostics. */
+ macro->syshdr = pfile->buffer->sysp != 0;
+
+ /* Commit the memory. */
+ POOL_COMMIT (&pfile->macro_pool, macro->count * sizeof (cpp_token));
+
+ if (node->type != NT_VOID)
+ {
+ if (warn_of_redefinition (pfile, node, macro))
+ {
+ cpp_pedwarn_with_line (pfile, pfile->directive_pos.line,
+ pfile->directive_pos.col,
+ "\"%s\" redefined", NODE_NAME (node));
+
+ if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
+ cpp_pedwarn_with_file_and_line (pfile,
+ node->value.macro->file,
+ node->value.macro->line, 1,
+ "this is the location of the previous definition");
+ }
+ _cpp_free_definition (node);
+ }
+
+ /* Enter definition in hash table. */
+ node->type = NT_MACRO;
+ node->value.macro = macro;
+ if (! ustrncmp (NODE_NAME (node), DSC ("__STDC_")))
+ node->flags |= NODE_WARN;
+
+ cleanup:
+
+ /* Stop the lexer accepting __VA_ARGS__. */
+ pfile->state.va_args_ok = 0;
+
+ /* Clear the fast argument lookup indices. */
+ for (i = macro->paramc; i-- > 0; )
+ macro->params[i]->arg_index = 0;
+
+ return ok;
+}
+
+/* Warn if a token in `string' matches one of the function macro
+ arguments in `info'. This function assumes that the macro is a
+ function macro and not an object macro. */
+static void
+check_trad_stringification (pfile, macro, string)
+ cpp_reader *pfile;
+ const cpp_macro *macro;
+ const cpp_string *string;
+{
+ unsigned int i, len;
+ const U_CHAR *p, *q, *limit = string->text + string->len;
+
+ /* Loop over the string. */
+ for (p = string->text; p < limit; p = q)
+ {
+ /* Find the start of an identifier. */
+ while (p < limit && !is_idstart (*p))
+ p++;
+
+ /* Find the end of the identifier. */
+ q = p;
+ while (q < limit && is_idchar (*q))
+ q++;
+
+ len = q - p;
+
+ /* Loop over the function macro arguments to see if the
+ identifier inside the string matches one of them. */
+ for (i = 0; i < macro->paramc; i++)
+ {
+ const cpp_hashnode *node = macro->params[i];
+
+ if (NODE_LEN (node) == len
+ && !memcmp (p, NODE_NAME (node), len))
+ {
+ cpp_warning (pfile,
+ "macro argument \"%s\" would be stringified with -traditional.",
+ NODE_NAME (node));
+ break;
+ }
+ }
+ }
+}
+
+/* Returns the name, arguments and expansion of a macro, in a format
+ suitable to be read back in again, and therefore also for DWARF 2
+ debugging info. e.g. "PASTE(X, Y) X ## Y", or "MACNAME EXPANSION".
+ Caller is expected to generate the "#define" bit if needed. The
+ returned text is temporary, and automatically freed later. */
+
+const unsigned char *
+cpp_macro_definition (pfile, node)
+ cpp_reader *pfile;
+ const cpp_hashnode *node;
+{
+ unsigned int i, len;
+ const cpp_macro *macro = node->value.macro;
+ unsigned char *buffer;
+
+ if (node->type != NT_MACRO || (node->flags & NODE_BUILTIN))
+ {
+ cpp_ice (pfile, "invalid hash type %d in cpp_macro_definition", node->type);
+ return 0;
+ }
+
+ /* Calculate length. */
+ len = NODE_LEN (node) + 1; /* ' ' */
+ if (macro->fun_like)
+ {
+ len += 3; /* "()" plus possible final "." of named
+ varargs (we have + 2 below). */
+ for (i = 0; i < macro->paramc; i++)
+ len += NODE_LEN (macro->params[i]) + 2; /* ", " */
+ }
+
+ for (i = 0; i < macro->count; i++)
+ {
+ cpp_token *token = ¯o->expansion[i];
+
+ if (token->type == CPP_MACRO_ARG)
+ len += NODE_LEN (macro->params[token->val.arg_no - 1]);
+ else
+ len += cpp_token_len (token); /* Includes room for ' '. */
+ if (token->flags & STRINGIFY_ARG)
+ len++; /* "#" */
+ if (token->flags & PASTE_LEFT)
+ len += 3; /* " ##" */
+ }
+
+ if (len > pfile->macro_buffer_len)
+ {
+ pfile->macro_buffer = (U_CHAR *) xrealloc (pfile->macro_buffer, len);
+ pfile->macro_buffer_len = len;
+ }
+
+ /* Fill in the buffer. Start with the macro name. */
+ buffer = pfile->macro_buffer;
+ memcpy (buffer, NODE_NAME (node), NODE_LEN (node));
+ buffer += NODE_LEN (node);
+
+ /* Parameter names. */
+ if (macro->fun_like)
+ {
+ *buffer++ = '(';
+ for (i = 0; i < macro->paramc; i++)
+ {
+ cpp_hashnode *param = macro->params[i];
+
+ if (param != pfile->spec_nodes.n__VA_ARGS__)
+ {
+ memcpy (buffer, NODE_NAME (param), NODE_LEN (param));
+ buffer += NODE_LEN (param);
+ }
+
+ if (i + 1 < macro->paramc)
+ *buffer++ = ',', *buffer++ = ' ';
+ else if (macro->variadic)
+ *buffer++ = '.', *buffer++ = '.', *buffer++ = '.';
+ }
+ *buffer++ = ')';
+ }
+
+ /* Expansion tokens. */
+ if (macro->count)
+ {
+ *buffer++ = ' ';
+ for (i = 0; i < macro->count; i++)
+ {
+ cpp_token *token = ¯o->expansion[i];
+
+ if (token->flags & PREV_WHITE)
+ *buffer++ = ' ';
+ if (token->flags & STRINGIFY_ARG)
+ *buffer++ = '#';
+
+ if (token->type == CPP_MACRO_ARG)
+ {
+ len = NODE_LEN (macro->params[token->val.arg_no - 1]);
+ memcpy (buffer,
+ NODE_NAME (macro->params[token->val.arg_no - 1]), len);
+ buffer += len;
+ }
+ else
+ buffer = cpp_spell_token (pfile, token, buffer);
+
+ if (token->flags & PASTE_LEFT)
+ {
+ *buffer++ = ' ';
+ *buffer++ = '#';
+ *buffer++ = '#';
+ /* Next has PREV_WHITE; see _cpp_create_definition. */
+ }
+ }
+ }
+
+ *buffer = '\0';
+ return pfile->macro_buffer;
+}
--- /dev/null
+/* CPP main program, using CPP Library.
+ Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001
+ Free Software Foundation, Inc.
+ Written by Per Bothner, 1994-95.
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ In other words, you are welcome to use, share and improve this program.
+ You are forbidden to forbid anyone else to use, share and improve
+ what you give them. Help stamp out software-hoarding! */
+
+#include "config.h"
+#include "system.h"
+#include "cpplib.h"
+#include "intl.h"
+
+/* Encapsulates state used to convert the stream of tokens coming from
+ cpp_get_token back into a text file. */
+struct printer
+{
+ FILE *outf; /* stream to write to. */
+ const char *last_fname; /* previous file name. */
+ const char *syshdr_flags; /* system header flags, if any. */
+ unsigned int lineno; /* line currently being written. */
+ unsigned char printed; /* nonzero if something output at lineno. */
+};
+
+int main PARAMS ((int, char **));
+static void general_init PARAMS ((const char *));
+static void do_preprocessing PARAMS ((int, char **));
+static void setup_callbacks PARAMS ((void));
+
+/* General output routines. */
+static void scan_buffer PARAMS ((cpp_reader *));
+static void check_multiline_token PARAMS ((cpp_string *));
+static int printer_init PARAMS ((cpp_reader *));
+static int dump_macro PARAMS ((cpp_reader *, cpp_hashnode *, void *));
+
+static void print_line PARAMS ((const char *));
+static void maybe_print_line PARAMS ((unsigned int));
+
+/* Callback routines for the parser. Most of these are active only
+ in specific modes. */
+static void cb_define PARAMS ((cpp_reader *, cpp_hashnode *));
+static void cb_undef PARAMS ((cpp_reader *, cpp_hashnode *));
+static void cb_include PARAMS ((cpp_reader *, const unsigned char *,
+ const cpp_token *));
+static void cb_ident PARAMS ((cpp_reader *, const cpp_string *));
+static void cb_file_change PARAMS ((cpp_reader *, const cpp_file_change *));
+static void cb_def_pragma PARAMS ((cpp_reader *));
+
+const char *progname; /* Needs to be global. */
+static cpp_reader *pfile; /* An opaque handle. */
+static cpp_options *options; /* Options of pfile. */
+static struct printer print;
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ general_init (argv[0]);
+
+ /* Contruct a reader with default language GNU C89. */
+ pfile = cpp_create_reader (NULL, CLK_GNUC89);
+ options = cpp_get_options (pfile);
+
+ do_preprocessing (argc, argv);
+
+ /* Call to cpp_destroy () omitted for performance reasons. */
+ if (cpp_errors (pfile))
+ return FATAL_EXIT_CODE;
+
+ return SUCCESS_EXIT_CODE;
+}
+
+/* Store the program name, and set the locale. */
+static void
+general_init (argv0)
+ const char *argv0;
+{
+ progname = argv0 + strlen (argv0);
+
+ while (progname != argv0 && ! IS_DIR_SEPARATOR (progname[-1]))
+ --progname;
+
+ xmalloc_set_program_name (progname);
+
+/* LC_CTYPE determines the character set used by the terminal so it
+ has to be set to output messages correctly. */
+
+#ifdef HAVE_LC_MESSAGES
+ setlocale (LC_CTYPE, "");
+ setlocale (LC_MESSAGES, "");
+#else
+ setlocale (LC_ALL, "");
+#endif
+
+ (void) bindtextdomain (PACKAGE, localedir);
+ (void) textdomain (PACKAGE);
+}
+
+/* Handle switches, preprocess and output. */
+static void
+do_preprocessing (argc, argv)
+ int argc;
+ char **argv;
+{
+ int argi = 1; /* Next argument to handle. */
+
+ argi += cpp_handle_options (pfile, argc - argi , argv + argi);
+ if (CPP_FATAL_ERRORS (pfile))
+ return;
+
+ if (argi < argc)
+ cpp_fatal (pfile, "Invalid option %s", argv[argi]);
+ else
+ cpp_post_options (pfile);
+
+ if (CPP_FATAL_ERRORS (pfile))
+ return;
+
+ /* If cpp_handle_options saw --help or --version on the command
+ line, it will have set pfile->help_only to indicate this. Exit
+ successfully. [The library does not exit itself, because
+ e.g. cc1 needs to print its own --help message at this point.] */
+ if (options->help_only)
+ return;
+
+ /* Open the output now. We must do so even if no_output is on,
+ because there may be other output than from the actual
+ preprocessing (e.g. from -dM). */
+ if (printer_init (pfile))
+ return;
+
+ setup_callbacks ();
+
+ if (cpp_start_read (pfile, options->in_fname))
+ {
+ /* A successful cpp_start_read guarantees that we can call
+ cpp_scan_buffer_nooutput or cpp_get_token next. */
+ if (options->no_output)
+ cpp_scan_buffer_nooutput (pfile, 1);
+ else
+ scan_buffer (pfile);
+
+ /* -dM command line option. Should this be in cpp_finish? */
+ if (options->dump_macros == dump_only)
+ cpp_forall_identifiers (pfile, dump_macro, NULL);
+
+ cpp_finish (pfile);
+ }
+
+ /* Flush any pending output. */
+ if (print.printed)
+ putc ('\n', print.outf);
+
+ if (ferror (print.outf) || fclose (print.outf))
+ cpp_notice_from_errno (pfile, options->out_fname);
+}
+
+/* Set up the callbacks as appropriate. */
+static void
+setup_callbacks ()
+{
+ cpp_callbacks *cb = cpp_get_callbacks (pfile);
+
+ if (! options->no_output)
+ {
+ cb->ident = cb_ident;
+ cb->def_pragma = cb_def_pragma;
+ if (! options->no_line_commands)
+ cb->file_change = cb_file_change;
+ }
+
+ if (options->dump_includes)
+ cb->include = cb_include;
+
+ if (options->dump_macros == dump_names
+ || options->dump_macros == dump_definitions)
+ {
+ cb->define = cb_define;
+ cb->undef = cb_undef;
+ cb->poison = cb_def_pragma;
+ }
+}
+
+/* Writes out the preprocessed file. Alternates between two tokens,
+ so that we can avoid accidental token pasting. */
+static void
+scan_buffer (pfile)
+ cpp_reader *pfile;
+{
+ unsigned int index, line;
+ cpp_token tokens[2], *token;
+
+ do
+ {
+ for (index = 0;; index = 1 - index)
+ {
+ token = &tokens[index];
+ cpp_get_token (pfile, token);
+
+ if (token->type == CPP_EOF)
+ break;
+
+ line = cpp_get_line (pfile)->output_line;
+ if (print.lineno != line)
+ {
+ unsigned int col = cpp_get_line (pfile)->col;
+
+ /* Supply enough whitespace to put this token in its original
+ column. Don't bother trying to reconstruct tabs; we can't
+ get it right in general, and nothing ought to care. (Yes,
+ some things do care; the fault lies with them.) */
+ maybe_print_line (line);
+ if (col > 1)
+ {
+ if (token->flags & PREV_WHITE)
+ col--;
+ while (--col)
+ putc (' ', print.outf);
+ }
+ }
+ else if ((token->flags & (PREV_WHITE | AVOID_LPASTE))
+ == AVOID_LPASTE
+ && cpp_avoid_paste (pfile, &tokens[1 - index], token))
+ token->flags |= PREV_WHITE;
+ /* Special case '# <directive name>': insert a space between
+ the # and the token. This will prevent it from being
+ treated as a directive when this code is re-preprocessed.
+ XXX Should do this only at the beginning of a line, but how? */
+ else if (token->type == CPP_NAME && token->val.node->directive_index
+ && tokens[1 - index].type == CPP_HASH)
+ token->flags |= PREV_WHITE;
+
+ cpp_output_token (token, print.outf);
+ print.printed = 1;
+ if (token->type == CPP_STRING || token->type == CPP_WSTRING
+ || token->type == CPP_COMMENT)
+ check_multiline_token (&token->val.str);
+ }
+ }
+ while (cpp_pop_buffer (pfile) != 0);
+}
+
+/* Adjust print.lineno for newlines embedded in tokens. */
+static void
+check_multiline_token (str)
+ cpp_string *str;
+{
+ unsigned int i;
+
+ for (i = 0; i < str->len; i++)
+ if (str->text[i] == '\n')
+ print.lineno++;
+}
+
+/* Initialize a cpp_printer structure. As a side effect, open the
+ output file. */
+static int
+printer_init (pfile)
+ cpp_reader *pfile;
+{
+ print.last_fname = 0;
+ print.lineno = 0;
+ print.printed = 0;
+
+ if (options->out_fname[0] == '\0')
+ print.outf = stdout;
+ else
+ {
+ print.outf = fopen (options->out_fname, "w");
+ if (! print.outf)
+ {
+ cpp_notice_from_errno (pfile, options->out_fname);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/* Newline-terminate any output line currently in progress. If
+ appropriate, write the current line number to the output, or pad
+ with newlines so the output line matches the current line. */
+static void
+maybe_print_line (line)
+ unsigned int line;
+{
+ /* End the previous line of text (probably only needed until we get
+ multi-line tokens fixed). */
+ if (print.printed)
+ {
+ putc ('\n', print.outf);
+ print.lineno++;
+ print.printed = 0;
+ }
+
+ if (options->no_line_commands)
+ {
+ print.lineno = line;
+ return;
+ }
+
+ /* print.lineno is zero if this is the first token of the file. We
+ handle this specially, so that a first line of "# 1 "foo.c" in
+ file foo.i outputs just the foo.c line, and not a foo.i line. */
+ if (line >= print.lineno && line < print.lineno + 8 && print.lineno)
+ {
+ while (line > print.lineno)
+ {
+ putc ('\n', print.outf);
+ print.lineno++;
+ }
+ }
+ else
+ {
+ print.lineno = line;
+ print_line ("");
+ }
+}
+
+static void
+print_line (special_flags)
+ const char *special_flags;
+{
+ /* End any previous line of text. */
+ if (print.printed)
+ putc ('\n', print.outf);
+ print.printed = 0;
+
+ /* SDCC likes #line, not # number. Should be fixed... */
+#if 0
+ fprintf (print.outf, "# %u \"%s\"%s%s\n",
+ print.lineno, print.last_fname, special_flags, print.syshdr_flags);
+#else
+ fprintf (print.outf, "#line %u \"%s\"%s%s\n",
+ print.lineno, print.last_fname, special_flags, print.syshdr_flags);
+#endif
+}
+
+/* Callbacks. */
+
+static void
+cb_ident (pfile, str)
+ cpp_reader *pfile ATTRIBUTE_UNUSED;
+ const cpp_string * str;
+{
+ maybe_print_line (cpp_get_line (pfile)->output_line);
+ fprintf (print.outf, "#ident \"%s\"\n", str->text);
+ print.lineno++;
+}
+
+static void
+cb_define (pfile, node)
+ cpp_reader *pfile;
+ cpp_hashnode *node;
+{
+ maybe_print_line (cpp_get_line (pfile)->output_line);
+ fputs ("#define ", print.outf);
+
+ /* -dD command line option. */
+ if (options->dump_macros == dump_definitions)
+ fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
+ else
+ fputs ((const char *) NODE_NAME (node), print.outf);
+
+ putc ('\n', print.outf);
+ print.lineno++;
+}
+
+static void
+cb_undef (pfile, node)
+ cpp_reader *pfile;
+ cpp_hashnode *node;
+{
+ maybe_print_line (cpp_get_line (pfile)->output_line);
+ fprintf (print.outf, "#undef %s\n", NODE_NAME (node));
+ print.lineno++;
+}
+
+static void
+cb_include (pfile, dir, header)
+ cpp_reader *pfile ATTRIBUTE_UNUSED;
+ const unsigned char *dir;
+ const cpp_token *header;
+{
+ maybe_print_line (cpp_get_line (pfile)->output_line);
+ fprintf (print.outf, "#%s %s\n", dir, cpp_token_as_text (pfile, header));
+ print.lineno++;
+}
+
+static void
+cb_file_change (pfile, fc)
+ cpp_reader *pfile ATTRIBUTE_UNUSED;
+ const cpp_file_change *fc;
+{
+ /* Bring current file to correct line (except first file). */
+ if (fc->reason == FC_ENTER && fc->from.filename)
+ maybe_print_line (fc->from.lineno);
+
+ print.last_fname = fc->to.filename;
+ if (fc->externc)
+ print.syshdr_flags = " 3 4";
+ else if (fc->sysp)
+ print.syshdr_flags = " 3";
+ else
+ print.syshdr_flags = "";
+
+ if (print.lineno)
+ {
+ const char *flags = "";
+
+ print.lineno = fc->to.lineno;
+ if (fc->reason == FC_ENTER)
+ flags = " 1";
+ else if (fc->reason == FC_LEAVE)
+ flags = " 2";
+
+ if (! options->no_line_commands)
+ print_line (flags);
+ }
+}
+
+static void
+cb_def_pragma (pfile)
+ cpp_reader *pfile;
+{
+ maybe_print_line (cpp_get_line (pfile)->output_line);
+ fputs ("#pragma ", print.outf);
+ cpp_output_line (pfile, print.outf);
+ print.lineno++;
+}
+
+/* Dump out the hash table. */
+static int
+dump_macro (pfile, node, v)
+ cpp_reader *pfile;
+ cpp_hashnode *node;
+ void *v ATTRIBUTE_UNUSED;
+{
+ if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
+ {
+ fputs ("#define ", print.outf);
+ fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
+ putc ('\n', print.outf);
+ print.lineno++;
+ }
+
+ return 1;
+}
--- /dev/null
+/* Hash tables.
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ In other words, you are welcome to use, share and improve this program.
+ You are forbidden to forbid anyone else to use, share and improve
+ what you give them. Help stamp out software-hoarding! */
+
+#include "config.h"
+#include "system.h"
+#include "hashtable.h"
+
+/* The code below is a specialization of Vladimir Makarov's expandable
+ hash tables (see libiberty/hashtab.c). The abstraction penalty was
+ too high to continue using the generic form. This code knows
+ intrinsically how to calculate a hash value, and how to compare an
+ existing entry with a potential new one. Also, the ability to
+ delete members from the table has been removed. */
+
+static unsigned int calc_hash PARAMS ((const unsigned char *, unsigned int));
+static void ht_expand PARAMS ((hash_table *));
+
+/* Let particular systems override the size of a chunk. */
+#ifndef OBSTACK_CHUNK_SIZE
+#define OBSTACK_CHUNK_SIZE 0
+#endif
+ /* Let them override the alloc and free routines too. */
+#ifndef OBSTACK_CHUNK_ALLOC
+#define OBSTACK_CHUNK_ALLOC malloc
+#endif
+#ifndef OBSTACK_CHUNK_FREE
+#define OBSTACK_CHUNK_FREE free
+#endif
+
+/* Initialise an obstack. */
+void
+gcc_obstack_init (obstack)
+ struct obstack *obstack;
+{
+ _obstack_begin (obstack, OBSTACK_CHUNK_SIZE, 0,
+ (void *(*) PARAMS ((long))) OBSTACK_CHUNK_ALLOC,
+ (void (*) PARAMS ((void *))) OBSTACK_CHUNK_FREE);
+}
+
+/* Calculate the hash of the string STR of length LEN. */
+
+static unsigned int
+calc_hash (str, len)
+ const unsigned char *str;
+ unsigned int len;
+{
+ unsigned int n = len;
+ unsigned int r = 0;
+#define HASHSTEP(r, c) ((r) * 67 + ((c) - 113));
+
+ while (n--)
+ r = HASHSTEP (r, *str++);
+
+ return r + len;
+#undef HASHSTEP
+}
+
+/* Initialize an identifier hashtable. */
+
+hash_table *
+ht_create (order)
+ unsigned int order;
+{
+ unsigned int nslots = 1 << order;
+ hash_table *table;
+
+ table = (hash_table *) xmalloc (sizeof (hash_table));
+ memset (table, 0, sizeof (hash_table));
+
+ /* Strings need no alignment. */
+ gcc_obstack_init (&table->stack);
+ obstack_alignment_mask (&table->stack) = 0;
+
+ table->entries = (hashnode *) xcalloc (nslots, sizeof (hashnode));
+ table->nslots = nslots;
+ return table;
+}
+
+/* Returns the hash entry for the a STR of length LEN. If that string
+ already exists in the table, returns the existing entry, and, if
+ INSERT is CPP_ALLOCED, frees the last obstack object. If the
+ identifier hasn't been seen before, and INSERT is CPP_NO_INSERT,
+ returns NULL. Otherwise insert and returns a new entry. A new
+ string is alloced if INSERT is CPP_ALLOC, otherwise INSERT is
+ CPP_ALLOCED and the item is assumed to be at the top of the
+ obstack. */
+hashnode
+ht_lookup (table, str, len, insert)
+ hash_table *table;
+ const unsigned char *str;
+ unsigned int len;
+ enum ht_lookup_option insert;
+{
+ unsigned int hash = calc_hash (str, len);
+ unsigned int hash2;
+ unsigned int index;
+ size_t sizemask;
+ hashnode node;
+
+ sizemask = table->nslots - 1;
+ index = hash & sizemask;
+
+ /* hash2 must be odd, so we're guaranteed to visit every possible
+ location in the table during rehashing. */
+ hash2 = ((hash * 17) & sizemask) | 1;
+ table->searches++;
+
+ for (;;)
+ {
+ node = table->entries[index];
+
+ if (node == NULL)
+ break;
+
+ if (HT_LEN (node) == len && !memcmp (HT_STR (node), str, len))
+ {
+ if (insert == HT_ALLOCED)
+ /* The string we search for was placed at the end of the
+ obstack. Release it. */
+ obstack_free (&table->stack, (PTR) str);
+ return node;
+ }
+
+ index = (index + hash2) & sizemask;
+ table->collisions++;
+ }
+
+ if (insert == HT_NO_INSERT)
+ return NULL;
+
+ node = (*table->alloc_node) (table);
+ table->entries[index] = node;
+
+ HT_LEN (node) = len;
+ if (insert == HT_ALLOC)
+ HT_STR (node) = obstack_copy (&table->stack, str, len + 1);
+ else
+ HT_STR (node) = str;
+
+ if (++table->nelements * 4 >= table->nslots * 3)
+ /* Must expand the string table. */
+ ht_expand (table);
+
+ return node;
+}
+
+/* Double the size of a hash table, re-hashing existing entries. */
+
+static void
+ht_expand (table)
+ hash_table *table;
+{
+ hashnode *nentries, *p, *limit;
+ unsigned int size, sizemask;
+
+ size = table->nslots * 2;
+ nentries = (hashnode *) xcalloc (size, sizeof (hashnode));
+ sizemask = size - 1;
+
+ p = table->entries;
+ limit = p + table->nslots;
+ do
+ if (*p)
+ {
+ unsigned int index, hash, hash2;
+
+ hash = calc_hash (HT_STR (*p), HT_LEN (*p));
+ hash2 = ((hash * 17) & sizemask) | 1;
+ index = hash & sizemask;
+
+ for (;;)
+ {
+ if (! nentries[index])
+ {
+ nentries[index] = *p;
+ break;
+ }
+
+ index = (index + hash2) & sizemask;
+ }
+ }
+ while (++p < limit);
+
+ free (table->entries);
+ table->entries = nentries;
+ table->nslots = size;
+}
+
+/* For all nodes in TABLE, callback CB with parameters TABLE->PFILE,
+ the node, and V. */
+void
+ht_forall (table, cb, v)
+ hash_table *table;
+ ht_cb cb;
+ const PTR v;
+{
+ hashnode *p, *limit;
+
+ p = table->entries;
+ limit = p + table->nslots;
+ do
+ if (*p)
+ {
+ if ((*cb) (table->pfile, *p, v) == 0)
+ break;
+ }
+ while (++p < limit);
+}
+
+/* Dump allocation statistics to stderr. */
+
+void
+ht_dump_statistics (table)
+ hash_table *table;
+{
+ size_t nelts, nids, overhead, headers;
+ size_t total_bytes, longest, sum_of_squares;
+ double exp_len, exp_len2, exp2_len;
+ hashnode *p, *limit;
+
+#define SCALE(x) ((unsigned long) ((x) < 1024*10 \
+ ? (x) \
+ : ((x) < 1024*1024*10 \
+ ? (x) / 1024 \
+ : (x) / (1024*1024))))
+#define LABEL(x) ((x) < 1024*10 ? ' ' : ((x) < 1024*1024*10 ? 'k' : 'M'))
+
+ total_bytes = longest = sum_of_squares = nids = 0;
+ p = table->entries;
+ limit = p + table->nslots;
+ do
+ if (*p)
+ {
+ size_t n = HT_LEN (*p);
+
+ total_bytes += n;
+ sum_of_squares += n * n;
+ if (n > longest)
+ longest = n;
+ nids++;
+ }
+ while (++p < limit);
+
+ nelts = table->nelements;
+ overhead = obstack_memory_used (&table->stack) - total_bytes;
+ headers = table->nslots * sizeof (hashnode);
+
+ fprintf (stderr, "\nString pool\nentries\t\t%lu\n",
+ (unsigned long) nelts);
+ fprintf (stderr, "identifiers\t%lu (%.2f%%)\n",
+ (unsigned long) nids, nids * 100.0 / nelts);
+ fprintf (stderr, "slots\t\t%lu\n",
+ (unsigned long) table->nslots);
+ fprintf (stderr, "bytes\t\t%lu%c (%lu%c overhead)\n",
+ SCALE (total_bytes), LABEL (total_bytes),
+ SCALE (overhead), LABEL (overhead));
+ fprintf (stderr, "table size\t%lu%c\n",
+ SCALE (headers), LABEL (headers));
+
+ exp_len = (double)total_bytes / (double)nelts;
+ exp2_len = exp_len * exp_len;
+ exp_len2 = (double) sum_of_squares / (double) nelts;
+
+ fprintf (stderr, "coll/search\t%.4f\n",
+ (double) table->collisions / (double) table->searches);
+ fprintf (stderr, "ins/search\t%.4f\n",
+ (double) nelts / (double) table->searches);
+ fprintf (stderr, "avg. entry\t%.2f bytes (+/- %.2f)\n",
+ exp_len, approx_sqrt (exp_len2 - exp2_len));
+ fprintf (stderr, "longest entry\t%lu\n",
+ (unsigned long) longest);
+#undef SCALE
+#undef LABEL
+}
+
+/* Return the approximate positive square root of a number N. This is for
+ statistical reports, not code generation. */
+double
+approx_sqrt (x)
+ double x;
+{
+ double s, d;
+
+ if (x < 0)
+ abort ();
+ if (x == 0)
+ return 0;
+
+ s = x;
+ do
+ {
+ d = (s * s - x) / (2 * s);
+ s -= d;
+ }
+ while (d > .0001);
+ return s;
+}
--- /dev/null
+/* Hash tables.
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef GCC_HASHTABLE_H
+#define GCC_HASHTABLE_H
+
+#include "obstack.h"
+
+/* This is what each hash table entry points to. It may be embedded
+ deeply within another object. */
+typedef struct ht_identifier ht_identifier;
+struct ht_identifier
+{
+ unsigned int len;
+ const unsigned char *str;
+};
+
+#define HT_LEN(NODE) ((NODE)->len)
+#define HT_STR(NODE) ((NODE)->str)
+
+/* We want code outside cpplib, such as the compiler front-ends, to be
+ able to include this header, and to be able to link with
+ cpphashtbl.o without pulling in any other parts of cpplib. */
+
+struct cpp_reader;
+typedef struct ht hash_table;
+typedef struct ht_identifier *hashnode;
+
+enum ht_lookup_option {HT_NO_INSERT = 0, HT_ALLOC, HT_ALLOCED};
+
+/* An identifier hash table for cpplib and the front ends. */
+struct ht
+{
+ /* Identifiers are allocated from here. */
+ struct obstack stack;
+
+ hashnode *entries;
+ /* Call back. */
+ hashnode (*alloc_node) PARAMS ((hash_table *));
+
+ unsigned int nslots; /* Total slots in the entries array. */
+ unsigned int nelements; /* Number of live elements. */
+
+ /* Link to reader, if any. For the benefit of cpplib. */
+ struct cpp_reader *pfile;
+
+ /* Table usage statistics. */
+ unsigned int searches;
+ unsigned int collisions;
+};
+
+extern void gcc_obstack_init PARAMS ((struct obstack *));
+/* Initialise the hashtable with 2 ^ order entries. */
+extern hash_table *ht_create PARAMS ((unsigned int order));
+extern hashnode ht_lookup PARAMS ((hash_table *, const unsigned char *,
+ unsigned int, enum ht_lookup_option));
+
+/* For all nodes in TABLE, make a callback. The callback takes
+ TABLE->PFILE, the node, and a PTR, and the callback sequence stops
+ if the callback returns zero. */
+typedef int (*ht_cb) PARAMS ((struct cpp_reader *, hashnode, const void *));
+extern void ht_forall PARAMS ((hash_table *, ht_cb, const void *));
+
+/* Dump allocation statistics to stderr. */
+extern void ht_dump_statistics PARAMS ((hash_table *));
+
+/* Approximate positive square root of a host double. This is for
+ statistical reports, not code generation. */
+extern double approx_sqrt PARAMS ((double));
+
+#endif /* GCC_HASHTABLE_H */
--- /dev/null
+/* HOST_WIDE_INT definitions for the GNU compiler.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+ This file is part of GNU CC.
+
+ Provide definitions for macros which depend on HOST_BITS_PER_INT
+ and HOST_BITS_PER_LONG. */
+
+#ifndef GCC_HWINT_H
+#define GCC_HWINT_H
+
+/* This describes the machine the compiler is hosted on. */
+#define HOST_BITS_PER_CHAR CHAR_BIT
+#define HOST_BITS_PER_SHORT (CHAR_BIT * SIZEOF_SHORT)
+#define HOST_BITS_PER_INT (CHAR_BIT * SIZEOF_INT)
+#define HOST_BITS_PER_LONG (CHAR_BIT * SIZEOF_LONG)
+
+#ifdef HAVE_LONG_LONG
+# define HOST_BITS_PER_LONGLONG (CHAR_BIT * SIZEOF_LONG_LONG)
+#else
+/* If we're here and we're GCC, assume this is stage 2+ of a bootstrap
+ and 'long long' has the width of the *target*'s long long. */
+# if GCC_VERSION > 3000
+# define HOST_BITS_PER_LONGLONG LONG_LONG_TYPE_SIZE
+# endif /* gcc */
+#endif /* no long long */
+
+/* Find the largest host integer type and set its size and type. */
+
+/* Use long long on the host if the target has a wider long type than
+ the host. */
+
+#if ! defined HOST_BITS_PER_WIDE_INT \
+ && defined HOST_BITS_PER_LONGLONG \
+ && (HOST_BITS_PER_LONGLONG > HOST_BITS_PER_LONG) \
+ && (defined (LONG_LONG_MAX) || defined (LONGLONG_MAX) \
+ || defined (LLONG_MAX) || defined (__GNUC__))
+
+# ifdef MAX_LONG_TYPE_SIZE
+# if MAX_LONG_TYPE_SIZE > HOST_BITS_PER_LONG
+# define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONGLONG
+# define HOST_WIDE_INT long long
+# endif
+# else
+# if LONG_TYPE_SIZE > HOST_BITS_PER_LONG
+# define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONGLONG
+# define HOST_WIDE_INT long long
+# endif
+# endif
+
+#endif
+
+#ifndef HOST_BITS_PER_WIDE_INT
+
+# if HOST_BITS_PER_LONG > HOST_BITS_PER_INT
+# define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONG
+# define HOST_WIDE_INT long
+# else
+# define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_INT
+# define HOST_WIDE_INT int
+# endif
+
+#endif /* ! HOST_BITS_PER_WIDE_INT */
+
+/* Provide defaults for the way to print a HOST_WIDE_INT
+ in various manners. */
+
+#ifndef HOST_WIDE_INT_PRINT_DEC
+# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
+# define HOST_WIDE_INT_PRINT_DEC "%d"
+# else
+# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
+# define HOST_WIDE_INT_PRINT_DEC "%ld"
+# else
+# define HOST_WIDE_INT_PRINT_DEC "%lld"
+# endif
+# endif
+#endif /* ! HOST_WIDE_INT_PRINT_DEC */
+
+#ifndef HOST_WIDE_INT_PRINT_UNSIGNED
+# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
+# define HOST_WIDE_INT_PRINT_UNSIGNED "%u"
+# else
+# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
+# define HOST_WIDE_INT_PRINT_UNSIGNED "%lu"
+# else
+# define HOST_WIDE_INT_PRINT_UNSIGNED "%llu"
+# endif
+# endif
+#endif /* ! HOST_WIDE_INT_PRINT_UNSIGNED */
+
+#ifndef HOST_WIDE_INT_PRINT_HEX
+# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
+# define HOST_WIDE_INT_PRINT_HEX "0x%x"
+# else
+# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
+# define HOST_WIDE_INT_PRINT_HEX "0x%lx"
+# else
+# define HOST_WIDE_INT_PRINT_HEX "0x%llx"
+# endif
+# endif
+#endif /* ! HOST_WIDE_INT_PRINT_HEX */
+
+#ifndef HOST_WIDE_INT_PRINT_DOUBLE_HEX
+# if HOST_BITS_PER_WIDE_INT == 64
+# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
+# define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%x%016x"
+# else
+# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
+# define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%lx%016lx"
+# else
+# define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%llx%016llx"
+# endif
+# endif
+# else
+# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
+# define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%x%08x"
+# else
+# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
+# define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%lx%08lx"
+# else
+# define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%llx%08llx"
+# endif
+# endif
+# endif
+#endif /* ! HOST_WIDE_INT_PRINT_DOUBLE_HEX */
+
+/* Find HOST_WIDEST_INT and set its bit size, type and print macros.
+ It will be the largest integer mode supported by the host which may
+ (or may not) be larger than HOST_WIDE_INT. */
+
+#ifndef HOST_WIDEST_INT
+#if defined HOST_BITS_PER_LONGLONG \
+ && HOST_BITS_PER_LONGLONG > HOST_BITS_PER_LONG
+# define HOST_BITS_PER_WIDEST_INT HOST_BITS_PER_LONGLONG
+# define HOST_WIDEST_INT long long
+# define HOST_WIDEST_INT_PRINT_DEC "%lld"
+# define HOST_WIDEST_INT_PRINT_UNSIGNED "%llu"
+# define HOST_WIDEST_INT_PRINT_HEX "0x%llx"
+# else
+# define HOST_BITS_PER_WIDEST_INT HOST_BITS_PER_LONG
+# define HOST_WIDEST_INT long
+# define HOST_WIDEST_INT_PRINT_DEC "%ld"
+# define HOST_WIDEST_INT_PRINT_UNSIGNED "%lu"
+# define HOST_WIDEST_INT_PRINT_HEX "0x%lx"
+# endif /* long long wider than long */
+#endif /* ! HOST_WIDEST_INT */
+
+#endif /* ! GCC_HWINT_H */
--- /dev/null
+/* intl.c - internationalization */
+
+#include "ansidecl.h"
+#include "intl.h"
+
+const char localedir[] = LOCALEDIR;
--- /dev/null
+/* intl.h - internationalization
+ Copyright 1998 Free Software Foundation, Inc.
+
+ GCC is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GCC 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 GCC; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifdef HAVE_LOCALE_H
+# include <locale.h>
+#endif
+
+#ifndef HAVE_SETLOCALE
+# define setlocale(category, locale) (locale)
+#endif
+
+#ifdef ENABLE_NLS
+# include <libintl.h>
+ extern const char localedir[];
+#else
+/* Stubs that do something close enough. */
+# ifdef textdomain
+# undef textdomain
+# endif
+# define textdomain(domain) (domain)
+# ifdef bindtextdomain
+# undef bindtextdomain
+# endif
+# define bindtextdomain(domain, directory) (domain)
+# ifdef gettext
+# undef gettext
+# endif
+# define gettext(msgid) (msgid)
+#endif
+
+#ifndef _
+# define _(msgid) gettext (msgid)
+#endif
+
+#ifndef N_
+# define N_(msgid) (msgid)
+#endif
--- /dev/null
+/* nada */
--- /dev/null
+/* Libiberty basename. Like basename, but is not overridden by the
+ system C library.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/*
+NAME
+ lbasename -- return pointer to last component of a pathname
+
+SYNOPSIS
+ char *lbasename (const char *name)
+
+DESCRIPTION
+ Given a pointer to a string containing a typical pathname
+ (/usr/src/cmd/ls/ls.c for example), returns a pointer to the
+ last component of the pathname ("ls.c" in this case). The
+ returned pointer is guaranteed to lie within the original
+ string. This latter fact is not true of many vendor C
+ libraries, which return special strings or modify the passed
+ strings for particular input.
+
+ In particular, the empty string returns the same empty string,
+ and a path ending in '/' returns the empty string after it.
+*/
+
+#include "ansidecl.h"
+#include "libiberty.h"
+#include "safe-ctype.h"
+
+#ifndef DIR_SEPARATOR
+# define DIR_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
+#endif
+
+/* Define IS_DIR_SEPARATOR. VMS uses '::', ':', '[...]' and '<...>' to
+ separate the different components of a file specification. It's a
+ bit of a stretch to call ':', ']' and '>' directory separators, so
+ just define the test to find the file name component. */
+#ifdef VMS
+# define IS_DIR_SEPARATOR(ch) ((ch) == ':' || (ch) == ']' || (ch) == '>')
+#else
+# ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+# else
+# define IS_DIR_SEPARATOR(ch) \
+ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+# endif
+#endif
+
+char *
+lbasename (name)
+ const char *name;
+{
+ const char *base;
+
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ /* Skip over a possible disk name. */
+ if (ISALPHA (name[0]) && name[1] == ':')
+ name += 2;
+#endif
+
+ for (base = name; *name; name++)
+ if (IS_DIR_SEPARATOR (*name))
+ base = name + 1;
+
+ return (char *) base;
+}
--- /dev/null
+/* obstack.c - subroutines used implicitly by object stack macros
+ Copyright (C) 1988,89,90,91,92,93,94,96,97 Free Software Foundation, Inc.
+
+
+ NOTE: This source is derived from an old version taken from the GNU C
+ Library (glibc).
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ USA. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "obstack.h"
+
+/* NOTE BEFORE MODIFYING THIS FILE: This version number must be
+ incremented whenever callers compiled using an old obstack.h can no
+ longer properly call the functions in this obstack.c. */
+#define OBSTACK_INTERFACE_VERSION 1
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+ actually compiling the library itself, and the installed library
+ supports the same library interface we do. This code is part of the GNU
+ C Library, but also included in many other GNU distributions. Compiling
+ and linking in this code is a waste when using the GNU C library
+ (especially if it is a shared library). Rather than having every GNU
+ program understand `configure --with-gnu-libc' and omit the object
+ files, it is simpler to just do this in the source for each such file. */
+
+#include <stdio.h> /* Random thing to get __GNU_LIBRARY__. */
+#if !defined (_LIBC) && defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1
+#include <gnu-versions.h>
+#if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION
+#define ELIDE_CODE
+#endif
+#endif
+
+
+#ifndef ELIDE_CODE
+
+
+#if defined (__STDC__) && __STDC__
+#define POINTER void *
+#else
+#define POINTER char *
+#endif
+
+/* Determine default alignment. */
+struct fooalign {char x; double d;};
+#define DEFAULT_ALIGNMENT \
+ ((PTR_INT_TYPE) ((char *) &((struct fooalign *) 0)->d - (char *) 0))
+/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
+ But in fact it might be less smart and round addresses to as much as
+ DEFAULT_ROUNDING. So we prepare for it to do that. */
+union fooround {long x; double d;};
+#define DEFAULT_ROUNDING (sizeof (union fooround))
+
+/* When we copy a long block of data, this is the unit to do it with.
+ On some machines, copying successive ints does not work;
+ in such a case, redefine COPYING_UNIT to `long' (if that works)
+ or `char' as a last resort. */
+#ifndef COPYING_UNIT
+#define COPYING_UNIT int
+#endif
+
+
+/* The functions allocating more room by calling `obstack_chunk_alloc'
+ jump to the handler pointed to by `obstack_alloc_failed_handler'.
+ This variable by default points to the internal function
+ `print_and_abort'. */
+#if defined (__STDC__) && __STDC__
+static void print_and_abort (void);
+void (*obstack_alloc_failed_handler) (void) = print_and_abort;
+#else
+static void print_and_abort ();
+void (*obstack_alloc_failed_handler) () = print_and_abort;
+#endif
+
+/* Exit value used when `print_and_abort' is used. */
+#if defined __GNU_LIBRARY__ || defined HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifndef EXIT_FAILURE
+#define EXIT_FAILURE 1
+#endif
+int obstack_exit_failure = EXIT_FAILURE;
+
+/* The non-GNU-C macros copy the obstack into this global variable
+ to avoid multiple evaluation. */
+
+struct obstack *_obstack;
+
+/* Define a macro that either calls functions with the traditional malloc/free
+ calling interface, or calls functions with the mmalloc/mfree interface
+ (that adds an extra first argument), based on the state of use_extra_arg.
+ For free, do not use ?:, since some compilers, like the MIPS compilers,
+ do not allow (expr) ? void : void. */
+
+#if defined (__STDC__) && __STDC__
+#define CALL_CHUNKFUN(h, size) \
+ (((h) -> use_extra_arg) \
+ ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
+ : (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size)))
+
+#define CALL_FREEFUN(h, old_chunk) \
+ do { \
+ if ((h) -> use_extra_arg) \
+ (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
+ else \
+ (*(void (*) (void *)) (h)->freefun) ((old_chunk)); \
+ } while (0)
+#else
+#define CALL_CHUNKFUN(h, size) \
+ (((h) -> use_extra_arg) \
+ ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
+ : (*(struct _obstack_chunk *(*) ()) (h)->chunkfun) ((size)))
+
+#define CALL_FREEFUN(h, old_chunk) \
+ do { \
+ if ((h) -> use_extra_arg) \
+ (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
+ else \
+ (*(void (*) ()) (h)->freefun) ((old_chunk)); \
+ } while (0)
+#endif
+
+\f
+/* Initialize an obstack H for use. Specify chunk size SIZE (0 means default).
+ Objects start on multiples of ALIGNMENT (0 means use default).
+ CHUNKFUN is the function to use to allocate chunks,
+ and FREEFUN the function to free them.
+
+ Return nonzero if successful, zero if out of memory.
+ To recover from an out of memory error,
+ free up some memory, then call this again. */
+
+int
+_obstack_begin (h, size, alignment, chunkfun, freefun)
+ struct obstack *h;
+ int size;
+ int alignment;
+#if defined (__STDC__) && __STDC__
+ POINTER (*chunkfun) (long);
+ void (*freefun) (void *);
+#else
+ POINTER (*chunkfun) ();
+ void (*freefun) ();
+#endif
+{
+ register struct _obstack_chunk *chunk; /* points to new chunk */
+
+ if (alignment == 0)
+ alignment = (int) DEFAULT_ALIGNMENT;
+ if (size == 0)
+ /* Default size is what GNU malloc can fit in a 4096-byte block. */
+ {
+ /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
+ Use the values for range checking, because if range checking is off,
+ the extra bytes won't be missed terribly, but if range checking is on
+ and we used a larger request, a whole extra 4096 bytes would be
+ allocated.
+
+ These number are irrelevant to the new GNU malloc. I suspect it is
+ less sensitive to the size of the request. */
+ int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
+ + 4 + DEFAULT_ROUNDING - 1)
+ & ~(DEFAULT_ROUNDING - 1));
+ size = 4096 - extra;
+ }
+
+#if defined (__STDC__) && __STDC__
+ h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun;
+ h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
+#else
+ h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
+ h->freefun = freefun;
+#endif
+ h->chunk_size = size;
+ h->alignment_mask = alignment - 1;
+ h->use_extra_arg = 0;
+
+ chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
+ if (!chunk)
+ (*obstack_alloc_failed_handler) ();
+ h->next_free = h->object_base = chunk->contents;
+ h->chunk_limit = chunk->limit
+ = (char *) chunk + h->chunk_size;
+ chunk->prev = 0;
+ /* The initial chunk now contains no empty object. */
+ h->maybe_empty_object = 0;
+ h->alloc_failed = 0;
+ return 1;
+}
+
+int
+_obstack_begin_1 (h, size, alignment, chunkfun, freefun, arg)
+ struct obstack *h;
+ int size;
+ int alignment;
+#if defined (__STDC__) && __STDC__
+ POINTER (*chunkfun) (POINTER, long);
+ void (*freefun) (POINTER, POINTER);
+#else
+ POINTER (*chunkfun) ();
+ void (*freefun) ();
+#endif
+ POINTER arg;
+{
+ register struct _obstack_chunk *chunk; /* points to new chunk */
+
+ if (alignment == 0)
+ alignment = (int) DEFAULT_ALIGNMENT;
+ if (size == 0)
+ /* Default size is what GNU malloc can fit in a 4096-byte block. */
+ {
+ /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
+ Use the values for range checking, because if range checking is off,
+ the extra bytes won't be missed terribly, but if range checking is on
+ and we used a larger request, a whole extra 4096 bytes would be
+ allocated.
+
+ These number are irrelevant to the new GNU malloc. I suspect it is
+ less sensitive to the size of the request. */
+ int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
+ + 4 + DEFAULT_ROUNDING - 1)
+ & ~(DEFAULT_ROUNDING - 1));
+ size = 4096 - extra;
+ }
+
+#if defined(__STDC__) && __STDC__
+ h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
+ h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
+#else
+ h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
+ h->freefun = freefun;
+#endif
+ h->chunk_size = size;
+ h->alignment_mask = alignment - 1;
+ h->extra_arg = arg;
+ h->use_extra_arg = 1;
+
+ chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
+ if (!chunk)
+ (*obstack_alloc_failed_handler) ();
+ h->next_free = h->object_base = chunk->contents;
+ h->chunk_limit = chunk->limit
+ = (char *) chunk + h->chunk_size;
+ chunk->prev = 0;
+ /* The initial chunk now contains no empty object. */
+ h->maybe_empty_object = 0;
+ h->alloc_failed = 0;
+ return 1;
+}
+
+/* Allocate a new current chunk for the obstack *H
+ on the assumption that LENGTH bytes need to be added
+ to the current object, or a new object of length LENGTH allocated.
+ Copies any partial object from the end of the old chunk
+ to the beginning of the new one. */
+
+void
+_obstack_newchunk (h, length)
+ struct obstack *h;
+ int length;
+{
+ register struct _obstack_chunk *old_chunk = h->chunk;
+ register struct _obstack_chunk *new_chunk;
+ register long new_size;
+ register long obj_size = h->next_free - h->object_base;
+ register long i;
+ long already;
+
+ /* Compute size for new chunk. */
+ new_size = (obj_size + length) + (obj_size >> 3) + 100;
+ if (new_size < h->chunk_size)
+ new_size = h->chunk_size;
+
+ /* Allocate and initialize the new chunk. */
+ new_chunk = CALL_CHUNKFUN (h, new_size);
+ if (!new_chunk)
+ (*obstack_alloc_failed_handler) ();
+ h->chunk = new_chunk;
+ new_chunk->prev = old_chunk;
+ new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
+
+ /* Move the existing object to the new chunk.
+ Word at a time is fast and is safe if the object
+ is sufficiently aligned. */
+ if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
+ {
+ for (i = obj_size / sizeof (COPYING_UNIT) - 1;
+ i >= 0; i--)
+ ((COPYING_UNIT *)new_chunk->contents)[i]
+ = ((COPYING_UNIT *)h->object_base)[i];
+ /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
+ but that can cross a page boundary on a machine
+ which does not do strict alignment for COPYING_UNITS. */
+ already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
+ }
+ else
+ already = 0;
+ /* Copy remaining bytes one by one. */
+ for (i = already; i < obj_size; i++)
+ new_chunk->contents[i] = h->object_base[i];
+
+ /* If the object just copied was the only data in OLD_CHUNK,
+ free that chunk and remove it from the chain.
+ But not if that chunk might contain an empty object. */
+ if (h->object_base == old_chunk->contents && ! h->maybe_empty_object)
+ {
+ new_chunk->prev = old_chunk->prev;
+ CALL_FREEFUN (h, old_chunk);
+ }
+
+ h->object_base = new_chunk->contents;
+ h->next_free = h->object_base + obj_size;
+ /* The new chunk certainly contains no empty object yet. */
+ h->maybe_empty_object = 0;
+}
+
+/* Return nonzero if object OBJ has been allocated from obstack H.
+ This is here for debugging.
+ If you use it in a program, you are probably losing. */
+
+#if defined (__STDC__) && __STDC__
+/* Suppress -Wmissing-prototypes warning. We don't want to declare this in
+ obstack.h because it is just for debugging. */
+int _obstack_allocated_p (struct obstack *h, POINTER obj);
+#endif
+
+int
+_obstack_allocated_p (h, obj)
+ struct obstack *h;
+ POINTER obj;
+{
+ register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
+ register struct _obstack_chunk *plp; /* point to previous chunk if any */
+
+ lp = (h)->chunk;
+ /* We use >= rather than > since the object cannot be exactly at
+ the beginning of the chunk but might be an empty object exactly
+ at the end of an adjacent chunk. */
+ while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
+ {
+ plp = lp->prev;
+ lp = plp;
+ }
+ return lp != 0;
+}
+\f
+/* Free objects in obstack H, including OBJ and everything allocate
+ more recently than OBJ. If OBJ is zero, free everything in H. */
+
+#undef obstack_free
+
+/* This function has two names with identical definitions.
+ This is the first one, called from non-ANSI code. */
+
+void
+_obstack_free (h, obj)
+ struct obstack *h;
+ POINTER obj;
+{
+ register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
+ register struct _obstack_chunk *plp; /* point to previous chunk if any */
+
+ lp = h->chunk;
+ /* We use >= because there cannot be an object at the beginning of a chunk.
+ But there can be an empty object at that address
+ at the end of another chunk. */
+ while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
+ {
+ plp = lp->prev;
+ CALL_FREEFUN (h, lp);
+ lp = plp;
+ /* If we switch chunks, we can't tell whether the new current
+ chunk contains an empty object, so assume that it may. */
+ h->maybe_empty_object = 1;
+ }
+ if (lp)
+ {
+ h->object_base = h->next_free = (char *) (obj);
+ h->chunk_limit = lp->limit;
+ h->chunk = lp;
+ }
+ else if (obj != 0)
+ /* obj is not in any of the chunks! */
+ abort ();
+}
+
+/* This function is used from ANSI code. */
+
+void
+obstack_free (h, obj)
+ struct obstack *h;
+ POINTER obj;
+{
+ register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
+ register struct _obstack_chunk *plp; /* point to previous chunk if any */
+
+ lp = h->chunk;
+ /* We use >= because there cannot be an object at the beginning of a chunk.
+ But there can be an empty object at that address
+ at the end of another chunk. */
+ while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
+ {
+ plp = lp->prev;
+ CALL_FREEFUN (h, lp);
+ lp = plp;
+ /* If we switch chunks, we can't tell whether the new current
+ chunk contains an empty object, so assume that it may. */
+ h->maybe_empty_object = 1;
+ }
+ if (lp)
+ {
+ h->object_base = h->next_free = (char *) (obj);
+ h->chunk_limit = lp->limit;
+ h->chunk = lp;
+ }
+ else if (obj != 0)
+ /* obj is not in any of the chunks! */
+ abort ();
+}
+\f
+int
+_obstack_memory_used (h)
+ struct obstack *h;
+{
+ register struct _obstack_chunk* lp;
+ register int nbytes = 0;
+
+ for (lp = h->chunk; lp != 0; lp = lp->prev)
+ {
+ nbytes += lp->limit - (char *) lp;
+ }
+ return nbytes;
+}
+\f
+/* Define the error handler. */
+#ifndef _
+# ifdef HAVE_LIBINTL_H
+# include <libintl.h>
+# ifndef _
+# define _(Str) gettext (Str)
+# endif
+# else
+# define _(Str) (Str)
+# endif
+#endif
+
+static void
+print_and_abort ()
+{
+ fputs (_("memory exhausted\n"), stderr);
+ exit (obstack_exit_failure);
+}
+\f
+#if 0
+/* These are now turned off because the applications do not use it
+ and it uses bcopy via obstack_grow, which causes trouble on sysV. */
+
+/* Now define the functional versions of the obstack macros.
+ Define them to simply use the corresponding macros to do the job. */
+
+#if defined (__STDC__) && __STDC__
+/* These function definitions do not work with non-ANSI preprocessors;
+ they won't pass through the macro names in parentheses. */
+
+/* The function names appear in parentheses in order to prevent
+ the macro-definitions of the names from being expanded there. */
+
+POINTER (obstack_base) (obstack)
+ struct obstack *obstack;
+{
+ return obstack_base (obstack);
+}
+
+POINTER (obstack_next_free) (obstack)
+ struct obstack *obstack;
+{
+ return obstack_next_free (obstack);
+}
+
+int (obstack_object_size) (obstack)
+ struct obstack *obstack;
+{
+ return obstack_object_size (obstack);
+}
+
+int (obstack_room) (obstack)
+ struct obstack *obstack;
+{
+ return obstack_room (obstack);
+}
+
+int (obstack_make_room) (obstack, length)
+ struct obstack *obstack;
+ int length;
+{
+ return obstack_make_room (obstack, length);
+}
+
+void (obstack_grow) (obstack, pointer, length)
+ struct obstack *obstack;
+ POINTER pointer;
+ int length;
+{
+ obstack_grow (obstack, pointer, length);
+}
+
+void (obstack_grow0) (obstack, pointer, length)
+ struct obstack *obstack;
+ POINTER pointer;
+ int length;
+{
+ obstack_grow0 (obstack, pointer, length);
+}
+
+void (obstack_1grow) (obstack, character)
+ struct obstack *obstack;
+ int character;
+{
+ obstack_1grow (obstack, character);
+}
+
+void (obstack_blank) (obstack, length)
+ struct obstack *obstack;
+ int length;
+{
+ obstack_blank (obstack, length);
+}
+
+void (obstack_1grow_fast) (obstack, character)
+ struct obstack *obstack;
+ int character;
+{
+ obstack_1grow_fast (obstack, character);
+}
+
+void (obstack_blank_fast) (obstack, length)
+ struct obstack *obstack;
+ int length;
+{
+ obstack_blank_fast (obstack, length);
+}
+
+POINTER (obstack_finish) (obstack)
+ struct obstack *obstack;
+{
+ return obstack_finish (obstack);
+}
+
+POINTER (obstack_alloc) (obstack, length)
+ struct obstack *obstack;
+ int length;
+{
+ return obstack_alloc (obstack, length);
+}
+
+POINTER (obstack_copy) (obstack, pointer, length)
+ struct obstack *obstack;
+ POINTER pointer;
+ int length;
+{
+ return obstack_copy (obstack, pointer, length);
+}
+
+POINTER (obstack_copy0) (obstack, pointer, length)
+ struct obstack *obstack;
+ POINTER pointer;
+ int length;
+{
+ return obstack_copy0 (obstack, pointer, length);
+}
+
+#endif /* __STDC__ */
+
+#endif /* 0 */
+
+#endif /* !ELIDE_CODE */
--- /dev/null
+/* obstack.h - object stack macros
+ Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998,
+ 1999, 2000
+ Free Software Foundation, Inc.
+
+
+ NOTE: The canonical source of this file is maintained with the GNU C Library.
+ Bugs can be reported to bug-glibc@gnu.org.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ USA. */
+
+/* Summary:
+
+All the apparent functions defined here are macros. The idea
+is that you would use these pre-tested macros to solve a
+very specific set of problems, and they would run fast.
+Caution: no side-effects in arguments please!! They may be
+evaluated MANY times!!
+
+These macros operate a stack of objects. Each object starts life
+small, and may grow to maturity. (Consider building a word syllable
+by syllable.) An object can move while it is growing. Once it has
+been "finished" it never changes address again. So the "top of the
+stack" is typically an immature growing object, while the rest of the
+stack is of mature, fixed size and fixed address objects.
+
+These routines grab large chunks of memory, using a function you
+supply, called `obstack_chunk_alloc'. On occasion, they free chunks,
+by calling `obstack_chunk_free'. You must define them and declare
+them before using any obstack macros.
+
+Each independent stack is represented by a `struct obstack'.
+Each of the obstack macros expects a pointer to such a structure
+as the first argument.
+
+One motivation for this package is the problem of growing char strings
+in symbol tables. Unless you are "fascist pig with a read-only mind"
+--Gosper's immortal quote from HAKMEM item 154, out of context--you
+would not like to put any arbitrary upper limit on the length of your
+symbols.
+
+In practice this often means you will build many short symbols and a
+few long symbols. At the time you are reading a symbol you don't know
+how long it is. One traditional method is to read a symbol into a
+buffer, realloc()ating the buffer every time you try to read a symbol
+that is longer than the buffer. This is beaut, but you still will
+want to copy the symbol from the buffer to a more permanent
+symbol-table entry say about half the time.
+
+With obstacks, you can work differently. Use one obstack for all symbol
+names. As you read a symbol, grow the name in the obstack gradually.
+When the name is complete, finalize it. Then, if the symbol exists already,
+free the newly read name.
+
+The way we do this is to take a large chunk, allocating memory from
+low addresses. When you want to build a symbol in the chunk you just
+add chars above the current "high water mark" in the chunk. When you
+have finished adding chars, because you got to the end of the symbol,
+you know how long the chars are, and you can create a new object.
+Mostly the chars will not burst over the highest address of the chunk,
+because you would typically expect a chunk to be (say) 100 times as
+long as an average object.
+
+In case that isn't clear, when we have enough chars to make up
+the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed)
+so we just point to it where it lies. No moving of chars is
+needed and this is the second win: potentially long strings need
+never be explicitly shuffled. Once an object is formed, it does not
+change its address during its lifetime.
+
+When the chars burst over a chunk boundary, we allocate a larger
+chunk, and then copy the partly formed object from the end of the old
+chunk to the beginning of the new larger chunk. We then carry on
+accreting characters to the end of the object as we normally would.
+
+A special macro is provided to add a single char at a time to a
+growing object. This allows the use of register variables, which
+break the ordinary 'growth' macro.
+
+Summary:
+ We allocate large chunks.
+ We carve out one object at a time from the current chunk.
+ Once carved, an object never moves.
+ We are free to append data of any size to the currently
+ growing object.
+ Exactly one object is growing in an obstack at any one time.
+ You can run one obstack per control block.
+ You may have as many control blocks as you dare.
+ Because of the way we do it, you can `unwind' an obstack
+ back to a previous state. (You may remove objects much
+ as you would with a stack.)
+*/
+
+
+/* Don't do the contents of this file more than once. */
+
+#ifndef _OBSTACK_H
+#define _OBSTACK_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+\f
+/* We use subtraction of (char *) 0 instead of casting to int
+ because on word-addressable machines a simple cast to int
+ may ignore the byte-within-word field of the pointer. */
+
+#ifndef __PTR_TO_INT
+# define __PTR_TO_INT(P) ((P) - (char *) 0)
+#endif
+
+#ifndef __INT_TO_PTR
+# define __INT_TO_PTR(P) ((P) + (char *) 0)
+#endif
+
+/* We need the type of the resulting object. If __PTRDIFF_TYPE__ is
+ defined, as with GNU C, use that; that way we don't pollute the
+ namespace with <stddef.h>'s symbols. Otherwise, if <stddef.h> is
+ available, include it and use ptrdiff_t. In traditional C, long is
+ the best that we can do. */
+
+#ifdef __PTRDIFF_TYPE__
+# define PTR_INT_TYPE __PTRDIFF_TYPE__
+#else
+# ifdef HAVE_STDDEF_H
+# include <stddef.h>
+# define PTR_INT_TYPE ptrdiff_t
+# else
+# define PTR_INT_TYPE long
+# endif
+#endif
+
+#if defined _LIBC || defined HAVE_STRING_H
+# include <string.h>
+# if defined __STDC__ && __STDC__
+# define _obstack_memcpy(To, From, N) memcpy ((To), (From), (N))
+# else
+# define _obstack_memcpy(To, From, N) memcpy ((To), (char *)(From), (N))
+# endif
+#else
+# ifdef memcpy
+# define _obstack_memcpy(To, From, N) memcpy ((To), (char *)(From), (N))
+# else
+# define _obstack_memcpy(To, From, N) bcopy ((char *)(From), (To), (N))
+# endif
+#endif
+
+struct _obstack_chunk /* Lives at front of each chunk. */
+{
+ char *limit; /* 1 past end of this chunk */
+ struct _obstack_chunk *prev; /* address of prior chunk or NULL */
+ char contents[4]; /* objects begin here */
+};
+
+struct obstack /* control current object in current chunk */
+{
+ long chunk_size; /* preferred size to allocate chunks in */
+ struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */
+ char *object_base; /* address of object we are building */
+ char *next_free; /* where to add next char to current object */
+ char *chunk_limit; /* address of char after current chunk */
+ PTR_INT_TYPE temp; /* Temporary for some macros. */
+ int alignment_mask; /* Mask of alignment for each object. */
+#if defined __STDC__ && __STDC__
+ /* These prototypes vary based on `use_extra_arg', and we use
+ casts to the prototypeless function type in all assignments,
+ but having prototypes here quiets -Wstrict-prototypes. */
+ struct _obstack_chunk *(*chunkfun) (void *, long);
+ void (*freefun) (void *, struct _obstack_chunk *);
+ void *extra_arg; /* first arg for chunk alloc/dealloc funcs */
+#else
+ struct _obstack_chunk *(*chunkfun) (); /* User's fcn to allocate a chunk. */
+ void (*freefun) (); /* User's function to free a chunk. */
+ char *extra_arg; /* first arg for chunk alloc/dealloc funcs */
+#endif
+ unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */
+ unsigned maybe_empty_object:1;/* There is a possibility that the current
+ chunk contains a zero-length object. This
+ prevents freeing the chunk if we allocate
+ a bigger chunk to replace it. */
+ unsigned alloc_failed:1; /* No longer used, as we now call the failed
+ handler on error, but retained for binary
+ compatibility. */
+};
+
+/* Declare the external functions we use; they are in obstack.c. */
+
+#if defined __STDC__ && __STDC__
+extern void _obstack_newchunk (struct obstack *, int);
+extern void _obstack_free (struct obstack *, void *);
+extern int _obstack_begin (struct obstack *, int, int,
+ void *(*) (long), void (*) (void *));
+extern int _obstack_begin_1 (struct obstack *, int, int,
+ void *(*) (void *, long),
+ void (*) (void *, void *), void *);
+extern int _obstack_memory_used (struct obstack *);
+#else
+extern void _obstack_newchunk ();
+extern void _obstack_free ();
+extern int _obstack_begin ();
+extern int _obstack_begin_1 ();
+extern int _obstack_memory_used ();
+#endif
+\f
+#if defined __STDC__ && __STDC__
+
+/* Do the function-declarations after the structs
+ but before defining the macros. */
+
+void obstack_init (struct obstack *obstack);
+
+void * obstack_alloc (struct obstack *obstack, int size);
+
+void * obstack_copy (struct obstack *obstack, void *address, int size);
+void * obstack_copy0 (struct obstack *obstack, void *address, int size);
+
+void obstack_free (struct obstack *obstack, void *block);
+
+void obstack_blank (struct obstack *obstack, int size);
+
+void obstack_grow (struct obstack *obstack, void *data, int size);
+void obstack_grow0 (struct obstack *obstack, void *data, int size);
+
+void obstack_1grow (struct obstack *obstack, int data_char);
+void obstack_ptr_grow (struct obstack *obstack, void *data);
+void obstack_int_grow (struct obstack *obstack, int data);
+
+void * obstack_finish (struct obstack *obstack);
+
+int obstack_object_size (struct obstack *obstack);
+
+int obstack_room (struct obstack *obstack);
+void obstack_make_room (struct obstack *obstack, int size);
+void obstack_1grow_fast (struct obstack *obstack, int data_char);
+void obstack_ptr_grow_fast (struct obstack *obstack, void *data);
+void obstack_int_grow_fast (struct obstack *obstack, int data);
+void obstack_blank_fast (struct obstack *obstack, int size);
+
+void * obstack_base (struct obstack *obstack);
+void * obstack_next_free (struct obstack *obstack);
+int obstack_alignment_mask (struct obstack *obstack);
+int obstack_chunk_size (struct obstack *obstack);
+int obstack_memory_used (struct obstack *obstack);
+
+#endif /* __STDC__ */
+
+/* Non-ANSI C cannot really support alternative functions for these macros,
+ so we do not declare them. */
+
+/* Error handler called when `obstack_chunk_alloc' failed to allocate
+ more memory. This can be set to a user defined function. The
+ default action is to print a message and abort. */
+#if defined __STDC__ && __STDC__
+extern void (*obstack_alloc_failed_handler) (void);
+#else
+extern void (*obstack_alloc_failed_handler) ();
+#endif
+
+/* Exit value used when `print_and_abort' is used. */
+extern int obstack_exit_failure;
+\f
+/* Pointer to beginning of object being allocated or to be allocated next.
+ Note that this might not be the final address of the object
+ because a new chunk might be needed to hold the final size. */
+
+#define obstack_base(h) ((h)->object_base)
+
+/* Size for allocating ordinary chunks. */
+
+#define obstack_chunk_size(h) ((h)->chunk_size)
+
+/* Pointer to next byte not yet allocated in current chunk. */
+
+#define obstack_next_free(h) ((h)->next_free)
+
+/* Mask specifying low bits that should be clear in address of an object. */
+
+#define obstack_alignment_mask(h) ((h)->alignment_mask)
+
+/* To prevent prototype warnings provide complete argument list in
+ standard C version. */
+#if defined __STDC__ && __STDC__
+
+# define obstack_init(h) \
+ _obstack_begin ((h), 0, 0, \
+ (void *(*) (long)) obstack_chunk_alloc, (void (*) (void *)) obstack_chunk_free)
+
+# define obstack_begin(h, size) \
+ _obstack_begin ((h), (size), 0, \
+ (void *(*) (long)) obstack_chunk_alloc, (void (*) (void *)) obstack_chunk_free)
+
+# define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \
+ _obstack_begin ((h), (size), (alignment), \
+ (void *(*) (long)) (chunkfun), (void (*) (void *)) (freefun))
+
+# define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
+ _obstack_begin_1 ((h), (size), (alignment), \
+ (void *(*) (void *, long)) (chunkfun), \
+ (void (*) (void *, void *)) (freefun), (arg))
+
+# define obstack_chunkfun(h, newchunkfun) \
+ ((h) -> chunkfun = (struct _obstack_chunk *(*)(void *, long)) (newchunkfun))
+
+# define obstack_freefun(h, newfreefun) \
+ ((h) -> freefun = (void (*)(void *, struct _obstack_chunk *)) (newfreefun))
+
+#else
+
+# define obstack_init(h) \
+ _obstack_begin ((h), 0, 0, \
+ (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free)
+
+# define obstack_begin(h, size) \
+ _obstack_begin ((h), (size), 0, \
+ (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free)
+
+# define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \
+ _obstack_begin ((h), (size), (alignment), \
+ (void *(*) ()) (chunkfun), (void (*) ()) (freefun))
+
+# define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
+ _obstack_begin_1 ((h), (size), (alignment), \
+ (void *(*) ()) (chunkfun), (void (*) ()) (freefun), (arg))
+
+# define obstack_chunkfun(h, newchunkfun) \
+ ((h) -> chunkfun = (struct _obstack_chunk *(*)()) (newchunkfun))
+
+# define obstack_freefun(h, newfreefun) \
+ ((h) -> freefun = (void (*)()) (newfreefun))
+
+#endif
+
+#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = achar)
+
+#define obstack_blank_fast(h,n) ((h)->next_free += (n))
+
+#define obstack_memory_used(h) _obstack_memory_used (h)
+\f
+#if defined __GNUC__ && defined __STDC__ && __STDC__
+/* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and
+ does not implement __extension__. But that compiler doesn't define
+ __GNUC_MINOR__. */
+# if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__)
+# define __extension__
+# endif
+
+/* For GNU C, if not -traditional,
+ we can define these macros to compute all args only once
+ without using a global variable.
+ Also, we can avoid using the `temp' slot, to make faster code. */
+
+# define obstack_object_size(OBSTACK) \
+ __extension__ \
+ ({ struct obstack *__o = (OBSTACK); \
+ (unsigned) (__o->next_free - __o->object_base); })
+
+# define obstack_room(OBSTACK) \
+ __extension__ \
+ ({ struct obstack *__o = (OBSTACK); \
+ (unsigned) (__o->chunk_limit - __o->next_free); })
+
+# define obstack_make_room(OBSTACK,length) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ int __len = (length); \
+ if (__o->chunk_limit - __o->next_free < __len) \
+ _obstack_newchunk (__o, __len); \
+ (void) 0; })
+
+# define obstack_empty_p(OBSTACK) \
+ __extension__ \
+ ({ struct obstack *__o = (OBSTACK); \
+ (__o->chunk->prev == 0 && __o->next_free - __o->chunk->contents == 0); })
+
+# define obstack_grow(OBSTACK,where,length) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ int __len = (length); \
+ if (__o->next_free + __len > __o->chunk_limit) \
+ _obstack_newchunk (__o, __len); \
+ _obstack_memcpy (__o->next_free, (where), __len); \
+ __o->next_free += __len; \
+ (void) 0; })
+
+# define obstack_grow0(OBSTACK,where,length) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ int __len = (length); \
+ if (__o->next_free + __len + 1 > __o->chunk_limit) \
+ _obstack_newchunk (__o, __len + 1); \
+ _obstack_memcpy (__o->next_free, (where), __len); \
+ __o->next_free += __len; \
+ *(__o->next_free)++ = 0; \
+ (void) 0; })
+
+# define obstack_1grow(OBSTACK,datum) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ if (__o->next_free + 1 > __o->chunk_limit) \
+ _obstack_newchunk (__o, 1); \
+ *(__o->next_free)++ = (datum); \
+ (void) 0; })
+
+/* These assume that the obstack alignment is good enough for pointers or ints,
+ and that the data added so far to the current object
+ shares that much alignment. */
+
+# define obstack_ptr_grow(OBSTACK,datum) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ if (__o->next_free + sizeof (void *) > __o->chunk_limit) \
+ _obstack_newchunk (__o, sizeof (void *)); \
+ *((void **)__o->next_free)++ = ((void *)datum); \
+ (void) 0; })
+
+# define obstack_int_grow(OBSTACK,datum) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ if (__o->next_free + sizeof (int) > __o->chunk_limit) \
+ _obstack_newchunk (__o, sizeof (int)); \
+ *((int *)__o->next_free)++ = ((int)datum); \
+ (void) 0; })
+
+# define obstack_ptr_grow_fast(h,aptr) (*((void **) (h)->next_free)++ = (void *)aptr)
+# define obstack_int_grow_fast(h,aint) (*((int *) (h)->next_free)++ = (int) aint)
+
+# define obstack_blank(OBSTACK,length) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ int __len = (length); \
+ if (__o->chunk_limit - __o->next_free < __len) \
+ _obstack_newchunk (__o, __len); \
+ __o->next_free += __len; \
+ (void) 0; })
+
+# define obstack_alloc(OBSTACK,length) \
+__extension__ \
+({ struct obstack *__h = (OBSTACK); \
+ obstack_blank (__h, (length)); \
+ obstack_finish (__h); })
+
+# define obstack_copy(OBSTACK,where,length) \
+__extension__ \
+({ struct obstack *__h = (OBSTACK); \
+ obstack_grow (__h, (where), (length)); \
+ obstack_finish (__h); })
+
+# define obstack_copy0(OBSTACK,where,length) \
+__extension__ \
+({ struct obstack *__h = (OBSTACK); \
+ obstack_grow0 (__h, (where), (length)); \
+ obstack_finish (__h); })
+
+/* The local variable is named __o1 to avoid a name conflict
+ when obstack_blank is called. */
+# define obstack_finish(OBSTACK) \
+__extension__ \
+({ struct obstack *__o1 = (OBSTACK); \
+ void *value; \
+ value = (void *) __o1->object_base; \
+ if (__o1->next_free == value) \
+ __o1->maybe_empty_object = 1; \
+ __o1->next_free \
+ = __INT_TO_PTR ((__PTR_TO_INT (__o1->next_free)+__o1->alignment_mask)\
+ & ~ (__o1->alignment_mask)); \
+ if (__o1->next_free - (char *)__o1->chunk \
+ > __o1->chunk_limit - (char *)__o1->chunk) \
+ __o1->next_free = __o1->chunk_limit; \
+ __o1->object_base = __o1->next_free; \
+ value; })
+
+# define obstack_free(OBSTACK, OBJ) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ void *__obj = (OBJ); \
+ if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \
+ __o->next_free = __o->object_base = __obj; \
+ else (obstack_free) (__o, __obj); })
+\f
+#else /* not __GNUC__ or not __STDC__ */
+
+# define obstack_object_size(h) \
+ (unsigned) ((h)->next_free - (h)->object_base)
+
+# define obstack_room(h) \
+ (unsigned) ((h)->chunk_limit - (h)->next_free)
+
+# define obstack_empty_p(h) \
+ ((h)->chunk->prev == 0 && (h)->next_free - (h)->chunk->contents == 0)
+
+/* Note that the call to _obstack_newchunk is enclosed in (..., 0)
+ so that we can avoid having void expressions
+ in the arms of the conditional expression.
+ Casting the third operand to void was tried before,
+ but some compilers won't accept it. */
+
+# define obstack_make_room(h,length) \
+( (h)->temp = (length), \
+ (((h)->next_free + (h)->temp > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), (h)->temp), 0) : 0))
+
+# define obstack_grow(h,where,length) \
+( (h)->temp = (length), \
+ (((h)->next_free + (h)->temp > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \
+ _obstack_memcpy ((h)->next_free, (where), (h)->temp), \
+ (h)->next_free += (h)->temp)
+
+# define obstack_grow0(h,where,length) \
+( (h)->temp = (length), \
+ (((h)->next_free + (h)->temp + 1 > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), (h)->temp + 1), 0) : 0), \
+ _obstack_memcpy ((h)->next_free, (where), (h)->temp), \
+ (h)->next_free += (h)->temp, \
+ *((h)->next_free)++ = 0)
+
+# define obstack_1grow(h,datum) \
+( (((h)->next_free + 1 > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), 1), 0) : 0), \
+ (*((h)->next_free)++ = (datum)))
+
+# define obstack_ptr_grow(h,datum) \
+( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \
+ (*((char **) (((h)->next_free+=sizeof(char *))-sizeof(char *))) = ((char *) datum)))
+
+# define obstack_int_grow(h,datum) \
+( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \
+ (*((int *) (((h)->next_free+=sizeof(int))-sizeof(int))) = ((int) datum)))
+
+# define obstack_ptr_grow_fast(h,aptr) (*((char **) (h)->next_free)++ = (char *) aptr)
+# define obstack_int_grow_fast(h,aint) (*((int *) (h)->next_free)++ = (int) aint)
+
+# define obstack_blank(h,length) \
+( (h)->temp = (length), \
+ (((h)->chunk_limit - (h)->next_free < (h)->temp) \
+ ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \
+ ((h)->next_free += (h)->temp))
+
+# define obstack_alloc(h,length) \
+ (obstack_blank ((h), (length)), obstack_finish ((h)))
+
+# define obstack_copy(h,where,length) \
+ (obstack_grow ((h), (where), (length)), obstack_finish ((h)))
+
+# define obstack_copy0(h,where,length) \
+ (obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
+
+# define obstack_finish(h) \
+( ((h)->next_free == (h)->object_base \
+ ? (((h)->maybe_empty_object = 1), 0) \
+ : 0), \
+ (h)->temp = __PTR_TO_INT ((h)->object_base), \
+ (h)->next_free \
+ = __INT_TO_PTR ((__PTR_TO_INT ((h)->next_free)+(h)->alignment_mask) \
+ & ~ ((h)->alignment_mask)), \
+ (((h)->next_free - (char *) (h)->chunk \
+ > (h)->chunk_limit - (char *) (h)->chunk) \
+ ? ((h)->next_free = (h)->chunk_limit) : 0), \
+ (h)->object_base = (h)->next_free, \
+ __INT_TO_PTR ((h)->temp))
+
+# if defined __STDC__ && __STDC__
+# define obstack_free(h,obj) \
+( (h)->temp = (char *) (obj) - (char *) (h)->chunk, \
+ (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\
+ ? (int) ((h)->next_free = (h)->object_base \
+ = (h)->temp + (char *) (h)->chunk) \
+ : (((obstack_free) ((h), (h)->temp + (char *) (h)->chunk), 0), 0)))
+# else
+# define obstack_free(h,obj) \
+( (h)->temp = (char *) (obj) - (char *) (h)->chunk, \
+ (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\
+ ? (int) ((h)->next_free = (h)->object_base \
+ = (h)->temp + (char *) (h)->chunk) \
+ : (_obstack_free ((h), (h)->temp + (char *) (h)->chunk), 0)))
+# endif
+
+#endif /* not __GNUC__ or not __STDC__ */
+
+#ifdef __cplusplus
+} /* C++ */
+#endif
+
+#endif /* obstack.h */
--- /dev/null
+/* <ctype.h> replacement macros.
+
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ Contributed by Zack Weinberg <zackw@stanford.edu>.
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* This is a compatible replacement of the standard C library's <ctype.h>
+ with the following properties:
+
+ - Implements all isxxx() macros required by C99.
+ - Also implements some character classes useful when
+ parsing C-like languages.
+ - Does not change behavior depending on the current locale.
+ - Behaves properly for all values in the range of a signed or
+ unsigned char. */
+
+#include "ansidecl.h"
+#include <safe-ctype.h>
+#include <stdio.h> /* for EOF */
+
+/* Shorthand */
+#define bl _sch_isblank
+#define cn _sch_iscntrl
+#define di _sch_isdigit
+#define is _sch_isidst
+#define lo _sch_islower
+#define nv _sch_isnvsp
+#define pn _sch_ispunct
+#define pr _sch_isprint
+#define sp _sch_isspace
+#define up _sch_isupper
+#define vs _sch_isvsp
+#define xd _sch_isxdigit
+
+/* Masks. */
+#define L lo|is |pr /* lower case letter */
+#define XL lo|is|xd|pr /* lowercase hex digit */
+#define U up|is |pr /* upper case letter */
+#define XU up|is|xd|pr /* uppercase hex digit */
+#define D di |xd|pr /* decimal digit */
+#define P pn |pr /* punctuation */
+#define _ pn|is |pr /* underscore */
+
+#define C cn /* control character */
+#define Z nv |cn /* NUL */
+#define M nv|sp |cn /* cursor movement: \f \v */
+#define V vs|sp |cn /* vertical space: \r \n */
+#define T nv|sp|bl|cn /* tab */
+#define S nv|sp|bl|pr /* space */
+
+/* Are we ASCII? */
+#if '\n' == 0x0A && ' ' == 0x20 && '0' == 0x30 \
+ && 'A' == 0x41 && 'a' == 0x61 && '!' == 0x21 \
+ && EOF == -1
+
+const unsigned short _sch_istable[256] =
+{
+ Z, C, C, C, C, C, C, C, /* NUL SOH STX ETX EOT ENQ ACK BEL */
+ C, T, V, M, M, V, C, C, /* BS HT LF VT FF CR SO SI */
+ C, C, C, C, C, C, C, C, /* DLE DC1 DC2 DC3 DC4 NAK SYN ETB */
+ C, C, C, C, C, C, C, C, /* CAN EM SUB ESC FS GS RS US */
+ S, P, P, P, P, P, P, P, /* SP ! " # $ % & ' */
+ P, P, P, P, P, P, P, P, /* ( ) * + , - . / */
+ D, D, D, D, D, D, D, D, /* 0 1 2 3 4 5 6 7 */
+ D, D, P, P, P, P, P, P, /* 8 9 : ; < = > ? */
+ P, XU, XU, XU, XU, XU, XU, U, /* @ A B C D E F G */
+ U, U, U, U, U, U, U, U, /* H I J K L M N O */
+ U, U, U, U, U, U, U, U, /* P Q R S T U V W */
+ U, U, U, P, P, P, P, _, /* X Y Z [ \ ] ^ _ */
+ P, XL, XL, XL, XL, XL, XL, L, /* ` a b c d e f g */
+ L, L, L, L, L, L, L, L, /* h i j k l m n o */
+ L, L, L, L, L, L, L, L, /* p q r s t u v w */
+ L, L, L, P, P, P, P, C, /* x y z { | } ~ DEL */
+
+ /* high half of unsigned char is locale-specific, so all tests are
+ false in "C" locale */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+const unsigned char _sch_tolower[256] =
+{
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64,
+
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+ 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+
+ 91, 92, 93, 94, 95, 96,
+
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+ 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+
+ 123,124,125,126,127,
+
+ 128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
+ 144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159,
+ 160,161,162,163, 164,165,166,167, 168,169,170,171, 172,173,174,175,
+ 176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,190,191,
+
+ 192,193,194,195, 196,197,198,199, 200,201,202,203, 204,205,206,207,
+ 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
+ 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
+ 240,241,242,243, 244,245,246,247, 248,249,250,251, 252,253,254,255,
+};
+
+const unsigned char _sch_toupper[256] =
+{
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64,
+
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
+ 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+
+ 91, 92, 93, 94, 95, 96,
+
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
+ 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+
+ 123,124,125,126,127,
+
+ 128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
+ 144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159,
+ 160,161,162,163, 164,165,166,167, 168,169,170,171, 172,173,174,175,
+ 176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,190,191,
+
+ 192,193,194,195, 196,197,198,199, 200,201,202,203, 204,205,206,207,
+ 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
+ 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
+ 240,241,242,243, 244,245,246,247, 248,249,250,251, 252,253,254,255,
+};
+
+#else
+ #error "Unsupported host character set"
+#endif /* not ASCII */
--- /dev/null
+/* <ctype.h> replacement macros.
+
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Zack Weinberg <zackw@stanford.edu>.
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* This is a compatible replacement of the standard C library's <ctype.h>
+ with the following properties:
+
+ - Implements all isxxx() macros required by C99.
+ - Also implements some character classes useful when
+ parsing C-like languages.
+ - Does not change behavior depending on the current locale.
+ - Behaves properly for all values in the range of a signed or
+ unsigned char.
+
+ To avoid conflicts, this header defines the isxxx functions in upper
+ case, e.g. ISALPHA not isalpha. */
+
+#ifndef SAFE_CTYPE_H
+#define SAFE_CTYPE_H
+
+#ifdef isalpha
+ #error "safe-ctype.h and ctype.h may not be used simultaneously"
+#else
+
+/* Categories. */
+
+enum {
+ /* In C99 */
+ _sch_isblank = 0x0001, /* space \t */
+ _sch_iscntrl = 0x0002, /* nonprinting characters */
+ _sch_isdigit = 0x0004, /* 0-9 */
+ _sch_islower = 0x0008, /* a-z */
+ _sch_isprint = 0x0010, /* any printing character including ' ' */
+ _sch_ispunct = 0x0020, /* all punctuation */
+ _sch_isspace = 0x0040, /* space \t \n \r \f \v */
+ _sch_isupper = 0x0080, /* A-Z */
+ _sch_isxdigit = 0x0100, /* 0-9A-Fa-f */
+
+ /* Extra categories useful to cpplib. */
+ _sch_isidst = 0x0200, /* A-Za-z_ */
+ _sch_isvsp = 0x0400, /* \n \r */
+ _sch_isnvsp = 0x0800, /* space \t \f \v \0 */
+
+ /* Combinations of the above. */
+ _sch_isalpha = _sch_isupper|_sch_islower, /* A-Za-z */
+ _sch_isalnum = _sch_isalpha|_sch_isdigit, /* A-Za-z0-9 */
+ _sch_isidnum = _sch_isidst|_sch_isdigit, /* A-Za-z0-9_ */
+ _sch_isgraph = _sch_isalnum|_sch_ispunct, /* isprint and not space */
+ _sch_iscppsp = _sch_isvsp|_sch_isnvsp /* isspace + \0 */
+};
+
+/* Character classification. */
+extern const unsigned short _sch_istable[256];
+
+#define _sch_test(c, bit) (_sch_istable[(c) & 0xff] & (unsigned short)(bit))
+
+#define ISALPHA(c) _sch_test(c, _sch_isalpha)
+#define ISALNUM(c) _sch_test(c, _sch_isalnum)
+#define ISBLANK(c) _sch_test(c, _sch_isblank)
+#define ISCNTRL(c) _sch_test(c, _sch_iscntrl)
+#define ISDIGIT(c) _sch_test(c, _sch_isdigit)
+#define ISGRAPH(c) _sch_test(c, _sch_isgraph)
+#define ISLOWER(c) _sch_test(c, _sch_islower)
+#define ISPRINT(c) _sch_test(c, _sch_isprint)
+#define ISPUNCT(c) _sch_test(c, _sch_ispunct)
+#define ISSPACE(c) _sch_test(c, _sch_isspace)
+#define ISUPPER(c) _sch_test(c, _sch_isupper)
+#define ISXDIGIT(c) _sch_test(c, _sch_isxdigit)
+
+#define ISIDNUM(c) _sch_test(c, _sch_isidnum)
+#define ISIDST(c) _sch_test(c, _sch_isidst)
+#define IS_VSPACE(c) _sch_test(c, _sch_isvsp)
+#define IS_NVSPACE(c) _sch_test(c, _sch_isnvsp)
+#define IS_SPACE_OR_NUL(c) _sch_test(c, _sch_iscppsp)
+
+/* Character transformation. */
+extern const unsigned char _sch_toupper[256];
+extern const unsigned char _sch_tolower[256];
+#define TOUPPER(c) _sch_toupper[(c) & 0xff]
+#define TOLOWER(c) _sch_tolower[(c) & 0xff]
+
+#endif /* no ctype.h */
+#endif /* SAFE_CTYPE_H */
--- /dev/null
+/* A splay-tree datatype.
+ Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Mark Mitchell (mark@markmitchell.com).
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* For an easily readable description of splay-trees, see:
+
+ Lewis, Harry R. and Denenberg, Larry. Data Structures and Their
+ Algorithms. Harper-Collins, Inc. 1991. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#include <stdio.h>
+
+#include "libiberty.h"
+#include "splay-tree.h"
+
+static void splay_tree_delete_helper PARAMS((splay_tree,
+ splay_tree_node));
+static void splay_tree_splay PARAMS((splay_tree,
+ splay_tree_key));
+static splay_tree_node splay_tree_splay_helper
+ PARAMS((splay_tree,
+ splay_tree_key,
+ splay_tree_node*,
+ splay_tree_node*,
+ splay_tree_node*));
+static int splay_tree_foreach_helper PARAMS((splay_tree,
+ splay_tree_node,
+ splay_tree_foreach_fn,
+ void*));
+
+/* Deallocate NODE (a member of SP), and all its sub-trees. */
+
+static void
+splay_tree_delete_helper (sp, node)
+ splay_tree sp;
+ splay_tree_node node;
+{
+ if (!node)
+ return;
+
+ splay_tree_delete_helper (sp, node->left);
+ splay_tree_delete_helper (sp, node->right);
+
+ if (sp->delete_key)
+ (*sp->delete_key)(node->key);
+ if (sp->delete_value)
+ (*sp->delete_value)(node->value);
+
+ free ((char*) node);
+}
+
+/* Help splay SP around KEY. PARENT and GRANDPARENT are the parent
+ and grandparent, respectively, of NODE. */
+
+static splay_tree_node
+splay_tree_splay_helper (sp, key, node, parent, grandparent)
+ splay_tree sp;
+ splay_tree_key key;
+ splay_tree_node *node;
+ splay_tree_node *parent;
+ splay_tree_node *grandparent;
+{
+ splay_tree_node *next;
+ splay_tree_node n;
+ int comparison;
+
+ n = *node;
+
+ if (!n)
+ return *parent;
+
+ comparison = (*sp->comp) (key, n->key);
+
+ if (comparison == 0)
+ /* We've found the target. */
+ next = 0;
+ else if (comparison < 0)
+ /* The target is to the left. */
+ next = &n->left;
+ else
+ /* The target is to the right. */
+ next = &n->right;
+
+ if (next)
+ {
+ /* Continue down the tree. */
+ n = splay_tree_splay_helper (sp, key, next, node, parent);
+
+ /* The recursive call will change the place to which NODE
+ points. */
+ if (*node != n)
+ return n;
+ }
+
+ if (!parent)
+ /* NODE is the root. We are done. */
+ return n;
+
+ /* First, handle the case where there is no grandparent (i.e.,
+ *PARENT is the root of the tree.) */
+ if (!grandparent)
+ {
+ if (n == (*parent)->left)
+ {
+ *node = n->right;
+ n->right = *parent;
+ }
+ else
+ {
+ *node = n->left;
+ n->left = *parent;
+ }
+ *parent = n;
+ return n;
+ }
+
+ /* Next handle the cases where both N and *PARENT are left children,
+ or where both are right children. */
+ if (n == (*parent)->left && *parent == (*grandparent)->left)
+ {
+ splay_tree_node p = *parent;
+
+ (*grandparent)->left = p->right;
+ p->right = *grandparent;
+ p->left = n->right;
+ n->right = p;
+ *grandparent = n;
+ return n;
+ }
+ else if (n == (*parent)->right && *parent == (*grandparent)->right)
+ {
+ splay_tree_node p = *parent;
+
+ (*grandparent)->right = p->left;
+ p->left = *grandparent;
+ p->right = n->left;
+ n->left = p;
+ *grandparent = n;
+ return n;
+ }
+
+ /* Finally, deal with the case where N is a left child, but *PARENT
+ is a right child, or vice versa. */
+ if (n == (*parent)->left)
+ {
+ (*parent)->left = n->right;
+ n->right = *parent;
+ (*grandparent)->right = n->left;
+ n->left = *grandparent;
+ *grandparent = n;
+ return n;
+ }
+ else
+ {
+ (*parent)->right = n->left;
+ n->left = *parent;
+ (*grandparent)->left = n->right;
+ n->right = *grandparent;
+ *grandparent = n;
+ return n;
+ }
+}
+
+/* Splay SP around KEY. */
+
+static void
+splay_tree_splay (sp, key)
+ splay_tree sp;
+ splay_tree_key key;
+{
+ if (sp->root == 0)
+ return;
+
+ splay_tree_splay_helper (sp, key, &sp->root,
+ /*grandparent=*/0, /*parent=*/0);
+}
+
+/* Call FN, passing it the DATA, for every node below NODE, all of
+ which are from SP, following an in-order traversal. If FN every
+ returns a non-zero value, the iteration ceases immediately, and the
+ value is returned. Otherwise, this function returns 0. */
+
+static int
+splay_tree_foreach_helper (sp, node, fn, data)
+ splay_tree sp;
+ splay_tree_node node;
+ splay_tree_foreach_fn fn;
+ void* data;
+{
+ int val;
+
+ if (!node)
+ return 0;
+
+ val = splay_tree_foreach_helper (sp, node->left, fn, data);
+ if (val)
+ return val;
+
+ val = (*fn)(node, data);
+ if (val)
+ return val;
+
+ return splay_tree_foreach_helper (sp, node->right, fn, data);
+}
+
+/* Allocate a new splay tree, using COMPARE_FN to compare nodes,
+ DELETE_KEY_FN to deallocate keys, and DELETE_VALUE_FN to deallocate
+ values. */
+
+splay_tree
+splay_tree_new (compare_fn, delete_key_fn, delete_value_fn)
+ splay_tree_compare_fn compare_fn;
+ splay_tree_delete_key_fn delete_key_fn;
+ splay_tree_delete_value_fn delete_value_fn;
+{
+ splay_tree sp = (splay_tree) xmalloc (sizeof (struct splay_tree_s));
+ sp->root = 0;
+ sp->comp = compare_fn;
+ sp->delete_key = delete_key_fn;
+ sp->delete_value = delete_value_fn;
+
+ return sp;
+}
+
+/* Deallocate SP. */
+
+void
+splay_tree_delete (sp)
+ splay_tree sp;
+{
+ splay_tree_delete_helper (sp, sp->root);
+ free ((char*) sp);
+}
+
+/* Insert a new node (associating KEY with DATA) into SP. If a
+ previous node with the indicated KEY exists, its data is replaced
+ with the new value. Returns the new node. */
+
+splay_tree_node
+splay_tree_insert (sp, key, value)
+ splay_tree sp;
+ splay_tree_key key;
+ splay_tree_value value;
+{
+ int comparison = 0;
+
+ splay_tree_splay (sp, key);
+
+ if (sp->root)
+ comparison = (*sp->comp)(sp->root->key, key);
+
+ if (sp->root && comparison == 0)
+ {
+ /* If the root of the tree already has the indicated KEY, just
+ replace the value with VALUE. */
+ if (sp->delete_value)
+ (*sp->delete_value)(sp->root->value);
+ sp->root->value = value;
+ }
+ else
+ {
+ /* Create a new node, and insert it at the root. */
+ splay_tree_node node;
+
+ node = (splay_tree_node) xmalloc (sizeof (struct splay_tree_node_s));
+ node->key = key;
+ node->value = value;
+
+ if (!sp->root)
+ node->left = node->right = 0;
+ else if (comparison < 0)
+ {
+ node->left = sp->root;
+ node->right = node->left->right;
+ node->left->right = 0;
+ }
+ else
+ {
+ node->right = sp->root;
+ node->left = node->right->left;
+ node->right->left = 0;
+ }
+
+ sp->root = node;
+ }
+
+ return sp->root;
+}
+
+/* Remove KEY from SP. It is not an error if it did not exist. */
+
+void
+splay_tree_remove (sp, key)
+ splay_tree sp;
+ splay_tree_key key;
+{
+ splay_tree_splay (sp, key);
+
+ if (sp->root && (*sp->comp) (sp->root->key, key) == 0)
+ {
+ splay_tree_node left, right;
+
+ left = sp->root->left;
+ right = sp->root->right;
+
+ /* Delete the root node itself. */
+ if (sp->delete_value)
+ (*sp->delete_value) (sp->root->value);
+ free (sp->root);
+
+ /* One of the children is now the root. Doesn't matter much
+ which, so long as we preserve the properties of the tree. */
+ if (left)
+ {
+ sp->root = left;
+
+ /* If there was a right child as well, hang it off the
+ right-most leaf of the left child. */
+ if (right)
+ {
+ while (left->right)
+ left = left->right;
+ left->right = right;
+ }
+ }
+ else
+ sp->root = right;
+ }
+}
+
+/* Lookup KEY in SP, returning VALUE if present, and NULL
+ otherwise. */
+
+splay_tree_node
+splay_tree_lookup (sp, key)
+ splay_tree sp;
+ splay_tree_key key;
+{
+ splay_tree_splay (sp, key);
+
+ if (sp->root && (*sp->comp)(sp->root->key, key) == 0)
+ return sp->root;
+ else
+ return 0;
+}
+
+/* Return the node in SP with the greatest key. */
+
+splay_tree_node
+splay_tree_max (sp)
+ splay_tree sp;
+{
+ splay_tree_node n = sp->root;
+
+ if (!n)
+ return NULL;
+
+ while (n->right)
+ n = n->right;
+
+ return n;
+}
+
+/* Return the node in SP with the smallest key. */
+
+splay_tree_node
+splay_tree_min (sp)
+ splay_tree sp;
+{
+ splay_tree_node n = sp->root;
+
+ if (!n)
+ return NULL;
+
+ while (n->left)
+ n = n->left;
+
+ return n;
+}
+
+/* Return the immediate predecessor KEY, or NULL if there is no
+ predecessor. KEY need not be present in the tree. */
+
+splay_tree_node
+splay_tree_predecessor (sp, key)
+ splay_tree sp;
+ splay_tree_key key;
+{
+ int comparison;
+ splay_tree_node node;
+
+ /* If the tree is empty, there is certainly no predecessor. */
+ if (!sp->root)
+ return NULL;
+
+ /* Splay the tree around KEY. That will leave either the KEY
+ itself, its predecessor, or its successor at the root. */
+ splay_tree_splay (sp, key);
+ comparison = (*sp->comp)(sp->root->key, key);
+
+ /* If the predecessor is at the root, just return it. */
+ if (comparison < 0)
+ return sp->root;
+
+ /* Otherwise, find the leftmost element of the right subtree. */
+ node = sp->root->left;
+ if (node)
+ while (node->right)
+ node = node->right;
+
+ return node;
+}
+
+/* Return the immediate successor KEY, or NULL if there is no
+ predecessor. KEY need not be present in the tree. */
+
+splay_tree_node
+splay_tree_successor (sp, key)
+ splay_tree sp;
+ splay_tree_key key;
+{
+ int comparison;
+ splay_tree_node node;
+
+ /* If the tree is empty, there is certainly no predecessor. */
+ if (!sp->root)
+ return NULL;
+
+ /* Splay the tree around KEY. That will leave either the KEY
+ itself, its predecessor, or its successor at the root. */
+ splay_tree_splay (sp, key);
+ comparison = (*sp->comp)(sp->root->key, key);
+
+ /* If the successor is at the root, just return it. */
+ if (comparison > 0)
+ return sp->root;
+
+ /* Otherwise, find the rightmost element of the left subtree. */
+ node = sp->root->right;
+ if (node)
+ while (node->left)
+ node = node->left;
+
+ return node;
+}
+
+/* Call FN, passing it the DATA, for every node in SP, following an
+ in-order traversal. If FN every returns a non-zero value, the
+ iteration ceases immediately, and the value is returned.
+ Otherwise, this function returns 0. */
+
+int
+splay_tree_foreach (sp, fn, data)
+ splay_tree sp;
+ splay_tree_foreach_fn fn;
+ void *data;
+{
+ return splay_tree_foreach_helper (sp, sp->root, fn, data);
+}
+
+/* Splay-tree comparison function, treating the keys as ints. */
+
+int
+splay_tree_compare_ints (k1, k2)
+ splay_tree_key k1;
+ splay_tree_key k2;
+{
+ if ((int) k1 < (int) k2)
+ return -1;
+ else if ((int) k1 > (int) k2)
+ return 1;
+ else
+ return 0;
+}
+
+/* Splay-tree comparison function, treating the keys as pointers. */
+
+int
+splay_tree_compare_pointers (k1, k2)
+ splay_tree_key k1;
+ splay_tree_key k2;
+{
+ if ((char*) k1 < (char*) k2)
+ return -1;
+ else if ((char*) k1 > (char*) k2)
+ return 1;
+ else
+ return 0;
+}
--- /dev/null
+/* A splay-tree datatype.
+ Copyright 1998, 1999, 2000 Free Software Foundation, Inc.
+ Contributed by Mark Mitchell (mark@markmitchell.com).
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* For an easily readable description of splay-trees, see:
+
+ Lewis, Harry R. and Denenberg, Larry. Data Structures and Their
+ Algorithms. Harper-Collins, Inc. 1991.
+
+ The major feature of splay trees is that all basic tree operations
+ are amortized O(log n) time for a tree with n nodes. */
+
+#ifndef _SPLAY_TREE_H
+#define _SPLAY_TREE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <ansidecl.h>
+
+/* Use typedefs for the key and data types to facilitate changing
+ these types, if necessary. These types should be sufficiently wide
+ that any pointer or scalar can be cast to these types, and then
+ cast back, without loss of precision. */
+typedef unsigned long int splay_tree_key;
+typedef unsigned long int splay_tree_value;
+
+/* Forward declaration for a node in the tree. */
+typedef struct splay_tree_node_s *splay_tree_node;
+
+/* The type of a function which compares two splay-tree keys. The
+ function should return values as for qsort. */
+typedef int (*splay_tree_compare_fn) PARAMS((splay_tree_key, splay_tree_key));
+
+/* The type of a function used to deallocate any resources associated
+ with the key. */
+typedef void (*splay_tree_delete_key_fn) PARAMS((splay_tree_key));
+
+/* The type of a function used to deallocate any resources associated
+ with the value. */
+typedef void (*splay_tree_delete_value_fn) PARAMS((splay_tree_value));
+
+/* The type of a function used to iterate over the tree. */
+typedef int (*splay_tree_foreach_fn) PARAMS((splay_tree_node, void*));
+
+/* The nodes in the splay tree. */
+struct splay_tree_node_s
+{
+ /* The key. */
+ splay_tree_key key;
+
+ /* The value. */
+ splay_tree_value value;
+
+ /* The left and right children, respectively. */
+ splay_tree_node left;
+ splay_tree_node right;
+};
+
+/* The splay tree itself. */
+typedef struct splay_tree_s
+{
+ /* The root of the tree. */
+ splay_tree_node root;
+
+ /* The comparision function. */
+ splay_tree_compare_fn comp;
+
+ /* The deallocate-key function. NULL if no cleanup is necessary. */
+ splay_tree_delete_key_fn delete_key;
+
+ /* The deallocate-value function. NULL if no cleanup is necessary. */
+ splay_tree_delete_value_fn delete_value;
+} *splay_tree;
+
+extern splay_tree splay_tree_new PARAMS((splay_tree_compare_fn,
+ splay_tree_delete_key_fn,
+ splay_tree_delete_value_fn));
+extern void splay_tree_delete PARAMS((splay_tree));
+extern splay_tree_node splay_tree_insert
+ PARAMS((splay_tree,
+ splay_tree_key,
+ splay_tree_value));
+extern void splay_tree_remove PARAMS((splay_tree,
+ splay_tree_key));
+extern splay_tree_node splay_tree_lookup
+ PARAMS((splay_tree,
+ splay_tree_key));
+extern splay_tree_node splay_tree_predecessor
+ PARAMS((splay_tree,
+ splay_tree_key));
+extern splay_tree_node splay_tree_successor
+ PARAMS((splay_tree,
+ splay_tree_key));
+extern splay_tree_node splay_tree_max
+ PARAMS((splay_tree));
+extern splay_tree_node splay_tree_min
+ PARAMS((splay_tree));
+extern int splay_tree_foreach PARAMS((splay_tree,
+ splay_tree_foreach_fn,
+ void*));
+extern int splay_tree_compare_ints PARAMS((splay_tree_key,
+ splay_tree_key));
+extern int splay_tree_compare_pointers PARAMS((splay_tree_key,
+ splay_tree_key));
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _SPLAY_TREE_H */
--- /dev/null
+/* Multibyte Character Functions.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* Note regarding cross compilation:
+
+ In general, translation of multibyte characters to wide characters can
+ only work in a native compiler since the translation function (mbtowc)
+ needs to know about both the source and target character encoding. However,
+ this particular implementation for JIS, SJIS and EUCJP source characters
+ will work for any compiler with a newlib target. Other targets may also
+ work provided that their wchar_t implementation is 2 bytes and the encoding
+ leaves the source character values unchanged (except for removing the
+ state shifting markers). */
+
+#include "config.h"
+#ifdef MULTIBYTE_CHARS
+#include "system.h"
+#include "mbchar.h"
+#include <locale.h>
+
+typedef enum {ESCAPE, DOLLAR, BRACKET, AT, B, J, NUL, JIS_CHAR, OTHER,
+ JIS_C_NUM} JIS_CHAR_TYPE;
+
+typedef enum {ASCII, A_ESC, A_ESC_DL, JIS, JIS_1, JIS_2, J_ESC, J_ESC_BR,
+ J2_ESC, J2_ESC_BR, INV, JIS_S_NUM} JIS_STATE;
+
+typedef enum {COPYA, COPYJ, COPYJ2, MAKE_A, MAKE_J, NOOP,
+ EMPTY, ERROR} JIS_ACTION;
+
+/* State/action tables for processing JIS encoding:
+
+ Where possible, switches to JIS are grouped with proceding JIS characters
+ and switches to ASCII are grouped with preceding JIS characters.
+ Thus, maximum returned length is:
+ 2 (switch to JIS) + 2 (JIS characters) + 2 (switch back to ASCII) = 6. */
+
+static JIS_STATE JIS_state_table[JIS_S_NUM][JIS_C_NUM] = {
+/* ESCAPE DOLLAR BRACKET AT B J NUL JIS_CHAR OTH*/
+/*ASCII*/ { A_ESC, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,ASCII,ASCII},
+/*A_ESC*/ { ASCII, A_ESC_DL,ASCII, ASCII, ASCII, ASCII, ASCII,ASCII,ASCII},
+/*A_ESC_DL*/{ ASCII, ASCII, ASCII, JIS, JIS, ASCII, ASCII,ASCII,ASCII},
+/*JIS*/ { J_ESC, JIS_1, JIS_1, JIS_1, JIS_1, JIS_1, INV, JIS_1,INV },
+/*JIS_1*/ { INV, JIS_2, JIS_2, JIS_2, JIS_2, JIS_2, INV, JIS_2,INV },
+/*JIS_2*/ { J2_ESC,JIS, JIS, JIS, JIS, JIS, INV, JIS, JIS },
+/*J_ESC*/ { INV, INV, J_ESC_BR, INV, INV, INV, INV, INV, INV },
+/*J_ESC_BR*/{ INV, INV, INV, INV, ASCII, ASCII, INV, INV, INV },
+/*J2_ESC*/ { INV, INV, J2_ESC_BR,INV, INV, INV, INV, INV, INV },
+/*J2_ESC_BR*/{INV, INV, INV, INV, ASCII, ASCII, INV, INV, INV },
+};
+
+static JIS_ACTION JIS_action_table[JIS_S_NUM][JIS_C_NUM] = {
+/* ESCAPE DOLLAR BRACKET AT B J NUL JIS_CHAR OTH */
+/*ASCII */ {NOOP, COPYA, COPYA, COPYA, COPYA, COPYA, EMPTY, COPYA, COPYA},
+/*A_ESC */ {COPYA, NOOP, COPYA, COPYA, COPYA, COPYA, COPYA, COPYA, COPYA},
+/*A_ESC_DL */{COPYA, COPYA, COPYA, MAKE_J, MAKE_J, COPYA, COPYA, COPYA, COPYA},
+/*JIS */ {NOOP, NOOP, NOOP, NOOP, NOOP, NOOP, ERROR, NOOP, ERROR},
+/*JIS_1 */ {ERROR, NOOP, NOOP, NOOP, NOOP, NOOP, ERROR, NOOP, ERROR},
+/*JIS_2 */ {NOOP, COPYJ2,COPYJ2,COPYJ2, COPYJ2, COPYJ2,ERROR, COPYJ2,COPYJ2},
+/*J_ESC */ {ERROR, ERROR, NOOP, ERROR, ERROR, ERROR, ERROR, ERROR, ERROR},
+/*J_ESC_BR */{ERROR, ERROR, ERROR, ERROR, NOOP, NOOP, ERROR, ERROR, ERROR},
+/*J2_ESC */ {ERROR, ERROR, NOOP, ERROR, ERROR, ERROR, ERROR, ERROR, ERROR},
+/*J2_ESC_BR*/{ERROR, ERROR, ERROR, ERROR, COPYJ, COPYJ, ERROR, ERROR, ERROR},
+};
+
+
+const char *literal_codeset = NULL;
+
+/* Store into *PWC (if PWC is not null) the wide character
+ corresponding to the multibyte character at the start of the
+ buffer S of size N. Return the number of bytes in the multibyte
+ character. Return -1 if the bytes do not form a valid character,
+ or 0 if S is null or points to a null byte.
+
+ This function behaves like the Standard C function mbtowc, except
+ it treats locale names of the form "C-..." specially. */
+
+int
+local_mbtowc (pwc, s, n)
+ wchar_t *pwc;
+ const char *s;
+ size_t n;
+{
+ static JIS_STATE save_state = ASCII;
+ JIS_STATE curr_state = save_state;
+ const unsigned char *t = (const unsigned char *) s;
+
+ if (s != NULL && n == 0)
+ return -1;
+
+ if (literal_codeset == NULL || strlen (literal_codeset) <= 1)
+ /* This must be the "C" locale or unknown locale -- fall thru */
+ ;
+ else if (! strcmp (literal_codeset, "C-SJIS"))
+ {
+ int char1;
+ if (s == NULL)
+ /* Not state-dependent. */
+ return 0;
+
+ char1 = *t;
+ if (ISSJIS1 (char1))
+ {
+ int char2 = t[1];
+
+ if (n <= 1)
+ return -1;
+
+ if (ISSJIS2 (char2))
+ {
+ if (pwc != NULL)
+ *pwc = (((wchar_t) *t) << 8) + (wchar_t) (*(t + 1));
+ return 2;
+ }
+
+ return -1;
+ }
+
+ if (pwc != NULL)
+ *pwc = (wchar_t) *t;
+
+ if (*t == '\0')
+ return 0;
+
+ return 1;
+ }
+ else if (! strcmp (literal_codeset, "C-EUCJP"))
+ {
+ int char1;
+
+ if (s == NULL)
+ /* Not state-dependent. */
+ return 0;
+
+ char1 = *t;
+ if (ISEUCJP (char1))
+ {
+ int char2 = t[1];
+
+ if (n <= 1)
+ return -1;
+
+ if (ISEUCJP (char2))
+ {
+ if (pwc != NULL)
+ *pwc = (((wchar_t) *t) << 8) + (wchar_t) (*(t + 1));
+ return 2;
+ }
+
+ return -1;
+ }
+
+ if (pwc != NULL)
+ *pwc = (wchar_t) *t;
+
+ if (*t == '\0')
+ return 0;
+
+ return 1;
+ }
+ else if (! strcmp (literal_codeset, "C-JIS"))
+ {
+ JIS_ACTION action;
+ JIS_CHAR_TYPE ch;
+ const unsigned char *ptr;
+ size_t i, curr_ch;
+
+ if (s == NULL)
+ {
+ save_state = ASCII;
+ /* State-dependent. */
+ return 1;
+ }
+
+ ptr = t;
+
+ for (i = 0; i < n; i++)
+ {
+ curr_ch = t[i];
+ switch (curr_ch)
+ {
+ case JIS_ESC_CHAR:
+ ch = ESCAPE;
+ break;
+ case '$':
+ ch = DOLLAR;
+ break;
+ case '@':
+ ch = AT;
+ break;
+ case '(':
+ ch = BRACKET;
+ break;
+ case 'B':
+ ch = B;
+ break;
+ case 'J':
+ ch = J;
+ break;
+ case '\0':
+ ch = NUL;
+ break;
+ default:
+ if (ISJIS (curr_ch))
+ ch = JIS_CHAR;
+ else
+ ch = OTHER;
+ }
+
+ action = JIS_action_table[curr_state][ch];
+ curr_state = JIS_state_table[curr_state][ch];
+
+ switch (action)
+ {
+ case NOOP:
+ break;
+
+ case EMPTY:
+ if (pwc != NULL)
+ *pwc = (wchar_t) 0;
+
+ save_state = curr_state;
+ return i;
+
+ case COPYA:
+ if (pwc != NULL)
+ *pwc = (wchar_t) *ptr;
+ save_state = curr_state;
+ return i + 1;
+
+ case COPYJ:
+ if (pwc != NULL)
+ *pwc = (((wchar_t) *ptr) << 8) + (wchar_t) (*(ptr + 1));
+
+ save_state = curr_state;
+ return i + 1;
+
+ case COPYJ2:
+ if (pwc != NULL)
+ *pwc = (((wchar_t) *ptr) << 8) + (wchar_t) (*(ptr + 1));
+
+ save_state = curr_state;
+ return ptr - t + 2;
+
+ case MAKE_A:
+ case MAKE_J:
+ ptr = (const unsigned char *) (t + i + 1);
+ break;
+
+ case ERROR:
+ default:
+ return -1;
+ }
+ }
+
+ /* More than n bytes needed. */
+ return -1;
+ }
+
+#ifdef CROSS_COMPILE
+ if (s == NULL)
+ /* Not state-dependent. */
+ return 0;
+
+ if (pwc != NULL)
+ *pwc = *s;
+ return 1;
+#else
+
+ /* This must be the "C" locale or unknown locale. */
+ return mbtowc (pwc, s, n);
+#endif
+}
+
+/* Return the number of bytes in the multibyte character at the start
+ of the buffer S of size N. Return -1 if the bytes do not form a
+ valid character, or 0 if S is null or points to a null byte.
+
+ This function behaves like the Standard C function mblen, except
+ it treats locale names of the form "C-..." specially. */
+
+int
+local_mblen (s, n)
+ const char *s;
+ size_t n;
+{
+ return local_mbtowc (NULL, s, n);
+}
+
+/* Return the maximum mumber of bytes in a multibyte character.
+
+ This function returns the same value as the Standard C macro MB_CUR_MAX,
+ except it treats locale names of the form "C-..." specially. */
+
+int
+local_mb_cur_max ()
+{
+ if (literal_codeset == NULL || strlen (literal_codeset) <= 1)
+ ;
+ else if (! strcmp (literal_codeset, "C-SJIS"))
+ return 2;
+ else if (! strcmp (literal_codeset, "C-EUCJP"))
+ return 2;
+ else if (! strcmp (literal_codeset, "C-JIS"))
+ return 8; /* 3 + 2 + 3 */
+
+#ifdef CROSS_COMPILE
+ return 1;
+#else
+ if (MB_CUR_MAX > 0)
+ return MB_CUR_MAX;
+
+ return 1; /* default */
+#endif
+}
+#else /* MULTIBYTE_CHARS */
+extern int dummy; /* silence 'ANSI C forbids an empty source file' warning */
+#endif /* MULTIBYTE_CHARS */
--- /dev/null
+/* Various declarations for functions found in mbchar.c
+ Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#ifndef GCC_MBCHAR_H
+#define GCC_MBCHAR_H
+
+#ifdef MULTIBYTE_CHARS
+
+/* Escape character used for JIS encoding */
+#define JIS_ESC_CHAR 0x1b
+
+#define ISSJIS1(c) (((c) >= 0x81 && (c) <= 0x9f) || ((c) >= 0xe0 && (c) <= 0xef))
+#define ISSJIS2(c) (((c) >= 0x40 && (c) <= 0x7e) || ((c) >= 0x80 && (c) <= 0xfc))
+#define ISEUCJP(c) ((c) >= 0xa1 && (c) <= 0xfe)
+#define ISJIS(c) ((c) >= 0x21 && (c) <= 0x7e)
+
+extern int local_mbtowc PARAMS ((wchar_t *, const char *, size_t));
+extern int local_mblen PARAMS ((const char *, size_t));
+extern int local_mb_cur_max PARAMS ((void));
+
+/* The locale being used for multibyte characters in string/char literals. */
+extern const char *literal_codeset;
+#endif /* MULTIBYTE_CHARS */
+#endif /* ! GCC_MBCHAR_H */
--- /dev/null
+/* Dependency generator for Makefile fragments.
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Zack Weinberg, Mar 2000
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ In other words, you are welcome to use, share and improve this program.
+ You are forbidden to forbid anyone else to use, share and improve
+ what you give them. Help stamp out software-hoarding! */
+
+#include "config.h"
+#include "system.h"
+#include "mkdeps.h"
+
+/* Keep this structure local to this file, so clients don't find it
+ easy to start making assumptions. */
+struct deps
+{
+ const char **targetv;
+ unsigned int ntargets; /* number of slots actually occupied */
+ unsigned int targets_size; /* amt of allocated space - in words */
+
+ const char **depv;
+ unsigned int ndeps;
+ unsigned int deps_size;
+};
+
+static const char *munge PARAMS ((const char *));
+
+/* Given a filename, quote characters in that filename which are
+ significant to Make. Note that it's not possible to quote all such
+ characters - e.g. \n, %, *, ?, [, \ (in some contexts), and ~ are
+ not properly handled. It isn't possible to get this right in any
+ current version of Make. (??? Still true? Old comment referred to
+ 3.76.1.) */
+
+static const char *
+munge (filename)
+ const char *filename;
+{
+ int len;
+ const char *p, *q;
+ char *dst, *buffer;
+
+ for (p = filename, len = 0; *p; p++, len++)
+ {
+ switch (*p)
+ {
+ case ' ':
+ case '\t':
+ /* GNU make uses a weird quoting scheme for white space.
+ A space or tab preceded by 2N+1 backslashes represents
+ N backslashes followed by space; a space or tab
+ preceded by 2N backslashes represents N backslashes at
+ the end of a file name; and backslashes in other
+ contexts should not be doubled. */
+ for (q = p - 1; filename <= q && *q == '\\'; q--)
+ len++;
+ len++;
+ break;
+
+ case '$':
+ /* '$' is quoted by doubling it. */
+ len++;
+ break;
+ }
+ }
+
+ /* Now we know how big to make the buffer. */
+ buffer = xmalloc (len + 1);
+
+ for (p = filename, dst = buffer; *p; p++, dst++)
+ {
+ switch (*p)
+ {
+ case ' ':
+ case '\t':
+ for (q = p - 1; filename <= q && *q == '\\'; q--)
+ *dst++ = '\\';
+ *dst++ = '\\';
+ break;
+
+ case '$':
+ *dst++ = '$';
+ break;
+
+ default:
+ /* nothing */;
+ }
+ *dst = *p;
+ }
+
+ *dst = '\0';
+ return buffer;
+}
+
+/* Public routines. */
+
+struct deps *
+deps_init ()
+{
+ struct deps *d = (struct deps *) xmalloc (sizeof (struct deps));
+
+ /* Allocate space for the vectors only if we need it. */
+
+ d->targetv = 0;
+ d->depv = 0;
+
+ d->ntargets = 0;
+ d->targets_size = 0;
+ d->ndeps = 0;
+ d->deps_size = 0;
+
+ return d;
+}
+
+void
+deps_free (d)
+ struct deps *d;
+{
+ unsigned int i;
+
+ if (d->targetv)
+ {
+ for (i = 0; i < d->ntargets; i++)
+ free ((PTR) d->targetv[i]);
+ free (d->targetv);
+ }
+
+ if (d->depv)
+ {
+ for (i = 0; i < d->ndeps; i++)
+ free ((PTR) d->depv[i]);
+ free (d->depv);
+ }
+
+ free (d);
+}
+
+/* Adds a target T. We make a copy, so it need not be a permanent
+ string. QUOTE is true if the string should be quoted. */
+void
+deps_add_target (d, t, quote)
+ struct deps *d;
+ const char *t;
+ int quote;
+{
+ if (d->ntargets == d->targets_size)
+ {
+ d->targets_size = d->targets_size * 2 + 4;
+ d->targetv = (const char **) xrealloc (d->targetv,
+ d->targets_size * sizeof (const char *));
+ }
+
+ if (quote)
+ t = munge (t); /* Also makes permanent copy. */
+ else
+ t = xstrdup (t);
+
+ d->targetv[d->ntargets++] = t;
+}
+
+/* Sets the default target if none has been given already. An empty
+ string as the default target in interpreted as stdin. The string
+ is quoted for MAKE. */
+void
+deps_add_default_target (d, tgt)
+ struct deps *d;
+ const char *tgt;
+{
+ /* Only if we have no targets. */
+ if (d->ntargets)
+ return;
+
+ if (tgt[0] == '\0')
+ deps_add_target (d, "-", 1);
+ else
+ {
+#ifndef TARGET_OBJECT_SUFFIX
+# define TARGET_OBJECT_SUFFIX ".o"
+#endif
+ char *start = lbasename (tgt);
+ char *o = (char *) alloca (strlen (start) + strlen (TARGET_OBJECT_SUFFIX) + 1);
+ char *suffix;
+
+ strcpy (o, start);
+
+ suffix = strrchr (o, '.');
+ if (!suffix)
+ suffix = o + strlen (o);
+ strcpy (suffix, TARGET_OBJECT_SUFFIX);
+
+ deps_add_target (d, o, 1);
+ }
+}
+
+void
+deps_add_dep (d, t)
+ struct deps *d;
+ const char *t;
+{
+ t = munge (t); /* Also makes permanent copy. */
+
+ if (d->ndeps == d->deps_size)
+ {
+ d->deps_size = d->deps_size * 2 + 8;
+ d->depv = (const char **)
+ xrealloc (d->depv, d->deps_size * sizeof (const char *));
+ }
+ d->depv[d->ndeps++] = t;
+}
+
+void
+deps_write (d, fp, colmax)
+ const struct deps *d;
+ FILE *fp;
+ unsigned int colmax;
+{
+ unsigned int size, i, column;
+
+ column = 0;
+ if (colmax && colmax < 34)
+ colmax = 34;
+
+ for (i = 0; i < d->ntargets; i++)
+ {
+ size = strlen (d->targetv[i]);
+ column += size;
+ if (colmax && column > colmax)
+ {
+ fputs (" \\\n ", fp);
+ column = 1 + size;
+ }
+ if (i)
+ {
+ putc (' ', fp);
+ column++;
+ }
+ fputs (d->targetv[i], fp);
+ }
+
+ putc (':', fp);
+ putc (' ', fp);
+ column += 2;
+
+ for (i = 0; i < d->ndeps; i++)
+ {
+ size = strlen (d->depv[i]);
+ column += size;
+ if (colmax && column > colmax)
+ {
+ fputs (" \\\n ", fp);
+ column = 1 + size;
+ }
+ if (i)
+ {
+ putc (' ', fp);
+ column++;
+ }
+ fputs (d->depv[i], fp);
+ }
+ putc ('\n', fp);
+}
+
+void
+deps_phony_targets (d, fp)
+ const struct deps *d;
+ FILE *fp;
+{
+ unsigned int i;
+
+ for (i = 1; i < d->ndeps; i++)
+ {
+ putc ('\n', fp);
+ fputs (d->depv[i], fp);
+ putc (':', fp);
+ putc ('\n', fp);
+ }
+}
--- /dev/null
+/* Dependency generator for Makefile fragments.
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Zack Weinberg, Mar 2000
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ In other words, you are welcome to use, share and improve this program.
+ You are forbidden to forbid anyone else to use, share and improve
+ what you give them. Help stamp out software-hoarding! */
+
+#ifndef GCC_MKDEPS_H
+#define GCC_MKDEPS_H
+
+/* This is the data structure used by all the functions in mkdeps.c.
+ It's quite straightforward, but should be treated as opaque. */
+
+struct deps;
+
+/* Create a deps buffer. */
+extern struct deps *deps_init PARAMS ((void));
+
+/* Destroy a deps buffer. */
+extern void deps_free PARAMS ((struct deps *));
+
+/* Add a target (appears on left side of the colon) to the deps list. Takes
+ a boolean indicating whether to quote the target for MAKE. */
+extern void deps_add_target PARAMS ((struct deps *, const char *, int));
+
+/* Sets the default target if none has been given already. An empty
+ string as the default target in interpreted as stdin. */
+extern void deps_add_default_target PARAMS ((struct deps *, const char *));
+
+/* Add a dependency (appears on the right side of the colon) to the
+ deps list. Dependencies will be printed in the order that they
+ were entered with this function. By convention, the first
+ dependency entered should be the primary source file. */
+extern void deps_add_dep PARAMS ((struct deps *, const char *));
+
+/* Write out a deps buffer to a specified file. The third argument
+ is the number of columns to word-wrap at (0 means don't wrap). */
+extern void deps_write PARAMS ((const struct deps *, FILE *,
+ unsigned int));
+
+/* For each dependency *except the first*, emit a dummy rule for that
+ file, causing it to depend on nothing. This is used to work around
+ the intermediate-file deletion misfeature in Make, in some
+ automatic dependency schemes. */
+extern void deps_phony_targets PARAMS ((const struct deps *, FILE *));
+
+#endif /* ! GCC_MKDEPS_H */
--- /dev/null
+/* Declarations for insn-output.c. These functions are defined in recog.c,
+ final.c, and varasm.c.
+ Copyright (C) 1987, 1991, 1994, 1997, 1998,
+ 1999, 2000 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* Initialize data in final at the beginning of a compilation. */
+extern void init_final PARAMS ((const char *));
+
+/* Called at end of source file,
+ to output the block-profiling table for this entire compilation. */
+extern void end_final PARAMS ((const char *));
+
+/* Enable APP processing of subsequent output.
+ Used before the output from an `asm' statement. */
+extern void app_enable PARAMS ((void));
+
+/* Disable APP processing of subsequent output.
+ Called from varasm.c before most kinds of output. */
+extern void app_disable PARAMS ((void));
+
+/* Return the number of slots filled in the current
+ delayed branch sequence (we don't count the insn needing the
+ delay slot). Zero if not in a delayed branch sequence. */
+extern int dbr_sequence_length PARAMS ((void));
+
+/* Indicate that branch shortening hasn't yet been done. */
+extern void init_insn_lengths PARAMS ((void));
+
+#ifdef RTX_CODE
+/* Obtain the current length of an insn. If branch shortening has been done,
+ get its actual length. Otherwise, get its maximum length. */
+extern int get_attr_length PARAMS ((rtx));
+
+/* Make a pass over all insns and compute their actual lengths by shortening
+ any branches of variable length if possible. */
+extern void shorten_branches PARAMS ((rtx));
+
+/* Output assembler code for the start of a function,
+ and initialize some of the variables in this file
+ for the new function. The label for the function and associated
+ assembler pseudo-ops have already been output in
+ `assemble_start_function'. */
+extern void final_start_function PARAMS ((rtx, FILE *, int));
+
+/* Output assembler code for the end of a function.
+ For clarity, args are same as those of `final_start_function'
+ even though not all of them are needed. */
+extern void final_end_function PARAMS ((rtx, FILE *, int));
+
+/* Output assembler code for some insns: all or part of a function. */
+extern void final PARAMS ((rtx, FILE *, int, int));
+
+/* The final scan for one insn, INSN. Args are same as in `final', except
+ that INSN is the insn being scanned. Value returned is the next insn to
+ be scanned. */
+extern rtx final_scan_insn PARAMS ((rtx, FILE *, int, int, int));
+
+/* Replace a SUBREG with a REG or a MEM, based on the thing it is a
+ subreg of. */
+extern rtx alter_subreg PARAMS ((rtx));
+
+/* Report inconsistency between the assembler template and the operands.
+ In an `asm', it's the user's fault; otherwise, the compiler's fault. */
+extern void output_operand_lossage PARAMS ((const char *));
+
+/* Output a string of assembler code, substituting insn operands.
+ Defined in final.c. */
+extern void output_asm_insn PARAMS ((const char *, rtx *));
+
+/* Compute a worst-case reference address of a branch so that it
+ can be safely used in the presence of aligned labels.
+ Defined in final.c. */
+extern int insn_current_reference_address PARAMS ((rtx));
+
+/* Find the alignment associated with a CODE_LABEL.
+ Defined in final.c. */
+extern int label_to_alignment PARAMS ((rtx));
+
+/* Output a LABEL_REF, or a bare CODE_LABEL, as an assembler symbol. */
+extern void output_asm_label PARAMS ((rtx));
+
+/* Print a memory reference operand for address X
+ using machine-dependent assembler syntax. */
+extern void output_address PARAMS ((rtx));
+
+/* Print an integer constant expression in assembler syntax.
+ Addition and subtraction are the only arithmetic
+ that may appear in these expressions. */
+extern void output_addr_const PARAMS ((FILE *, rtx));
+
+/* Output a string of assembler code, substituting numbers, strings
+ and fixed syntactic prefixes. */
+extern void asm_fprintf PARAMS ((FILE *file, const char *p, ...));
+
+/* Split up a CONST_DOUBLE or integer constant rtx into two rtx's for single
+ words. */
+extern void split_double PARAMS ((rtx, rtx *, rtx *));
+
+/* Return nonzero if this function has no function calls. */
+extern int leaf_function_p PARAMS ((void));
+
+/* Return 1 if this function uses only the registers that can be
+ safely renumbered. */
+extern int only_leaf_regs_used PARAMS ((void));
+
+/* Scan IN_RTX and its subexpressions, and renumber all regs into those
+ available in leaf functions. */
+extern void leaf_renumber_regs_insn PARAMS ((rtx));
+
+/* Locate the proper template for the given insn-code. */
+extern const char *get_insn_template PARAMS ((int, rtx));
+
+/* Functions in flow.c */
+extern void allocate_for_life_analysis PARAMS ((void));
+extern int regno_uninitialized PARAMS ((int));
+extern int regno_clobbered_at_setjmp PARAMS ((int));
+extern void find_basic_blocks PARAMS ((rtx, int, FILE *));
+extern void cleanup_cfg PARAMS ((void));
+extern void check_function_return_warnings PARAMS ((void));
+#endif
+
+/* Functions in varasm.c. */
+
+/* Tell assembler to switch to text section. */
+extern void text_section PARAMS ((void));
+
+/* Tell assembler to switch to data section. */
+extern void data_section PARAMS ((void));
+
+/* Tell assembler to make sure its in the data section. */
+extern void force_data_section PARAMS ((void));
+
+/* Tell assembler to switch to read-only data section. This is normally
+ the text section. */
+extern void readonly_data_section PARAMS ((void));
+
+/* Determine if we're in the text section. */
+extern int in_text_section PARAMS ((void));
+
+#ifdef EH_FRAME_SECTION_ASM_OP
+extern void eh_frame_section PARAMS ((void));
+#endif
+
+#ifdef CTORS_SECTION_ASM_OP
+extern void ctors_section PARAMS ((void));
+#endif
+
+#ifdef DTORS_SECTION_ASM_OP
+extern void dtors_section PARAMS ((void));
+#endif
+
+#ifdef BSS_SECTION_ASM_OP
+extern void bss_section PARAMS ((void));
+#endif
+
+#ifdef CONST_SECTION_ASM_OP
+extern void const_section PARAMS ((void));
+#endif
+
+#ifdef INIT_SECTION_ASM_OP
+extern void init_section PARAMS ((void));
+#endif
+
+#ifdef FINI_SECTION_ASM_OP
+extern void fini_section PARAMS ((void));
+#endif
+
+#ifdef TDESC_SECTION_ASM_OP
+extern void tdesc_section PARAMS ((void));
+#endif
+
+#ifdef TREE_CODE
+/* Tell assembler to change to section NAME for DECL.
+ If DECL is NULL, just switch to section NAME.
+ If NAME is NULL, get the name from DECL.
+ If RELOC is 1, the initializer for DECL contains relocs. */
+extern void named_section PARAMS ((tree, const char *, int));
+
+/* Tell assembler to switch to the section for function DECL. */
+extern void function_section PARAMS ((tree));
+
+/* Tell assembler to switch to the section for the exception table. */
+extern void exception_section PARAMS ((void));
+
+/* Declare DECL to be a weak symbol. */
+extern void declare_weak PARAMS ((tree));
+#endif /* TREE_CODE */
+
+/* Emit any pending weak declarations. */
+extern void weak_finish PARAMS ((void));
+
+/* Decode an `asm' spec for a declaration as a register name.
+ Return the register number, or -1 if nothing specified,
+ or -2 if the ASMSPEC is not `cc' or `memory' and is not recognized,
+ or -3 if ASMSPEC is `cc' and is not recognized,
+ or -4 if ASMSPEC is `memory' and is not recognized.
+ Accept an exact spelling or a decimal number.
+ Prefixes such as % are optional. */
+extern int decode_reg_name PARAMS ((const char *));
+
+#ifdef TREE_CODE
+/* Make the rtl for variable VAR be volatile.
+ Use this only for static variables. */
+extern void make_var_volatile PARAMS ((tree));
+
+/* Output alignment directive to align for constant expression EXP. */
+extern void assemble_constant_align PARAMS ((tree));
+
+extern void assemble_alias PARAMS ((tree, tree));
+
+/* Output a string of literal assembler code
+ for an `asm' keyword used between functions. */
+extern void assemble_asm PARAMS ((tree));
+
+/* Output assembler code for the constant pool of a function and associated
+ with defining the name of the function. DECL describes the function.
+ NAME is the function's name. For the constant pool, we use the current
+ constant pool data. */
+extern void assemble_start_function PARAMS ((tree, const char *));
+
+/* Output assembler code associated with defining the size of the
+ function. DECL describes the function. NAME is the function's name. */
+extern void assemble_end_function PARAMS ((tree, const char *));
+
+/* Assemble everything that is needed for a variable or function declaration.
+ Not used for automatic variables, and not used for function definitions.
+ Should not be called for variables of incomplete structure type.
+
+ TOP_LEVEL is nonzero if this variable has file scope.
+ AT_END is nonzero if this is the special handling, at end of compilation,
+ to define things that have had only tentative definitions.
+ DONT_OUTPUT_DATA if nonzero means don't actually output the
+ initial value (that will be done by the caller). */
+extern void assemble_variable PARAMS ((tree, int, int, int));
+
+/* Output something to declare an external symbol to the assembler.
+ (Most assemblers don't need this, so we normally output nothing.)
+ Do nothing if DECL is not external. */
+extern void assemble_external PARAMS ((tree));
+#endif /* TREE_CODE */
+
+/* Record an element in the table of global destructors.
+ How this is done depends on what sort of assembler and linker
+ are in use.
+
+ NAME should be the name of a global function to be called
+ at exit time. This name is output using assemble_name. */
+extern void assemble_destructor PARAMS ((const char *));
+
+/* Likewise for global constructors. */
+extern void assemble_constructor PARAMS ((const char *));
+
+/* Likewise for entries we want to record for garbage collection.
+ Garbage collection is still under development. */
+extern void assemble_gc_entry PARAMS ((const char *));
+
+/* Assemble code to leave SIZE bytes of zeros. */
+extern void assemble_zeros PARAMS ((int));
+
+/* Assemble an alignment pseudo op for an ALIGN-bit boundary. */
+extern void assemble_align PARAMS ((int));
+extern void assemble_eh_align PARAMS ((int));
+
+/* Assemble a string constant with the specified C string as contents. */
+extern void assemble_string PARAMS ((const char *, int));
+
+#ifdef RTX_CODE
+/* Similar, for calling a library function FUN. */
+extern void assemble_external_libcall PARAMS ((rtx));
+#endif
+
+/* Declare the label NAME global. */
+extern void assemble_global PARAMS ((const char *));
+
+/* Assemble a label named NAME. */
+extern void assemble_label PARAMS ((const char *));
+extern void assemble_eh_label PARAMS ((const char *));
+
+/* Output to FILE a reference to the assembler name of a C-level name NAME.
+ If NAME starts with a *, the rest of NAME is output verbatim.
+ Otherwise NAME is transformed in an implementation-defined way
+ (usually by the addition of an underscore).
+ Many macros in the tm file are defined to call this function. */
+extern void assemble_name PARAMS ((FILE *, const char *));
+
+#ifdef RTX_CODE
+/* Assemble the integer constant X into an object of SIZE bytes.
+ X must be either a CONST_INT or CONST_DOUBLE.
+
+ Return 1 if we were able to output the constant, otherwise 0. If FORCE is
+ non-zero, abort if we can't output the constant. */
+extern int assemble_integer PARAMS ((rtx, int, int));
+extern int assemble_eh_integer PARAMS ((rtx, int, int));
+
+#ifdef REAL_VALUE_TYPE
+/* Assemble the floating-point constant D into an object of size MODE. */
+extern void assemble_real PARAMS ((REAL_VALUE_TYPE,
+ enum machine_mode));
+#endif
+#endif
+
+/* At the end of a function, forget the memory-constants
+ previously made for CONST_DOUBLEs. Mark them as not on real_constant_chain.
+ Also clear out real_constant_chain and clear out all the chain-pointers. */
+extern void clear_const_double_mem PARAMS ((void));
+
+/* Start deferring output of subconstants. */
+extern void defer_addressed_constants PARAMS ((void));
+
+/* Stop deferring output of subconstants,
+ and output now all those that have been deferred. */
+extern void output_deferred_addressed_constants PARAMS ((void));
+
+/* Return the size of the constant pool. */
+extern int get_pool_size PARAMS ((void));
+
+#ifdef HAVE_peephole
+extern rtx peephole PARAMS ((rtx));
+#endif
+
+#ifdef TREE_CODE
+/* Write all the constants in the constant pool. */
+extern void output_constant_pool PARAMS ((const char *, tree));
+
+/* Return nonzero if VALUE is a valid constant-valued expression
+ for use in initializing a static variable; one that can be an
+ element of a "constant" initializer.
+
+ Return null_pointer_node if the value is absolute;
+ if it is relocatable, return the variable that determines the relocation.
+ We assume that VALUE has been folded as much as possible;
+ therefore, we do not need to check for such things as
+ arithmetic-combinations of integers. */
+extern tree initializer_constant_valid_p PARAMS ((tree, tree));
+
+/* Output assembler code for constant EXP to FILE, with no label.
+ This includes the pseudo-op such as ".int" or ".byte", and a newline.
+ Assumes output_addressed_constants has been done on EXP already.
+
+ Generate exactly SIZE bytes of assembler data, padding at the end
+ with zeros if necessary. SIZE must always be specified. */
+extern void output_constant PARAMS ((tree, int));
+#endif
+
+#ifdef RTX_CODE
+/* When outputting delayed branch sequences, this rtx holds the
+ sequence being output. It is null when no delayed branch
+ sequence is being output, so it can be used as a test in the
+ insn output code.
+
+ This variable is defined in final.c. */
+extern rtx final_sequence;
+#endif
+
+/* The line number of the beginning of the current function.
+ sdbout.c needs this so that it can output relative linenumbers. */
+
+#ifdef SDB_DEBUGGING_INFO /* Avoid undef sym in certain broken linkers. */
+extern int sdb_begin_function_line;
+#endif
+
+/* File in which assembler code is being written. */
+
+#ifdef BUFSIZ
+extern FILE *asm_out_file;
+#endif
+
+/* The first global object in the file. */
+extern const char *first_global_object_name;
+
+/* The first weak object in the file. */
+extern const char *weak_global_object_name;
+
+/* Nonzero if function being compiled doesn't contain any calls
+ (ignoring the prologue and epilogue). This is set prior to
+ local register allocation and is valid for the remaining
+ compiler passes. */
+
+extern int current_function_is_leaf;
+
+/* Nonzero if function being compiled doesn't contain any instructions
+ that can throw an exception. This is set prior to final. */
+
+extern int current_function_nothrow;
+
+/* Nonzero if function being compiled doesn't modify the stack pointer
+ (ignoring the prologue and epilogue). This is only valid after
+ life_analysis has run. */
+
+extern int current_function_sp_is_unchanging;
+
+/* Nonzero if the function being compiled is a leaf function which only
+ uses leaf registers. This is valid after reload (specifically after
+ sched2) and is useful only if the port defines LEAF_REGISTERS. */
+
+extern int current_function_uses_only_leaf_regs;
+
+/* Default file in which to dump debug output. */
+
+#ifdef BUFSIZ
+extern FILE *rtl_dump_file;
+#endif
+
+/* Nonnull if the insn currently being emitted was a COND_EXEC pattern. */
+extern struct rtx_def *current_insn_predicate;
+
+/* Last insn processed by final_scan_insn. */
+extern struct rtx_def *current_output_insn;
+
+/* Decide whether DECL needs to be in a writable section. RELOC is the same
+ as for SELECT_SECTION. */
+
+#define DECL_READONLY_SECTION(DECL,RELOC) \
+ (TREE_READONLY (DECL) \
+ && ! TREE_THIS_VOLATILE (DECL) \
+ && DECL_INITIAL (DECL) \
+ && (DECL_INITIAL (DECL) == error_mark_node \
+ || TREE_CONSTANT (DECL_INITIAL (DECL))) \
+ && ! (RELOC && (flag_pic || DECL_ONE_ONLY (DECL))))
+
+/* User label prefix in effect for this compilation. */
+extern const char *user_label_prefix;
+
+/* This macro gets just the user-specified name
+ out of the string in a SYMBOL_REF. On most machines,
+ we discard the * if any and that's all. */
+#ifndef STRIP_NAME_ENCODING
+#define STRIP_NAME_ENCODING(VAR,SYMBOL_NAME) \
+ (VAR) = ((SYMBOL_NAME) + ((SYMBOL_NAME)[0] == '*'))
+#endif
+/* Assign unique numbers to labels generated for profiling. */
+
+extern int profile_label_no;
--- /dev/null
+/* Utility to update paths from internal to external forms.
+ Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* This file contains routines to update a path, both to canonicalize
+ the directory format and to handle any prefix translation.
+
+ This file must be compiled with -DPREFIX= to specify the "prefix"
+ value used by configure. If a filename does not begin with this
+ prefix, it will not be affected other than by directory canonicalization.
+
+ Each caller of 'update_path' may specify both a filename and
+ a translation prefix and consist of the name of the package that contains
+ the file ("@GCC", "@BINUTIL", "@GNU", etc).
+
+ If the prefix is not specified, the filename will only undergo
+ directory canonicalization.
+
+ If it is specified, the string given by PREFIX will be replaced
+ by the specified prefix (with a '@' in front unless the prefix begins
+ with a '$') and further translation will be done as follows
+ until none of the two conditions below are met:
+
+ 1) If the filename begins with '@', the string between the '@' and
+ the end of the name or the first '/' or directory separator will
+ be considered a "key" and looked up as follows:
+
+ -- If this is a Win32 OS, then the Registry will be examined for
+ an entry of "key" in
+
+ HKEY_LOCAL_MACHINE\SOFTWARE\Free Software Foundation\<KEY>
+
+ if found, that value will be used. <KEY> defaults to GCC version
+ string, but can be overridden at configuration time.
+
+ -- If not found (or not a Win32 OS), the environment variable
+ key_ROOT (the value of "key" concatenated with the constant "_ROOT")
+ is tried. If that fails, then PREFIX (see above) is used.
+
+ 2) If the filename begins with a '$', the rest of the string up
+ to the end or the first '/' or directory separator will be used
+ as an environment variable, whose value will be returned.
+
+ Once all this is done, any '/' will be converted to DIR_SEPARATOR,
+ if they are different.
+
+ NOTE: using resolve_keyed_path under Win32 requires linking with
+ advapi32.dll. */
+
+
+#include "config.h"
+#include "system.h"
+#if defined(_WIN32) && defined(ENABLE_WIN32_REGISTRY)
+#include <windows.h>
+#endif
+#include "prefix.h"
+
+static const char *std_prefix = PREFIX;
+
+static const char *get_key_value PARAMS ((char *));
+static const char *translate_name PARAMS ((const char *));
+static char *save_string PARAMS ((const char *, int));
+char *concat VPARAMS ((const char *first, ...));
+
+#if defined(_WIN32) && defined(ENABLE_WIN32_REGISTRY)
+static char *lookup_key PARAMS ((char *));
+static HKEY reg_key = (HKEY) INVALID_HANDLE_VALUE;
+#endif
+
+/* Given KEY, as above, return its value. */
+
+static const char *
+get_key_value (key)
+ char *key;
+{
+ const char *prefix = 0;
+ char *temp = 0;
+
+#if defined(_WIN32) && defined(ENABLE_WIN32_REGISTRY)
+ prefix = lookup_key (key);
+#endif
+
+ if (prefix == 0)
+ prefix = getenv (temp = concat (key, "_ROOT", NULL));
+
+ if (prefix == 0)
+ prefix = std_prefix;
+
+ if (temp)
+ free (temp);
+
+ return prefix;
+}
+
+/* Concatenate a sequence of strings, returning the result.
+
+ This function is based on the one in libiberty. */
+
+char *
+concat VPARAMS ((const char *first, ...))
+{
+ register int length;
+ register char *newstr;
+ register char *end;
+ register const char *arg;
+ va_list args;
+#ifndef ANSI_PROTOTYPES
+ const char *first;
+#endif
+
+ /* First compute the size of the result and get sufficient memory. */
+
+ VA_START (args, first);
+#ifndef ANSI_PROTOTYPES
+ first = va_arg (args, const char *);
+#endif
+
+ arg = first;
+ length = 0;
+
+ while (arg != 0)
+ {
+ length += strlen (arg);
+ arg = va_arg (args, const char *);
+ }
+
+ newstr = (char *) xmalloc (length + 1);
+ va_end (args);
+
+ /* Now copy the individual pieces to the result string. */
+
+ VA_START (args, first);
+#ifndef ANSI_PROTOTYPES
+ first = va_arg (args, char *);
+#endif
+
+ end = newstr;
+ arg = first;
+ while (arg != 0)
+ {
+ while (*arg)
+ *end++ = *arg++;
+ arg = va_arg (args, const char *);
+ }
+ *end = '\000';
+ va_end (args);
+
+ return (newstr);
+}
+
+/* Return a copy of a string that has been placed in the heap. */
+
+static char *
+save_string (s, len)
+ const char *s;
+ int len;
+{
+ register char *result = xmalloc (len + 1);
+
+ memcpy (result, s, len);
+ result[len] = 0;
+ return result;
+}
+
+#if defined(_WIN32) && defined(ENABLE_WIN32_REGISTRY)
+
+/* Look up "key" in the registry, as above. */
+
+static char *
+lookup_key (key)
+ char *key;
+{
+ char *dst;
+ DWORD size;
+ DWORD type;
+ LONG res;
+
+ if (reg_key == (HKEY) INVALID_HANDLE_VALUE)
+ {
+ res = RegOpenKeyExA (HKEY_LOCAL_MACHINE, "SOFTWARE", 0,
+ KEY_READ, ®_key);
+
+ if (res == ERROR_SUCCESS)
+ res = RegOpenKeyExA (reg_key, "Free Software Foundation", 0,
+ KEY_READ, ®_key);
+
+ if (res == ERROR_SUCCESS)
+ res = RegOpenKeyExA (reg_key, WIN32_REGISTRY_KEY, 0,
+ KEY_READ, ®_key);
+
+ if (res != ERROR_SUCCESS)
+ {
+ reg_key = (HKEY) INVALID_HANDLE_VALUE;
+ return 0;
+ }
+ }
+
+ size = 32;
+ dst = (char *) xmalloc (size);
+
+ res = RegQueryValueExA (reg_key, key, 0, &type, dst, &size);
+ if (res == ERROR_MORE_DATA && type == REG_SZ)
+ {
+ dst = (char *) xrealloc (dst, size);
+ res = RegQueryValueExA (reg_key, key, 0, &type, dst, &size);
+ }
+
+ if (type != REG_SZ || res != ERROR_SUCCESS)
+ {
+ free (dst);
+ dst = 0;
+ }
+
+ return dst;
+}
+#endif
+
+/* If NAME starts with a '@' or '$', apply the translation rules above
+ and return a new name. Otherwise, return the given name. */
+
+static const char *
+translate_name (name)
+ const char *name;
+{
+ char code = name[0];
+ char *key;
+ const char *prefix = 0;
+ int keylen;
+
+ if (code != '@' && code != '$')
+ return name;
+
+ for (keylen = 0;
+ (name[keylen + 1] != 0 && !IS_DIR_SEPARATOR (name[keylen + 1]));
+ keylen++)
+ ;
+
+ key = (char *) alloca (keylen + 1);
+ strncpy (key, &name[1], keylen);
+ key[keylen] = 0;
+
+ name = &name[keylen + 1];
+
+ if (code == '@')
+ {
+ prefix = get_key_value (key);
+ if (prefix == 0)
+ prefix = std_prefix;
+ }
+ else
+ prefix = getenv (key);
+
+ if (prefix == 0)
+ prefix = PREFIX;
+
+ /* We used to strip trailing DIR_SEPARATORs here, but that can
+ sometimes yield a result with no separator when one was coded
+ and intended by the user, causing two path components to run
+ together. */
+
+ return concat (prefix, name, NULL);
+}
+
+/* Update PATH using KEY if PATH starts with PREFIX. */
+
+const char *
+update_path (path, key)
+ const char *path;
+ const char *key;
+{
+ if (! strncmp (path, std_prefix, strlen (std_prefix)) && key != 0)
+ {
+ if (key[0] != '$')
+ key = concat ("@", key, NULL);
+
+ path = concat (key, &path[strlen (std_prefix)], NULL);
+
+ while (path[0] == '@' || path[0] == '$')
+ path = translate_name (path);
+ }
+
+#ifdef UPDATE_PATH_HOST_CANONICALIZE
+/* Perform host dependant canonicalization when needed. */
+UPDATE_PATH_HOST_CANONICALIZE (path, key);
+#endif
+
+#ifdef DIR_SEPARATOR_2
+ /* Convert DIR_SEPARATOR_2 to DIR_SEPARATOR. */
+ if (DIR_SEPARATOR != DIR_SEPARATOR_2)
+ {
+ char *new_path = xstrdup (path);
+ path = new_path;
+ do {
+ if (*new_path == DIR_SEPARATOR_2)
+ *new_path = DIR_SEPARATOR;
+ } while (*new_path++);
+ }
+#endif
+
+#if defined (DIR_SEPARATOR) && !defined (DIR_SEPARATOR_2)
+ if (DIR_SEPARATOR != '/')
+ {
+ char *new_path = xstrdup (path);
+ path = new_path;
+ do {
+ if (*new_path == '/')
+ *new_path = DIR_SEPARATOR;
+ } while (*new_path++);
+ }
+#endif
+
+ return path;
+}
+
+/* Reset the standard prefix */
+void
+set_std_prefix (prefix, len)
+ const char *prefix;
+ int len;
+{
+ std_prefix = save_string (prefix, len);
+}
--- /dev/null
+/* Provide prototypes for functions exported from prefix.c.
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+
+#ifndef GCC_PREFIX_H
+#define GCC_PREFIX_H
+
+extern const char *update_path PARAMS ((const char *, const char *));
+extern void set_std_prefix PARAMS ((const char *, int));
+
+#endif /* ! GCC_PREFIX_H */
--- /dev/null
+/* Various stuff needed to hack the build for SDCC. */
+#define xmalloc(s) malloc(s)
+#define xstrdup(s) strdup(s)
+#define xrealloc(p,s) realloc(p,s)
+#define xcalloc(n,e) calloc(n,e)
+#define xmalloc_set_program_name(n) /* nada */
+#define xstrerror(e) strerror(e)
+
+extern char *lbasename(const char *path);
+
+/* Define results of standard character escape sequences. */
+#define TARGET_BELL 007
+#define TARGET_BS 010
+#define TARGET_TAB 011
+#define TARGET_NEWLINE 012
+#define TARGET_VT 013
+#define TARGET_FF 014
+#define TARGET_CR 015
+
+#define CHAR_TYPE_SIZE 8
+#define WCHAR_TYPE_SIZE 32 /* ? maybe ? */
+
+#define SUPPORTS_ONE_ONLY 0
--- /dev/null
+/* A splay-tree datatype.
+ Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Contributed by Mark Mitchell (mark@markmitchell.com).
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* For an easily readable description of splay-trees, see:
+
+ Lewis, Harry R. and Denenberg, Larry. Data Structures and Their
+ Algorithms. Harper-Collins, Inc. 1991. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#include <stdio.h>
+
+#include "libiberty.h"
+#include "splay-tree.h"
+
+static void splay_tree_delete_helper PARAMS((splay_tree,
+ splay_tree_node));
+static void splay_tree_splay PARAMS((splay_tree,
+ splay_tree_key));
+static splay_tree_node splay_tree_splay_helper
+ PARAMS((splay_tree,
+ splay_tree_key,
+ splay_tree_node*,
+ splay_tree_node*,
+ splay_tree_node*));
+static int splay_tree_foreach_helper PARAMS((splay_tree,
+ splay_tree_node,
+ splay_tree_foreach_fn,
+ void*));
+
+/* Deallocate NODE (a member of SP), and all its sub-trees. */
+
+static void
+splay_tree_delete_helper (sp, node)
+ splay_tree sp;
+ splay_tree_node node;
+{
+ if (!node)
+ return;
+
+ splay_tree_delete_helper (sp, node->left);
+ splay_tree_delete_helper (sp, node->right);
+
+ if (sp->delete_key)
+ (*sp->delete_key)(node->key);
+ if (sp->delete_value)
+ (*sp->delete_value)(node->value);
+
+ free ((char*) node);
+}
+
+/* Help splay SP around KEY. PARENT and GRANDPARENT are the parent
+ and grandparent, respectively, of NODE. */
+
+static splay_tree_node
+splay_tree_splay_helper (sp, key, node, parent, grandparent)
+ splay_tree sp;
+ splay_tree_key key;
+ splay_tree_node *node;
+ splay_tree_node *parent;
+ splay_tree_node *grandparent;
+{
+ splay_tree_node *next;
+ splay_tree_node n;
+ int comparison;
+
+ n = *node;
+
+ if (!n)
+ return *parent;
+
+ comparison = (*sp->comp) (key, n->key);
+
+ if (comparison == 0)
+ /* We've found the target. */
+ next = 0;
+ else if (comparison < 0)
+ /* The target is to the left. */
+ next = &n->left;
+ else
+ /* The target is to the right. */
+ next = &n->right;
+
+ if (next)
+ {
+ /* Continue down the tree. */
+ n = splay_tree_splay_helper (sp, key, next, node, parent);
+
+ /* The recursive call will change the place to which NODE
+ points. */
+ if (*node != n)
+ return n;
+ }
+
+ if (!parent)
+ /* NODE is the root. We are done. */
+ return n;
+
+ /* First, handle the case where there is no grandparent (i.e.,
+ *PARENT is the root of the tree.) */
+ if (!grandparent)
+ {
+ if (n == (*parent)->left)
+ {
+ *node = n->right;
+ n->right = *parent;
+ }
+ else
+ {
+ *node = n->left;
+ n->left = *parent;
+ }
+ *parent = n;
+ return n;
+ }
+
+ /* Next handle the cases where both N and *PARENT are left children,
+ or where both are right children. */
+ if (n == (*parent)->left && *parent == (*grandparent)->left)
+ {
+ splay_tree_node p = *parent;
+
+ (*grandparent)->left = p->right;
+ p->right = *grandparent;
+ p->left = n->right;
+ n->right = p;
+ *grandparent = n;
+ return n;
+ }
+ else if (n == (*parent)->right && *parent == (*grandparent)->right)
+ {
+ splay_tree_node p = *parent;
+
+ (*grandparent)->right = p->left;
+ p->left = *grandparent;
+ p->right = n->left;
+ n->left = p;
+ *grandparent = n;
+ return n;
+ }
+
+ /* Finally, deal with the case where N is a left child, but *PARENT
+ is a right child, or vice versa. */
+ if (n == (*parent)->left)
+ {
+ (*parent)->left = n->right;
+ n->right = *parent;
+ (*grandparent)->right = n->left;
+ n->left = *grandparent;
+ *grandparent = n;
+ return n;
+ }
+ else
+ {
+ (*parent)->right = n->left;
+ n->left = *parent;
+ (*grandparent)->left = n->right;
+ n->right = *grandparent;
+ *grandparent = n;
+ return n;
+ }
+}
+
+/* Splay SP around KEY. */
+
+static void
+splay_tree_splay (sp, key)
+ splay_tree sp;
+ splay_tree_key key;
+{
+ if (sp->root == 0)
+ return;
+
+ splay_tree_splay_helper (sp, key, &sp->root,
+ /*grandparent=*/0, /*parent=*/0);
+}
+
+/* Call FN, passing it the DATA, for every node below NODE, all of
+ which are from SP, following an in-order traversal. If FN every
+ returns a non-zero value, the iteration ceases immediately, and the
+ value is returned. Otherwise, this function returns 0. */
+
+static int
+splay_tree_foreach_helper (sp, node, fn, data)
+ splay_tree sp;
+ splay_tree_node node;
+ splay_tree_foreach_fn fn;
+ void* data;
+{
+ int val;
+
+ if (!node)
+ return 0;
+
+ val = splay_tree_foreach_helper (sp, node->left, fn, data);
+ if (val)
+ return val;
+
+ val = (*fn)(node, data);
+ if (val)
+ return val;
+
+ return splay_tree_foreach_helper (sp, node->right, fn, data);
+}
+
+/* Allocate a new splay tree, using COMPARE_FN to compare nodes,
+ DELETE_KEY_FN to deallocate keys, and DELETE_VALUE_FN to deallocate
+ values. */
+
+splay_tree
+splay_tree_new (compare_fn, delete_key_fn, delete_value_fn)
+ splay_tree_compare_fn compare_fn;
+ splay_tree_delete_key_fn delete_key_fn;
+ splay_tree_delete_value_fn delete_value_fn;
+{
+ splay_tree sp = (splay_tree) xmalloc (sizeof (struct splay_tree_s));
+ sp->root = 0;
+ sp->comp = compare_fn;
+ sp->delete_key = delete_key_fn;
+ sp->delete_value = delete_value_fn;
+
+ return sp;
+}
+
+/* Deallocate SP. */
+
+void
+splay_tree_delete (sp)
+ splay_tree sp;
+{
+ splay_tree_delete_helper (sp, sp->root);
+ free ((char*) sp);
+}
+
+/* Insert a new node (associating KEY with DATA) into SP. If a
+ previous node with the indicated KEY exists, its data is replaced
+ with the new value. Returns the new node. */
+
+splay_tree_node
+splay_tree_insert (sp, key, value)
+ splay_tree sp;
+ splay_tree_key key;
+ splay_tree_value value;
+{
+ int comparison = 0;
+
+ splay_tree_splay (sp, key);
+
+ if (sp->root)
+ comparison = (*sp->comp)(sp->root->key, key);
+
+ if (sp->root && comparison == 0)
+ {
+ /* If the root of the tree already has the indicated KEY, just
+ replace the value with VALUE. */
+ if (sp->delete_value)
+ (*sp->delete_value)(sp->root->value);
+ sp->root->value = value;
+ }
+ else
+ {
+ /* Create a new node, and insert it at the root. */
+ splay_tree_node node;
+
+ node = (splay_tree_node) xmalloc (sizeof (struct splay_tree_node_s));
+ node->key = key;
+ node->value = value;
+
+ if (!sp->root)
+ node->left = node->right = 0;
+ else if (comparison < 0)
+ {
+ node->left = sp->root;
+ node->right = node->left->right;
+ node->left->right = 0;
+ }
+ else
+ {
+ node->right = sp->root;
+ node->left = node->right->left;
+ node->right->left = 0;
+ }
+
+ sp->root = node;
+ }
+
+ return sp->root;
+}
+
+/* Remove KEY from SP. It is not an error if it did not exist. */
+
+void
+splay_tree_remove (sp, key)
+ splay_tree sp;
+ splay_tree_key key;
+{
+ splay_tree_splay (sp, key);
+
+ if (sp->root && (*sp->comp) (sp->root->key, key) == 0)
+ {
+ splay_tree_node left, right;
+
+ left = sp->root->left;
+ right = sp->root->right;
+
+ /* Delete the root node itself. */
+ if (sp->delete_value)
+ (*sp->delete_value) (sp->root->value);
+ free (sp->root);
+
+ /* One of the children is now the root. Doesn't matter much
+ which, so long as we preserve the properties of the tree. */
+ if (left)
+ {
+ sp->root = left;
+
+ /* If there was a right child as well, hang it off the
+ right-most leaf of the left child. */
+ if (right)
+ {
+ while (left->right)
+ left = left->right;
+ left->right = right;
+ }
+ }
+ else
+ sp->root = right;
+ }
+}
+
+/* Lookup KEY in SP, returning VALUE if present, and NULL
+ otherwise. */
+
+splay_tree_node
+splay_tree_lookup (sp, key)
+ splay_tree sp;
+ splay_tree_key key;
+{
+ splay_tree_splay (sp, key);
+
+ if (sp->root && (*sp->comp)(sp->root->key, key) == 0)
+ return sp->root;
+ else
+ return 0;
+}
+
+/* Return the node in SP with the greatest key. */
+
+splay_tree_node
+splay_tree_max (sp)
+ splay_tree sp;
+{
+ splay_tree_node n = sp->root;
+
+ if (!n)
+ return NULL;
+
+ while (n->right)
+ n = n->right;
+
+ return n;
+}
+
+/* Return the node in SP with the smallest key. */
+
+splay_tree_node
+splay_tree_min (sp)
+ splay_tree sp;
+{
+ splay_tree_node n = sp->root;
+
+ if (!n)
+ return NULL;
+
+ while (n->left)
+ n = n->left;
+
+ return n;
+}
+
+/* Return the immediate predecessor KEY, or NULL if there is no
+ predecessor. KEY need not be present in the tree. */
+
+splay_tree_node
+splay_tree_predecessor (sp, key)
+ splay_tree sp;
+ splay_tree_key key;
+{
+ int comparison;
+ splay_tree_node node;
+
+ /* If the tree is empty, there is certainly no predecessor. */
+ if (!sp->root)
+ return NULL;
+
+ /* Splay the tree around KEY. That will leave either the KEY
+ itself, its predecessor, or its successor at the root. */
+ splay_tree_splay (sp, key);
+ comparison = (*sp->comp)(sp->root->key, key);
+
+ /* If the predecessor is at the root, just return it. */
+ if (comparison < 0)
+ return sp->root;
+
+ /* Otherwise, find the leftmost element of the right subtree. */
+ node = sp->root->left;
+ if (node)
+ while (node->right)
+ node = node->right;
+
+ return node;
+}
+
+/* Return the immediate successor KEY, or NULL if there is no
+ predecessor. KEY need not be present in the tree. */
+
+splay_tree_node
+splay_tree_successor (sp, key)
+ splay_tree sp;
+ splay_tree_key key;
+{
+ int comparison;
+ splay_tree_node node;
+
+ /* If the tree is empty, there is certainly no predecessor. */
+ if (!sp->root)
+ return NULL;
+
+ /* Splay the tree around KEY. That will leave either the KEY
+ itself, its predecessor, or its successor at the root. */
+ splay_tree_splay (sp, key);
+ comparison = (*sp->comp)(sp->root->key, key);
+
+ /* If the successor is at the root, just return it. */
+ if (comparison > 0)
+ return sp->root;
+
+ /* Otherwise, find the rightmost element of the left subtree. */
+ node = sp->root->right;
+ if (node)
+ while (node->left)
+ node = node->left;
+
+ return node;
+}
+
+/* Call FN, passing it the DATA, for every node in SP, following an
+ in-order traversal. If FN every returns a non-zero value, the
+ iteration ceases immediately, and the value is returned.
+ Otherwise, this function returns 0. */
+
+int
+splay_tree_foreach (sp, fn, data)
+ splay_tree sp;
+ splay_tree_foreach_fn fn;
+ void *data;
+{
+ return splay_tree_foreach_helper (sp, sp->root, fn, data);
+}
+
+/* Splay-tree comparison function, treating the keys as ints. */
+
+int
+splay_tree_compare_ints (k1, k2)
+ splay_tree_key k1;
+ splay_tree_key k2;
+{
+ if ((int) k1 < (int) k2)
+ return -1;
+ else if ((int) k1 > (int) k2)
+ return 1;
+ else
+ return 0;
+}
+
+/* Splay-tree comparison function, treating the keys as pointers. */
+
+int
+splay_tree_compare_pointers (k1, k2)
+ splay_tree_key k1;
+ splay_tree_key k2;
+{
+ if ((char*) k1 < (char*) k2)
+ return -1;
+ else if ((char*) k1 > (char*) k2)
+ return 1;
+ else
+ return 0;
+}
--- /dev/null
+/* A splay-tree datatype.
+ Copyright 1998, 1999, 2000 Free Software Foundation, Inc.
+ Contributed by Mark Mitchell (mark@markmitchell.com).
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* For an easily readable description of splay-trees, see:
+
+ Lewis, Harry R. and Denenberg, Larry. Data Structures and Their
+ Algorithms. Harper-Collins, Inc. 1991.
+
+ The major feature of splay trees is that all basic tree operations
+ are amortized O(log n) time for a tree with n nodes. */
+
+#ifndef _SPLAY_TREE_H
+#define _SPLAY_TREE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <ansidecl.h>
+
+/* Use typedefs for the key and data types to facilitate changing
+ these types, if necessary. These types should be sufficiently wide
+ that any pointer or scalar can be cast to these types, and then
+ cast back, without loss of precision. */
+typedef unsigned long int splay_tree_key;
+typedef unsigned long int splay_tree_value;
+
+/* Forward declaration for a node in the tree. */
+typedef struct splay_tree_node_s *splay_tree_node;
+
+/* The type of a function which compares two splay-tree keys. The
+ function should return values as for qsort. */
+typedef int (*splay_tree_compare_fn) PARAMS((splay_tree_key, splay_tree_key));
+
+/* The type of a function used to deallocate any resources associated
+ with the key. */
+typedef void (*splay_tree_delete_key_fn) PARAMS((splay_tree_key));
+
+/* The type of a function used to deallocate any resources associated
+ with the value. */
+typedef void (*splay_tree_delete_value_fn) PARAMS((splay_tree_value));
+
+/* The type of a function used to iterate over the tree. */
+typedef int (*splay_tree_foreach_fn) PARAMS((splay_tree_node, void*));
+
+/* The nodes in the splay tree. */
+struct splay_tree_node_s
+{
+ /* The key. */
+ splay_tree_key key;
+
+ /* The value. */
+ splay_tree_value value;
+
+ /* The left and right children, respectively. */
+ splay_tree_node left;
+ splay_tree_node right;
+};
+
+/* The splay tree itself. */
+typedef struct splay_tree_s
+{
+ /* The root of the tree. */
+ splay_tree_node root;
+
+ /* The comparision function. */
+ splay_tree_compare_fn comp;
+
+ /* The deallocate-key function. NULL if no cleanup is necessary. */
+ splay_tree_delete_key_fn delete_key;
+
+ /* The deallocate-value function. NULL if no cleanup is necessary. */
+ splay_tree_delete_value_fn delete_value;
+} *splay_tree;
+
+extern splay_tree splay_tree_new PARAMS((splay_tree_compare_fn,
+ splay_tree_delete_key_fn,
+ splay_tree_delete_value_fn));
+extern void splay_tree_delete PARAMS((splay_tree));
+extern splay_tree_node splay_tree_insert
+ PARAMS((splay_tree,
+ splay_tree_key,
+ splay_tree_value));
+extern void splay_tree_remove PARAMS((splay_tree,
+ splay_tree_key));
+extern splay_tree_node splay_tree_lookup
+ PARAMS((splay_tree,
+ splay_tree_key));
+extern splay_tree_node splay_tree_predecessor
+ PARAMS((splay_tree,
+ splay_tree_key));
+extern splay_tree_node splay_tree_successor
+ PARAMS((splay_tree,
+ splay_tree_key));
+extern splay_tree_node splay_tree_max
+ PARAMS((splay_tree));
+extern splay_tree_node splay_tree_min
+ PARAMS((splay_tree));
+extern int splay_tree_foreach PARAMS((splay_tree,
+ splay_tree_foreach_fn,
+ void*));
+extern int splay_tree_compare_ints PARAMS((splay_tree_key,
+ splay_tree_key));
+extern int splay_tree_compare_pointers PARAMS((splay_tree_key,
+ splay_tree_key));
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _SPLAY_TREE_H */
--- /dev/null
+/* Symbol concatenation utilities.
+
+ Copyright (C) 1998, 2000 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ 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. */
+
+#ifndef SYM_CAT_H
+#define SYM_CAT_H
+
+#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
+#define CONCAT2(a,b) a##b
+#define CONCAT3(a,b,c) a##b##c
+#define CONCAT4(a,b,c,d) a##b##c##d
+#define STRINGX(s) #s
+#else
+/* Note one should never pass extra whitespace to the CONCATn macros,
+ e.g. CONCAT2(foo, bar) because traditonal C will keep the space between
+ the two labels instead of concatenating them. Instead, make sure to
+ write CONCAT2(foo,bar). */
+#define CONCAT2(a,b) a/**/b
+#define CONCAT3(a,b,c) a/**/b/**/c
+#define CONCAT4(a,b,c,d) a/**/b/**/c/**/d
+#define STRINGX(s) "s"
+#endif
+
+#define XCONCAT2(a,b) CONCAT2(a,b)
+#define XCONCAT3(a,b,c) CONCAT3(a,b,c)
+#define XCONCAT4(a,b,c,d) CONCAT4(a,b,c,d)
+
+/* Note the layer of indirection here is typically used to allow
+ stringification of the expansion of macros. I.e. "#define foo
+ bar", "XSTRING(foo)", to yield "bar". Be aware that this only
+ works for __STDC__, not for traditional C which will still resolve
+ to "foo". */
+#define XSTRING(s) STRINGX(s)
+
+#endif /* SYM_CAT_H */
--- /dev/null
+/* Get common system includes and various definitions and declarations based
+ on autoconf macros.
+ Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+
+#ifndef GCC_SYSTEM_H
+#define GCC_SYSTEM_H
+
+/* This is the location of the online document giving information how
+ to report bugs. If you change this string, also check for strings
+ not under control of the preprocessor. */
+#define GCCBUGURL "<URL:http://www.gnu.org/software/gcc/bugs.html>"
+
+#include "ansidecl.h"
+
+/* We must include stdarg.h/varargs.h before stdio.h. */
+#ifdef ANSI_PROTOTYPES
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#ifndef va_copy
+# ifdef __va_copy
+# define va_copy(d,s) __va_copy((d),(s))
+# else
+# define va_copy(d,s) ((d) = (s))
+# endif
+#endif
+
+#ifdef HAVE_STDDEF_H
+# include <stddef.h>
+#endif
+
+#include <stdio.h>
+
+#define CHAR_BIT 8
+
+/* Define a generic NULL if one hasn't already been defined. */
+#ifndef NULL
+#define NULL 0
+#endif
+
+/* There are an extraordinary number of issues with <ctype.h>.
+ The last straw is that it varies with the locale. Use libiberty's
+ replacement instead. */
+#include <safe-ctype.h>
+
+/* Define a default escape character; it's different for EBCDIC. */
+#ifndef TARGET_ESC
+#define TARGET_ESC 033
+#endif
+
+#include <sys/types.h>
+
+#include <errno.h>
+
+#if !defined (errno) && defined (HAVE_DECL_ERRNO) && !HAVE_DECL_ERRNO
+extern int errno;
+#endif
+
+#ifdef STRING_WITH_STRINGS
+# include <string.h>
+# include <strings.h>
+#else
+# ifdef HAVE_STRING_H
+# include <string.h>
+# else
+# ifdef HAVE_STRINGS_H
+# include <strings.h>
+# endif
+# endif
+#endif
+
+#ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
+
+/* If we don't have an overriding definition, set SUCCESS_EXIT_CODE and
+ FATAL_EXIT_CODE to EXIT_SUCCESS and EXIT_FAILURE respectively,
+ or 0 and 1 if those macros are not defined. */
+#ifndef SUCCESS_EXIT_CODE
+# ifdef EXIT_SUCCESS
+# define SUCCESS_EXIT_CODE EXIT_SUCCESS
+# else
+# define SUCCESS_EXIT_CODE 0
+# endif
+#endif
+
+#ifndef FATAL_EXIT_CODE
+# ifdef EXIT_FAILURE
+# define FATAL_EXIT_CODE EXIT_FAILURE
+# else
+# define FATAL_EXIT_CODE 1
+# endif
+#endif
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+
+#if HAVE_LIMITS_H
+# include <limits.h>
+#endif
+
+/* Get definitions of HOST_WIDE_INT and HOST_WIDEST_INT. */
+#include "hwint.h"
+
+/* Infrastructure for defining missing _MAX and _MIN macros. Note that
+ macros defined with these cannot be used in #if. */
+
+/* The extra casts work around common compiler bugs. */
+#define INTTYPE_SIGNED(t) (! ((t) 0 < (t) -1))
+/* The outer cast is needed to work around a bug in Cray C 5.0.3.0.
+ It is necessary at least when t == time_t. */
+#define INTTYPE_MINIMUM(t) ((t) (INTTYPE_SIGNED (t) \
+ ? ~ (t) 0 << (sizeof(t) * CHAR_BIT - 1) : (t) 0))
+#define INTTYPE_MAXIMUM(t) ((t) (~ (t) 0 - INTTYPE_MINIMUM (t)))
+
+/* Use that infrastructure to provide a few constants. */
+#ifndef UCHAR_MAX
+# define UCHAR_MAX INTTYPE_MAXIMUM (unsigned char)
+#endif
+
+#ifdef TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# ifdef HAVE_TIME_H
+# include <time.h>
+# endif
+# endif
+#endif
+
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#else
+# ifdef HAVE_SYS_FILE_H
+# include <sys/file.h>
+# endif
+#endif
+
+#ifndef SEEK_SET
+# define SEEK_SET 0
+# define SEEK_CUR 1
+# define SEEK_END 2
+#endif
+#ifndef F_OK
+# define F_OK 0
+# define X_OK 1
+# define W_OK 2
+# define R_OK 4
+#endif
+#ifndef O_RDONLY
+# define O_RDONLY 0
+#endif
+#ifndef O_WRONLY
+# define O_WRONLY 1
+#endif
+
+/* Some systems define these in, e.g., param.h. We undefine these names
+ here to avoid the warnings. We prefer to use our definitions since we
+ know they are correct. */
+
+#undef MIN
+#undef MAX
+#define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
+#define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
+
+/* Returns the least number N such that N * Y >= X. */
+#define CEIL(x,y) (((x) + (y) - 1) / (y))
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#ifndef WIFSIGNALED
+#define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f)
+#endif
+#ifndef WTERMSIG
+#define WTERMSIG(S) ((S) & 0x7f)
+#endif
+#ifndef WIFEXITED
+#define WIFEXITED(S) (((S) & 0xff) == 0)
+#endif
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
+#endif
+#ifndef WSTOPSIG
+#define WSTOPSIG WEXITSTATUS
+#endif
+
+/* The HAVE_DECL_* macros are three-state, undefined, 0 or 1. If they
+ are defined to 0 then we must provide the relevant declaration
+ here. These checks will be in the undefined state while configure
+ is running so be careful to test "defined (HAVE_DECL_*)". */
+
+#if defined (HAVE_DECL_ATOF) && !HAVE_DECL_ATOF
+extern double atof PARAMS ((const char *));
+#endif
+
+#if defined (HAVE_DECL_ATOL) && !HAVE_DECL_ATOL
+extern long atol PARAMS ((const char *));
+#endif
+
+#if defined (HAVE_DECL_FREE) && !HAVE_DECL_FREE
+extern void free PARAMS ((PTR));
+#endif
+
+#if defined (HAVE_DECL_GETCWD) && !HAVE_DECL_GETCWD
+extern char *getcwd PARAMS ((char *, size_t));
+#endif
+
+#if defined (HAVE_DECL_GETENV) && !HAVE_DECL_GETENV
+extern char *getenv PARAMS ((const char *));
+#endif
+
+#if defined (HAVE_DECL_GETOPT) && !HAVE_DECL_GETOPT
+extern int getopt PARAMS ((int, char * const *, const char *));
+#endif
+
+#if defined (HAVE_DECL_GETWD) && !HAVE_DECL_GETWD
+extern char *getwd PARAMS ((char *));
+#endif
+
+#if defined (HAVE_DECL_SBRK) && !HAVE_DECL_SBRK
+extern PTR sbrk PARAMS ((int));
+#endif
+
+#if defined (HAVE_DECL_STRSTR) && !HAVE_DECL_STRSTR
+extern char *strstr PARAMS ((const char *, const char *));
+#endif
+
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#if defined (HAVE_DECL_MALLOC) && !HAVE_DECL_MALLOC
+extern PTR malloc PARAMS ((size_t));
+#endif
+
+#if defined (HAVE_DECL_CALLOC) && !HAVE_DECL_CALLOC
+extern PTR calloc PARAMS ((size_t, size_t));
+#endif
+
+#if defined (HAVE_DECL_REALLOC) && !HAVE_DECL_REALLOC
+extern PTR realloc PARAMS ((PTR, size_t));
+#endif
+
+#ifdef HAVE_GETRLIMIT
+# if defined (HAVE_DECL_GETRLIMIT) && !HAVE_DECL_GETRLIMIT
+# ifndef getrlimit
+# ifdef ANSI_PROTOTYPES
+struct rlimit;
+# endif
+extern int getrlimit PARAMS ((int, struct rlimit *));
+# endif
+# endif
+#endif
+
+#ifdef HAVE_SETRLIMIT
+# if defined (HAVE_DECL_SETRLIMIT) && !HAVE_DECL_SETRLIMIT
+# ifndef setrlimit
+# ifdef ANSI_PROTOTYPES
+struct rlimit;
+# endif
+extern int setrlimit PARAMS ((int, const struct rlimit *));
+# endif
+# endif
+#endif
+
+#if !defined(__STDC__) && !defined(volatile)
+#define volatile
+#endif
+
+#if defined (HAVE_DECL_ABORT) && !HAVE_DECL_ABORT
+extern void abort PARAMS ((void));
+#endif
+
+/* 1 if we have C99 designated initializers. */
+#if !defined(HAVE_DESIGNATED_INITIALIZERS)
+#define HAVE_DESIGNATED_INITIALIZERS \
+ ((GCC_VERSION >= 2007) || (__STDC_VERSION__ >= 199901L))
+#endif
+
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+
+/* Test if something is a normal file. */
+#ifndef S_ISREG
+#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#endif
+
+/* Test if something is a directory. */
+#ifndef S_ISDIR
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+
+/* Test if something is a character special file. */
+#ifndef S_ISCHR
+#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
+#endif
+
+/* Test if something is a block special file. */
+#ifndef S_ISBLK
+#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
+#endif
+
+/* Test if something is a socket. */
+#ifndef S_ISSOCK
+# ifdef S_IFSOCK
+# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
+# else
+# define S_ISSOCK(m) 0
+# endif
+#endif
+
+/* Test if something is a FIFO. */
+#ifndef S_ISFIFO
+# ifdef S_IFIFO
+# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
+# else
+# define S_ISFIFO(m) 0
+# endif
+#endif
+
+/* Approximate O_NONBLOCK. */
+#ifndef O_NONBLOCK
+#define O_NONBLOCK O_NDELAY
+#endif
+
+/* Approximate O_NOCTTY. */
+#ifndef O_NOCTTY
+#define O_NOCTTY 0
+#endif
+
+/* Define well known filenos if the system does not define them. */
+#ifndef STDIN_FILENO
+# define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+# define STDOUT_FILENO 1
+#endif
+#ifndef STDERR_FILENO
+# define STDERR_FILENO 2
+#endif
+
+/* Some systems have mkdir that takes a single argument. */
+#ifdef MKDIR_TAKES_ONE_ARG
+# define mkdir(a,b) mkdir(a)
+#endif
+
+/* Provide a way to print an address via printf. */
+#ifndef HOST_PTR_PRINTF
+# ifdef HAVE_PRINTF_PTR
+# define HOST_PTR_PRINTF "%p"
+# else
+# define HOST_PTR_PRINTF \
+ (sizeof (int) == sizeof (char *) ? "%x" \
+ : sizeof (long) == sizeof (char *) ? "%lx" : "%llx")
+# endif
+#endif /* ! HOST_PTR_PRINTF */
+
+/* By default, colon separates directories in a path. */
+#ifndef PATH_SEPARATOR
+#define PATH_SEPARATOR ':'
+#endif
+
+#ifndef DIR_SEPARATOR
+#define DIR_SEPARATOR '/'
+#endif
+
+/* Define IS_DIR_SEPARATOR. */
+#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 */
+
+/* Say how to test for an absolute pathname. On Unix systems, this is if
+ it starts with a leading slash or a '$', the latter meaning the value of
+ an environment variable is to be used. On machien with DOS-based
+ file systems, it is also absolute if it starts with a drive identifier. */
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+#define IS_ABSOLUTE_PATHNAME(STR) \
+ (IS_DIR_SEPARATOR ((STR)[0]) || (STR)[0] == '$' \
+ || ((STR)[0] != '\0' && (STR)[1] == ':' && IS_DIR_SEPARATOR ((STR)[2])))
+#else
+#define IS_ABSOLUTE_PATHNAME(STR) \
+ (IS_DIR_SEPARATOR ((STR)[0]) || (STR)[0] == '$')
+#endif
+
+/* Get libiberty declarations. */
+/* #include "libiberty.h" */
+#include "sdcc.h"
+#include "symcat.h"
+
+/* Provide a default for the HOST_BIT_BUCKET.
+ This suffices for POSIX-like hosts. */
+
+#ifndef HOST_BIT_BUCKET
+#define HOST_BIT_BUCKET "/dev/null"
+#endif
+
+/* Be conservative and only use enum bitfields with GCC.
+ FIXME: provide a complete autoconf test for buggy enum bitfields. */
+
+#if (GCC_VERSION > 2000)
+#define ENUM_BITFIELD(TYPE) enum TYPE
+#else
+#define ENUM_BITFIELD(TYPE) unsigned int
+#endif
+
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+/* Traditional C cannot initialize union members of structs. Provide
+ a macro which expands appropriately to handle it. This only works
+ if you intend to initalize the union member to zero since it relies
+ on default initialization to zero in the traditional C case. */
+#ifdef __STDC__
+#define UNION_INIT_ZERO , {0}
+#else
+#define UNION_INIT_ZERO
+#endif
+
+/* Various error reporting routines want to use __FUNCTION__. */
+#if (GCC_VERSION < 2007)
+#ifndef __FUNCTION__
+#define __FUNCTION__ "?"
+#endif /* ! __FUNCTION__ */
+#endif
+
+/* As the last action in this file, we poison the identifiers that
+ shouldn't be used. Note, luckily gcc-3.0's token-based integrated
+ preprocessor won't trip on poisoned identifiers that arrive from
+ the expansion of macros. E.g. #define strrchr rindex, won't error
+ if rindex is poisoned after this directive is issued and later on
+ strrchr is called.
+
+ Note: We define bypass macros for the few cases where we really
+ want to use the libc memory allocation routines. Otherwise we
+ insist you use the "x" versions from libiberty. */
+
+#define really_call_malloc malloc
+#define really_call_calloc calloc
+#define really_call_realloc realloc
+
+#if (GCC_VERSION >= 3000)
+
+/* Note autoconf checks for prototype declarations and includes
+ system.h while doing so. Only poison these tokens if actually
+ compiling gcc, so that the autoconf declaration tests for malloc
+ etc don't spuriously fail. */
+#ifdef IN_GCC
+#undef malloc
+#undef realloc
+#undef calloc
+#undef strdup
+ #pragma GCC poison malloc realloc calloc strdup
+#endif /* IN_GCC */
+
+/* Note: not all uses of the `index' token (e.g. variable names and
+ structure members) have been eliminated. */
+#undef bcopy
+#undef bzero
+#undef bcmp
+#undef rindex
+ #pragma GCC poison bcopy bzero bcmp rindex
+
+#endif /* GCC >= 3.0 */
+
+#endif /* ! GCC_SYSTEM_H */
--- /dev/null
+#include "ansidecl.h"
+#include "version.h"
+
+const char *const version_string = "3.1 20010625 (experimental) + SDCC";
--- /dev/null
+#ifndef GCC_VERSION_H
+#define GCC_VERSION_H
+extern const char *const version_string;
+#endif /* ! GCC_VERSION_H */