diff options
| author | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-18 00:31:54 +0200 |
|---|---|---|
| committer | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-18 00:31:54 +0200 |
| commit | 268a53de823a6750d6256ee1fb1e7707b4b45740 (patch) | |
| tree | 42c1799a9a82b2f7d9790ee9fe181d72a7274751 /support/cpp | |
| download | sdcc-gas-268a53de823a6750d6256ee1fb1e7707b4b45740.tar.gz | |
sdcc-3.9.0 fork implementing GNU assembler syntax
This fork aims to provide better support for stm8-binutils
Diffstat (limited to 'support/cpp')
66 files changed, 42195 insertions, 0 deletions
diff --git a/support/cpp/Makefile b/support/cpp/Makefile new file mode 100644 index 0000000..132789e --- /dev/null +++ b/support/cpp/Makefile @@ -0,0 +1,323 @@ +# 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. + +EXEEXT = +TARGET = ../../bin/sdcpp$(EXEEXT) + + + +# This is the default target. +all: $(TARGET) + +# Directory where sources are, from where we are. +srcdir = . + + + +LIBS = +CFLAGS = -g -O2 -Wall +ALL_CFLAGS = $(INTERNAL_CFLAGS) $(X_CFLAGS) $(T_CFLAGS) \ + $(CFLAGS) $(WARN_CFLAGS) $(XCFLAGS) -DHAVE_CONFIG_H +ALL_CPPFLAGS = $(CPPFLAGS) $(X_CPPFLAGS) $(T_CPPFLAGS) +LDFLAGS = + +AWK = gawk +CC = gcc +AR = ar +AR_FLAGS = rc +RANLIB = ranlib +SHELL = /bin/sh +STRIP = strip +# on sysV, define this as cp. +INSTALL = /usr/bin/install -c +# 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} +INSTALL_DATA = ${INSTALL} -m 644 + +# 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 = -o $@ + +# 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)/../sdbinutils/include +LIBCPP_DIR = $(srcdir)/libcpp +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 = /usr/local +# 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 = /usr/local +# Directory in which to put host dependent programs and libraries +exec_prefix = ${prefix} +# Directory in which to put the executable for the command `gcc' +bindir = ${exec_prefix}/bin +includedir = $(local_prefix)/include +# where the info files go +exeext = + +transform = s,x,x, +lang_opt_files=$(srcdir)/sdcpp.opt + +# All option source files +ALL_OPT_FILES=$(lang_opt_files) $(extra_opt_files) + +# 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 + mkdir -p $(DESTDIR)$(bindir) + $(INSTALL) $(TARGET) $(DESTDIR)$(bindir)/`echo sdcpp|sed '$(transform)'`$(EXEEXT) + $(STRIP) $(DESTDIR)$(bindir)/`echo sdcpp|sed '$(transform)'`$(EXEEXT) + +uninstall: + rm -f $(DESTDIR)$(bindir)/`echo sdcpp|sed '$(transform)'`$(EXEEXT) +clean: + -rm -f $(TARGET) *.o core libcpp.a + rm -f s-options optionlist options.h s-options-h options.c + +distclean: clean + -rm -f auto-host.h auto-build.h cstamp-h Makefile \ + config.status config.run config.cache config.bak config.log *~ \ + configargs.h + +# 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@ +# + +INCLUDES = -I$(srcdir) -I$(LIBCPP_DIR) -I$(LIBCPP_DIR)/include -I$(LIBIBERTY_DIR) -I. + +# Always use -I$(srcdir)/config when compiling. +.c.o: + $(CC) -c $(ALL_CFLAGS) $(INCLUDES) $(ALL_CPPFLAGS) $< $(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 + + +optionlist: s-options ; @true +s-options: $(ALL_OPT_FILES) Makefile $(srcdir)/opt-gather.awk + $(AWK) -f $(srcdir)/opt-gather.awk $(ALL_OPT_FILES) > tmp-optionlist + $(SHELL) $(srcdir)/move-if-change tmp-optionlist optionlist + $(STAMP) s-options + +options.c: optionlist $(srcdir)/opt-functions.awk $(srcdir)/optc-gen.awk + $(AWK) -f $(srcdir)/opt-functions.awk -f $(srcdir)/optc-gen.awk \ + -v header_name="config.h system.h options.h" < $< > $@ + +options.h: s-options-h ; @true +s-options-h: optionlist $(srcdir)/opt-functions.awk $(srcdir)/opth-gen.awk + $(AWK) -f $(srcdir)/opt-functions.awk -f $(srcdir)/opth-gen.awk \ + < $< > tmp-options.h + $(SHELL) $(srcdir)/move-if-change tmp-options.h options.h + $(STAMP) $@ + +# +# 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 + +LIBCPP_OBJS = charset.o directives.o errors.o expr.o files.o identifiers.o \ + init.o lex.o line-map.o macro.o mkdeps.o symtab.o traditional.o + + +##LIBCPP_DEPS = cpplib.h cpphash.h hashtable.h intl.h options.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 + +charset.o: $(LIBCPP_DIR)/charset.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +directives.o: $(LIBCPP_DIR)/directives.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +errors.o: $(LIBCPP_DIR)/errors.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +expr.o: $(LIBCPP_DIR)/expr.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +files.o: $(LIBCPP_DIR)/files.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +identifiers.o: $(LIBCPP_DIR)/identifiers.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +init.o: $(LIBCPP_DIR)/init.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +lex.o: $(LIBCPP_DIR)/lex.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +line-map.o: $(LIBCPP_DIR)/line-map.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +macro.o: $(LIBCPP_DIR)/macro.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +mkdeps.o: $(LIBCPP_DIR)/mkdeps.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +symtab.o: $(LIBCPP_DIR)/symtab.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +traditional.o: $(LIBCPP_DIR)/traditional.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +########################## +# Libiberty + +LIBIBERTY = ../sdbinutils/libiberty/libiberty.a + +$(LIBIBERTY): + cd ../sdbinutils/libiberty/ && if [ -e Makefile ]; then $(MAKE); else ./configure && $(MAKE); fi + +########################## +# Sdcpp + +SDCC_OBJS = sdcpp.o sdcpp-opts.o sdcpp-diagnostic.o c-ppoutput.o cppdefault.o prefix.o version.o opts.o opts-common.o options.o c-incpath.o + +$(TARGET): $(SDCC_OBJS) $(LIBIBERTY) libcpp.a $(LIBDEPS) + mkdir -p $(dir $@) + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(SDCC_OBJS) \ + libcpp.a $(LIBIBERTY) $(LIBS) + +sdcpp.o: sdcpp.c $(CONFIG_H) $(SYSTEM_H) options.h + +sdcpp-opts.o: sdcpp-opts.c $(CONFIG_H) $(LIBCPP_DEPS) options.h + +sdcpp-diagnostic.o: sdcpp-diagnostic.c $(CONFIG_H) $(LIBCPP_DEPS) + +c-ppoutput.o: c-ppoutput.c $(CONFIG_H) $(SYSTEM_H) + +options.o: options.c $(CONFIG_H) $(LIBCPP_DEPS) options.h + +opts.o: opts.c $(CONFIG_H) $(LIBCPP_DEPS) options.h + +opts-common.o: opts.c $(CONFIG_H) $(LIBCPP_DEPS) options.h + +c-incpath.o: $(CONFIG_H) $(LIBCPP_DEPS) c-incpath.h + +version.o: version.c version.h + +cppcharset.o: cppcharset.c $(CONFIG_H) $(SYSTEM_H) + +prefix.o: prefix.c $(CONFIG_H) $(SYSTEM_H) Makefile prefix.h + $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ + -DPREFIX=\"$(prefix)\" \ + -c $(srcdir)/prefix.c + +cppdefault.o: cppdefault.c $(CONFIG_H) $(SYSTEM_H) cppdefault.h Makefile + $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ + $(PREPROCESSOR_DEFINES) \ + -c $(srcdir)/cppdefault.c diff --git a/support/cpp/Makefile.in b/support/cpp/Makefile.in new file mode 100644 index 0000000..a2e0cda --- /dev/null +++ b/support/cpp/Makefile.in @@ -0,0 +1,323 @@ +# 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. + +EXEEXT = @EXEEXT@ +TARGET = ../../bin/sdcpp$(EXEEXT) + +VPATH = @srcdir@ + +# This is the default target. +all: $(TARGET) + +# Directory where sources are, from where we are. +srcdir = @srcdir@ + + + +LIBS = @LIBS@ +CFLAGS = @CFLAGS@ @WALL_FLAG@ +ALL_CFLAGS = $(INTERNAL_CFLAGS) $(X_CFLAGS) $(T_CFLAGS) \ + $(CFLAGS) $(WARN_CFLAGS) $(XCFLAGS) @DEFS@ +ALL_CPPFLAGS = $(CPPFLAGS) $(X_CPPFLAGS) $(T_CPPFLAGS) +LDFLAGS = @LDFLAGS@ + +AWK = @AWK@ +CC = @CC@ +AR = @AR@ +AR_FLAGS = rc +RANLIB = @RANLIB@ +SHELL = /bin/sh +STRIP = @STRIP@ +# 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)/../sdbinutils/include +LIBCPP_DIR = $(srcdir)/libcpp +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@ + +transform = @program_transform_name@ +lang_opt_files=$(srcdir)/sdcpp.opt + +# All option source files +ALL_OPT_FILES=$(lang_opt_files) $(extra_opt_files) + +# Top build directory, relative to here. +top_builddir = @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 + mkdir -p $(DESTDIR)$(bindir) + $(INSTALL) $(TARGET) $(DESTDIR)$(bindir)/`echo sdcpp|sed '$(transform)'`$(EXEEXT) + $(STRIP) $(DESTDIR)$(bindir)/`echo sdcpp|sed '$(transform)'`$(EXEEXT) + +uninstall: + rm -f $(DESTDIR)$(bindir)/`echo sdcpp|sed '$(transform)'`$(EXEEXT) +clean: + -rm -f $(TARGET) *.o core libcpp.a + rm -f s-options optionlist options.h s-options-h options.c + +distclean: clean + -rm -f auto-host.h auto-build.h cstamp-h Makefile \ + config.status config.run config.cache config.bak config.log *~ \ + configargs.h + +# 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@ +# + +INCLUDES = -I$(srcdir) -I$(LIBCPP_DIR) -I$(LIBCPP_DIR)/include -I$(LIBIBERTY_DIR) -I. + +# Always use -I$(srcdir)/config when compiling. +.c.o: + $(CC) -c $(ALL_CFLAGS) $(INCLUDES) $(ALL_CPPFLAGS) $< $(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 + + +optionlist: s-options ; @true +s-options: $(ALL_OPT_FILES) Makefile $(srcdir)/opt-gather.awk + $(AWK) -f $(srcdir)/opt-gather.awk $(ALL_OPT_FILES) > tmp-optionlist + $(SHELL) $(srcdir)/move-if-change tmp-optionlist optionlist + $(STAMP) s-options + +options.c: optionlist $(srcdir)/opt-functions.awk $(srcdir)/optc-gen.awk + $(AWK) -f $(srcdir)/opt-functions.awk -f $(srcdir)/optc-gen.awk \ + -v header_name="config.h system.h options.h" < $< > $@ + +options.h: s-options-h ; @true +s-options-h: optionlist $(srcdir)/opt-functions.awk $(srcdir)/opth-gen.awk + $(AWK) -f $(srcdir)/opt-functions.awk -f $(srcdir)/opth-gen.awk \ + < $< > tmp-options.h + $(SHELL) $(srcdir)/move-if-change tmp-options.h options.h + $(STAMP) $@ + +# +# 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 + +LIBCPP_OBJS = charset.o directives.o errors.o expr.o files.o identifiers.o \ + init.o lex.o line-map.o macro.o mkdeps.o symtab.o traditional.o + + +##LIBCPP_DEPS = cpplib.h cpphash.h hashtable.h intl.h options.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 + +charset.o: $(LIBCPP_DIR)/charset.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +directives.o: $(LIBCPP_DIR)/directives.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +errors.o: $(LIBCPP_DIR)/errors.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +expr.o: $(LIBCPP_DIR)/expr.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +files.o: $(LIBCPP_DIR)/files.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +identifiers.o: $(LIBCPP_DIR)/identifiers.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +init.o: $(LIBCPP_DIR)/init.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +lex.o: $(LIBCPP_DIR)/lex.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +line-map.o: $(LIBCPP_DIR)/line-map.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +macro.o: $(LIBCPP_DIR)/macro.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +mkdeps.o: $(LIBCPP_DIR)/mkdeps.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +symtab.o: $(LIBCPP_DIR)/symtab.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +traditional.o: $(LIBCPP_DIR)/traditional.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +########################## +# Libiberty + +LIBIBERTY = ../sdbinutils/libiberty/libiberty.a + +$(LIBIBERTY): + cd ../sdbinutils/libiberty/ && if [ -e Makefile ]; then $(MAKE); else ./configure && $(MAKE); fi + +########################## +# Sdcpp + +SDCC_OBJS = sdcpp.o sdcpp-opts.o sdcpp-diagnostic.o c-ppoutput.o cppdefault.o prefix.o version.o opts.o opts-common.o options.o c-incpath.o + +$(TARGET): $(SDCC_OBJS) $(LIBIBERTY) libcpp.a $(LIBDEPS) + mkdir -p $(dir $@) + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(SDCC_OBJS) \ + libcpp.a $(LIBIBERTY) $(LIBS) + +sdcpp.o: sdcpp.c $(CONFIG_H) $(SYSTEM_H) options.h + +sdcpp-opts.o: sdcpp-opts.c $(CONFIG_H) $(LIBCPP_DEPS) options.h + +sdcpp-diagnostic.o: sdcpp-diagnostic.c $(CONFIG_H) $(LIBCPP_DEPS) + +c-ppoutput.o: c-ppoutput.c $(CONFIG_H) $(SYSTEM_H) + +options.o: options.c $(CONFIG_H) $(LIBCPP_DEPS) options.h + +opts.o: opts.c $(CONFIG_H) $(LIBCPP_DEPS) options.h + +opts-common.o: opts.c $(CONFIG_H) $(LIBCPP_DEPS) options.h + +c-incpath.o: $(CONFIG_H) $(LIBCPP_DEPS) c-incpath.h + +version.o: version.c version.h + +cppcharset.o: cppcharset.c $(CONFIG_H) $(SYSTEM_H) + +prefix.o: prefix.c $(CONFIG_H) $(SYSTEM_H) Makefile prefix.h + $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ + -DPREFIX=\"$(prefix)\" \ + -c $(srcdir)/prefix.c + +cppdefault.o: cppdefault.c $(CONFIG_H) $(SYSTEM_H) cppdefault.h Makefile + $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ + $(PREPROCESSOR_DEFINES) \ + -c $(srcdir)/cppdefault.c diff --git a/support/cpp/acconfig.h b/support/cpp/acconfig.h new file mode 100644 index 0000000..6367cf1 --- /dev/null +++ b/support/cpp/acconfig.h @@ -0,0 +1,44 @@ +/* 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 + +/* Define if cpp should also search $prefix/include. */ +#undef PREFIX_INCLUDE_DIR + +@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 diff --git a/support/cpp/aclocal.m4 b/support/cpp/aclocal.m4 new file mode 100644 index 0000000..b30c780 --- /dev/null +++ b/support/cpp/aclocal.m4 @@ -0,0 +1,913 @@ +dnl See if stdbool.h properly defines bool and true/false. +AC_DEFUN(gcc_AC_HEADER_STDBOOL, +[AC_CACHE_CHECK([for working stdbool.h], + ac_cv_header_stdbool_h, +[AC_TRY_COMPILE([#include <stdbool.h>], +[bool foo = false;], +ac_cv_header_stdbool_h=yes, ac_cv_header_stdbool_h=no)]) +if test $ac_cv_header_stdbool_h = yes; then + AC_DEFINE(HAVE_STDBOOL_H, 1, + [Define if you have a working <stdbool.h> header file.]) +fi +]) + +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 Check whether _Bool is built-in. +AC_DEFUN(gcc_AC_C__BOOL, +[AC_CACHE_CHECK(for built-in _Bool, gcc_cv_c__bool, +[AC_TRY_COMPILE(, +[_Bool foo;], +gcc_cv_c__bool=yes, gcc_cv_c__bool=no) +]) +if test $gcc_cv_c__bool = yes; then + AC_DEFINE(HAVE__BOOL, 1, [Define if the \`_Bool' type is built-in.]) +fi +]) + +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 +]) + diff --git a/support/cpp/auto-host.h b/support/cpp/auto-host.h new file mode 100644 index 0000000..530ae19 --- /dev/null +++ b/support/cpp/auto-host.h @@ -0,0 +1,253 @@ +/* auto-host.h. Generated from config.in by configure. */ +/* config.in. Generated from configure.ac by autoheader. */ +/* 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 */ + +/* Define if cpp should also search $prefix/include. */ +/* #undef PREFIX_INCLUDE_DIR */ + + +/* Define if building universal (internal helper macro) */ +/* #undef AC_APPLE_UNIVERSAL_BUILD */ + +/* Define as the number of bits in a byte, if \`limits.h' doesn't. */ +/* #undef CHAR_BIT */ + +/* Define to enable the use of a default assembler. */ +/* #undef DEFAULT_ASSEMBLER */ + +/* Define to enable the use of a default linker. */ +/* #undef DEFAULT_LINKER */ + +/* Define to 1 if you have the `clock' function. */ +#define HAVE_CLOCK 1 + +/* Define to 1 if we found this declaration otherwise define to 0. */ +#define HAVE_DECL_ABORT 0 + +/* Define to 1 if we found this declaration otherwise define to 0. */ +#define HAVE_DECL_CALLOC 0 + +/* Define to 1 if we found this declaration otherwise define to 0. */ +#define HAVE_DECL_CLOCK 0 + +/* Define to 1 if we found this declaration otherwise define to 0. */ +#define HAVE_DECL_ERRNO 0 + +/* Define to 1 if we found this declaration otherwise define to 0. */ +#define HAVE_DECL_FREE 0 + +/* Define to 1 if we found this declaration otherwise define to 0. */ +#define HAVE_DECL_GETENV 0 + +/* Define to 1 if we found this declaration otherwise define to 0. */ +#define HAVE_DECL_MALLOC 0 + +/* Define to 1 if we found this declaration otherwise define to 0. */ +#define HAVE_DECL_REALLOC 0 + +/* Define to 1 if we found this declaration otherwise define to 0. */ +#define HAVE_DECL_STRSIGNAL 0 + +/* Define to 1 if you have the <direct.h> header file. */ +/* #undef HAVE_DIRECT_H */ + +/* Define to 1 if you have the <fcntl.h> header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have the `getpagesize' function. */ +#define HAVE_GETPAGESIZE 1 + +/* Define to 1 if you have the <inttypes.h> header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the <limits.h> header file. */ +#define HAVE_LIMITS_H 1 + +/* Define to 1 if you have the `lstat' function. */ +#define HAVE_LSTAT 1 + +/* Define to 1 if you have the <malloc.h> header file. */ +#define HAVE_MALLOC_H 1 + +/* Define to 1 if you have the <memory.h> header file. */ +#define HAVE_MEMORY_H 1 + +/* Define if mmap can get us zeroed pages using MAP_ANON(YMOUS). */ +#define HAVE_MMAP_ANON 1 + +/* Define if mmap can get us zeroed pages from /dev/zero. */ +#define HAVE_MMAP_DEV_ZERO 1 + +/* Define if read-only mmap of a plain file works. */ +#define HAVE_MMAP_FILE 1 + +/* Define if you have a working <stdbool.h> header file. */ +#define HAVE_STDBOOL_H 1 + +/* Define to 1 if you have the <stddef.h> header file. */ +#define HAVE_STDDEF_H 1 + +/* Define to 1 if you have the <stdint.h> header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the <stdlib.h> header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `strchr' function. */ +#define HAVE_STRCHR 1 + +/* Define to 1 if cpp supports the ANSI # stringizing operator. */ +#define HAVE_STRINGIZE 1 + +/* Define to 1 if you have the <strings.h> header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the <string.h> header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strrchr' function. */ +#define HAVE_STRRCHR 1 + +/* Define to 1 if you have the `strsignal' function. */ +#define HAVE_STRSIGNAL 1 + +/* Define to 1 if you have the <sys/file.h> header file. */ +#define HAVE_SYS_FILE_H 1 + +/* Define to 1 if you have the <sys/param.h> header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the <sys/time.h> header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the <sys/types.h> header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define to 1 if you have the <time.h> header file. */ +#define HAVE_TIME_H 1 + +/* Define to 1 if you have the <unistd.h> header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if the \`_Bool' type is built-in. */ +#define HAVE__BOOL 1 + +/* Define if the host execution character set is EBCDIC. */ +/* #undef HOST_EBCDIC */ + +/* Define if host mkdir takes a single argument. */ +/* #undef MKDIR_TAKES_ONE_ARG */ + +/* Define if you want the C and C++ compilers to support multibyte character + sets for source code. */ +/* #undef MULTIBYTE_CHARS */ + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +/* #undef NO_MINUS_C_MINUS_O */ + +/* Define to the name of the distribution. */ +#define PACKAGE "sdcc" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "" + +/* The number of bytes in type int */ +#define SIZEOF_INT 4 + +/* The number of bytes in type long */ +#define SIZEOF_LONG 8 + +/* The number of bytes in type short */ +#define SIZEOF_SHORT 2 + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you can safely include both <string.h> and <strings.h>. */ +#define STRING_WITH_STRINGS 1 + +/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ +#define TIME_WITH_SYS_TIME 1 + +/* Define to the version of the distribution. */ +#define VERSION "const" + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +/* # undef WORDS_BIGENDIAN */ +# endif +#endif + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif + +/* Define to `int' if <sys/types.h> does not define. */ +/* #undef ssize_t */ + +/* 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 diff --git a/support/cpp/auto-host_vc_in.h b/support/cpp/auto-host_vc_in.h new file mode 100644 index 0000000..d5070be --- /dev/null +++ b/support/cpp/auto-host_vc_in.h @@ -0,0 +1,82 @@ +/* auto-host_in.h: Define values for MSVC 6.0. During build this file + should be copied to 'auto-host.h'. + +Copyright (C) 2002 Jesus Calvino-Fraga, jesusc@ieee.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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*/ + +#ifndef CPP_VC_H_ +#define CPP_VC_H_ + +#include <sys/stat.h> +#include <io.h> +#include <malloc.h> +#include <stdio.h> + +#define HAVE_STRINGIZE +#define STDC_HEADERS 1 +#define PACKAGE "sdcc" +#define LOCALEDIR "" +#define PREFIX "" +#define inline __inline +#define SIZEOF_INT 4 +#define SIZEOF_LONG 4 +#define HAVE_TIME_H 1 +#define HAVE_STRING_H 1 +#define HAVE_SYS_STAT_H 1 +#define HAVE_FCNTL_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STDDEF_H 1 +#define HAVE_LIMITS_H 1 +#ifndef __STDC__ +#define __STDC__ 1 +#endif + +#define ssize_t int + +#ifdef _MSC_VER +/*So, which ones are the standard types? */ +#define ino_t _ino_t +#define dev_t _dev_t +#define stat _stat +#define strdup _strdup +#define fstat _fstat +#define open _open +#define close _close +#define read _read +#define write _write + +#define O_APPEND _O_APPEND +#define O_CREAT _O_CREAT +#define O_EXCL _O_EXCL +#define O_RDONLY _O_RDONLY +#define O_RDWR _O_RDWR +#define O_TRUNC _O_TRUNC +#define O_WRONLY _O_WRONLY +#define O_BINARY _O_BINARY +#define O_TEXT _O_TEXT + +/*This one borrowed from \borland\bcc55\include\sys\stat.h*/ +#define S_IFBLK 0x3000 /* block special */ + +/*If you want to see all the scary warnings remove these ones:*/ +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4090 ) +#pragma warning( disable : 4022 ) + +typedef int intptr_t; +#endif /* _MSC_VER */ + +#endif /*CPP_VC_H_*/ diff --git a/support/cpp/c-incpath.c b/support/cpp/c-incpath.c new file mode 100644 index 0000000..3933dee --- /dev/null +++ b/support/cpp/c-incpath.c @@ -0,0 +1,413 @@ +/* Set up combined include path chain for the preprocessor. + Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. + + Broken out of cppinit.c and cppfiles.c and rewritten Mar 2003. + +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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include "config.h" +#include "system.h" +#include "cpplib.h" +#include "prefix.h" +#include "intl.h" +#include "c-incpath.h" +#include "cppdefault.h" + +/* 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))) +# define INO_T_COPY(DEST, SRC) memcpy(&(DEST), &(SRC), sizeof (SRC)) +#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 +# define INO_T_COPY(DEST, SRC) (DEST) = (SRC) +#endif + +static const char dir_separator_str[] = { DIR_SEPARATOR, 0 }; + +static void add_env_var_paths (const char *, int); +static void add_standard_paths (const char *, const char *, const char *, int); +static void free_path (struct cpp_dir *, int); +static void merge_include_chains (cpp_reader *, int); +static struct cpp_dir *remove_duplicates (cpp_reader *, struct cpp_dir *, + struct cpp_dir *, + struct cpp_dir *, int); + +/* Include chains heads and tails. */ +static struct cpp_dir *heads[4]; +static struct cpp_dir *tails[4]; +static bool quote_ignores_source_dir; +enum { REASON_QUIET = 0, REASON_NOENT, REASON_DUP, REASON_DUP_SYS }; + +/* Free an element of the include chain, possibly giving a reason. */ +static void +free_path (struct cpp_dir *path, int reason) +{ + switch (reason) + { + case REASON_DUP: + case REASON_DUP_SYS: + fprintf (stderr, _("ignoring duplicate directory \"%s\"\n"), path->name); + if (reason == REASON_DUP_SYS) + fprintf (stderr, + _(" as it is a non-system directory that duplicates a system directory\n")); + break; + + case REASON_NOENT: + fprintf (stderr, _("ignoring nonexistent directory \"%s\"\n"), + path->name); + break; + + case REASON_QUIET: + default: + break; + } + + free (path->name); + free (path); +} + +/* Read ENV_VAR for a PATH_SEPARATOR-separated list of file names; and + append all the names to the search path CHAIN. */ +static void +add_env_var_paths (const char *env_var, int chain) +{ + char *p, *q, *path; + + GET_ENVIRONMENT (q, env_var); + + if (!q) + return; + + for (p = q; *q; p = q + 1) + { + q = p; + while (*q != 0 && *q != PATH_SEPARATOR) + q++; + + if (p == q) + path = xstrdup ("."); + else + { + path = XNEWVEC (char, q - p + 1); + memcpy (path, p, q - p); + path[q - p] = '\0'; + } + + add_path (path, chain, chain == SYSTEM, false); + } +} + +/* Append the standard include chain defined in cppdefault.c. */ +static void +add_standard_paths (const char *sysroot, const char *iprefix, + const char *imultilib, int cxx_stdinc) +{ + const struct default_include *p; + size_t len; + + if (iprefix && (len = cpp_GCC_INCLUDE_DIR_len) != 0) + { + /* Look for directories that start with the standard prefix. + "Translate" them, i.e. replace /usr/local/lib/gcc... with + IPREFIX and search them first. */ + for (p = cpp_include_defaults; p->fname; p++) + { + if (!p->cplusplus || cxx_stdinc) + { + /* Should we be translating sysrooted dirs too? Assume + that iprefix and sysroot are mutually exclusive, for + now. */ + if (sysroot && p->add_sysroot) + continue; + if (!strncmp (p->fname, cpp_GCC_INCLUDE_DIR, len)) + { + char *str = concat (iprefix, p->fname + len, NULL); + if (p->multilib && imultilib) + str = concat (str, dir_separator_str, imultilib, NULL); + add_path (str, SYSTEM, p->cxx_aware, false); + } + } + } + } + + for (p = cpp_include_defaults; p->fname; p++) + { + if (!p->cplusplus || cxx_stdinc) + { + char *str; + + /* Should this directory start with the sysroot? */ + if (sysroot && p->add_sysroot) + str = concat (sysroot, p->fname, NULL); + else + str = update_path (p->fname, p->component); + + if (p->multilib && imultilib) + str = concat (str, dir_separator_str, imultilib, NULL); + + add_path (str, SYSTEM, p->cxx_aware, false); + } + } +} + +/* For each duplicate path in chain HEAD, keep just the first one. + Remove each path in chain HEAD that also exists in chain SYSTEM. + Set the NEXT pointer of the last path in the resulting chain to + JOIN, unless it duplicates JOIN in which case the last path is + removed. Return the head of the resulting chain. Any of HEAD, + JOIN and SYSTEM can be NULL. */ + +static struct cpp_dir * +remove_duplicates (cpp_reader *pfile, struct cpp_dir *head, + struct cpp_dir *system, struct cpp_dir *join, + int verbose) +{ + struct cpp_dir **pcur, *tmp, *cur; + struct stat st; + + for (pcur = &head; *pcur; ) + { + int reason = REASON_QUIET; + + cur = *pcur; + + if (stat (cur->name, &st)) + { + /* Dirs that don't exist are silently ignored, unless verbose. */ + if (errno != ENOENT) + cpp_errno (pfile, CPP_DL_ERROR, cur->name); + else + { + /* If -Wmissing-include-dirs is given, warn. */ + cpp_options *opts = cpp_get_options (pfile); + if (opts->warn_missing_include_dirs && cur->user_supplied_p) + cpp_errno (pfile, CPP_DL_WARNING, cur->name); + reason = REASON_NOENT; + } + } + else if (!S_ISDIR (st.st_mode)) + cpp_error_with_line (pfile, CPP_DL_ERROR, 0, 0, + "%s: not a directory", cur->name); + else + { + INO_T_COPY (cur->ino, st.st_ino); + cur->dev = st.st_dev; + + /* Remove this one if it is in the system chain. */ + reason = REASON_DUP_SYS; + for (tmp = system; tmp; tmp = tmp->next) + if (INO_T_EQ (tmp->ino, cur->ino) && tmp->dev == cur->dev + && cur->construct == tmp->construct) + break; + + if (!tmp) + { + /* Duplicate of something earlier in the same chain? */ + reason = REASON_DUP; + for (tmp = head; tmp != cur; tmp = tmp->next) + if (INO_T_EQ (cur->ino, tmp->ino) && cur->dev == tmp->dev + && cur->construct == tmp->construct) + break; + + if (tmp == cur + /* Last in the chain and duplicate of JOIN? */ + && !(cur->next == NULL && join + && INO_T_EQ (cur->ino, join->ino) + && cur->dev == join->dev + && cur->construct == join->construct)) + { + /* Unique, so keep this directory. */ + pcur = &cur->next; + continue; + } + } + } + + /* Remove this entry from the chain. */ + *pcur = cur->next; + free_path (cur, verbose ? reason: REASON_QUIET); + } + + *pcur = join; + return head; +} + +/* Merge the four include chains together in the order quote, bracket, + system, after. Remove duplicate dirs (as determined by + INO_T_EQ()). + + 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 -iquote foo -iquote bar -Ifoo -Iquux. It is + however safe to treat -iquote bar -iquote foo -Ifoo -Iquux as if + written -iquote bar -Ifoo -Iquux. */ + +static void +merge_include_chains (cpp_reader *pfile, int verbose) +{ + /* Join the SYSTEM and AFTER chains. Remove duplicates in the + resulting SYSTEM chain. */ + if (heads[SYSTEM]) + tails[SYSTEM]->next = heads[AFTER]; + else + heads[SYSTEM] = heads[AFTER]; + heads[SYSTEM] = remove_duplicates (pfile, heads[SYSTEM], 0, 0, verbose); + + /* Remove duplicates from BRACKET that are in itself or SYSTEM, and + join it to SYSTEM. */ + heads[BRACKET] = remove_duplicates (pfile, heads[BRACKET], heads[SYSTEM], + heads[SYSTEM], verbose); + + /* Remove duplicates from QUOTE that are in itself or SYSTEM, and + join it to BRACKET. */ + heads[QUOTE] = remove_duplicates (pfile, heads[QUOTE], heads[SYSTEM], + heads[BRACKET], verbose); + + /* If verbose, print the list of dirs to search. */ + if (verbose) + { + struct cpp_dir *p; + + fprintf (stderr, _("#include \"...\" search starts here:\n")); + for (p = heads[QUOTE];; p = p->next) + { + if (p == heads[BRACKET]) + fprintf (stderr, _("#include <...> search starts here:\n")); + if (!p) + break; + fprintf (stderr, " %s\n", p->name); + } + fprintf (stderr, _("End of search list.\n")); + } +} + +/* Use given -I paths for #include "..." but not #include <...>, and + 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.) */ +void +split_quote_chain (void) +{ + heads[QUOTE] = heads[BRACKET]; + tails[QUOTE] = tails[BRACKET]; + heads[BRACKET] = NULL; + tails[BRACKET] = NULL; + /* This is NOT redundant. */ + quote_ignores_source_dir = true; +} + +/* Add P to the chain specified by CHAIN. */ + +void +add_cpp_dir_path (cpp_dir *p, int chain) +{ + if (tails[chain]) + tails[chain]->next = p; + else + heads[chain] = p; + tails[chain] = p; +} + +/* Add PATH to the include chain CHAIN. PATH must be malloc-ed and + NUL-terminated. */ +void +add_path (char *path, int chain, int cxx_aware, bool user_supplied_p) +{ + cpp_dir *p; + +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + /* Convert all backslashes to slashes. The native CRT stat() + function does not recognize a directory that ends in a backslash + (unless it is a drive root dir, such "c:\"). Forward slashes, + trailing or otherwise, cause no problems for stat(). */ + char* c; + for (c = path; *c; c++) + if (*c == '\\') *c = '/'; +#endif + + p = XNEW (cpp_dir); + p->next = NULL; + p->name = path; + if (chain == SYSTEM || chain == AFTER) + p->sysp = 1 + !cxx_aware; + else + p->sysp = 0; + p->construct = 0; + p->user_supplied_p = user_supplied_p; + + add_cpp_dir_path (p, chain); +} + +/* Exported function to handle include chain merging, duplicate + removal, and registration with cpplib. */ +void +register_include_chains (cpp_reader *pfile, const char *sysroot, + const char *iprefix, const char *imultilib, + int stdinc, int cxx_stdinc, int verbose) +{ + static const char *const lang_env_vars[] = + { "C_INCLUDE_PATH", "CPLUS_INCLUDE_PATH", + "OBJC_INCLUDE_PATH", "OBJCPLUS_INCLUDE_PATH" }; + cpp_options *cpp_opts = cpp_get_options (pfile); + size_t idx = (cpp_opts->objc ? 2: 0); + + if (cpp_opts->cplusplus) + idx++; + else + cxx_stdinc = false; + + /* CPATH and language-dependent environment variables may add to the + include chain. */ + add_env_var_paths ("CPATH", BRACKET); + add_env_var_paths (lang_env_vars[idx], SYSTEM); + + target_c_incpath.extra_pre_includes (sysroot, iprefix, stdinc); + + /* Finally chain on the standard directories. */ + if (stdinc) + add_standard_paths (sysroot, iprefix, imultilib, cxx_stdinc); + + target_c_incpath.extra_includes (sysroot, iprefix, stdinc); + + merge_include_chains (pfile, verbose); + + cpp_set_include_chains (pfile, heads[QUOTE], heads[BRACKET], + quote_ignores_source_dir); +} +#if !(defined TARGET_EXTRA_INCLUDES) || !(defined TARGET_EXTRA_PRE_INCLUDES) +static void hook_void_charptr_charptr_int (const char *sysroot ATTRIBUTE_UNUSED, + const char *iprefix ATTRIBUTE_UNUSED, + int stdinc ATTRIBUTE_UNUSED) +{ +} +#endif + +#ifndef TARGET_EXTRA_INCLUDES +#define TARGET_EXTRA_INCLUDES hook_void_charptr_charptr_int +#endif +#ifndef TARGET_EXTRA_PRE_INCLUDES +#define TARGET_EXTRA_PRE_INCLUDES hook_void_charptr_charptr_int +#endif + +struct target_c_incpath_s target_c_incpath = { TARGET_EXTRA_PRE_INCLUDES, TARGET_EXTRA_INCLUDES }; + diff --git a/support/cpp/c-incpath.h b/support/cpp/c-incpath.h new file mode 100644 index 0000000..3f268b7 --- /dev/null +++ b/support/cpp/c-incpath.h @@ -0,0 +1,33 @@ +/* Set up combined include path for the preprocessor. + Copyright (C) 2003, 2004, 2005, 2006 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +extern void split_quote_chain (void); +extern void add_path (char *, int, int, bool); +extern void register_include_chains (cpp_reader *, const char *, + const char *, const char *, + int, int, int); +extern void add_cpp_dir_path (struct cpp_dir *, int); + +struct target_c_incpath_s { + /* Do extra includes processing. STDINC is false iff -nostdinc was given. */ + void (*extra_pre_includes) (const char *, const char *, int); + void (*extra_includes) (const char *, const char *, int); +}; + +extern struct target_c_incpath_s target_c_incpath; + +enum { QUOTE = 0, BRACKET, SYSTEM, AFTER }; diff --git a/support/cpp/c-ppoutput.c b/support/cpp/c-ppoutput.c new file mode 100644 index 0000000..99f0402 --- /dev/null +++ b/support/cpp/c-ppoutput.c @@ -0,0 +1,469 @@ +/* Preprocess only, using cpplib. + Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007, + 2008 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 3, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "cpplib.h" +#include "../libcpp/internal.h" + +/* Encapsulates state used to convert a stream of tokens into a text + file. */ +static struct +{ + FILE *outf; /* Stream to write to. */ + const cpp_token *prev; /* Previous token. */ + const cpp_token *source; /* Source token for spacing. */ + int src_line; /* Line number currently being written. */ + unsigned char printed; /* Nonzero if something output at line. */ + bool first_time; /* pp_file_change hasn't been called yet. */ +} print; + +/* General output routines. */ +static void scan_translation_unit (cpp_reader *); +static void scan_translation_unit_trad (cpp_reader *); +static void account_for_newlines (const unsigned char *, size_t); +static int dump_macro (cpp_reader *, cpp_hashnode *, void *); + +static void print_line (source_location, const char *); +static void maybe_print_line (source_location); + +/* Callback routines for the parser. Most of these are active only + in specific modes. */ +static void cb_line_change (cpp_reader *, const cpp_token *, int); +static void cb_define (cpp_reader *, source_location, cpp_hashnode *); +static void cb_undef (cpp_reader *, source_location, cpp_hashnode *); +static void cb_include (cpp_reader *, source_location, const unsigned char *, + const char *, int, const cpp_token **); +static void cb_ident (cpp_reader *, source_location, const cpp_string *); +static void cb_def_pragma (cpp_reader *, source_location); +#if 0 +static void cb_read_pch (cpp_reader *pfile, const char *name, + int fd, const char *orig_name); +#endif + +/* Preprocess and output. */ +void +preprocess_file (cpp_reader *pfile) +{ + /* A successful cpp_read_main_file guarantees that we can call + cpp_scan_nooutput or cpp_get_token next. */ + if (flag_no_output) + { + /* Scan -included buffers, then the main file. */ + while (pfile->buffer->prev) + cpp_scan_nooutput (pfile); + cpp_scan_nooutput (pfile); + } + else if (cpp_get_options (pfile)->traditional) + scan_translation_unit_trad (pfile); + else + scan_translation_unit (pfile); + + /* -dM command line option. Should this be elsewhere? */ + if (flag_dump_macros == 'M') + cpp_forall_identifiers (pfile, dump_macro, NULL); + + /* Flush any pending output. */ + if (print.printed) + putc ('\n', print.outf); +} + +/* Set up the callbacks as appropriate. */ +void +init_pp_output (FILE *out_stream) +{ + cpp_callbacks *cb = cpp_get_callbacks (parse_in); + + if (!flag_no_output) + { + cb->line_change = cb_line_change; + /* Don't emit #pragma or #ident directives if we are processing + assembly language; the assembler may choke on them. */ + if (cpp_get_options (parse_in)->lang != CLK_ASM) + { + cb->ident = cb_ident; + cb->def_pragma = cb_def_pragma; + } + } + + if (flag_dump_includes) + cb->include = cb_include; + +#if 0 + if (flag_pch_preprocess) + { + cb->valid_pch = c_common_valid_pch; + cb->read_pch = cb_read_pch; + } +#endif + + if (flag_dump_macros == 'N' || flag_dump_macros == 'D') + { + cb->define = cb_define; + cb->undef = cb_undef; + } + + /* Initialize the print structure. Setting print.src_line to -1 here is + a trick to guarantee that the first token of the file will cause + a linemarker to be output by maybe_print_line. */ + print.src_line = -1; + print.printed = 0; + print.prev = 0; + print.outf = out_stream; + print.first_time = 1; +} + +extern int in_asm; + +/* Writes out the preprocessed file, handling spacing and paste + avoidance issues. */ +static void +scan_translation_unit (cpp_reader *pfile) +{ + bool avoid_paste = false; + + print.source = NULL; + for (;;) + { + const cpp_token *token = cpp_get_token (pfile); + + if (token->type == CPP_PADDING) + { + avoid_paste = true; + if (print.source == NULL + || (!(print.source->flags & PREV_WHITE) + && token->val.source == NULL)) + print.source = token->val.source; + continue; + } + + if (token->type == CPP_EOF) + break; + + /* Subtle logic to output a space if and only if necessary. */ + if (avoid_paste) + { + if (print.source == NULL) + print.source = token; + if (print.source->flags & PREV_WHITE + || (print.prev + && cpp_avoid_paste (pfile, print.prev, token)) + || (print.prev == NULL && token->type == CPP_HASH)) + putc (' ', print.outf); + if (in_asm && print.source->flags & PREV_NL) + fputs ("\x87 ", print.outf); + } + else + { + if (token->flags & PREV_WHITE) + putc (' ', print.outf); + if (in_asm && token->flags & PREV_NL) + fputs ("\x87 ", print.outf); + } + + avoid_paste = false; + print.source = NULL; + print.prev = token; + cpp_output_token (token, print.outf); + + if (token->type == CPP_COMMENT) + account_for_newlines (token->val.str.text, token->val.str.len); + } +} + +/* Adjust print.src_line for newlines embedded in output. */ +static void +account_for_newlines (const unsigned char *str, size_t len) +{ + while (len--) + if (*str++ == '\n') + print.src_line++; +} + +/* Writes out a traditionally preprocessed file. */ +static void +scan_translation_unit_trad (cpp_reader *pfile) +{ + while (_cpp_read_logical_line_trad (pfile)) + { + size_t len = pfile->out.cur - pfile->out.base; + maybe_print_line (pfile->out.first_line); + fwrite (pfile->out.base, 1, len, print.outf); + print.printed = 1; + if (!CPP_OPTION (pfile, discard_comments)) + account_for_newlines (pfile->out.base, len); + } +} + +/* If the token read on logical line LINE needs to be output on a + different line to the current one, output the required newlines or + a line marker, and return 1. Otherwise return 0. */ +static void +maybe_print_line (source_location src_loc) +{ + const struct line_map *map = linemap_lookup (line_table, src_loc); + int src_line = SOURCE_LINE (map, src_loc); + /* End the previous line of text. */ + if (print.printed) + { + putc ('\n', print.outf); + print.src_line++; + print.printed = 0; + } + + /* sdcpp specific: disabled # LINE directive generation in __asm __endasm block */ + if (in_asm || (src_line >= print.src_line && src_line < print.src_line + 8)) + { + while (src_line > print.src_line) + { + putc ('\n', print.outf); + print.src_line++; + } + } + else + print_line (src_loc, ""); +} + +/* Output a line marker for logical line LINE. Special flags are "1" + or "2" indicating entering or leaving a file. */ +static void +print_line (source_location src_loc, const char *special_flags) +{ + /* End any previous line of text. */ + if (print.printed) + putc ('\n', print.outf); + print.printed = 0; + + if (!flag_no_line_commands) + { + const struct line_map *map = linemap_lookup (line_table, src_loc); + + size_t to_file_len = strlen (map->to_file); + unsigned char *to_file_quoted = + (unsigned char *) alloca (to_file_len * 4 + 1); + unsigned char *p; + + print.src_line = SOURCE_LINE (map, src_loc); + + /* cpp_quote_string does not nul-terminate, so we have to do it + ourselves. */ + p = cpp_quote_string (to_file_quoted, + (unsigned char *) map->to_file, to_file_len); + *p = '\0'; + fprintf (print.outf, "# %u \"%s\"%s", + print.src_line == 0 ? 1 : print.src_line, + to_file_quoted, special_flags); + + if (map->sysp == 2) + fputs (" 3 4", print.outf); + else if (map->sysp == 1) + fputs (" 3", print.outf); + + putc ('\n', print.outf); + } +} + +/* Called when a line of output is started. TOKEN is the first token + of the line, and at end of file will be CPP_EOF. */ +static void +cb_line_change (cpp_reader *pfile, const cpp_token *token, + int parsing_args) +{ + source_location src_loc = token->src_loc; + + if (token->type == CPP_EOF || parsing_args) + return; + + maybe_print_line (src_loc); + print.prev = 0; + print.source = 0; + + /* Supply enough spaces to put this token in its original column, + one space per column greater than 2, since scan_translation_unit + will provide a space if PREV_WHITE. Don't bother trying to + reconstruct tabs; we can't get it right in general, and nothing + ought to care. Some things do care; the fault lies with them. */ + if (!CPP_OPTION (pfile, traditional)) + { + const struct line_map *map = linemap_lookup (line_table, src_loc); + int spaces = SOURCE_COLUMN (map, src_loc) - 2; + print.printed = 1; + + while (-- spaces >= 0) + putc (' ', print.outf); + } +} + +static void +cb_ident (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line, + const cpp_string *str) +{ + maybe_print_line (line); + fprintf (print.outf, "#ident %s\n", str->text); + print.src_line++; +} + +static void +cb_define (cpp_reader *pfile, source_location line, cpp_hashnode *node) +{ + maybe_print_line (line); + fputs ("#define ", print.outf); + + /* 'D' is whole definition; 'N' is name only. */ + if (flag_dump_macros == 'D') + fputs ((const char *) cpp_macro_definition (pfile, node), + print.outf); + else + fputs ((const char *) NODE_NAME (node), print.outf); + + putc ('\n', print.outf); + if (linemap_lookup (line_table, line)->to_line != 0) + print.src_line++; +} + +static void +cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line, + cpp_hashnode *node) +{ + maybe_print_line (line); + fprintf (print.outf, "#undef %s\n", NODE_NAME (node)); + print.src_line++; +} + +static void +cb_include (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line, + const unsigned char *dir, const char *header, int angle_brackets, + const cpp_token **comments) +{ + maybe_print_line (line); + if (angle_brackets) + fprintf (print.outf, "#%s <%s>", dir, header); + else + fprintf (print.outf, "#%s \"%s\"", dir, header); + + if (comments != NULL) + { + while (*comments != NULL) + { + if ((*comments)->flags & PREV_WHITE) + putc (' ', print.outf); + cpp_output_token (*comments, print.outf); + ++comments; + } + } + + putc ('\n', print.outf); + print.src_line++; +} + +/* Callback called when -fworking-director and -E to emit working + directory in cpp output file. */ + +void +pp_dir_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const char *dir) +{ + size_t to_file_len = strlen (dir); + unsigned char *to_file_quoted = + (unsigned char *) alloca (to_file_len * 4 + 1); + unsigned char *p; + + /* cpp_quote_string does not nul-terminate, so we have to do it ourselves. */ + p = cpp_quote_string (to_file_quoted, (unsigned char *) dir, to_file_len); + *p = '\0'; + fprintf (print.outf, "# 1 \"%s//\"\n", to_file_quoted); +} + +/* The file name, line number or system header flags have changed, as + described in MAP. */ + +void +pp_file_change (const struct line_map *map) +{ + const char *flags = ""; + + if (flag_no_line_commands) + return; + + if (map != NULL) + { + if (print.first_time) + { + /* Avoid printing foo.i when the main file is foo.c. */ + if (!cpp_get_options (parse_in)->preprocessed) + print_line (map->start_location, flags); + print.first_time = 0; + } + else + { + /* Bring current file to correct line when entering a new file. */ + if (map->reason == LC_ENTER) + { + const struct line_map *from = INCLUDED_FROM (line_table, map); + maybe_print_line (LAST_SOURCE_LINE_LOCATION (from)); + } + if (map->reason == LC_ENTER) + flags = " 1"; + else if (map->reason == LC_LEAVE) + flags = " 2"; + print_line (map->start_location, flags); + } + } +} + +/* Copy a #pragma directive to the preprocessed output. */ +static void +cb_def_pragma (cpp_reader *pfile, source_location line) +{ + maybe_print_line (line); + fputs ("#pragma ", print.outf); + cpp_output_line (pfile, print.outf); + print.src_line++; +} + +/* Dump out the hash table. */ +static int +dump_macro (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.src_line++; + } + + return 1; +} + +#if 0 +/* Load in the PCH file NAME, open on FD. It was originally searched for + by ORIG_NAME. Also, print out a #include command so that the PCH + file can be loaded when the preprocessed output is compiled. */ + +static void +cb_read_pch (cpp_reader *pfile, const char *name, + int fd, const char *orig_name ATTRIBUTE_UNUSED) +{ + c_common_read_pch (pfile, name, fd, orig_name); + + fprintf (print.outf, "#pragma GCC pch_preprocess \"%s\"\n", name); + print.src_line++; +} +#endif diff --git a/support/cpp/config.h b/support/cpp/config.h new file mode 100644 index 0000000..c6bbaa2 --- /dev/null +++ b/support/cpp/config.h @@ -0,0 +1,11 @@ +#include "auto-host.h" +/* Provide three core typedefs used by everything, if we are compiling + GCC. These used to be found in rtl.h and tree.h, but this is no + longer practical. Providing these here rather that system.h allows + the typedefs to be used everywhere within GCC. */ +struct rtx_def; +typedef struct rtx_def *rtx; +struct rtvec_def; +typedef struct rtvec_def *rtvec; +union tree_node; +typedef union tree_node *tree; diff --git a/support/cpp/config.in b/support/cpp/config.in new file mode 100644 index 0000000..42e7030 --- /dev/null +++ b/support/cpp/config.in @@ -0,0 +1,252 @@ +/* config.in. Generated from configure.ac by autoheader. */ +/* 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 + +/* Define if cpp should also search $prefix/include. */ +#undef PREFIX_INCLUDE_DIR + + +/* Define if building universal (internal helper macro) */ +#undef AC_APPLE_UNIVERSAL_BUILD + +/* Define as the number of bits in a byte, if \`limits.h' doesn't. */ +#undef CHAR_BIT + +/* Define to enable the use of a default assembler. */ +#undef DEFAULT_ASSEMBLER + +/* Define to enable the use of a default linker. */ +#undef DEFAULT_LINKER + +/* Define to 1 if you have the `clock' function. */ +#undef HAVE_CLOCK + +/* 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_CALLOC + +/* 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_ERRNO + +/* 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_GETENV + +/* 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_STRSIGNAL + +/* Define to 1 if you have the <direct.h> header file. */ +#undef HAVE_DIRECT_H + +/* Define to 1 if you have the <fcntl.h> header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the `getpagesize' function. */ +#undef HAVE_GETPAGESIZE + +/* Define to 1 if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the <limits.h> header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if you have the `lstat' function. */ +#undef HAVE_LSTAT + +/* Define to 1 if you have the <malloc.h> header file. */ +#undef HAVE_MALLOC_H + +/* Define to 1 if you have the <memory.h> header file. */ +#undef HAVE_MEMORY_H + +/* Define if mmap can get us zeroed pages using MAP_ANON(YMOUS). */ +#undef HAVE_MMAP_ANON + +/* Define if mmap can get us zeroed pages from /dev/zero. */ +#undef HAVE_MMAP_DEV_ZERO + +/* Define if read-only mmap of a plain file works. */ +#undef HAVE_MMAP_FILE + +/* Define if you have a working <stdbool.h> header file. */ +#undef HAVE_STDBOOL_H + +/* Define to 1 if you have the <stddef.h> header file. */ +#undef HAVE_STDDEF_H + +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strchr' function. */ +#undef HAVE_STRCHR + +/* Define to 1 if cpp supports the ANSI # stringizing operator. */ +#undef HAVE_STRINGIZE + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strrchr' function. */ +#undef HAVE_STRRCHR + +/* Define to 1 if you have the `strsignal' function. */ +#undef HAVE_STRSIGNAL + +/* Define to 1 if you have the <sys/file.h> header file. */ +#undef HAVE_SYS_FILE_H + +/* Define to 1 if you have the <sys/param.h> header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/time.h> header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */ +#undef HAVE_SYS_WAIT_H + +/* Define to 1 if you have the <time.h> header file. */ +#undef HAVE_TIME_H + +/* Define to 1 if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Define if the \`_Bool' type is built-in. */ +#undef HAVE__BOOL + +/* Define if the host execution character set is EBCDIC. */ +#undef HOST_EBCDIC + +/* Define if host mkdir takes a single argument. */ +#undef MKDIR_TAKES_ONE_ARG + +/* Define if you want the C and C++ compilers to support multibyte character + sets for source code. */ +#undef MULTIBYTE_CHARS + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +#undef NO_MINUS_C_MINUS_O + +/* Define to the name of the distribution. */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* The number of bytes in type int */ +#undef SIZEOF_INT + +/* The number of bytes in type long */ +#undef SIZEOF_LONG + +/* The number of bytes in type short */ +#undef SIZEOF_SHORT + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define if you can safely include both <string.h> and <strings.h>. */ +#undef STRING_WITH_STRINGS + +/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ +#undef TIME_WITH_SYS_TIME + +/* Define to the version of the distribution. */ +#undef VERSION + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +# undef WORDS_BIGENDIAN +# endif +#endif + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to `int' if <sys/types.h> does not define. */ +#undef ssize_t + +/* 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 diff --git a/support/cpp/config.log b/support/cpp/config.log new file mode 100644 index 0000000..4f02229 --- /dev/null +++ b/support/cpp/config.log @@ -0,0 +1,2407 @@ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by configure, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ ./configure --disable-option-checking --prefix=/usr/local --disable-mcs51-port --disable-z80-port --disable-z180-port --disable-r2k-port --disable-r3ka-port --disable-gbz80-port --disable-tlcs90-port --disable-ez80_z80-port --disable-ds390-port --disable-ds400-port --disable-pic14-port --disable-pic16-port --disable-hc08-port --disable-s08-port --disable-pdk13-port --disable-pdk14-port --disable-pdk15-port --enable-pdk16-port --disable-ucsim --disable-device-lib --disable-packihx --disable-pdk16-port docdir=${datarootdir}/doc/${PACKAGE} --cache-file=/dev/null --srcdir=. + +## --------- ## +## Platform. ## +## --------- ## + +hostname = xavier-asus +uname -m = x86_64 +uname -r = 4.15.0-65-generic +uname -s = Linux +uname -v = #74-Ubuntu SMP Tue Sep 17 17:06:04 UTC 2019 + +/usr/bin/uname -p = unknown +/bin/uname -X = unknown + +/bin/arch = unknown +/usr/bin/arch -k = unknown +/usr/convex/getsysinfo = unknown +/usr/bin/hostinfo = unknown +/bin/machine = unknown +/usr/bin/oslevel = unknown +/bin/universe = unknown + +PATH: /home/xavier/.cargo/bin +PATH: /home/xavier/.local/bin +PATH: /usr/local/sbin +PATH: /usr/local/bin +PATH: /usr/sbin +PATH: /usr/bin +PATH: /sbin +PATH: /bin +PATH: /usr/games +PATH: /usr/local/games +PATH: /snap/bin +PATH: /usr/local/xtensa-esp32-elf/bin + + +## ----------- ## +## Core tests. ## +## ----------- ## + +configure:2411: checking for gcc +configure:2427: found /usr/bin/gcc +configure:2438: result: gcc +configure:2667: checking for C compiler version +configure:2676: gcc --version >&5 +gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0 +Copyright (C) 2017 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +configure:2687: $? = 0 +configure:2676: gcc -v >&5 +Using built-in specs. +COLLECT_GCC=gcc +COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper +OFFLOAD_TARGET_NAMES=nvptx-none +OFFLOAD_TARGET_DEFAULT=1 +Target: x86_64-linux-gnu +Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.4.0-1ubuntu1~18.04.1' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu +Thread model: posix +gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1) +configure:2687: $? = 0 +configure:2676: gcc -V >&5 +gcc: error: unrecognized command line option '-V' +gcc: fatal error: no input files +compilation terminated. +configure:2687: $? = 1 +configure:2676: gcc -qversion >&5 +gcc: error: unrecognized command line option '-qversion'; did you mean '--version'? +gcc: fatal error: no input files +compilation terminated. +configure:2687: $? = 1 +configure:2707: checking whether the C compiler works +configure:2729: gcc conftest.c >&5 +configure:2733: $? = 0 +configure:2781: result: yes +configure:2784: checking for C compiler default output file name +configure:2786: result: a.out +configure:2792: checking for suffix of executables +configure:2799: gcc -o conftest conftest.c >&5 +configure:2803: $? = 0 +configure:2825: result: +configure:2847: checking whether we are cross compiling +configure:2855: gcc -o conftest conftest.c >&5 +configure:2859: $? = 0 +configure:2866: ./conftest +configure:2870: $? = 0 +configure:2885: result: no +configure:2890: checking for suffix of object files +configure:2912: gcc -c conftest.c >&5 +configure:2916: $? = 0 +configure:2937: result: o +configure:2941: checking whether we are using the GNU C compiler +configure:2960: gcc -c conftest.c >&5 +configure:2960: $? = 0 +configure:2969: result: yes +configure:2978: checking whether gcc accepts -g +configure:2998: gcc -c -g conftest.c >&5 +configure:2998: $? = 0 +configure:3039: result: yes +configure:3056: checking for gcc option to accept ISO C89 +configure:3119: gcc -c -g -O2 conftest.c >&5 +configure:3119: $? = 0 +configure:3132: result: none needed +configure:3153: checking whether gcc and cc understand -c and -o together +configure:3184: gcc -c conftest.c -o conftest2.o >&5 +configure:3188: $? = 0 +configure:3194: gcc -c conftest.c -o conftest2.o >&5 +configure:3198: $? = 0 +configure:3209: cc -c conftest.c >&5 +configure:3213: $? = 0 +configure:3221: cc -c conftest.c -o conftest2.o >&5 +configure:3225: $? = 0 +configure:3231: cc -c conftest.c -o conftest2.o >&5 +configure:3235: $? = 0 +configure:3253: result: yes +configure:3277: checking how to run the C preprocessor +configure:3308: gcc -E conftest.c +configure:3308: $? = 0 +configure:3322: gcc -E conftest.c +conftest.c:9:10: fatal error: ac_nonexistent.h: No such file or directory + #include <ac_nonexistent.h> + ^~~~~~~~~~~~~~~~~~ +compilation terminated. +configure:3322: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| /* end confdefs.h. */ +| #include <ac_nonexistent.h> +configure:3347: result: gcc -E +configure:3367: gcc -E conftest.c +configure:3367: $? = 0 +configure:3381: gcc -E conftest.c +conftest.c:9:10: fatal error: ac_nonexistent.h: No such file or directory + #include <ac_nonexistent.h> + ^~~~~~~~~~~~~~~~~~ +compilation terminated. +configure:3381: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| /* end confdefs.h. */ +| #include <ac_nonexistent.h> +configure:3410: checking for inline +configure:3426: gcc -c -g -O2 conftest.c >&5 +configure:3426: $? = 0 +configure:3434: result: inline +configure:3453: checking for built-in _Bool +configure:3469: gcc -c -g -O2 conftest.c >&5 +configure:3469: $? = 0 +configure:3477: result: yes +configure:3487: checking size of short +configure:3507: gcc -c -g -O2 conftest.c >&5 +conftest.c: In function 'main': +conftest.c:17:20: error: duplicate case value + switch (0) case 0: case (sizeof (short) == 4):; + ^~~~ +conftest.c:17:12: note: previously used here + switch (0) case 0: case (sizeof (short) == 4):; + ^~~~ +configure:3507: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define HAVE__BOOL 1 +| /* end confdefs.h. */ +| #include "confdefs.h" +| #include <sys/types.h> +| +| +| int +| main () +| { +| switch (0) case 0: case (sizeof (short) == 4):; +| ; +| return 0; +| } +configure:3507: gcc -c -g -O2 conftest.c >&5 +conftest.c: In function 'main': +conftest.c:17:20: error: duplicate case value + switch (0) case 0: case (sizeof (short) == 8):; + ^~~~ +conftest.c:17:12: note: previously used here + switch (0) case 0: case (sizeof (short) == 8):; + ^~~~ +configure:3507: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define HAVE__BOOL 1 +| /* end confdefs.h. */ +| #include "confdefs.h" +| #include <sys/types.h> +| +| +| int +| main () +| { +| switch (0) case 0: case (sizeof (short) == 8):; +| ; +| return 0; +| } +configure:3507: gcc -c -g -O2 conftest.c >&5 +conftest.c: In function 'main': +conftest.c:17:20: error: duplicate case value + switch (0) case 0: case (sizeof (short) == 1):; + ^~~~ +conftest.c:17:12: note: previously used here + switch (0) case 0: case (sizeof (short) == 1):; + ^~~~ +configure:3507: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define HAVE__BOOL 1 +| /* end confdefs.h. */ +| #include "confdefs.h" +| #include <sys/types.h> +| +| +| int +| main () +| { +| switch (0) case 0: case (sizeof (short) == 1):; +| ; +| return 0; +| } +configure:3507: gcc -c -g -O2 conftest.c >&5 +configure:3507: $? = 0 +configure:3519: result: 2 +configure:3527: checking size of int +configure:3547: gcc -c -g -O2 conftest.c >&5 +configure:3547: $? = 0 +configure:3559: result: 4 +configure:3567: checking size of long +configure:3587: gcc -c -g -O2 conftest.c >&5 +conftest.c: In function 'main': +conftest.c:19:20: error: duplicate case value + switch (0) case 0: case (sizeof (long) == 4):; + ^~~~ +conftest.c:19:12: note: previously used here + switch (0) case 0: case (sizeof (long) == 4):; + ^~~~ +configure:3587: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define HAVE__BOOL 1 +| #define SIZEOF_SHORT 2 +| #define SIZEOF_INT 4 +| /* end confdefs.h. */ +| #include "confdefs.h" +| #include <sys/types.h> +| +| +| int +| main () +| { +| switch (0) case 0: case (sizeof (long) == 4):; +| ; +| return 0; +| } +configure:3587: gcc -c -g -O2 conftest.c >&5 +configure:3587: $? = 0 +configure:3599: result: 8 +configure:3609: checking for grep that handles long lines and -e +configure:3667: result: /bin/grep +configure:3672: checking for egrep +configure:3734: result: /bin/grep -E +configure:3739: checking execution character set +configure:3776: result: ASCII +configure:3795: checking whether make sets $(MAKE) +configure:3817: result: yes +configure:3827: checking whether a default assembler was specified +configure:3838: result: no +configure:3842: checking whether a default linker was specified +configure:3853: result: no +configure:3862: checking for gawk +configure:3878: found /usr/bin/gawk +configure:3889: result: gawk +configure:3906: checking whether ln works +configure:3929: result: yes +configure:3941: checking whether ln -s works +configure:3964: result: yes +configure:4019: checking for ranlib +configure:4035: found /usr/bin/ranlib +configure:4046: result: ranlib +configure:4107: checking for a BSD compatible install +configure:4149: result: /usr/bin/install -c +configure:4159: checking for ANSI C header files +configure:4179: gcc -c -g -O2 conftest.c >&5 +configure:4179: $? = 0 +configure:4252: gcc -o conftest -g -O2 conftest.c >&5 +configure:4252: $? = 0 +configure:4252: ./conftest +configure:4252: $? = 0 +configure:4263: result: yes +configure:4271: checking whether time.h and sys/time.h may both be included +configure:4291: gcc -c -g -O2 conftest.c >&5 +configure:4291: $? = 0 +configure:4298: result: yes +configure:4306: checking for working stdbool.h +configure:4322: gcc -c -g -O2 conftest.c >&5 +configure:4322: $? = 0 +configure:4329: result: yes +configure:4337: checking whether string.h and strings.h may both be included +configure:4354: gcc -c -g -O2 conftest.c >&5 +configure:4354: $? = 0 +configure:4361: result: yes +configure:4369: checking for sys/wait.h that is POSIX.1 compatible +configure:4395: gcc -c -g -O2 conftest.c >&5 +configure:4395: $? = 0 +configure:4402: result: yes +configure:4415: checking for sys/types.h +configure:4415: gcc -c -g -O2 conftest.c >&5 +configure:4415: $? = 0 +configure:4415: result: yes +configure:4415: checking for sys/stat.h +configure:4415: gcc -c -g -O2 conftest.c >&5 +configure:4415: $? = 0 +configure:4415: result: yes +configure:4415: checking for stdlib.h +configure:4415: gcc -c -g -O2 conftest.c >&5 +configure:4415: $? = 0 +configure:4415: result: yes +configure:4415: checking for string.h +configure:4415: gcc -c -g -O2 conftest.c >&5 +configure:4415: $? = 0 +configure:4415: result: yes +configure:4415: checking for memory.h +configure:4415: gcc -c -g -O2 conftest.c >&5 +configure:4415: $? = 0 +configure:4415: result: yes +configure:4415: checking for strings.h +configure:4415: gcc -c -g -O2 conftest.c >&5 +configure:4415: $? = 0 +configure:4415: result: yes +configure:4415: checking for inttypes.h +configure:4415: gcc -c -g -O2 conftest.c >&5 +configure:4415: $? = 0 +configure:4415: result: yes +configure:4415: checking for stdint.h +configure:4415: gcc -c -g -O2 conftest.c >&5 +configure:4415: $? = 0 +configure:4415: result: yes +configure:4415: checking for unistd.h +configure:4415: gcc -c -g -O2 conftest.c >&5 +configure:4415: $? = 0 +configure:4415: result: yes +configure:4433: checking limits.h usability +configure:4433: gcc -c -g -O2 conftest.c >&5 +configure:4433: $? = 0 +configure:4433: result: yes +configure:4433: checking limits.h presence +configure:4433: gcc -E conftest.c +configure:4433: $? = 0 +configure:4433: result: yes +configure:4433: checking for limits.h +configure:4433: result: yes +configure:4433: checking stddef.h usability +configure:4433: gcc -c -g -O2 conftest.c >&5 +configure:4433: $? = 0 +configure:4433: result: yes +configure:4433: checking stddef.h presence +configure:4433: gcc -E conftest.c +configure:4433: $? = 0 +configure:4433: result: yes +configure:4433: checking for stddef.h +configure:4433: result: yes +configure:4433: checking for string.h +configure:4433: result: yes +configure:4433: checking for strings.h +configure:4433: result: yes +configure:4433: checking for stdlib.h +configure:4433: result: yes +configure:4433: checking time.h usability +configure:4433: gcc -c -g -O2 conftest.c >&5 +configure:4433: $? = 0 +configure:4433: result: yes +configure:4433: checking time.h presence +configure:4433: gcc -E conftest.c +configure:4433: $? = 0 +configure:4433: result: yes +configure:4433: checking for time.h +configure:4433: result: yes +configure:4433: checking fcntl.h usability +configure:4433: gcc -c -g -O2 conftest.c >&5 +configure:4433: $? = 0 +configure:4433: result: yes +configure:4433: checking fcntl.h presence +configure:4433: gcc -E conftest.c +configure:4433: $? = 0 +configure:4433: result: yes +configure:4433: checking for fcntl.h +configure:4433: result: yes +configure:4433: checking for unistd.h +configure:4433: result: yes +configure:4433: checking sys/file.h usability +configure:4433: gcc -c -g -O2 conftest.c >&5 +configure:4433: $? = 0 +configure:4433: result: yes +configure:4433: checking sys/file.h presence +configure:4433: gcc -E conftest.c +configure:4433: $? = 0 +configure:4433: result: yes +configure:4433: checking for sys/file.h +configure:4433: result: yes +configure:4433: checking sys/time.h usability +configure:4433: gcc -c -g -O2 conftest.c >&5 +configure:4433: $? = 0 +configure:4433: result: yes +configure:4433: checking sys/time.h presence +configure:4433: gcc -E conftest.c +configure:4433: $? = 0 +configure:4433: result: yes +configure:4433: checking for sys/time.h +configure:4433: result: yes +configure:4433: checking sys/param.h usability +configure:4433: gcc -c -g -O2 conftest.c >&5 +configure:4433: $? = 0 +configure:4433: result: yes +configure:4433: checking sys/param.h presence +configure:4433: gcc -E conftest.c +configure:4433: $? = 0 +configure:4433: result: yes +configure:4433: checking for sys/param.h +configure:4433: result: yes +configure:4433: checking for sys/stat.h +configure:4433: result: yes +configure:4433: checking direct.h usability +configure:4433: gcc -c -g -O2 conftest.c >&5 +conftest.c:72:10: fatal error: direct.h: No such file or directory + #include <direct.h> + ^~~~~~~~~~ +compilation terminated. +configure:4433: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define HAVE__BOOL 1 +| #define SIZEOF_SHORT 2 +| #define SIZEOF_INT 4 +| #define SIZEOF_LONG 8 +| #define STDC_HEADERS 1 +| #define TIME_WITH_SYS_TIME 1 +| #define HAVE_STDBOOL_H 1 +| #define STRING_WITH_STRINGS 1 +| #define HAVE_SYS_WAIT_H 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_LIMITS_H 1 +| #define HAVE_STDDEF_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_TIME_H 1 +| #define HAVE_FCNTL_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_SYS_FILE_H 1 +| #define HAVE_SYS_TIME_H 1 +| #define HAVE_SYS_PARAM_H 1 +| #define HAVE_SYS_STAT_H 1 +| /* end confdefs.h. */ +| #include <stdio.h> +| #ifdef HAVE_SYS_TYPES_H +| # include <sys/types.h> +| #endif +| #ifdef HAVE_SYS_STAT_H +| # include <sys/stat.h> +| #endif +| #ifdef STDC_HEADERS +| # include <stdlib.h> +| # include <stddef.h> +| #else +| # ifdef HAVE_STDLIB_H +| # include <stdlib.h> +| # endif +| #endif +| #ifdef HAVE_STRING_H +| # if !defined STDC_HEADERS && defined HAVE_MEMORY_H +| # include <memory.h> +| # endif +| # include <string.h> +| #endif +| #ifdef HAVE_STRINGS_H +| # include <strings.h> +| #endif +| #ifdef HAVE_INTTYPES_H +| # include <inttypes.h> +| #endif +| #ifdef HAVE_STDINT_H +| # include <stdint.h> +| #endif +| #ifdef HAVE_UNISTD_H +| # include <unistd.h> +| #endif +| #include <direct.h> +configure:4433: result: no +configure:4433: checking direct.h presence +configure:4433: gcc -E conftest.c +conftest.c:39:10: fatal error: direct.h: No such file or directory + #include <direct.h> + ^~~~~~~~~~ +compilation terminated. +configure:4433: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define HAVE__BOOL 1 +| #define SIZEOF_SHORT 2 +| #define SIZEOF_INT 4 +| #define SIZEOF_LONG 8 +| #define STDC_HEADERS 1 +| #define TIME_WITH_SYS_TIME 1 +| #define HAVE_STDBOOL_H 1 +| #define STRING_WITH_STRINGS 1 +| #define HAVE_SYS_WAIT_H 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_LIMITS_H 1 +| #define HAVE_STDDEF_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_TIME_H 1 +| #define HAVE_FCNTL_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_SYS_FILE_H 1 +| #define HAVE_SYS_TIME_H 1 +| #define HAVE_SYS_PARAM_H 1 +| #define HAVE_SYS_STAT_H 1 +| /* end confdefs.h. */ +| #include <direct.h> +configure:4433: result: no +configure:4433: checking for direct.h +configure:4433: result: no +configure:4433: checking malloc.h usability +configure:4433: gcc -c -g -O2 conftest.c >&5 +configure:4433: $? = 0 +configure:4433: result: yes +configure:4433: checking malloc.h presence +configure:4433: gcc -E conftest.c +configure:4433: $? = 0 +configure:4433: result: yes +configure:4433: checking for malloc.h +configure:4433: result: yes +configure:4447: checking for CHAR_BIT +configure:4471: result: yes +configure:4517: checking whether byte ordering is bigendian +configure:4532: gcc -c -g -O2 conftest.c >&5 +conftest.c:41:9: error: unknown type name 'not' + not a universal capable compiler + ^~~ +conftest.c:41:15: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'universal' + not a universal capable compiler + ^~~~~~~~~ +conftest.c:41:15: error: unknown type name 'universal' +configure:4532: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define HAVE__BOOL 1 +| #define SIZEOF_SHORT 2 +| #define SIZEOF_INT 4 +| #define SIZEOF_LONG 8 +| #define STDC_HEADERS 1 +| #define TIME_WITH_SYS_TIME 1 +| #define HAVE_STDBOOL_H 1 +| #define STRING_WITH_STRINGS 1 +| #define HAVE_SYS_WAIT_H 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_LIMITS_H 1 +| #define HAVE_STDDEF_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_TIME_H 1 +| #define HAVE_FCNTL_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_SYS_FILE_H 1 +| #define HAVE_SYS_TIME_H 1 +| #define HAVE_SYS_PARAM_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_MALLOC_H 1 +| /* end confdefs.h. */ +| #ifndef __APPLE_CC__ +| not a universal capable compiler +| #endif +| typedef int dummy; +| +configure:4577: gcc -c -g -O2 conftest.c >&5 +configure:4577: $? = 0 +configure:4595: gcc -c -g -O2 conftest.c >&5 +conftest.c: In function 'main': +conftest.c:47:4: error: unknown type name 'not'; did you mean 'ino_t'? + not big endian + ^~~ + ino_t +conftest.c:47:12: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'endian' + not big endian + ^~~~~~ +configure:4595: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define HAVE__BOOL 1 +| #define SIZEOF_SHORT 2 +| #define SIZEOF_INT 4 +| #define SIZEOF_LONG 8 +| #define STDC_HEADERS 1 +| #define TIME_WITH_SYS_TIME 1 +| #define HAVE_STDBOOL_H 1 +| #define STRING_WITH_STRINGS 1 +| #define HAVE_SYS_WAIT_H 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_LIMITS_H 1 +| #define HAVE_STDDEF_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_TIME_H 1 +| #define HAVE_FCNTL_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_SYS_FILE_H 1 +| #define HAVE_SYS_TIME_H 1 +| #define HAVE_SYS_PARAM_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_MALLOC_H 1 +| /* end confdefs.h. */ +| #include <sys/types.h> +| #include <sys/param.h> +| +| int +| main () +| { +| #if BYTE_ORDER != BIG_ENDIAN +| not big endian +| #endif +| +| ; +| return 0; +| } +configure:4723: result: no +configure:4745: checking for mktemp +configure:4761: found /bin/mktemp +configure:4773: result: yes +configure:4784: checking for strip +configure:4800: found /usr/bin/strip +configure:4812: result: strip +configure:4822: checking for ar +configure:4838: found /usr/bin/ar +configure:4850: result: ar +configure:4861: checking for preprocessor stringizing operator +configure:4881: result: yes +configure:4894: checking for clock +configure:4894: gcc -o conftest -g -O2 conftest.c >&5 +configure:4894: $? = 0 +configure:4894: result: yes +configure:4894: checking for strsignal +configure:4894: gcc -o conftest -g -O2 conftest.c >&5 +configure:4894: $? = 0 +configure:4894: result: yes +configure:4894: checking for strchr +configure:4894: gcc -o conftest -g -O2 conftest.c >&5 +conftest.c:66:6: warning: conflicting types for built-in function 'strchr' [-Wbuiltin-declaration-mismatch] + char strchr (); + ^~~~~~ +configure:4894: $? = 0 +configure:4894: result: yes +configure:4894: checking for strrchr +configure:4894: gcc -o conftest -g -O2 conftest.c >&5 +conftest.c:67:6: warning: conflicting types for built-in function 'strrchr' [-Wbuiltin-declaration-mismatch] + char strrchr (); + ^~~~~~~ +configure:4894: $? = 0 +configure:4894: result: yes +configure:4894: checking for lstat +configure:4894: gcc -o conftest -g -O2 conftest.c >&5 +configure:4894: $? = 0 +configure:4894: result: yes +configure:4904: checking for ssize_t +configure:4904: gcc -c -g -O2 conftest.c >&5 +configure:4904: $? = 0 +configure:4904: gcc -c -g -O2 conftest.c >&5 +conftest.c: In function 'main': +conftest.c:82:22: error: expected expression before ')' token + if (sizeof ((ssize_t))) + ^ +configure:4904: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define HAVE__BOOL 1 +| #define SIZEOF_SHORT 2 +| #define SIZEOF_INT 4 +| #define SIZEOF_LONG 8 +| #define STDC_HEADERS 1 +| #define TIME_WITH_SYS_TIME 1 +| #define HAVE_STDBOOL_H 1 +| #define STRING_WITH_STRINGS 1 +| #define HAVE_SYS_WAIT_H 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_LIMITS_H 1 +| #define HAVE_STDDEF_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_TIME_H 1 +| #define HAVE_FCNTL_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_SYS_FILE_H 1 +| #define HAVE_SYS_TIME_H 1 +| #define HAVE_SYS_PARAM_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_MALLOC_H 1 +| #define HAVE_STRINGIZE 1 +| #define HAVE_CLOCK 1 +| #define HAVE_STRSIGNAL 1 +| #define HAVE_STRCHR 1 +| #define HAVE_STRRCHR 1 +| #define HAVE_LSTAT 1 +| /* end confdefs.h. */ +| #include <stdio.h> +| #ifdef HAVE_SYS_TYPES_H +| # include <sys/types.h> +| #endif +| #ifdef HAVE_SYS_STAT_H +| # include <sys/stat.h> +| #endif +| #ifdef STDC_HEADERS +| # include <stdlib.h> +| # include <stddef.h> +| #else +| # ifdef HAVE_STDLIB_H +| # include <stdlib.h> +| # endif +| #endif +| #ifdef HAVE_STRING_H +| # if !defined STDC_HEADERS && defined HAVE_MEMORY_H +| # include <memory.h> +| # endif +| # include <string.h> +| #endif +| #ifdef HAVE_STRINGS_H +| # include <strings.h> +| #endif +| #ifdef HAVE_INTTYPES_H +| # include <inttypes.h> +| #endif +| #ifdef HAVE_STDINT_H +| # include <stdint.h> +| #endif +| #ifdef HAVE_UNISTD_H +| # include <unistd.h> +| #endif +| int +| main () +| { +| if (sizeof ((ssize_t))) +| return 0; +| ; +| return 0; +| } +configure:4904: result: yes +configure:4918: checking for getpagesize +configure:4918: gcc -o conftest -g -O2 conftest.c >&5 +configure:4918: $? = 0 +configure:4918: result: yes +configure:5173: checking for working mmap from /dev/zero +configure:5193: gcc -o conftest -g -O2 conftest.c >&5 +In file included from conftest.c:47:0: +ct-mmap.inc: In function 'test_0': +ct-mmap.inc:59:21: warning: implicit declaration of function 'exit' [-Wimplicit-function-declaration] + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:97:5: note: in expansion of macro 'perror_exit' + perror_exit("test 0 mmap", 2); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:97:5: note: in expansion of macro 'perror_exit' + perror_exit("test 0 mmap", 2); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:97:5: note: in expansion of macro 'perror_exit' + perror_exit("test 0 mmap", 2); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:102:5: note: in expansion of macro 'perror_exit' + perror_exit("test 0 munmap", 3); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:102:5: note: in expansion of macro 'perror_exit' + perror_exit("test 0 munmap", 3); + ^~~~~~~~~~~ +ct-mmap.inc: In function 'test_1': +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:112:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 1 mmap", 4); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:112:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 1 mmap", 4); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:116:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 1 fault", 5); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:116:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 1 fault", 5); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:122:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 1 munmap 1", 6); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:122:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 1 munmap 1", 6); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:128:7: note: in expansion of macro 'perror_exit' + perror_exit ("test 1 no fault", 7); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:128:7: note: in expansion of macro 'perror_exit' + perror_exit ("test 1 no fault", 7); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:131:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 1 munmap 2", 8); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:131:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 1 munmap 2", 8); + ^~~~~~~~~~~ +ct-mmap.inc: In function 'test_2': +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:141:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 2 mmap", 9); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:141:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 2 mmap", 9); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:145:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 2 fault", 10); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:145:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 2 fault", 10); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:151:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 2 munmap 1", 11); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:151:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 2 munmap 1", 11); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:158:7: note: in expansion of macro 'perror_exit' + perror_exit ("test 2 no fault", 12); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:158:7: note: in expansion of macro 'perror_exit' + perror_exit ("test 2 no fault", 12); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:162:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 2 munmap 2", 13); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:162:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 2 munmap 2", 13); + ^~~~~~~~~~~ +ct-mmap.inc: In function 'test_3': +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:182:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 3 mmap 1", 14); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:182:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 3 mmap 1", 14); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:185:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 3 mmap 2", 15); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:185:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 3 mmap 2", 15); + ^~~~~~~~~~~ +ct-mmap.inc:195:4: warning: incompatible implicit declaration of built-in function 'exit' + exit (16); + ^~~~ +ct-mmap.inc:195:4: note: include '<stdlib.h>' or provide a declaration of 'exit' +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:201:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 3 fault", 17); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:201:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 3 fault", 17); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:207:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 3 munmap", 18); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:207:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 3 munmap", 18); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:212:7: note: in expansion of macro 'perror_exit' + perror_exit ("test 3 no fault 1", 19); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:212:7: note: in expansion of macro 'perror_exit' + perror_exit ("test 3 no fault 1", 19); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:219:7: note: in expansion of macro 'perror_exit' + perror_exit ("test 3 no fault 2", 20); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:219:7: note: in expansion of macro 'perror_exit' + perror_exit ("test 3 no fault 2", 20); + ^~~~~~~~~~~ +ct-mmap.inc: In function 'main': +ct-mmap.inc:228:8: warning: implicit declaration of function 'getpagesize' [-Wimplicit-function-declaration] + pg = getpagesize (); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:232:5: note: in expansion of macro 'perror_exit' + perror_exit ("open /dev/zero", 1); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:232:5: note: in expansion of macro 'perror_exit' + perror_exit ("open /dev/zero", 1); + ^~~~~~~~~~~ +ct-mmap.inc:240:3: warning: incompatible implicit declaration of built-in function 'exit' + exit(0); + ^~~~ +ct-mmap.inc:240:3: note: include '<stdlib.h>' or provide a declaration of 'exit' +configure:5193: $? = 0 +configure:5193: ./conftest +configure:5193: $? = 0 +configure:5207: result: yes +configure:5215: checking for working mmap with MAP_ANON(YMOUS) +configure:5230: gcc -o conftest -g -O2 conftest.c >&5 +In file included from conftest.c:49:0: +ct-mmap.inc: In function 'test_0': +ct-mmap.inc:59:21: warning: implicit declaration of function 'exit' [-Wimplicit-function-declaration] + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:97:5: note: in expansion of macro 'perror_exit' + perror_exit("test 0 mmap", 2); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:97:5: note: in expansion of macro 'perror_exit' + perror_exit("test 0 mmap", 2); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:97:5: note: in expansion of macro 'perror_exit' + perror_exit("test 0 mmap", 2); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:102:5: note: in expansion of macro 'perror_exit' + perror_exit("test 0 munmap", 3); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:102:5: note: in expansion of macro 'perror_exit' + perror_exit("test 0 munmap", 3); + ^~~~~~~~~~~ +ct-mmap.inc: In function 'test_1': +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:112:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 1 mmap", 4); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:112:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 1 mmap", 4); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:116:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 1 fault", 5); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:116:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 1 fault", 5); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:122:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 1 munmap 1", 6); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:122:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 1 munmap 1", 6); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:128:7: note: in expansion of macro 'perror_exit' + perror_exit ("test 1 no fault", 7); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:128:7: note: in expansion of macro 'perror_exit' + perror_exit ("test 1 no fault", 7); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:131:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 1 munmap 2", 8); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:131:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 1 munmap 2", 8); + ^~~~~~~~~~~ +ct-mmap.inc: In function 'test_2': +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:141:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 2 mmap", 9); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:141:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 2 mmap", 9); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:145:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 2 fault", 10); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:145:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 2 fault", 10); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:151:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 2 munmap 1", 11); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:151:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 2 munmap 1", 11); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:158:7: note: in expansion of macro 'perror_exit' + perror_exit ("test 2 no fault", 12); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:158:7: note: in expansion of macro 'perror_exit' + perror_exit ("test 2 no fault", 12); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:162:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 2 munmap 2", 13); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:162:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 2 munmap 2", 13); + ^~~~~~~~~~~ +ct-mmap.inc: In function 'test_3': +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:182:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 3 mmap 1", 14); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:182:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 3 mmap 1", 14); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:185:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 3 mmap 2", 15); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:185:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 3 mmap 2", 15); + ^~~~~~~~~~~ +ct-mmap.inc:195:4: warning: incompatible implicit declaration of built-in function 'exit' + exit (16); + ^~~~ +ct-mmap.inc:195:4: note: include '<stdlib.h>' or provide a declaration of 'exit' +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:201:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 3 fault", 17); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:201:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 3 fault", 17); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:207:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 3 munmap", 18); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:207:5: note: in expansion of macro 'perror_exit' + perror_exit ("test 3 munmap", 18); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:212:7: note: in expansion of macro 'perror_exit' + perror_exit ("test 3 no fault 1", 19); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:212:7: note: in expansion of macro 'perror_exit' + perror_exit ("test 3 no fault 1", 19); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: warning: incompatible implicit declaration of built-in function 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:219:7: note: in expansion of macro 'perror_exit' + perror_exit ("test 3 no fault 2", 20); + ^~~~~~~~~~~ +ct-mmap.inc:59:21: note: include '<stdlib.h>' or provide a declaration of 'exit' + do { perror(str); exit(val); } while (0) + ^ +ct-mmap.inc:219:7: note: in expansion of macro 'perror_exit' + perror_exit ("test 3 no fault 2", 20); + ^~~~~~~~~~~ +ct-mmap.inc: In function 'main': +ct-mmap.inc:228:8: warning: implicit declaration of function 'getpagesize' [-Wimplicit-function-declaration] + pg = getpagesize (); + ^~~~~~~~~~~ +ct-mmap.inc:240:3: warning: incompatible implicit declaration of built-in function 'exit' + exit(0); + ^~~~ +ct-mmap.inc:240:3: note: include '<stdlib.h>' or provide a declaration of 'exit' +configure:5230: $? = 0 +configure:5230: ./conftest +configure:5230: $? = 0 +configure:5244: result: yes +configure:5253: checking for working mmap of a file +configure:5305: gcc -o conftest -g -O2 conftest.c >&5 +conftest.c: In function 'main': +conftest.c:66:5: warning: implicit declaration of function 'exit' [-Wimplicit-function-declaration] + exit(1); + ^~~~ +conftest.c:66:5: warning: incompatible implicit declaration of built-in function 'exit' +conftest.c:66:5: note: include '<stdlib.h>' or provide a declaration of 'exit' +conftest.c:69:5: warning: incompatible implicit declaration of built-in function 'exit' + exit(2); + ^~~~ +conftest.c:69:5: note: include '<stdlib.h>' or provide a declaration of 'exit' +conftest.c:73:5: warning: incompatible implicit declaration of built-in function 'exit' + exit(3); + ^~~~ +conftest.c:73:5: note: include '<stdlib.h>' or provide a declaration of 'exit' +conftest.c:76:5: warning: incompatible implicit declaration of built-in function 'exit' + exit(4); + ^~~~ +conftest.c:76:5: note: include '<stdlib.h>' or provide a declaration of 'exit' +conftest.c:79:5: warning: incompatible implicit declaration of built-in function 'exit' + exit(5); + ^~~~ +conftest.c:79:5: note: include '<stdlib.h>' or provide a declaration of 'exit' +conftest.c:81:3: warning: incompatible implicit declaration of built-in function 'exit' + exit(0); + ^~~~ +conftest.c:81:3: note: include '<stdlib.h>' or provide a declaration of 'exit' +configure:5305: $? = 0 +configure:5305: ./conftest +configure:5305: $? = 0 +configure:5315: result: yes +configure:5331: checking whether getenv is declared +configure:5354: gcc -c -g -O2 -I. -I./libiberty -I./libcpp/include conftest.c >&5 +conftest.c:53:10: fatal error: ansidecl.h: No such file or directory + #include "ansidecl.h" + ^~~~~~~~~~~~ +compilation terminated. +configure:5354: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define HAVE__BOOL 1 +| #define SIZEOF_SHORT 2 +| #define SIZEOF_INT 4 +| #define SIZEOF_LONG 8 +| #define STDC_HEADERS 1 +| #define TIME_WITH_SYS_TIME 1 +| #define HAVE_STDBOOL_H 1 +| #define STRING_WITH_STRINGS 1 +| #define HAVE_SYS_WAIT_H 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_LIMITS_H 1 +| #define HAVE_STDDEF_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_TIME_H 1 +| #define HAVE_FCNTL_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_SYS_FILE_H 1 +| #define HAVE_SYS_TIME_H 1 +| #define HAVE_SYS_PARAM_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_MALLOC_H 1 +| #define HAVE_STRINGIZE 1 +| #define HAVE_CLOCK 1 +| #define HAVE_STRSIGNAL 1 +| #define HAVE_STRCHR 1 +| #define HAVE_STRRCHR 1 +| #define HAVE_LSTAT 1 +| #define HAVE_GETPAGESIZE 1 +| #define HAVE_MMAP_DEV_ZERO 1 +| #define HAVE_MMAP_ANON 1 +| #define HAVE_MMAP_FILE 1 +| /* end confdefs.h. */ +| #undef HAVE_DECL_GETENV +| #define HAVE_DECL_GETENV 1 +| +| #include "ansidecl.h" +| #include "system.h" +| +| int +| main () +| { +| #ifndef getenv +| char *(*pfn) = (char *(*)) getenv ; +| #endif +| ; +| return 0; +| } +configure:5369: result: no +configure:5331: checking whether abort is declared +configure:5354: gcc -c -g -O2 -I. -I./libiberty -I./libcpp/include conftest.c >&5 +conftest.c:54:10: fatal error: ansidecl.h: No such file or directory + #include "ansidecl.h" + ^~~~~~~~~~~~ +compilation terminated. +configure:5354: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define HAVE__BOOL 1 +| #define SIZEOF_SHORT 2 +| #define SIZEOF_INT 4 +| #define SIZEOF_LONG 8 +| #define STDC_HEADERS 1 +| #define TIME_WITH_SYS_TIME 1 +| #define HAVE_STDBOOL_H 1 +| #define STRING_WITH_STRINGS 1 +| #define HAVE_SYS_WAIT_H 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_LIMITS_H 1 +| #define HAVE_STDDEF_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_TIME_H 1 +| #define HAVE_FCNTL_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_SYS_FILE_H 1 +| #define HAVE_SYS_TIME_H 1 +| #define HAVE_SYS_PARAM_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_MALLOC_H 1 +| #define HAVE_STRINGIZE 1 +| #define HAVE_CLOCK 1 +| #define HAVE_STRSIGNAL 1 +| #define HAVE_STRCHR 1 +| #define HAVE_STRRCHR 1 +| #define HAVE_LSTAT 1 +| #define HAVE_GETPAGESIZE 1 +| #define HAVE_MMAP_DEV_ZERO 1 +| #define HAVE_MMAP_ANON 1 +| #define HAVE_MMAP_FILE 1 +| #define HAVE_DECL_GETENV 0 +| /* end confdefs.h. */ +| #undef HAVE_DECL_ABORT +| #define HAVE_DECL_ABORT 1 +| +| #include "ansidecl.h" +| #include "system.h" +| +| int +| main () +| { +| #ifndef abort +| char *(*pfn) = (char *(*)) abort ; +| #endif +| ; +| return 0; +| } +configure:5369: result: no +configure:5331: checking whether strsignal is declared +configure:5354: gcc -c -g -O2 -I. -I./libiberty -I./libcpp/include conftest.c >&5 +conftest.c:55:10: fatal error: ansidecl.h: No such file or directory + #include "ansidecl.h" + ^~~~~~~~~~~~ +compilation terminated. +configure:5354: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define HAVE__BOOL 1 +| #define SIZEOF_SHORT 2 +| #define SIZEOF_INT 4 +| #define SIZEOF_LONG 8 +| #define STDC_HEADERS 1 +| #define TIME_WITH_SYS_TIME 1 +| #define HAVE_STDBOOL_H 1 +| #define STRING_WITH_STRINGS 1 +| #define HAVE_SYS_WAIT_H 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_LIMITS_H 1 +| #define HAVE_STDDEF_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_TIME_H 1 +| #define HAVE_FCNTL_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_SYS_FILE_H 1 +| #define HAVE_SYS_TIME_H 1 +| #define HAVE_SYS_PARAM_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_MALLOC_H 1 +| #define HAVE_STRINGIZE 1 +| #define HAVE_CLOCK 1 +| #define HAVE_STRSIGNAL 1 +| #define HAVE_STRCHR 1 +| #define HAVE_STRRCHR 1 +| #define HAVE_LSTAT 1 +| #define HAVE_GETPAGESIZE 1 +| #define HAVE_MMAP_DEV_ZERO 1 +| #define HAVE_MMAP_ANON 1 +| #define HAVE_MMAP_FILE 1 +| #define HAVE_DECL_GETENV 0 +| #define HAVE_DECL_ABORT 0 +| /* end confdefs.h. */ +| #undef HAVE_DECL_STRSIGNAL +| #define HAVE_DECL_STRSIGNAL 1 +| +| #include "ansidecl.h" +| #include "system.h" +| +| int +| main () +| { +| #ifndef strsignal +| char *(*pfn) = (char *(*)) strsignal ; +| #endif +| ; +| return 0; +| } +configure:5369: result: no +configure:5331: checking whether errno is declared +configure:5354: gcc -c -g -O2 -I. -I./libiberty -I./libcpp/include conftest.c >&5 +conftest.c:56:10: fatal error: ansidecl.h: No such file or directory + #include "ansidecl.h" + ^~~~~~~~~~~~ +compilation terminated. +configure:5354: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define HAVE__BOOL 1 +| #define SIZEOF_SHORT 2 +| #define SIZEOF_INT 4 +| #define SIZEOF_LONG 8 +| #define STDC_HEADERS 1 +| #define TIME_WITH_SYS_TIME 1 +| #define HAVE_STDBOOL_H 1 +| #define STRING_WITH_STRINGS 1 +| #define HAVE_SYS_WAIT_H 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_LIMITS_H 1 +| #define HAVE_STDDEF_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_TIME_H 1 +| #define HAVE_FCNTL_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_SYS_FILE_H 1 +| #define HAVE_SYS_TIME_H 1 +| #define HAVE_SYS_PARAM_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_MALLOC_H 1 +| #define HAVE_STRINGIZE 1 +| #define HAVE_CLOCK 1 +| #define HAVE_STRSIGNAL 1 +| #define HAVE_STRCHR 1 +| #define HAVE_STRRCHR 1 +| #define HAVE_LSTAT 1 +| #define HAVE_GETPAGESIZE 1 +| #define HAVE_MMAP_DEV_ZERO 1 +| #define HAVE_MMAP_ANON 1 +| #define HAVE_MMAP_FILE 1 +| #define HAVE_DECL_GETENV 0 +| #define HAVE_DECL_ABORT 0 +| #define HAVE_DECL_STRSIGNAL 0 +| /* end confdefs.h. */ +| #undef HAVE_DECL_ERRNO +| #define HAVE_DECL_ERRNO 1 +| +| #include "ansidecl.h" +| #include "system.h" +| +| int +| main () +| { +| #ifndef errno +| char *(*pfn) = (char *(*)) errno ; +| #endif +| ; +| return 0; +| } +configure:5369: result: no +configure:5331: checking whether malloc is declared +configure:5354: gcc -c -g -O2 -I. -I./libiberty -I./libcpp/include conftest.c >&5 +conftest.c:57:10: fatal error: ansidecl.h: No such file or directory + #include "ansidecl.h" + ^~~~~~~~~~~~ +compilation terminated. +configure:5354: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define HAVE__BOOL 1 +| #define SIZEOF_SHORT 2 +| #define SIZEOF_INT 4 +| #define SIZEOF_LONG 8 +| #define STDC_HEADERS 1 +| #define TIME_WITH_SYS_TIME 1 +| #define HAVE_STDBOOL_H 1 +| #define STRING_WITH_STRINGS 1 +| #define HAVE_SYS_WAIT_H 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_LIMITS_H 1 +| #define HAVE_STDDEF_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_TIME_H 1 +| #define HAVE_FCNTL_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_SYS_FILE_H 1 +| #define HAVE_SYS_TIME_H 1 +| #define HAVE_SYS_PARAM_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_MALLOC_H 1 +| #define HAVE_STRINGIZE 1 +| #define HAVE_CLOCK 1 +| #define HAVE_STRSIGNAL 1 +| #define HAVE_STRCHR 1 +| #define HAVE_STRRCHR 1 +| #define HAVE_LSTAT 1 +| #define HAVE_GETPAGESIZE 1 +| #define HAVE_MMAP_DEV_ZERO 1 +| #define HAVE_MMAP_ANON 1 +| #define HAVE_MMAP_FILE 1 +| #define HAVE_DECL_GETENV 0 +| #define HAVE_DECL_ABORT 0 +| #define HAVE_DECL_STRSIGNAL 0 +| #define HAVE_DECL_ERRNO 0 +| /* end confdefs.h. */ +| #undef HAVE_DECL_MALLOC +| #define HAVE_DECL_MALLOC 1 +| +| #include "ansidecl.h" +| #include "system.h" +| +| int +| main () +| { +| #ifndef malloc +| char *(*pfn) = (char *(*)) malloc ; +| #endif +| ; +| return 0; +| } +configure:5369: result: no +configure:5331: checking whether realloc is declared +configure:5354: gcc -c -g -O2 -I. -I./libiberty -I./libcpp/include conftest.c >&5 +conftest.c:58:10: fatal error: ansidecl.h: No such file or directory + #include "ansidecl.h" + ^~~~~~~~~~~~ +compilation terminated. +configure:5354: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define HAVE__BOOL 1 +| #define SIZEOF_SHORT 2 +| #define SIZEOF_INT 4 +| #define SIZEOF_LONG 8 +| #define STDC_HEADERS 1 +| #define TIME_WITH_SYS_TIME 1 +| #define HAVE_STDBOOL_H 1 +| #define STRING_WITH_STRINGS 1 +| #define HAVE_SYS_WAIT_H 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_LIMITS_H 1 +| #define HAVE_STDDEF_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_TIME_H 1 +| #define HAVE_FCNTL_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_SYS_FILE_H 1 +| #define HAVE_SYS_TIME_H 1 +| #define HAVE_SYS_PARAM_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_MALLOC_H 1 +| #define HAVE_STRINGIZE 1 +| #define HAVE_CLOCK 1 +| #define HAVE_STRSIGNAL 1 +| #define HAVE_STRCHR 1 +| #define HAVE_STRRCHR 1 +| #define HAVE_LSTAT 1 +| #define HAVE_GETPAGESIZE 1 +| #define HAVE_MMAP_DEV_ZERO 1 +| #define HAVE_MMAP_ANON 1 +| #define HAVE_MMAP_FILE 1 +| #define HAVE_DECL_GETENV 0 +| #define HAVE_DECL_ABORT 0 +| #define HAVE_DECL_STRSIGNAL 0 +| #define HAVE_DECL_ERRNO 0 +| #define HAVE_DECL_MALLOC 0 +| /* end confdefs.h. */ +| #undef HAVE_DECL_REALLOC +| #define HAVE_DECL_REALLOC 1 +| +| #include "ansidecl.h" +| #include "system.h" +| +| int +| main () +| { +| #ifndef realloc +| char *(*pfn) = (char *(*)) realloc ; +| #endif +| ; +| return 0; +| } +configure:5369: result: no +configure:5331: checking whether calloc is declared +configure:5354: gcc -c -g -O2 -I. -I./libiberty -I./libcpp/include conftest.c >&5 +conftest.c:59:10: fatal error: ansidecl.h: No such file or directory + #include "ansidecl.h" + ^~~~~~~~~~~~ +compilation terminated. +configure:5354: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define HAVE__BOOL 1 +| #define SIZEOF_SHORT 2 +| #define SIZEOF_INT 4 +| #define SIZEOF_LONG 8 +| #define STDC_HEADERS 1 +| #define TIME_WITH_SYS_TIME 1 +| #define HAVE_STDBOOL_H 1 +| #define STRING_WITH_STRINGS 1 +| #define HAVE_SYS_WAIT_H 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_LIMITS_H 1 +| #define HAVE_STDDEF_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_TIME_H 1 +| #define HAVE_FCNTL_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_SYS_FILE_H 1 +| #define HAVE_SYS_TIME_H 1 +| #define HAVE_SYS_PARAM_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_MALLOC_H 1 +| #define HAVE_STRINGIZE 1 +| #define HAVE_CLOCK 1 +| #define HAVE_STRSIGNAL 1 +| #define HAVE_STRCHR 1 +| #define HAVE_STRRCHR 1 +| #define HAVE_LSTAT 1 +| #define HAVE_GETPAGESIZE 1 +| #define HAVE_MMAP_DEV_ZERO 1 +| #define HAVE_MMAP_ANON 1 +| #define HAVE_MMAP_FILE 1 +| #define HAVE_DECL_GETENV 0 +| #define HAVE_DECL_ABORT 0 +| #define HAVE_DECL_STRSIGNAL 0 +| #define HAVE_DECL_ERRNO 0 +| #define HAVE_DECL_MALLOC 0 +| #define HAVE_DECL_REALLOC 0 +| /* end confdefs.h. */ +| #undef HAVE_DECL_CALLOC +| #define HAVE_DECL_CALLOC 1 +| +| #include "ansidecl.h" +| #include "system.h" +| +| int +| main () +| { +| #ifndef calloc +| char *(*pfn) = (char *(*)) calloc ; +| #endif +| ; +| return 0; +| } +configure:5369: result: no +configure:5331: checking whether free is declared +configure:5354: gcc -c -g -O2 -I. -I./libiberty -I./libcpp/include conftest.c >&5 +conftest.c:60:10: fatal error: ansidecl.h: No such file or directory + #include "ansidecl.h" + ^~~~~~~~~~~~ +compilation terminated. +configure:5354: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define HAVE__BOOL 1 +| #define SIZEOF_SHORT 2 +| #define SIZEOF_INT 4 +| #define SIZEOF_LONG 8 +| #define STDC_HEADERS 1 +| #define TIME_WITH_SYS_TIME 1 +| #define HAVE_STDBOOL_H 1 +| #define STRING_WITH_STRINGS 1 +| #define HAVE_SYS_WAIT_H 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_LIMITS_H 1 +| #define HAVE_STDDEF_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_TIME_H 1 +| #define HAVE_FCNTL_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_SYS_FILE_H 1 +| #define HAVE_SYS_TIME_H 1 +| #define HAVE_SYS_PARAM_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_MALLOC_H 1 +| #define HAVE_STRINGIZE 1 +| #define HAVE_CLOCK 1 +| #define HAVE_STRSIGNAL 1 +| #define HAVE_STRCHR 1 +| #define HAVE_STRRCHR 1 +| #define HAVE_LSTAT 1 +| #define HAVE_GETPAGESIZE 1 +| #define HAVE_MMAP_DEV_ZERO 1 +| #define HAVE_MMAP_ANON 1 +| #define HAVE_MMAP_FILE 1 +| #define HAVE_DECL_GETENV 0 +| #define HAVE_DECL_ABORT 0 +| #define HAVE_DECL_STRSIGNAL 0 +| #define HAVE_DECL_ERRNO 0 +| #define HAVE_DECL_MALLOC 0 +| #define HAVE_DECL_REALLOC 0 +| #define HAVE_DECL_CALLOC 0 +| /* end confdefs.h. */ +| #undef HAVE_DECL_FREE +| #define HAVE_DECL_FREE 1 +| +| #include "ansidecl.h" +| #include "system.h" +| +| int +| main () +| { +| #ifndef free +| char *(*pfn) = (char *(*)) free ; +| #endif +| ; +| return 0; +| } +configure:5369: result: no +configure:5331: checking whether clock is declared +configure:5354: gcc -c -g -O2 -I. -I./libiberty -I./libcpp/include conftest.c >&5 +conftest.c:61:10: fatal error: ansidecl.h: No such file or directory + #include "ansidecl.h" + ^~~~~~~~~~~~ +compilation terminated. +configure:5354: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define PACKAGE_URL "" +| #define HAVE__BOOL 1 +| #define SIZEOF_SHORT 2 +| #define SIZEOF_INT 4 +| #define SIZEOF_LONG 8 +| #define STDC_HEADERS 1 +| #define TIME_WITH_SYS_TIME 1 +| #define HAVE_STDBOOL_H 1 +| #define STRING_WITH_STRINGS 1 +| #define HAVE_SYS_WAIT_H 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_LIMITS_H 1 +| #define HAVE_STDDEF_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_TIME_H 1 +| #define HAVE_FCNTL_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_SYS_FILE_H 1 +| #define HAVE_SYS_TIME_H 1 +| #define HAVE_SYS_PARAM_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_MALLOC_H 1 +| #define HAVE_STRINGIZE 1 +| #define HAVE_CLOCK 1 +| #define HAVE_STRSIGNAL 1 +| #define HAVE_STRCHR 1 +| #define HAVE_STRRCHR 1 +| #define HAVE_LSTAT 1 +| #define HAVE_GETPAGESIZE 1 +| #define HAVE_MMAP_DEV_ZERO 1 +| #define HAVE_MMAP_ANON 1 +| #define HAVE_MMAP_FILE 1 +| #define HAVE_DECL_GETENV 0 +| #define HAVE_DECL_ABORT 0 +| #define HAVE_DECL_STRSIGNAL 0 +| #define HAVE_DECL_ERRNO 0 +| #define HAVE_DECL_MALLOC 0 +| #define HAVE_DECL_REALLOC 0 +| #define HAVE_DECL_CALLOC 0 +| #define HAVE_DECL_FREE 0 +| /* end confdefs.h. */ +| #undef HAVE_DECL_CLOCK +| #define HAVE_DECL_CLOCK 1 +| +| #include "ansidecl.h" +| #include "system.h" +| +| int +| main () +| { +| #ifndef clock +| char *(*pfn) = (char *(*)) clock ; +| #endif +| ; +| return 0; +| } +configure:5369: result: no +configure:5404: checking for gcc option to accept ISO C99 +configure:5553: gcc -c -g -O2 conftest.c >&5 +configure:5553: $? = 0 +configure:5566: result: none needed +configure:5586: checking if mkdir takes one argument +configure:5612: gcc -c -g -O2 conftest.c >&5 +configure:5612: $? = 0 +configure:5619: result: no +configure:5760: checking what assembler to use +configure:5842: result: /usr/bin/as +configure:5847: checking what nm to use +configure:5855: result: nm +configure:5859: checking whether to enable maintainer-specific portions of Makefiles +configure:5869: result: no +configure:6076: creating ./config.status + +## ---------------------- ## +## Running config.status. ## +## ---------------------- ## + +This file was extended by config.status, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = + CONFIG_HEADERS = + CONFIG_LINKS = + CONFIG_COMMANDS = + $ ./config.status + +on xavier-asus + +config.status:940: creating Makefile +config.status:940: creating auto-host.h +config.status:1110: auto-host.h is unchanged +config.status:1124: executing default commands + +## ---------------- ## +## Cache variables. ## +## ---------------- ## + +ac_cv_c_bigendian=no +ac_cv_c_charset=ASCII +ac_cv_c_compiler_gnu=yes +ac_cv_c_inline=inline +ac_cv_c_stringize=yes +ac_cv_env_CC_set= +ac_cv_env_CC_value= +ac_cv_env_CFLAGS_set= +ac_cv_env_CFLAGS_value= +ac_cv_env_CPPFLAGS_set= +ac_cv_env_CPPFLAGS_value= +ac_cv_env_CPP_set= +ac_cv_env_CPP_value= +ac_cv_env_LDFLAGS_set= +ac_cv_env_LDFLAGS_value= +ac_cv_env_LIBS_set= +ac_cv_env_LIBS_value= +ac_cv_env_build_alias_set= +ac_cv_env_build_alias_value= +ac_cv_env_host_alias_set= +ac_cv_env_host_alias_value= +ac_cv_env_target_alias_set= +ac_cv_env_target_alias_value= +ac_cv_func_clock=yes +ac_cv_func_getpagesize=yes +ac_cv_func_lstat=yes +ac_cv_func_mmap_anon=yes +ac_cv_func_mmap_dev_zero=yes +ac_cv_func_mmap_file=yes +ac_cv_func_strchr=yes +ac_cv_func_strrchr=yes +ac_cv_func_strsignal=yes +ac_cv_header_direct_h=no +ac_cv_header_fcntl_h=yes +ac_cv_header_inttypes_h=yes +ac_cv_header_limits_h=yes +ac_cv_header_malloc_h=yes +ac_cv_header_memory_h=yes +ac_cv_header_stdbool_h=yes +ac_cv_header_stdc=yes +ac_cv_header_stddef_h=yes +ac_cv_header_stdint_h=yes +ac_cv_header_stdlib_h=yes +ac_cv_header_string_h=yes +ac_cv_header_strings_h=yes +ac_cv_header_sys_file_h=yes +ac_cv_header_sys_param_h=yes +ac_cv_header_sys_stat_h=yes +ac_cv_header_sys_time_h=yes +ac_cv_header_sys_types_h=yes +ac_cv_header_sys_wait_h=yes +ac_cv_header_time=yes +ac_cv_header_time_h=yes +ac_cv_header_unistd_h=yes +ac_cv_objext=o +ac_cv_path_EGREP='/bin/grep -E' +ac_cv_path_GREP=/bin/grep +ac_cv_path_install='/usr/bin/install -c' +ac_cv_prog_AR=ar +ac_cv_prog_AWK=gawk +ac_cv_prog_CPP='gcc -E' +ac_cv_prog_STRIP=strip +ac_cv_prog_ac_ct_CC=gcc +ac_cv_prog_ac_ct_RANLIB=ranlib +ac_cv_prog_cc_c89= +ac_cv_prog_cc_c99= +ac_cv_prog_cc_g=yes +ac_cv_prog_cc_gcc_c_o=yes +ac_cv_prog_have_mktemp_command=yes +ac_cv_prog_make_make_set=yes +ac_cv_sizeof_int=4 +ac_cv_sizeof_long=8 +ac_cv_sizeof_short=2 +ac_cv_type_ssize_t=yes +gcc_cv_as=/usr/bin/as +gcc_cv_as_gas_srcdir=./gas +gcc_cv_c__bool=yes +gcc_cv_decl_char_bit=yes +gcc_cv_gas_major_version= +gcc_cv_gas_minor_version= +gcc_cv_have_decl_abort=no +gcc_cv_have_decl_calloc=no +gcc_cv_have_decl_clock=no +gcc_cv_have_decl_errno=no +gcc_cv_have_decl_free=no +gcc_cv_have_decl_getenv=no +gcc_cv_have_decl_malloc=no +gcc_cv_have_decl_realloc=no +gcc_cv_have_decl_strsignal=no +gcc_cv_header_string=yes +gcc_cv_mkdir_takes_one_arg=no +gcc_cv_nm=nm +gcc_cv_prog_LN=ln +gcc_cv_prog_LN_S='ln -s' + +## ----------------- ## +## Output variables. ## +## ----------------- ## + +AR='ar' +AWK='gawk' +CC='gcc' +CFLAGS=' -g -O2' +CPP='gcc -E' +CPPFLAGS='' +DEFS='-DHAVE_CONFIG_H' +ECHO_C='' +ECHO_N='-n' +ECHO_T='' +EGREP='/bin/grep -E' +EXEEXT='' +GREP='/bin/grep' +INSTALL='/usr/bin/install -c' +INSTALL_DATA='${INSTALL} -m 644' +INSTALL_PROGRAM='${INSTALL}' +LDFLAGS='' +LIBOBJS='' +LIBS='' +LN='ln' +LN_S='ln -s' +LTLIBOBJS='' +MAINT='#' +NO_MINUS_C_MINUS_O='' +OBJEXT='o' +OUTPUT_OPTION='-o $@' +PACKAGE='sdcc' +PACKAGE_BUGREPORT='' +PACKAGE_NAME='' +PACKAGE_STRING='' +PACKAGE_TARNAME='' +PACKAGE_URL='' +PACKAGE_VERSION='' +PATH_SEPARATOR=':' +RANLIB='ranlib' +SET_MAKE='' +SHELL='/bin/bash' +STRIP='strip' +VERSION='const' +WALL_FLAG='-Wall' +ac_ct_CC='gcc' +all_stagestuff='' +bindir='${exec_prefix}/bin' +build_alias='' +build_canonical='' +build_exeext='' +build_install_headers_dir='install-headers-tar' +build_xm_defines='' +build_xm_file='auto-host.h ansidecl.h /.h defaults.h' +build_xm_file_list='' +c_target_objs='' +check_languages='' +const char pkgversion_string[] = PKGVERSION;' +datadir='${datarootdir}' +datarootdir='${prefix}/share' +dep_host_xmake_file='' +dep_tmake_file='' +docdir='${datarootdir}/doc/${PACKAGE}' +dvidir='${docdir}' +exec_prefix='${prefix}' +extra_c_flags='' +extra_headers_list='' +extra_objs=' ' +extra_parts='' +extra_passes='' +extra_programs='' +gcc_config_arguments='' +gcc_version='const' +gcc_version_full='const char version_string[] = BASEVER DATESTAMP DEVPHASE VERSUFFIX; +gcc_version_trigger='./version.c' +have_mktemp_command='yes' +host_alias='' +host_canonical='' +host_exeext='' +host_extra_gcc_objs='' +htmldir='${docdir}' +includedir='${prefix}/include' +infodir='${datarootdir}/info' +install='' +lang_tree_files='' +libdir='${exec_prefix}/lib' +libexecdir='${exec_prefix}/libexec' +local_prefix='/usr/local' +localedir='${datarootdir}/locale' +localstatedir='${prefix}/var' +mandir='${datarootdir}/man' +manext='.1' +md_file='/.md' +objdir='/home/xavier/sdcc/support/cpp' +objext='.o' +oldincludedir='/usr/include' +out_file='/.c' +out_object_file='.c.o' +pdfdir='${docdir}' +prefix='/usr/local' +program_transform_name='s,x,x,' +psdir='${docdir}' +runstatedir='${localstatedir}/run' +sbindir='${exec_prefix}/sbin' +sharedstatedir='${prefix}/com' +symbolic_link='ln -s' +sysconfdir='${prefix}/etc' +target_alias='' +target_subdir='' +thread_file='' +warn_cflags='$(GCC_WARN_CFLAGS)' + +## ----------- ## +## confdefs.h. ## +## ----------- ## + +/* confdefs.h */ +#define PACKAGE_NAME "" +#define PACKAGE_TARNAME "" +#define PACKAGE_VERSION "" +#define PACKAGE_STRING "" +#define PACKAGE_BUGREPORT "" +#define PACKAGE_URL "" +#define HAVE__BOOL 1 +#define SIZEOF_SHORT 2 +#define SIZEOF_INT 4 +#define SIZEOF_LONG 8 +#define STDC_HEADERS 1 +#define TIME_WITH_SYS_TIME 1 +#define HAVE_STDBOOL_H 1 +#define STRING_WITH_STRINGS 1 +#define HAVE_SYS_WAIT_H 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_SYS_STAT_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STRING_H 1 +#define HAVE_MEMORY_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_UNISTD_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_STDDEF_H 1 +#define HAVE_STRING_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_TIME_H 1 +#define HAVE_FCNTL_H 1 +#define HAVE_UNISTD_H 1 +#define HAVE_SYS_FILE_H 1 +#define HAVE_SYS_TIME_H 1 +#define HAVE_SYS_PARAM_H 1 +#define HAVE_SYS_STAT_H 1 +#define HAVE_MALLOC_H 1 +#define HAVE_STRINGIZE 1 +#define HAVE_CLOCK 1 +#define HAVE_STRSIGNAL 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_LSTAT 1 +#define HAVE_GETPAGESIZE 1 +#define HAVE_MMAP_DEV_ZERO 1 +#define HAVE_MMAP_ANON 1 +#define HAVE_MMAP_FILE 1 +#define HAVE_DECL_GETENV 0 +#define HAVE_DECL_ABORT 0 +#define HAVE_DECL_STRSIGNAL 0 +#define HAVE_DECL_ERRNO 0 +#define HAVE_DECL_MALLOC 0 +#define HAVE_DECL_REALLOC 0 +#define HAVE_DECL_CALLOC 0 +#define HAVE_DECL_FREE 0 +#define HAVE_DECL_CLOCK 0 +#define PACKAGE "sdcc" +#define VERSION "const" + +configure: exit 0 diff --git a/support/cpp/config.status b/support/cpp/config.status new file mode 100755 index 0000000..91969b9 --- /dev/null +++ b/support/cpp/config.status @@ -0,0 +1,1148 @@ +#! /bin/bash +# Generated by configure. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=${CONFIG_SHELL-/bin/bash} +export SHELL +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +# Files that config.status was made for. +config_files=" Makefile" +config_headers=" auto-host.h:config.in" +config_commands=" default" + +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to the package provider." + +ac_cs_config="'--disable-option-checking' '--prefix=/usr/local' '--disable-mcs51-port' '--disable-z80-port' '--disable-z180-port' '--disable-r2k-port' '--disable-r3ka-port' '--disable-gbz80-port' '--disable-tlcs90-port' '--disable-ez80_z80-port' '--disable-ds390-port' '--disable-ds400-port' '--disable-pic14-port' '--disable-pic16-port' '--disable-hc08-port' '--disable-s08-port' '--disable-pdk13-port' '--disable-pdk14-port' '--disable-pdk15-port' '--enable-pdk16-port' '--disable-ucsim' '--disable-device-lib' '--disable-packihx' '--disable-pdk16-port' 'docdir=\${datarootdir}/doc/\${PACKAGE}' '--cache-file=/dev/null' '--srcdir=.'" +ac_cs_version="\ +config.status +configured by ./configure, generated by GNU Autoconf 2.69, + with options \"$ac_cs_config\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='/home/xavier/sdcc/support/cpp' +srcdir='.' +AWK='gawk' +test -n "$AWK" || AWK=awk +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +if $ac_cs_recheck; then + set X /bin/bash './configure' '--disable-option-checking' '--prefix=/usr/local' '--disable-mcs51-port' '--disable-z80-port' '--disable-z180-port' '--disable-r2k-port' '--disable-r3ka-port' '--disable-gbz80-port' '--disable-tlcs90-port' '--disable-ez80_z80-port' '--disable-ds390-port' '--disable-ds400-port' '--disable-pic14-port' '--disable-pic16-port' '--disable-hc08-port' '--disable-s08-port' '--disable-pdk13-port' '--disable-pdk14-port' '--disable-pdk15-port' '--enable-pdk16-port' '--disable-ucsim' '--disable-device-lib' '--disable-packihx' '--disable-pdk16-port' 'docdir=${datarootdir}/doc/${PACKAGE}' '--cache-file=/dev/null' '--srcdir=.' $ac_configure_extra_args --no-create --no-recursion + shift + $as_echo "running CONFIG_SHELL=/bin/bash $*" >&6 + CONFIG_SHELL='/bin/bash' + export CONFIG_SHELL + exec "$@" +fi + +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +# +# INIT-COMMANDS +# + +host='' +build='' +target='' +target_alias='' +srcdir='.' +symbolic_link='ln -s' +program_transform_set='' +program_transform_name='s,x,x,' +dep_host_xmake_file='' +host_xmake_file='' +dep_tmake_file='' +tmake_file='/t- t-install-cpp' +thread_file='' +gcc_config_arguments='' +gcc_version='const' +gcc_version_full='const char version_string[] = BASEVER DATESTAMP DEVPHASE VERSUFFIX; +const char pkgversion_string[] = PKGVERSION;' +gcc_version_trigger='./version.c' +local_prefix='/usr/local' +build_install_headers_dir='install-headers-tar' +build_exeext='' +host_exeext='' +out_file='/.c' +gdb_needs_out_file_path='' +SET_MAKE='' +target_list='' +target_overrides='' +host_overrides='' +cross_defines='' +cross_overrides='' +build_overrides='' +cpp_install_dir='' + + + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "auto-host.h") CONFIG_HEADERS="$CONFIG_HEADERS auto-host.h:config.in" ;; + "$all_outputs") CONFIG_FILES="$CONFIG_FILES $all_outputs" ;; + "default") CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +cat >>"$ac_tmp/subs1.awk" <<\_ACAWK && +S["LTLIBOBJS"]="" +S["LIBOBJS"]="" +S["c_target_objs"]="" +S["thread_file"]="" +S["symbolic_link"]="ln -s" +S["out_object_file"]=".c.o" +S["out_file"]="/.c" +S["md_file"]="/.md" +S["local_prefix"]="/usr/local" +S["lang_tree_files"]="" +S["install"]="" +S["host_extra_gcc_objs"]="" +S["host_exeext"]="" +S["gcc_version_trigger"]="./version.c" +S["gcc_version_full"]="const char version_string[] = BASEVER DATESTAMP DEVPHASE VERSUFFIX;\n"\ +"const char pkgversion_string[] = PKGVERSION;" +S["gcc_version"]="const" +S["gcc_config_arguments"]="" +S["extra_programs"]="" +S["extra_passes"]="" +S["extra_parts"]="" +S["extra_objs"]=" " +S["extra_headers_list"]="" +S["extra_c_flags"]="" +S["dep_tmake_file"]="" +S["dep_host_xmake_file"]="" +S["check_languages"]="" +S["build_xm_defines"]="" +S["build_xm_file"]="auto-host.h ansidecl.h /.h defaults.h" +S["build_xm_file_list"]="" +S["build_install_headers_dir"]="install-headers-tar" +S["build_exeext"]="" +S["all_stagestuff"]="" +S["WALL_FLAG"]="-Wall" +S["objdir"]="/home/xavier/sdcc/support/cpp" +S["target_subdir"]="" +S["host_canonical"]="" +S["build_canonical"]="" +S["MAINT"]="#" +S["VERSION"]="const" +S["PACKAGE"]="sdcc" +S["objext"]=".o" +S["manext"]=".1" +S["AR"]="ar" +S["STRIP"]="strip" +S["have_mktemp_command"]="yes" +S["INSTALL_DATA"]="${INSTALL} -m 644" +S["INSTALL_PROGRAM"]="${INSTALL}" +S["INSTALL"]="/usr/bin/install -c" +S["RANLIB"]="ranlib" +S["LN_S"]="ln -s" +S["LN"]="ln" +S["AWK"]="gawk" +S["SET_MAKE"]="" +S["warn_cflags"]="$(GCC_WARN_CFLAGS)" +S["EGREP"]="/bin/grep -E" +S["GREP"]="/bin/grep" +S["CPP"]="gcc -E" +S["OUTPUT_OPTION"]="-o $@" +S["NO_MINUS_C_MINUS_O"]="" +S["OBJEXT"]="o" +S["EXEEXT"]="" +S["ac_ct_CC"]="gcc" +S["CPPFLAGS"]="" +S["LDFLAGS"]="" +S["CFLAGS"]=" -g -O2" +S["CC"]="gcc" +S["target_alias"]="" +S["host_alias"]="" +S["build_alias"]="" +S["LIBS"]="" +S["ECHO_T"]="" +S["ECHO_N"]="-n" +S["ECHO_C"]="" +S["DEFS"]="-DHAVE_CONFIG_H" +S["mandir"]="${datarootdir}/man" +S["localedir"]="${datarootdir}/locale" +S["libdir"]="${exec_prefix}/lib" +S["psdir"]="${docdir}" +S["pdfdir"]="${docdir}" +S["dvidir"]="${docdir}" +S["htmldir"]="${docdir}" +S["infodir"]="${datarootdir}/info" +S["docdir"]="${datarootdir}/doc/${PACKAGE}" +S["oldincludedir"]="/usr/include" +S["includedir"]="${prefix}/include" +S["runstatedir"]="${localstatedir}/run" +S["localstatedir"]="${prefix}/var" +S["sharedstatedir"]="${prefix}/com" +S["sysconfdir"]="${prefix}/etc" +S["datadir"]="${datarootdir}" +S["datarootdir"]="${prefix}/share" +S["libexecdir"]="${exec_prefix}/libexec" +S["sbindir"]="${exec_prefix}/sbin" +S["bindir"]="${exec_prefix}/bin" +S["program_transform_name"]="s,x,x," +S["prefix"]="/usr/local" +S["exec_prefix"]="${prefix}" +S["PACKAGE_URL"]="" +S["PACKAGE_BUGREPORT"]="" +S["PACKAGE_STRING"]="" +S["PACKAGE_VERSION"]="" +S["PACKAGE_TARNAME"]="" +S["PACKAGE_NAME"]="" +S["PATH_SEPARATOR"]=":" +S["SHELL"]="/bin/bash" +_ACAWK +cat >>"$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +D["PACKAGE_NAME"]=" \"\"" +D["PACKAGE_TARNAME"]=" \"\"" +D["PACKAGE_VERSION"]=" \"\"" +D["PACKAGE_STRING"]=" \"\"" +D["PACKAGE_BUGREPORT"]=" \"\"" +D["PACKAGE_URL"]=" \"\"" +D["HAVE__BOOL"]=" 1" +D["SIZEOF_SHORT"]=" 2" +D["SIZEOF_INT"]=" 4" +D["SIZEOF_LONG"]=" 8" +D["STDC_HEADERS"]=" 1" +D["TIME_WITH_SYS_TIME"]=" 1" +D["HAVE_STDBOOL_H"]=" 1" +D["STRING_WITH_STRINGS"]=" 1" +D["HAVE_SYS_WAIT_H"]=" 1" +D["HAVE_SYS_TYPES_H"]=" 1" +D["HAVE_SYS_STAT_H"]=" 1" +D["HAVE_STDLIB_H"]=" 1" +D["HAVE_STRING_H"]=" 1" +D["HAVE_MEMORY_H"]=" 1" +D["HAVE_STRINGS_H"]=" 1" +D["HAVE_INTTYPES_H"]=" 1" +D["HAVE_STDINT_H"]=" 1" +D["HAVE_UNISTD_H"]=" 1" +D["HAVE_LIMITS_H"]=" 1" +D["HAVE_STDDEF_H"]=" 1" +D["HAVE_STRING_H"]=" 1" +D["HAVE_STRINGS_H"]=" 1" +D["HAVE_STDLIB_H"]=" 1" +D["HAVE_TIME_H"]=" 1" +D["HAVE_FCNTL_H"]=" 1" +D["HAVE_UNISTD_H"]=" 1" +D["HAVE_SYS_FILE_H"]=" 1" +D["HAVE_SYS_TIME_H"]=" 1" +D["HAVE_SYS_PARAM_H"]=" 1" +D["HAVE_SYS_STAT_H"]=" 1" +D["HAVE_MALLOC_H"]=" 1" +D["HAVE_STRINGIZE"]=" 1" +D["HAVE_CLOCK"]=" 1" +D["HAVE_STRSIGNAL"]=" 1" +D["HAVE_STRCHR"]=" 1" +D["HAVE_STRRCHR"]=" 1" +D["HAVE_LSTAT"]=" 1" +D["HAVE_GETPAGESIZE"]=" 1" +D["HAVE_MMAP_DEV_ZERO"]=" 1" +D["HAVE_MMAP_ANON"]=" 1" +D["HAVE_MMAP_FILE"]=" 1" +D["HAVE_DECL_GETENV"]=" 0" +D["HAVE_DECL_ABORT"]=" 0" +D["HAVE_DECL_STRSIGNAL"]=" 0" +D["HAVE_DECL_ERRNO"]=" 0" +D["HAVE_DECL_MALLOC"]=" 0" +D["HAVE_DECL_REALLOC"]=" 0" +D["HAVE_DECL_CALLOC"]=" 0" +D["HAVE_DECL_FREE"]=" 0" +D["HAVE_DECL_CLOCK"]=" 0" +D["PACKAGE"]=" \"sdcc\"" +D["VERSION"]=" \"const\"" + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+[_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ][_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]*([\t (]|$)/ { + line = $ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} + ac_datarootdir_hack=' + s&@datadir@&${datarootdir}&g + s&@docdir@&${datarootdir}/doc/${PACKAGE}&g + s&@infodir@&${datarootdir}/info&g + s&@localedir@&${datarootdir}/locale&g + s&@mandir@&${datarootdir}/man&g + s&\${datarootdir}&${prefix}/share&g' ;; +esac +ac_sed_extra="/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +} + +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "default":C) +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 + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 diff --git a/support/cpp/configure b/support/cpp/configure new file mode 100755 index 0000000..59b955e --- /dev/null +++ b/support/cpp/configure @@ -0,0 +1,7295 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69. +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 </dev/null +exec 6>&1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= +PACKAGE_URL= + +ac_unique_file="sdcpp.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include <stdio.h> +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif +#ifdef STDC_HEADERS +# include <stdlib.h> +# include <stddef.h> +#else +# ifdef HAVE_STDLIB_H +# include <stdlib.h> +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include <memory.h> +# endif +# include <string.h> +#endif +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif +#ifdef HAVE_INTTYPES_H +# include <inttypes.h> +#endif +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif" + +ac_subst_vars='LTLIBOBJS +LIBOBJS +c_target_objs +thread_file +symbolic_link +out_object_file +out_file +md_file +local_prefix +lang_tree_files +install +host_extra_gcc_objs +host_exeext +gcc_version_trigger +gcc_version_full +gcc_version +gcc_config_arguments +extra_programs +extra_passes +extra_parts +extra_objs +extra_headers_list +extra_c_flags +dep_tmake_file +dep_host_xmake_file +check_languages +build_xm_defines +build_xm_file +build_xm_file_list +build_install_headers_dir +build_exeext +all_stagestuff +WALL_FLAG +objdir +target_subdir +host_canonical +build_canonical +MAINT +VERSION +PACKAGE +objext +manext +AR +STRIP +have_mktemp_command +INSTALL_DATA +INSTALL_PROGRAM +INSTALL +RANLIB +LN_S +LN +AWK +SET_MAKE +warn_cflags +EGREP +GREP +CPP +OUTPUT_OPTION +NO_MINUS_C_MINUS_O +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +runstatedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +with_gnu_ld +with_ld +with_gnu_as +with_as +with_stabs +with_elf +with_local_prefix +enable_c_mbchar +enable_maintainer_mode +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir runstatedir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-c-mbchar enable multibyte characters for C and C++ + --enable-maintainer-mode + enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-gnu-ld arrange to work with GNU ld. + --with-ld arrange to use the specified ld (full pathname) + --with-gnu-as arrange to work with GNU as + --with-as arrange to use the specified as (full pathname) + --with-stabs arrange to use stabs instead of host debug format + --with-elf arrange to use ELF instead of host debug format + --with-local-prefix=DIR specifies directory to put local include + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a + nonstandard directory <lib dir> + LIBS libraries to pass to the linker, e.g. -l<library> + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if + you have headers in a nonstandard directory <include dir> + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to the package provider. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +configure +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case <limits.h> declares $2. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_config_headers="$ac_config_headers auto-host.h:config.in" + + +remove=rm +hard_link=ln +symbolic_link='ln -s' +copy=cp + +# Check for additional parameters + +# With GNU ld + +# Check whether --with-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 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 + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot execute: $DEFAULT_LINKER: check --with-ld or env. var. DEFAULT_LINKER" >&5 +$as_echo "$as_me: WARNING: cannot execute: $DEFAULT_LINKER: check --with-ld or env. var. DEFAULT_LINKER" >&2;} + elif $DEFAULT_LINKER -v < /dev/null 2>&1 | grep GNU > /dev/null; then + gnu_ld_flag=yes + fi + +cat >>confdefs.h <<_ACEOF +#define DEFAULT_LINKER "$DEFAULT_LINKER" +_ACEOF + +fi + +# With GNU as + +# Check whether --with-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 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 + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot execute: $DEFAULT_ASSEMBLER: check --with-as or env. var. DEFAULT_ASSEMBLER" >&5 +$as_echo "$as_me: WARNING: cannot execute: $DEFAULT_ASSEMBLER: check --with-as or env. var. DEFAULT_ASSEMBLER" >&2;} + elif $DEFAULT_ASSEMBLER -v < /dev/null 2>&1 | grep GNU > /dev/null; then + gas_flag=yes + fi + +cat >>confdefs.h <<_ACEOF +#define DEFAULT_ASSEMBLER "$DEFAULT_ASSEMBLER" +_ACEOF + +fi + +# With stabs + +# Check whether --with-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 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 was given. +if test "${with_local_prefix+set}" = set; then : + withval=$with_local_prefix; case "${withval}" in +yes) as_fn_error $? "bad value ${withval} given for local include directory prefix" "$LINENO" 5 ;; +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 + +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + + +# Enable Multibyte Characters for C/C++ +# Check whether --enable-c-mbchar was given. +if test "${enable_c_mbchar+set}" = set; then : + enableval=$enable_c_mbchar; if test x$enable_c_mbchar != xno; then + +$as_echo "#define MULTIBYTE_CHARS 1" >>confdefs.h + +fi +fi + + +# Find the native compiler +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdarg.h> +#include <stdio.h> +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +if test "x$CC" != xcc; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5 +$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5 +$as_echo_n "checking whether cc understands -c and -o together... " >&6; } +fi +set dummy $CC; ac_cc=`$as_echo "$2" | + sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` +if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +# Make sure it works both with $CC and with simple cc. +# 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 -c conftest.$ac_ext -o conftest2.$ac_objext >&5' +rm -f conftest2.* +if { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && + test -f conftest2.$ac_objext && { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; +then + 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.$ac_ext >&5' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5' + rm -f conftest2.* + if { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && + test -f conftest2.$ac_objext && { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; + then + # 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 core conftest* + +fi +if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +$as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h + +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 + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 +$as_echo_n "checking for inline... " >&6; } +if ${ac_cv_c_inline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_inline=$ac_kw +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 +$as_echo "$ac_cv_c_inline" >&6; } + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for built-in _Bool" >&5 +$as_echo_n "checking for built-in _Bool... " >&6; } +if ${gcc_cv_c__bool+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +_Bool foo; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gcc_cv_c__bool=yes +else + gcc_cv_c__bool=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_c__bool" >&5 +$as_echo "$gcc_cv_c__bool" >&6; } +if test $gcc_cv_c__bool = yes; then + +$as_echo "#define HAVE__BOOL 1" >>confdefs.h + +fi + + +# sizeof(char) is 1 by definition. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of short" >&5 +$as_echo_n "checking size of short... " >&6; } +if ${ac_cv_sizeof_short+:} false; then : + $as_echo_n "(cached) " >&6 +else + for ac_size in 4 8 1 2 16 ; do # List sizes in rough order of prevalence. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include "confdefs.h" +#include <sys/types.h> + + +int +main () +{ +switch (0) case 0: case (sizeof (short) == $ac_size):; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sizeof_short=$ac_size +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test x$ac_cv_sizeof_short != x ; then break; fi +done + +fi + +if test x$ac_cv_sizeof_short = x ; then + as_fn_error $? "cannot determine a size for short" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5 +$as_echo "$ac_cv_sizeof_short" >&6; } + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_SHORT $ac_cv_sizeof_short +_ACEOF + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 +$as_echo_n "checking size of int... " >&6; } +if ${ac_cv_sizeof_int+:} false; then : + $as_echo_n "(cached) " >&6 +else + for ac_size in 4 8 1 2 16 ; do # List sizes in rough order of prevalence. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include "confdefs.h" +#include <sys/types.h> + + +int +main () +{ +switch (0) case 0: case (sizeof (int) == $ac_size):; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sizeof_int=$ac_size +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test x$ac_cv_sizeof_int != x ; then break; fi +done + +fi + +if test x$ac_cv_sizeof_int = x ; then + as_fn_error $? "cannot determine a size for int" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 +$as_echo "$ac_cv_sizeof_int" >&6; } + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_INT $ac_cv_sizeof_int +_ACEOF + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 +$as_echo_n "checking size of long... " >&6; } +if ${ac_cv_sizeof_long+:} false; then : + $as_echo_n "(cached) " >&6 +else + for ac_size in 4 8 1 2 16 ; do # List sizes in rough order of prevalence. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include "confdefs.h" +#include <sys/types.h> + + +int +main () +{ +switch (0) case 0: case (sizeof (long) == $ac_size):; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sizeof_long=$ac_size +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test x$ac_cv_sizeof_long != x ; then break; fi +done + +fi + +if test x$ac_cv_sizeof_long = x ; then + as_fn_error $? "cannot determine a size for long" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 +$as_echo "$ac_cv_sizeof_long" >&6; } + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_LONG $ac_cv_sizeof_long +_ACEOF + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking execution character set" >&5 +$as_echo_n "checking execution character set... " >&6; } +if ${ac_cv_c_charset+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if '\n' == 0x0A && ' ' == 0x20 && '0' == 0x30 \ + && 'A' == 0x41 && 'a' == 0x61 && '!' == 0x21 +ASCII +#endif +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "ASCII" >/dev/null 2>&1; then : + ac_cv_c_charset=ASCII +fi +rm -f conftest* + + if test x${ac_cv_c_charset+set} != xset; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if '\n' == 0x15 && ' ' == 0x40 && '0' == 0xF0 \ + && 'A' == 0xC1 && 'a' == 0x81 && '!' == 0x5A +EBCDIC +#endif +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "EBCDIC" >/dev/null 2>&1; then : + 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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_charset" >&5 +$as_echo "$ac_cv_c_charset" >&6; } +if test $ac_cv_c_charset = unknown; then + as_fn_error $? "*** Cannot determine host character set." "$LINENO" 5 +elif test $ac_cv_c_charset = EBCDIC; then + +$as_echo "#define HOST_EBCDIC 1" >>confdefs.h + +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 + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a default assembler was specified" >&5 +$as_echo_n "checking whether a default assembler was specified... " >&6; } +if test x"${DEFAULT_ASSEMBLER+set}" = x"set"; then + if test x"$gas_flag" = x"no"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes ($DEFAULT_ASSEMBLER)" >&5 +$as_echo "yes ($DEFAULT_ASSEMBLER)" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes ($DEFAULT_ASSEMBLER - GNU as)" >&5 +$as_echo "yes ($DEFAULT_ASSEMBLER - GNU as)" >&6; } + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a default linker was specified" >&5 +$as_echo_n "checking whether a default linker was specified... " >&6; } +if test x"${DEFAULT_LINKER+set}" = x"set"; then + if test x"$gnu_ld_flag" = x"no"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes ($DEFAULT_LINKER)" >&5 +$as_echo "yes ($DEFAULT_LINKER)" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes ($DEFAULT_LINKER - GNU ld)" >&5 +$as_echo "yes ($DEFAULT_LINKER - GNU ld)" >&6; } + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Find some useful tools +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +# We need awk to run opts.sh (to create options.c and options.h). +# Bail out if it's missing. +case ${AWK} in + "") as_fn_error $? "can't build without awk, bailing out" "$LINENO" 5 ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln works" >&5 +$as_echo_n "checking whether ln works... " >&6; } +if ${gcc_cv_prog_LN+:} false; then : + $as_echo_n "(cached) " >&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 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + if test "$gcc_cv_prog_LN" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using ln -s" >&5 +$as_echo "no, using ln -s" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, and neither does ln -s, so using cp" >&5 +$as_echo "no, and neither does ln -s, so using cp" >&6; } + fi +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +if ${gcc_cv_prog_LN_S+:} false; then : + $as_echo_n "(cached) " >&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 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + if test "$gcc_cv_prog_LN_S" = "ln"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using ln" >&5 +$as_echo "no, using ln" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, and neither does ln, so using cp" >&5 +$as_echo "no, and neither does ln, so using cp" >&6; } + fi +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# 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. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD compatible install" >&5 +$as_echo_n "checking for a BSD compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + 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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <string.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ctype.h> +#include <stdlib.h> +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 +$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } +if ${ac_cv_header_time+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> +#include <sys/time.h> +#include <time.h> + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_time=yes +else + ac_cv_header_time=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 +$as_echo "$ac_cv_header_time" >&6; } +if test $ac_cv_header_time = yes; then + +$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working stdbool.h" >&5 +$as_echo_n "checking for working stdbool.h... " >&6; } +if ${ac_cv_header_stdbool_h+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdbool.h> +int +main () +{ +bool foo = false; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdbool_h=yes +else + ac_cv_header_stdbool_h=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5 +$as_echo "$ac_cv_header_stdbool_h" >&6; } +if test $ac_cv_header_stdbool_h = yes; then + +$as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether string.h and strings.h may both be included" >&5 +$as_echo_n "checking whether string.h and strings.h may both be included... " >&6; } +if ${gcc_cv_header_string+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <string.h> +#include <strings.h> +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gcc_cv_header_string=yes +else + gcc_cv_header_string=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_header_string" >&5 +$as_echo "$gcc_cv_header_string" >&6; } +if test $gcc_cv_header_string = yes; then + +$as_echo "#define STRING_WITH_STRINGS 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5 +$as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; } +if ${ac_cv_header_sys_wait_h+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> +#include <sys/wait.h> +#ifndef WEXITSTATUS +# define WEXITSTATUS(stat_val) ((unsigned int) (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; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_sys_wait_h=yes +else + ac_cv_header_sys_wait_h=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_wait_h" >&5 +$as_echo "$ac_cv_header_sys_wait_h" >&6; } +if test $ac_cv_header_sys_wait_h = yes; then + +$as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in limits.h stddef.h string.h strings.h stdlib.h time.h \ + fcntl.h unistd.h sys/file.h sys/time.h \ + sys/param.h sys/stat.h \ + direct.h malloc.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +# Check for thread headers. + +# These tests can't be done till we know if we have limits.h. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for CHAR_BIT" >&5 +$as_echo_n "checking for CHAR_BIT... " >&6; } +if ${gcc_cv_decl_char_bit+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif +#ifdef CHAR_BIT +found +#endif +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "found" >/dev/null 2>&1; then : + gcc_cv_decl_char_bit=yes +else + gcc_cv_decl_char_bit=no +fi +rm -f conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_decl_char_bit" >&5 +$as_echo "$gcc_cv_decl_char_bit" >&6; } +if test $gcc_cv_decl_char_bit = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking number of bits in a byte" >&5 +$as_echo_n "checking number of bits in a byte... " >&6; } +if ${gcc_cv_c_nbby+:} false; then : + $as_echo_n "(cached) " >&6 +else + i=8 + gcc_cv_c_nbby= + while test $i -lt 65; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end 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; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gcc_cv_c_nbby=$i; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + i=`expr $i + 1` + done + test -z "$gcc_cv_c_nbby" && gcc_cv_c_nbby=failed + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_c_nbby" >&5 +$as_echo "$gcc_cv_c_nbby" >&6; } +if test $gcc_cv_c_nbby = failed; then + as_fn_error $? "cannot determine number of bits in a byte" "$LINENO" 5 +else + +cat >>confdefs.h <<_ACEOF +#define CHAR_BIT $gcc_cv_c_nbby +_ACEOF + +fi +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 +$as_echo_n "checking whether byte ordering is bigendian... " >&6; } +if ${ac_cv_c_bigendian+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_bigendian=unknown + # See if we're dealing with a universal compiler. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __APPLE_CC__ + not a universal capable compiler + #endif + typedef int dummy; + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + # Check for potential -arch flags. It is not universal unless + # there are at least two -arch flags with different values. + ac_arch= + ac_prev= + for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do + if test -n "$ac_prev"; then + case $ac_word in + i?86 | x86_64 | ppc | ppc64) + if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then + ac_arch=$ac_word + else + ac_cv_c_bigendian=universal + break + fi + ;; + esac + ac_prev= + elif test "x$ac_word" = "x-arch"; then + ac_prev=arch + fi + done +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test $ac_cv_c_bigendian = unknown; then + # See if sys/param.h defines the BYTE_ORDER macro. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> + #include <sys/param.h> + +int +main () +{ +#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ + && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ + && LITTLE_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> + #include <sys/param.h> + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <limits.h> + +int +main () +{ +#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to _BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <limits.h> + +int +main () +{ +#ifndef _BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # Compile a test program. + if test "$cross_compiling" = yes; then : + # Try to guess by grepping values from an object file. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +short int ascii_mm[] = + { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; + short int ascii_ii[] = + { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; + int use_ascii (int i) { + return ascii_mm[i] + ascii_ii[i]; + } + short int ebcdic_ii[] = + { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; + short int ebcdic_mm[] = + { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; + int use_ebcdic (int i) { + return ebcdic_mm[i] + ebcdic_ii[i]; + } + extern int foo; + +int +main () +{ +return use_ascii (foo) == use_ebcdic (foo); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then + ac_cv_c_bigendian=yes + fi + if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long int l; + char c[sizeof (long int)]; + } u; + u.l = 1; + return u.c[sizeof (long int) - 1] == 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_bigendian=no +else + ac_cv_c_bigendian=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 +$as_echo "$ac_cv_c_bigendian" >&6; } + case $ac_cv_c_bigendian in #( + yes) + $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h +;; #( + no) + ;; #( + universal) + +$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h + + ;; #( + *) + as_fn_error $? "unknown endianness + presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; + esac + + +# 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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_have_mktemp_command+:} false; then : + $as_echo_n "(cached) " >&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 +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_have_mktemp_command="yes" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_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 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_mktemp_command" >&5 +$as_echo "$have_mktemp_command" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + +# Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_STRIP" && ac_cv_prog_STRIP=":" +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +# Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_AR" && ac_cv_prog_AR=":" +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + +# See if the stage1 system preprocessor understands the ANSI C +# preprocessor stringification operator. (Used by symcat.h.) +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for preprocessor stringizing operator" >&5 +$as_echo_n "checking for preprocessor stringizing operator... " >&6; } +if ${ac_cv_c_stringize+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define x(y) #y + +char *s = x(teststring); +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "#teststring" >/dev/null 2>&1; then : + ac_cv_c_stringize=no +else + ac_cv_c_stringize=yes +fi +rm -f conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stringize" >&5 +$as_echo "$ac_cv_c_stringize" >&6; } +if test $ac_cv_c_stringize = yes; then + +$as_echo "#define HAVE_STRINGIZE 1" >>confdefs.h + +fi + + + +for ac_func in clock strsignal strchr strrchr lstat +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" "$ac_includes_default" +if test "x$ac_cv_type_ssize_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define ssize_t int +_ACEOF + +fi + + +for ac_func in getpagesize +do : + ac_fn_c_check_func "$LINENO" "getpagesize" "ac_cv_func_getpagesize" +if test "x$ac_cv_func_getpagesize" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_GETPAGESIZE 1 +_ACEOF + +fi +done + +# 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 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working mmap from /dev/zero" >&5 +$as_echo_n "checking for working mmap from /dev/zero... " >&6; } +if ${ac_cv_func_mmap_dev_zero+:} false; then : + $as_echo_n "(cached) " >&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 confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include "ct-mmap.inc" +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_mmap_dev_zero=yes +else + if test $? -lt 4 + then ac_cv_func_mmap_dev_zero=no + else ac_cv_func_mmap_dev_zero=buggy + fi +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_mmap_dev_zero" >&5 +$as_echo "$ac_cv_func_mmap_dev_zero" >&6; } +if test $ac_cv_func_mmap_dev_zero = yes; then + +$as_echo "#define HAVE_MMAP_DEV_ZERO 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working mmap with MAP_ANON(YMOUS)" >&5 +$as_echo_n "checking for working mmap with MAP_ANON(YMOUS)... " >&6; } +if ${ac_cv_func_mmap_anon+:} false; then : + $as_echo_n "(cached) " >&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 confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define USE_MAP_ANON +#include "ct-mmap.inc" +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_mmap_anon=yes +else + if test $? -lt 4 + then ac_cv_func_mmap_anon=no + else ac_cv_func_mmap_anon=buggy + fi +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_mmap_anon" >&5 +$as_echo "$ac_cv_func_mmap_anon" >&6; } +if test $ac_cv_func_mmap_anon = yes; then + +$as_echo "#define HAVE_MMAP_ANON 1" >>confdefs.h + +fi +rm -f ct-mmap.inc + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working mmap of a file" >&5 +$as_echo_n "checking for working mmap of a file... " >&6; } +if ${ac_cv_func_mmap_file+:} false; then : + $as_echo_n "(cached) " >&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 confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end 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); +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_mmap_file=yes +else + ac_cv_func_mmap_file=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_mmap_file" >&5 +$as_echo "$ac_cv_func_mmap_file" >&6; } +if test $ac_cv_func_mmap_file = yes; then + +$as_echo "#define HAVE_MMAP_FILE 1" >>confdefs.h + +fi + + +# We will need to find libiberty.h and ansidecl.h +saved_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -I${srcdir} -I${srcdir}/libiberty -I${srcdir}/libcpp/include" +for ac_func in getenv abort strsignal errno \ + malloc realloc calloc free clock +do + ac_tr_decl=HAVE_DECL_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $ac_func is declared" >&5 +$as_echo_n "checking whether $ac_func is declared... " >&6; } +if eval \${gcc_cv_have_decl_$ac_func+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end 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; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "gcc_cv_have_decl_$ac_func=yes" +else + eval "gcc_cv_have_decl_$ac_func=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +if eval "test \"`echo '$gcc_cv_have_decl_'$ac_func`\" = yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } ; cat >>confdefs.h <<_ACEOF +#define $ac_tr_decl 1 +_ACEOF + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } ; cat >>confdefs.h <<_ACEOF +#define $ac_tr_decl 0 +_ACEOF + +fi + +done +if test x = y ; then + +$as_echo "#define HAVE_DECL_GETENV 1" >>confdefs.h + +$as_echo "#define HAVE_DECL_ABORT 1" >>confdefs.h + +$as_echo "#define HAVE_DECL_STRSIGNAL 1" >>confdefs.h + +$as_echo "#define HAVE_DECL_ERRNO 1" >>confdefs.h + \ + +$as_echo "#define HAVE_DECL_MALLOC 1" >>confdefs.h + +$as_echo "#define HAVE_DECL_REALLOC 1" >>confdefs.h + +$as_echo "#define HAVE_DECL_CALLOC 1" >>confdefs.h + +$as_echo "#define HAVE_DECL_FREE 1" >>confdefs.h + +$as_echo "#define HAVE_DECL_CLOCK 1" >>confdefs.h +fi + + +# Restore CFLAGS from before the gcc_AC_NEED_DECLARATIONS tests. +CFLAGS="$saved_CFLAGS" + +# Try to append a c99 flag + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5 +$as_echo_n "checking for $CC option to accept ISO C99... " >&6; } +if ${ac_cv_prog_cc_c99+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c99=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdarg.h> +#include <stdbool.h> +#include <stdlib.h> +#include <wchar.h> +#include <stdio.h> + +// Check varargs macros. These examples are taken from C99 6.10.3.5. +#define debug(...) fprintf (stderr, __VA_ARGS__) +#define showlist(...) puts (#__VA_ARGS__) +#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) +static void +test_varargs_macros (void) +{ + int x = 1234; + int y = 5678; + debug ("Flag"); + debug ("X = %d\n", x); + showlist (The first, second, and third items.); + report (x>y, "x is %d but y is %d", x, y); +} + +// Check long long types. +#define BIG64 18446744073709551615ull +#define BIG32 4294967295ul +#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) +#if !BIG_OK + your preprocessor is broken; +#endif +#if BIG_OK +#else + your preprocessor is broken; +#endif +static long long int bignum = -9223372036854775807LL; +static unsigned long long int ubignum = BIG64; + +struct incomplete_array +{ + int datasize; + double data[]; +}; + +struct named_init { + int number; + const wchar_t *name; + double average; +}; + +typedef const char *ccp; + +static inline int +test_restrict (ccp restrict text) +{ + // See if C++-style comments work. + // Iterate through items via the restricted pointer. + // Also check for declarations in for loops. + for (unsigned int i = 0; *(text+i) != '\0'; ++i) + continue; + return 0; +} + +// Check varargs and va_copy. +static void +test_varargs (const char *format, ...) +{ + va_list args; + va_start (args, format); + va_list args_copy; + va_copy (args_copy, args); + + const char *str; + int number; + float fnumber; + + while (*format) + { + switch (*format++) + { + case 's': // string + str = va_arg (args_copy, const char *); + break; + case 'd': // int + number = va_arg (args_copy, int); + break; + case 'f': // float + fnumber = va_arg (args_copy, double); + break; + default: + break; + } + } + va_end (args_copy); + va_end (args); +} + +int +main () +{ + + // Check bool. + _Bool success = false; + + // Check restrict. + if (test_restrict ("String literal") == 0) + success = true; + char *restrict newvar = "Another string"; + + // Check varargs. + test_varargs ("s, d' f .", "string", 65, 34.234); + test_varargs_macros (); + + // Check flexible array members. + struct incomplete_array *ia = + malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); + ia->datasize = 10; + for (int i = 0; i < ia->datasize; ++i) + ia->data[i] = i * 1.234; + + // Check named initializers. + struct named_init ni = { + .number = 34, + .name = L"Test wide string", + .average = 543.34343, + }; + + ni.number = 58; + + int dynamic_array[ni.number]; + dynamic_array[ni.number - 1] = 543; + + // work around unused variable warnings + return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x' + || dynamic_array[ni.number - 1] != 543); + + ; + return 0; +} +_ACEOF +for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99 +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c99=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c99" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c99" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c99" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 +$as_echo "$ac_cv_prog_cc_c99" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c99" != xno; then : + +fi + + +if test "$ac_cv_prog_cc_c99" != "no"; then + CFLAGS="$ac_cv_prog_cc_c99 ${CFLAGS}" +fi + +# mkdir takes a single argument on some systems. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if mkdir takes one argument" >&5 +$as_echo_n "checking if mkdir takes one argument... " >&6; } +if ${gcc_cv_mkdir_takes_one_arg+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end 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; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gcc_cv_mkdir_takes_one_arg=no +else + gcc_cv_mkdir_takes_one_arg=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_mkdir_takes_one_arg" >&5 +$as_echo "$gcc_cv_mkdir_takes_one_arg" >&6; } +if test $gcc_cv_mkdir_takes_one_arg = yes ; then + +$as_echo "#define MKDIR_TAKES_ONE_ARG 1" >>confdefs.h + +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/'` + + +# Internationalization +PACKAGE=sdcc +VERSION="$gcc_version" + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + + + + +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. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking what assembler to use" >&5 +$as_echo_n "checking what assembler to use... " >&6; } +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 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"newly built gas\"" >&5 +$as_echo "\"newly built gas\"" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as" >&5 +$as_echo "$gcc_cv_as" >&6; } +fi + +# Figure out what nm we will be using. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking what nm to use" >&5 +$as_echo_n "checking what nm to use... " >&6; } +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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_nm" >&5 +$as_echo "$gcc_cv_nm" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 +$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } + # Check whether --enable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then : + enableval=$enable_maintainer_mode; maintainer_mode=$enableval +else + maintainer_mode=no +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $maintainer_mode" >&5 +$as_echo "$maintainer_mode" >&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` + + +# -Wall c flag if GNU C +if test "$ac_cv_c_compiler_gnu" = "yes"; then + WALL_FLAG="-Wall" +else + WALL_FLAG= +fi + + +# Substitute configuration variables + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +#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_config_files="$ac_config_files $all_outputs" + +ac_config_commands="$ac_config_commands default" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to the package provider." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# + +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}' + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "auto-host.h") CONFIG_HEADERS="$CONFIG_HEADERS auto-host.h:config.in" ;; + "$all_outputs") CONFIG_FILES="$CONFIG_FILES $all_outputs" ;; + "default") CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' <conf$$subs.awk | sed ' +/^[^""]/{ + N + s/\n// +} +' >>$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' <confdefs.h | sed ' +s/'"$ac_delim"'/"\\\ +"/g' >>$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "default":C) +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 + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/support/cpp/configure.ac b/support/cpp/configure.ac new file mode 100644 index 0000000..cbf4e07 --- /dev/null +++ b/support/cpp/configure.ac @@ -0,0 +1,607 @@ +# configure.in for GCC +# Process this file with autoconf to generate a configuration script. + +# Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + +#This file is part of GCC. + +#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. + +# Initialization and defaults +AC_PREREQ(2.60) +AC_INIT(sdcpp.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 + +AC_ARG_PROGRAM + +# 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 + +gcc_AC_C__BOOL + +# 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 + +# Find some useful tools +AC_PROG_AWK +# We need awk to run opts.sh (to create options.c and options.h). +# Bail out if it's missing. +case ${AWK} in + "") AC_MSG_ERROR([can't build without awk, bailing out]) ;; +esac + +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_STDBOOL +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/param.h sys/stat.h \ + direct.h malloc.h) + +# Check for thread headers. + +# These tests can't be done till we know if we have limits.h. +gcc_AC_C_CHAR_BIT +AC_C_BIGENDIAN + +# See if we have the mktemp command. +AC_CHECK_PROG(have_mktemp_command, mktemp, yes, no) + +AC_CHECK_PROG(STRIP, strip, strip, :) +AC_CHECK_PROG(AR, ar, ar, :) + +# See if the stage1 system preprocessor understands the ANSI C +# preprocessor stringification operator. (Used by symcat.h.) +AC_C_STRINGIZE + +dnl Disabled until we have a complete test for buggy enum bitfields. +dnl gcc_AC_C_ENUM_BF_UNSIGNED + +AC_CHECK_FUNCS(clock strsignal 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}/libiberty -I${srcdir}/libcpp/include" +gcc_AC_CHECK_DECLS(getenv abort strsignal errno \ + malloc realloc calloc free clock, , ,[ +#include "ansidecl.h" +#include "system.h"]) + +# Restore CFLAGS from before the gcc_AC_NEED_DECLARATIONS tests. +CFLAGS="$saved_CFLAGS" + +# Try to append a c99 flag +AC_PROG_CC_C99 +if test "$ac_cv_prog_cc_c99" != "no"; then + CFLAGS="$ac_cv_prog_cc_c99 ${CFLAGS}" +fi + +# 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/'` + +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) + +# -Wall c flag if GNU C +if test "$ac_cv_c_compiler_gnu" = "yes"; then + WALL_FLAG="-Wall" +else + WALL_FLAG= +fi +AC_SUBST(WALL_FLAG) + +# 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}' +]) diff --git a/support/cpp/cppdefault.c b/support/cpp/cppdefault.c new file mode 100644 index 0000000..e869975 --- /dev/null +++ b/support/cpp/cppdefault.c @@ -0,0 +1,138 @@ +/* CPP Library. + Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + 1999, 2000, 2003, 2004, 2006, 2007 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 3, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "cppdefault.h" + +#ifndef STANDARD_INCLUDE_DIR +#define STANDARD_INCLUDE_DIR "/usr/include" +#endif + +#ifndef STANDARD_INCLUDE_COMPONENT +#define STANDARD_INCLUDE_COMPONENT 0 +#endif + +#if defined (CROSS_DIRECTORY_STRUCTURE) && !defined (TARGET_SYSTEM_ROOT) +# undef LOCAL_INCLUDE_DIR +# undef SYSTEM_INCLUDE_DIR +# undef STANDARD_INCLUDE_DIR +#else +# undef CROSS_INCLUDE_DIR +#endif + +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, 0, 0 }, +#endif +#ifdef GPLUSPLUS_TOOL_INCLUDE_DIR + /* Pick up GNU C++ target-dependent include files. */ + { GPLUSPLUS_TOOL_INCLUDE_DIR, "G++", 1, 1, 0, 1 }, +#endif +#ifdef GPLUSPLUS_BACKWARD_INCLUDE_DIR + /* Pick up GNU C++ backward and deprecated include files. */ + { GPLUSPLUS_BACKWARD_INCLUDE_DIR, "G++", 1, 1, 0, 0 }, +#endif +#ifdef LOCAL_INCLUDE_DIR + /* /usr/local/include comes before the fixincluded header files. */ + { LOCAL_INCLUDE_DIR, 0, 0, 1, 1, 0 }, +#endif +#ifdef PREFIX_INCLUDE_DIR + { PREFIX_INCLUDE_DIR, 0, 0, 1, 0, 0 }, +#endif +#ifdef GCC_INCLUDE_DIR + /* This is the dir for gcc's private headers. */ + { GCC_INCLUDE_DIR, "GCC", 0, 0, 0, 0 }, +#endif +#ifdef FIXED_INCLUDE_DIR + /* This is the dir for fixincludes. */ + { FIXED_INCLUDE_DIR, "GCC", 0, 0, 0, + /* A multilib suffix needs adding if different multilibs use + different headers. */ +#ifdef SYSROOT_HEADERS_SUFFIX_SPEC + 1 +#else + 0 +#endif + }, +#endif +#ifdef CROSS_INCLUDE_DIR + /* One place the target system's headers might be. */ + { CROSS_INCLUDE_DIR, "GCC", 0, 0, 0, 0 }, +#endif +#ifdef TOOL_INCLUDE_DIR + /* Another place the target system's headers might be. */ + { TOOL_INCLUDE_DIR, "BINUTILS", 0, 1, 0, 0 }, +#endif +#ifdef SYSTEM_INCLUDE_DIR + /* Some systems have an extra dir of include files. */ + { SYSTEM_INCLUDE_DIR, 0, 0, 0, 1, 0 }, +#endif +#ifdef STANDARD_INCLUDE_DIR + /* /usr/include comes dead last. */ + { STANDARD_INCLUDE_DIR, STANDARD_INCLUDE_COMPONENT, 0, 0, 1, 0 }, +#endif + { 0, 0, 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 + +#if 0 +/* The configured prefix. */ +const char cpp_PREFIX[] = PREFIX; +const size_t cpp_PREFIX_len = sizeof PREFIX - 1; +const char cpp_EXEC_PREFIX[] = STANDARD_EXEC_PREFIX; + +/* This value is set by cpp_relocated at runtime */ +const char *gcc_exec_prefix; + +/* Return true if the toolchain is relocated. */ +bool +cpp_relocated (void) +{ + static int relocated = -1; + + /* A relocated toolchain ignores standard include directories. */ + if (relocated == -1) + { + /* Check if the toolchain was relocated? */ + GET_ENVIRONMENT (gcc_exec_prefix, "GCC_EXEC_PREFIX"); + if (gcc_exec_prefix) + relocated = 1; + else + relocated = 0; + } + + return relocated; +} +#endif diff --git a/support/cpp/cppdefault.h b/support/cpp/cppdefault.h new file mode 100644 index 0000000..854d485 --- /dev/null +++ b/support/cpp/cppdefault.h @@ -0,0 +1,70 @@ +/* CPP Library. + Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + 1999, 2000, 2003, 2004, 2006, 2007 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 3, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#ifndef GCC_CPPDEFAULT_H +#define GCC_CPPDEFAULT_H + +/* 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 *const fname; /* The name of the directory. */ + const char *const component; /* The component containing the directory + (see update_path in prefix.c) */ + const char cplusplus; /* Only look here if we're compiling C++. */ + const char cxx_aware; /* Includes in this directory don't need to + be wrapped in extern "C" when compiling + C++. */ + const char add_sysroot; /* FNAME should be prefixed by + cpp_SYSROOT. */ + const char multilib; /* FNAME should have the multilib path + specified with -imultilib + appended. */ +}; + +extern const struct default_include cpp_include_defaults[]; +extern const char cpp_GCC_INCLUDE_DIR[]; +extern const size_t cpp_GCC_INCLUDE_DIR_len; + +/* The configure-time prefix, i.e., the value supplied as the argument + to --prefix=. */ +extern const char cpp_PREFIX[]; +/* The length of the configure-time prefix. */ +extern const size_t cpp_PREFIX_len; +/* The configure-time execution prefix. This is typically the lib/gcc + subdirectory of cpp_PREFIX. */ +extern const char cpp_EXEC_PREFIX[]; +/* The run-time execution prefix. This is typically the lib/gcc + subdirectory of the actual installation. */ +extern const char *gcc_exec_prefix; + +/* Return true if the toolchain is relocated. */ +bool cpp_relocated (void); + +#endif /* ! GCC_CPPDEFAULT_H */ diff --git a/support/cpp/except.h b/support/cpp/except.h new file mode 100644 index 0000000..c893d88 --- /dev/null +++ b/support/cpp/except.h @@ -0,0 +1,176 @@ +/* Exception Handling interface routines. + Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, + 2007, 2008 Free Software Foundation, Inc. + Contributed by Mike Stump <mrs@cygnus.com>. + +This file is part of GCC. + +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 3, 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 COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + + +struct function; + +/* Per-function EH data. Used only in except.c, but GC and others + manipulate pointers to the opaque type. */ +struct eh_status; + +/* Internal structure describing a region. */ +struct eh_region; + +/* Test: is exception handling turned on? */ +extern int doing_eh (int); + +/* Note that the current EH region (if any) may contain a throw, or a + call to a function which itself may contain a throw. */ +extern void note_eh_region_may_contain_throw (struct eh_region *); + +/* Invokes CALLBACK for every exception handler label. Only used by old + loop hackery; should not be used by new code. */ +extern void for_each_eh_label (void (*) (rtx)); + +/* Invokes CALLBACK for every exception region in the current function. */ +extern void for_each_eh_region (void (*) (struct eh_region *)); + +/* Determine if the given INSN can throw an exception. */ +extern bool can_throw_internal_1 (int, bool); +extern bool can_throw_internal (const_rtx); +extern bool can_throw_external_1 (int, bool); +extern bool can_throw_external (const_rtx); + +/* Set TREE_NOTHROW and cfun->all_throwers_are_sibcalls. */ +extern unsigned int set_nothrow_function_flags (void); + +/* After initial rtl generation, call back to finish generating + exception support code. */ +extern void finish_eh_generation (void); + +extern void init_eh (void); +extern void init_eh_for_function (void); + +extern rtx reachable_handlers (rtx); +extern void maybe_remove_eh_handler (rtx); + +extern void convert_from_eh_region_ranges (void); +extern unsigned int convert_to_eh_region_ranges (void); +extern void find_exception_handler_labels (void); +extern bool current_function_has_exception_handlers (void); +extern void output_function_exception_table (const char *); + +extern void expand_builtin_unwind_init (void); +extern rtx expand_builtin_eh_return_data_regno (tree); +extern rtx expand_builtin_extract_return_addr (tree); +extern void expand_builtin_init_dwarf_reg_sizes (tree); +extern rtx expand_builtin_frob_return_addr (tree); +extern rtx expand_builtin_dwarf_sp_column (void); +extern void expand_builtin_eh_return (tree, tree); +extern void expand_eh_return (void); +extern rtx expand_builtin_extend_pointer (tree); +extern rtx get_exception_pointer (void); +extern rtx get_exception_filter (void); +typedef tree (*duplicate_eh_regions_map) (tree, void *); +extern int duplicate_eh_regions (struct function *, duplicate_eh_regions_map, + void *, int, int); + +extern void sjlj_emit_function_exit_after (rtx); +extern void default_init_unwind_resume_libfunc (void); + +extern struct eh_region *gen_eh_region_cleanup (struct eh_region *, + struct eh_region *); +extern struct eh_region *gen_eh_region_try (struct eh_region *); +extern struct eh_region *gen_eh_region_catch (struct eh_region *, tree); +extern struct eh_region *gen_eh_region_allowed (struct eh_region *, tree); +extern struct eh_region *gen_eh_region_must_not_throw (struct eh_region *); +extern int get_eh_region_number (struct eh_region *); +extern bool get_eh_region_may_contain_throw (struct eh_region *); +extern tree get_eh_region_tree_label (struct eh_region *); +extern void set_eh_region_tree_label (struct eh_region *, tree); + +extern void foreach_reachable_handler (int, bool, + void (*) (struct eh_region *, void *), + void *); + +extern void collect_eh_region_array (void); +extern void expand_resx_expr (tree); +extern void verify_eh_tree (struct function *); +extern void dump_eh_tree (FILE *, struct function *); +extern bool eh_region_outer_p (struct function *, int, int); +extern int eh_region_outermost (struct function *, int, int); + +/* If non-NULL, this is a function that returns an expression to be + executed if an unhandled exception is propagated out of a cleanup + region. For example, in C++, an exception thrown by a destructor + during stack unwinding is required to result in a call to + `std::terminate', so the C++ version of this function returns a + CALL_EXPR for `std::terminate'. */ +extern gimple (*lang_protect_cleanup_actions) (void); + +/* Return true if type A catches type B. */ +extern int (*lang_eh_type_covers) (tree a, tree b); + +/* Map a type to a runtime object to match type. */ +extern tree (*lang_eh_runtime_type) (tree); + + +/* Just because the user configured --with-sjlj-exceptions=no doesn't + mean that we can use call frame exceptions. Detect that the target + has appropriate support. */ + +#ifndef MUST_USE_SJLJ_EXCEPTIONS +# if defined (EH_RETURN_DATA_REGNO) \ + && (defined (TARGET_UNWIND_INFO) \ + || (DWARF2_UNWIND_INFO \ + && (defined (EH_RETURN_HANDLER_RTX) \ + || defined (HAVE_eh_return)))) +# define MUST_USE_SJLJ_EXCEPTIONS 0 +# else +# define MUST_USE_SJLJ_EXCEPTIONS 1 +# endif +#endif + +#ifdef CONFIG_SJLJ_EXCEPTIONS +# if CONFIG_SJLJ_EXCEPTIONS == 1 +# define USING_SJLJ_EXCEPTIONS 1 +# endif +# if CONFIG_SJLJ_EXCEPTIONS == 0 +# define USING_SJLJ_EXCEPTIONS 0 +# if !defined(EH_RETURN_DATA_REGNO) + #error "EH_RETURN_DATA_REGNO required" +# endif +# if ! (defined(TARGET_UNWIND_INFO) || DWARF2_UNWIND_INFO) + #error "{DWARF2,TARGET}_UNWIND_INFO required" +# endif +# if !defined(TARGET_UNWIND_INFO) \ + && !(defined(EH_RETURN_HANDLER_RTX) || defined(HAVE_eh_return)) + #error "EH_RETURN_HANDLER_RTX or eh_return required" +# endif +/* Usually the above error checks will have already triggered an + error, but backends may set MUST_USE_SJLJ_EXCEPTIONS for their own + reasons. */ +# if MUST_USE_SJLJ_EXCEPTIONS + #error "Must use SJLJ exceptions but configured not to" +# endif +# endif +#else +# define USING_SJLJ_EXCEPTIONS MUST_USE_SJLJ_EXCEPTIONS +#endif + +struct throw_stmt_node GTY(()) +{ + gimple stmt; + int region_nr; +}; + +extern struct htab *get_eh_throw_stmt_table (struct function *); +extern void set_eh_throw_stmt_table (struct function *, struct htab *); diff --git a/support/cpp/hwint.h b/support/cpp/hwint.h new file mode 100644 index 0000000..4f6d02d --- /dev/null +++ b/support/cpp/hwint.h @@ -0,0 +1,150 @@ +/* HOST_WIDE_INT definitions for the GNU compiler. + Copyright (C) 1998, 2002, 2004, 2008 Free Software Foundation, Inc. + + This file is part of GCC. + + 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) + +/* The string that should be inserted into a printf style format to + indicate a "long long" operand. */ +#ifndef HOST_LONG_LONG_FORMAT +#define HOST_LONG_LONG_FORMAT "ll" +#endif + +/* If HAVE_LONG_LONG and SIZEOF_LONG_LONG aren't defined, but + GCC_VERSION >= 3000, assume this is the second or later stage of a + bootstrap, we do have long long, and it's 64 bits. (This is + required by C99; we do have some ports that violate that assumption + but they're all cross-compile-only.) Just in case, force a + constraint violation if that assumption is incorrect. */ +#if !defined HAVE_LONG_LONG +# if GCC_VERSION >= 3000 +# define HAVE_LONG_LONG 1 +# define SIZEOF_LONG_LONG 8 +extern char sizeof_long_long_must_be_8[sizeof(long long) == 8 ? 1 : -1]; +# endif +#endif + +#ifdef HAVE_LONG_LONG +# define HOST_BITS_PER_LONGLONG (CHAR_BIT * SIZEOF_LONG_LONG) +#endif +#ifdef HAVE___INT64 +# define HOST_BITS_PER___INT64 (CHAR_BIT * SIZEOF___INT64) +#endif + +/* Set HOST_WIDE_INT. This should be the widest efficient host + integer type. It can be 32 or 64 bits, except that if we are + targeting a machine with 64-bit size_t then it has to be 64 bits. + + With a sane ABI, 'long' is the largest efficient host integer type. + Thus, we use that unless we have to use 'long long' or '__int64' + because we're targeting a 64-bit machine from a 32-bit host. */ + +#if HOST_BITS_PER_LONG >= 64 || !defined NEED_64BIT_HOST_WIDE_INT +# define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONG +# define HOST_WIDE_INT long +#else +# if HOST_BITS_PER_LONGLONG >= 64 +# define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONGLONG +# define HOST_WIDE_INT long long +# else +# if HOST_BITS_PER___INT64 >= 64 +# define HOST_BITS_PER_WIDE_INT HOST_BITS_PER___INT64 +# define HOST_WIDE_INT __int64 +# else + #error "Unable to find a suitable type for HOST_WIDE_INT" +# endif +# endif +#endif + +/* Various printf format strings for HOST_WIDE_INT. */ + +#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG +# define HOST_WIDE_INT_PRINT "l" +# define HOST_WIDE_INT_PRINT_C "L" + /* 'long' might be 32 or 64 bits, and the number of leading zeroes + must be tweaked accordingly. */ +# if HOST_BITS_PER_WIDE_INT == 64 +# define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%lx%016lx" +# else +# define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%lx%08lx" +# endif +#else +# define HOST_WIDE_INT_PRINT HOST_LONG_LONG_FORMAT +# define HOST_WIDE_INT_PRINT_C "LL" + /* We can assume that 'long long' is at least 64 bits. */ +# define HOST_WIDE_INT_PRINT_DOUBLE_HEX \ + "0x%" HOST_LONG_LONG_FORMAT "x%016" HOST_LONG_LONG_FORMAT "x" +#endif /* HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG */ + +#define HOST_WIDE_INT_PRINT_DEC "%" HOST_WIDE_INT_PRINT "d" +#define HOST_WIDE_INT_PRINT_DEC_C HOST_WIDE_INT_PRINT_DEC HOST_WIDE_INT_PRINT_C +#define HOST_WIDE_INT_PRINT_UNSIGNED "%" HOST_WIDE_INT_PRINT "u" +#define HOST_WIDE_INT_PRINT_HEX "0x%" HOST_WIDE_INT_PRINT "x" + +/* Set HOST_WIDEST_INT. This is a 64-bit type unless the compiler + in use has no 64-bit type at all; in that case it's 32 bits. */ + +#if HOST_BITS_PER_WIDE_INT >= 64 \ + || (HOST_BITS_PER_LONGLONG < 64 && HOST_BITS_PER___INT64 < 64) +# define HOST_WIDEST_INT HOST_WIDE_INT +# define HOST_BITS_PER_WIDEST_INT HOST_BITS_PER_WIDE_INT +# define HOST_WIDEST_INT_PRINT_DEC HOST_WIDE_INT_PRINT_DEC +# define HOST_WIDEST_INT_PRINT_DEC_C HOST_WIDE_INT_PRINT_DEC_C +# define HOST_WIDEST_INT_PRINT_UNSIGNED HOST_WIDE_INT_PRINT_UNSIGNED +# define HOST_WIDEST_INT_PRINT_HEX HOST_WIDE_INT_PRINT_HEX +# define HOST_WIDEST_INT_PRINT_DOUBLE_HEX HOST_WIDE_INT_PRINT_DOUBLE_HEX +#else +# if HOST_BITS_PER_LONGLONG >= 64 +# define HOST_BITS_PER_WIDEST_INT HOST_BITS_PER_LONGLONG +# define HOST_WIDEST_INT long long +# else +# if HOST_BITS_PER___INT64 >= 64 +# define HOST_BITS_PER_WIDEST_INT HOST_BITS_PER___INT64 +# define HOST_WIDEST_INT __int64 +# else + #error "This line should be impossible to reach" +# endif +# endif +# define HOST_WIDEST_INT_PRINT_DEC "%" HOST_LONG_LONG_FORMAT "d" +# define HOST_WIDEST_INT_PRINT_DEC_C "%" HOST_LONG_LONG_FORMAT "dLL" +# define HOST_WIDEST_INT_PRINT_UNSIGNED "%" HOST_LONG_LONG_FORMAT "u" +# define HOST_WIDEST_INT_PRINT_HEX "0x%" HOST_LONG_LONG_FORMAT "x" +# define HOST_WIDEST_INT_PRINT_DOUBLE_HEX \ + "0x%" HOST_LONG_LONG_FORMAT "x%016" HOST_LONG_LONG_FORMAT "x" +#endif + +/* Define HOST_WIDEST_FAST_INT to the widest integer type supported + efficiently in hardware. (That is, the widest integer type that fits + in a hardware register.) Normally this is "long" but on some hosts it + should be "long long" or "__int64". This is no convenient way to + autodetect this, so such systems must set a flag in config.host; see there + for details. */ + +#ifdef USE_LONG_LONG_FOR_WIDEST_FAST_INT +# ifdef HAVE_LONG_LONG +# define HOST_WIDEST_FAST_INT long long +# define HOST_BITS_PER_WIDEST_FAST_INT HOST_BITS_PER_LONGLONG +# elif defined (HAVE___INT64) +# define HOST_WIDEST_FAST_INT __int64 +# define HOST_BITS_PER_WIDEST_FAST_INT HOST_BITS_PER___INT64 +# else +# error "Your host said it wanted to use long long or __int64 but neither" +# error "exist" +# endif +#else +# define HOST_WIDEST_FAST_INT long +# define HOST_BITS_PER_WIDEST_FAST_INT HOST_BITS_PER_LONG +#endif + +#endif /* ! GCC_HWINT_H */ diff --git a/support/cpp/intl.h b/support/cpp/intl.h new file mode 100644 index 0000000..8c0684a --- /dev/null +++ b/support/cpp/intl.h @@ -0,0 +1,60 @@ +/* intl.h - internationalization + Copyright 1998, 2001, 2003, 2004, 2007 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 3, 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 COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#ifndef GCC_INTL_H +#define GCC_INTL_H + +#ifdef HAVE_LOCALE_H +# include <locale.h> +#endif + +#ifndef HAVE_SETLOCALE +# define setlocale(category, locale) (locale) +#endif + +#ifdef ENABLE_NLS +#include <libintl.h> +extern void gcc_init_libintl (void); +extern size_t gcc_gettext_width (const char *); +#else +/* Stubs. */ +# undef textdomain +# define textdomain(domain) (domain) +# undef bindtextdomain +# define bindtextdomain(domain, directory) (domain) +# undef gettext +# define gettext(msgid) (msgid) +# define gcc_init_libintl() /* nothing */ +# define gcc_gettext_width(s) strlen(s) +#endif + +#ifndef _ +# define _(msgid) gettext (msgid) +#endif + +#ifndef N_ +# define N_(msgid) msgid +#endif + +#ifndef G_ +# define G_(gmsgid) gmsgid +#endif + +extern const char *open_quote; +extern const char *close_quote; + +#endif /* intl.h */ diff --git a/support/cpp/libcpp/charset.c b/support/cpp/libcpp/charset.c new file mode 100644 index 0000000..cba19a6 --- /dev/null +++ b/support/cpp/libcpp/charset.c @@ -0,0 +1,1797 @@ +/* CPP Library - charsets + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2008, 2009, + 2010 Free Software Foundation, Inc. + + Broken out of c-lex.c Apr 2003, adding valid C99 UCN ranges. + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "cpplib.h" +#include "internal.h" + +/* Character set handling for C-family languages. + + Terminological note: In what follows, "charset" or "character set" + will be taken to mean both an abstract set of characters and an + encoding for that set. + + The C99 standard discusses two character sets: source and execution. + The source character set is used for internal processing in translation + phases 1 through 4; the execution character set is used thereafter. + Both are required by 5.2.1.2p1 to be multibyte encodings, not wide + character encodings (see 3.7.2, 3.7.3 for the standardese meanings + of these terms). Furthermore, the "basic character set" (listed in + 5.2.1p3) is to be encoded in each with values one byte wide, and is + to appear in the initial shift state. + + It is not explicitly mentioned, but there is also a "wide execution + character set" used to encode wide character constants and wide + string literals; this is supposed to be the result of applying the + standard library function mbstowcs() to an equivalent narrow string + (6.4.5p5). However, the behavior of hexadecimal and octal + \-escapes is at odds with this; they are supposed to be translated + directly to wchar_t values (6.4.4.4p5,6). + + The source character set is not necessarily the character set used + to encode physical source files on disk; translation phase 1 converts + from whatever that encoding is to the source character set. + + The presence of universal character names in C99 (6.4.3 et seq.) + forces the source character set to be isomorphic to ISO 10646, + that is, Unicode. There is no such constraint on the execution + character set; note also that the conversion from source to + execution character set does not occur for identifiers (5.1.1.2p1#5). + + For convenience of implementation, the source character set's + encoding of the basic character set should be identical to the + execution character set OF THE HOST SYSTEM's encoding of the basic + character set, and it should not be a state-dependent encoding. + + cpplib uses UTF-8 or UTF-EBCDIC for the source character set, + depending on whether the host is based on ASCII or EBCDIC (see + respectively Unicode section 2.3/ISO10646 Amendment 2, and Unicode + Technical Report #16). With limited exceptions, it relies on the + system library's iconv() primitive to do charset conversion + (specified in SUSv2). */ + +#if !HAVE_ICONV +/* Make certain that the uses of iconv(), iconv_open(), iconv_close() + below, which are guarded only by if statements with compile-time + constant conditions, do not cause link errors. */ +#define iconv_open(x, y) (errno = EINVAL, (iconv_t)-1) +#define iconv(a,b,c,d,e) (errno = EINVAL, (size_t)-1) +#define iconv_close(x) (void)0 +#define ICONV_CONST +#endif + +#if HOST_CHARSET == HOST_CHARSET_ASCII +#define SOURCE_CHARSET "UTF-8" +#define LAST_POSSIBLY_BASIC_SOURCE_CHAR 0x7e +#elif HOST_CHARSET == HOST_CHARSET_EBCDIC +#define SOURCE_CHARSET "UTF-EBCDIC" +#define LAST_POSSIBLY_BASIC_SOURCE_CHAR 0xFF +#else +#error "Unrecognized basic host character set" +#endif + +#ifndef EILSEQ +#define EILSEQ EINVAL +#endif + +/* This structure is used for a resizable string buffer throughout. */ +/* Don't call it strbuf, as that conflicts with unistd.h on systems + such as DYNIX/ptx where unistd.h includes stropts.h. */ +struct _cpp_strbuf +{ + uchar *text; + size_t asize; + size_t len; +}; + +/* This is enough to hold any string that fits on a single 80-column + line, even if iconv quadruples its size (e.g. conversion from + ASCII to UTF-32) rounded up to a power of two. */ +#define OUTBUF_BLOCK_SIZE 256 + +/* Conversions between UTF-8 and UTF-16/32 are implemented by custom + logic. This is because a depressing number of systems lack iconv, + or have have iconv libraries that do not do these conversions, so + we need a fallback implementation for them. To ensure the fallback + doesn't break due to neglect, it is used on all systems. + + UTF-32 encoding is nice and simple: a four-byte binary number, + constrained to the range 00000000-7FFFFFFF to avoid questions of + signedness. We do have to cope with big- and little-endian + variants. + + UTF-16 encoding uses two-byte binary numbers, again in big- and + little-endian variants, for all values in the 00000000-0000FFFF + range. Values in the 00010000-0010FFFF range are encoded as pairs + of two-byte numbers, called "surrogate pairs": given a number S in + this range, it is mapped to a pair (H, L) as follows: + + H = (S - 0x10000) / 0x400 + 0xD800 + L = (S - 0x10000) % 0x400 + 0xDC00 + + Two-byte values in the D800...DFFF range are ill-formed except as a + component of a surrogate pair. Even if the encoding within a + two-byte value is little-endian, the H member of the surrogate pair + comes first. + + There is no way to encode values in the 00110000-7FFFFFFF range, + which is not currently a problem as there are no assigned code + points in that range; however, the author expects that it will + eventually become necessary to abandon UTF-16 due to this + limitation. Note also that, because of these pairs, UTF-16 does + not meet the requirements of the C standard for a wide character + encoding (see 3.7.3 and 6.4.4.4p11). + + UTF-8 encoding looks like this: + + value range encoded as + 00000000-0000007F 0xxxxxxx + 00000080-000007FF 110xxxxx 10xxxxxx + 00000800-0000FFFF 1110xxxx 10xxxxxx 10xxxxxx + 00010000-001FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + 00200000-03FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + 04000000-7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + + Values in the 0000D800 ... 0000DFFF range (surrogates) are invalid, + which means that three-byte sequences ED xx yy, with A0 <= xx <= BF, + never occur. Note also that any value that can be encoded by a + given row of the table can also be encoded by all successive rows, + but this is not done; only the shortest possible encoding for any + given value is valid. For instance, the character 07C0 could be + encoded as any of DF 80, E0 9F 80, F0 80 9F 80, F8 80 80 9F 80, or + FC 80 80 80 9F 80. Only the first is valid. + + An implementation note: the transformation from UTF-16 to UTF-8, or + vice versa, is easiest done by using UTF-32 as an intermediary. */ + +/* Internal primitives which go from an UTF-8 byte stream to native-endian + UTF-32 in a cppchar_t, or vice versa; this avoids an extra marshal/unmarshal + operation in several places below. */ +static inline int +one_utf8_to_cppchar (const uchar **inbufp, size_t *inbytesleftp, + cppchar_t *cp) +{ + static const uchar masks[6] = { 0x7F, 0x1F, 0x0F, 0x07, 0x03, 0x01 }; + static const uchar patns[6] = { 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + + cppchar_t c; + const uchar *inbuf = *inbufp; + size_t nbytes, i; + + if (*inbytesleftp < 1) + return EINVAL; + + c = *inbuf; + if (c < 0x80) + { + *cp = c; + *inbytesleftp -= 1; + *inbufp += 1; + return 0; + } + + /* The number of leading 1-bits in the first byte indicates how many + bytes follow. */ + for (nbytes = 2; nbytes < 7; nbytes++) + if ((c & ~masks[nbytes-1]) == patns[nbytes-1]) + goto found; + return EILSEQ; + found: + + if (*inbytesleftp < nbytes) + return EINVAL; + + c = (c & masks[nbytes-1]); + inbuf++; + for (i = 1; i < nbytes; i++) + { + cppchar_t n = *inbuf++; + if ((n & 0xC0) != 0x80) + return EILSEQ; + c = ((c << 6) + (n & 0x3F)); + } + + /* Make sure the shortest possible encoding was used. */ + if (c <= 0x7F && nbytes > 1) return EILSEQ; + if (c <= 0x7FF && nbytes > 2) return EILSEQ; + if (c <= 0xFFFF && nbytes > 3) return EILSEQ; + if (c <= 0x1FFFFF && nbytes > 4) return EILSEQ; + if (c <= 0x3FFFFFF && nbytes > 5) return EILSEQ; + + /* Make sure the character is valid. */ + if (c > 0x7FFFFFFF || (c >= 0xD800 && c <= 0xDFFF)) return EILSEQ; + + *cp = c; + *inbufp = inbuf; + *inbytesleftp -= nbytes; + return 0; +} + +static inline int +one_cppchar_to_utf8 (cppchar_t c, uchar **outbufp, size_t *outbytesleftp) +{ + static const uchar masks[6] = { 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + static const uchar limits[6] = { 0x80, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE }; + size_t nbytes; + uchar buf[6], *p = &buf[6]; + uchar *outbuf = *outbufp; + + nbytes = 1; + if (c < 0x80) + *--p = c; + else + { + do + { + *--p = ((c & 0x3F) | 0x80); + c >>= 6; + nbytes++; + } + while (c >= 0x3F || (c & limits[nbytes-1])); + *--p = (c | masks[nbytes-1]); + } + + if (*outbytesleftp < nbytes) + return E2BIG; + + while (p < &buf[6]) + *outbuf++ = *p++; + *outbytesleftp -= nbytes; + *outbufp = outbuf; + return 0; +} + +/* The following four functions transform one character between the two + encodings named in the function name. All have the signature + int (*)(iconv_t bigend, const uchar **inbufp, size_t *inbytesleftp, + uchar **outbufp, size_t *outbytesleftp) + + BIGEND must have the value 0 or 1, coerced to (iconv_t); it is + interpreted as a boolean indicating whether big-endian or + little-endian encoding is to be used for the member of the pair + that is not UTF-8. + + INBUFP, INBYTESLEFTP, OUTBUFP, OUTBYTESLEFTP work exactly as they + do for iconv. + + The return value is either 0 for success, or an errno value for + failure, which may be E2BIG (need more space), EILSEQ (ill-formed + input sequence), ir EINVAL (incomplete input sequence). */ + +static inline int +one_utf8_to_utf32 (iconv_t bigend, const uchar **inbufp, size_t *inbytesleftp, + uchar **outbufp, size_t *outbytesleftp) +{ + uchar *outbuf; + cppchar_t s = 0; + int rval; + + /* Check for space first, since we know exactly how much we need. */ + if (*outbytesleftp < 4) + return E2BIG; + + rval = one_utf8_to_cppchar (inbufp, inbytesleftp, &s); + if (rval) + return rval; + + outbuf = *outbufp; + outbuf[bigend ? 3 : 0] = (s & 0x000000FF); + outbuf[bigend ? 2 : 1] = (s & 0x0000FF00) >> 8; + outbuf[bigend ? 1 : 2] = (s & 0x00FF0000) >> 16; + outbuf[bigend ? 0 : 3] = (s & 0xFF000000) >> 24; + + *outbufp += 4; + *outbytesleftp -= 4; + return 0; +} + +static inline int +one_utf32_to_utf8 (iconv_t bigend, const uchar **inbufp, size_t *inbytesleftp, + uchar **outbufp, size_t *outbytesleftp) +{ + cppchar_t s; + int rval; + const uchar *inbuf; + + if (*inbytesleftp < 4) + return EINVAL; + + inbuf = *inbufp; + + s = inbuf[bigend ? 0 : 3] << 24; + s += inbuf[bigend ? 1 : 2] << 16; + s += inbuf[bigend ? 2 : 1] << 8; + s += inbuf[bigend ? 3 : 0]; + + if (s >= 0x7FFFFFFF || (s >= 0xD800 && s <= 0xDFFF)) + return EILSEQ; + + rval = one_cppchar_to_utf8 (s, outbufp, outbytesleftp); + if (rval) + return rval; + + *inbufp += 4; + *inbytesleftp -= 4; + return 0; +} + +static inline int +one_utf8_to_utf16 (iconv_t bigend, const uchar **inbufp, size_t *inbytesleftp, + uchar **outbufp, size_t *outbytesleftp) +{ + int rval; + cppchar_t s = 0; + const uchar *save_inbuf = *inbufp; + size_t save_inbytesleft = *inbytesleftp; + uchar *outbuf = *outbufp; + + rval = one_utf8_to_cppchar (inbufp, inbytesleftp, &s); + if (rval) + return rval; + + if (s > 0x0010FFFF) + { + *inbufp = save_inbuf; + *inbytesleftp = save_inbytesleft; + return EILSEQ; + } + + if (s < 0xFFFF) + { + if (*outbytesleftp < 2) + { + *inbufp = save_inbuf; + *inbytesleftp = save_inbytesleft; + return E2BIG; + } + outbuf[bigend ? 1 : 0] = (s & 0x00FF); + outbuf[bigend ? 0 : 1] = (s & 0xFF00) >> 8; + + *outbufp += 2; + *outbytesleftp -= 2; + return 0; + } + else + { + cppchar_t hi, lo; + + if (*outbytesleftp < 4) + { + *inbufp = save_inbuf; + *inbytesleftp = save_inbytesleft; + return E2BIG; + } + + hi = (s - 0x10000) / 0x400 + 0xD800; + lo = (s - 0x10000) % 0x400 + 0xDC00; + + /* Even if we are little-endian, put the high surrogate first. + ??? Matches practice? */ + outbuf[bigend ? 1 : 0] = (hi & 0x00FF); + outbuf[bigend ? 0 : 1] = (hi & 0xFF00) >> 8; + outbuf[bigend ? 3 : 2] = (lo & 0x00FF); + outbuf[bigend ? 2 : 3] = (lo & 0xFF00) >> 8; + + *outbufp += 4; + *outbytesleftp -= 4; + return 0; + } +} + +static inline int +one_utf16_to_utf8 (iconv_t bigend, const uchar **inbufp, size_t *inbytesleftp, + uchar **outbufp, size_t *outbytesleftp) +{ + cppchar_t s; + const uchar *inbuf = *inbufp; + int rval; + + if (*inbytesleftp < 2) + return EINVAL; + s = inbuf[bigend ? 0 : 1] << 8; + s += inbuf[bigend ? 1 : 0]; + + /* Low surrogate without immediately preceding high surrogate is invalid. */ + if (s >= 0xDC00 && s <= 0xDFFF) + return EILSEQ; + /* High surrogate must have a following low surrogate. */ + else if (s >= 0xD800 && s <= 0xDBFF) + { + cppchar_t hi = s, lo; + if (*inbytesleftp < 4) + return EINVAL; + + lo = inbuf[bigend ? 2 : 3] << 8; + lo += inbuf[bigend ? 3 : 2]; + + if (lo < 0xDC00 || lo > 0xDFFF) + return EILSEQ; + + s = (hi - 0xD800) * 0x400 + (lo - 0xDC00) + 0x10000; + } + + rval = one_cppchar_to_utf8 (s, outbufp, outbytesleftp); + if (rval) + return rval; + + /* Success - update the input pointers (one_cppchar_to_utf8 has done + the output pointers for us). */ + if (s <= 0xFFFF) + { + *inbufp += 2; + *inbytesleftp -= 2; + } + else + { + *inbufp += 4; + *inbytesleftp -= 4; + } + return 0; +} + +/* Helper routine for the next few functions. The 'const' on + one_conversion means that we promise not to modify what function is + pointed to, which lets the inliner see through it. */ + +static inline bool +conversion_loop (int (*const one_conversion)(iconv_t, const uchar **, size_t *, + uchar **, size_t *), + iconv_t cd, const uchar *from, size_t flen, struct _cpp_strbuf *to) +{ + const uchar *inbuf; + uchar *outbuf; + size_t inbytesleft, outbytesleft; + int rval; + + inbuf = from; + inbytesleft = flen; + outbuf = to->text + to->len; + outbytesleft = to->asize - to->len; + + for (;;) + { + do + rval = one_conversion (cd, &inbuf, &inbytesleft, + &outbuf, &outbytesleft); + while (inbytesleft && !rval); + + if (__builtin_expect (inbytesleft == 0, 1)) + { + to->len = to->asize - outbytesleft; + return true; + } + if (rval != E2BIG) + { + errno = rval; + return false; + } + + outbytesleft += OUTBUF_BLOCK_SIZE; + to->asize += OUTBUF_BLOCK_SIZE; + to->text = XRESIZEVEC (uchar, to->text, to->asize); + outbuf = to->text + to->asize - outbytesleft; + } +} + + +/* These functions convert entire strings between character sets. + They all have the signature + + bool (*)(iconv_t cd, const uchar *from, size_t flen, struct _cpp_strbuf *to); + + The input string FROM is converted as specified by the function + name plus the iconv descriptor CD (which may be fake), and the + result appended to TO. On any error, false is returned, otherwise true. */ + +/* These four use the custom conversion code above. */ +static bool +convert_utf8_utf16 (iconv_t cd, const uchar *from, size_t flen, + struct _cpp_strbuf *to) +{ + return conversion_loop (one_utf8_to_utf16, cd, from, flen, to); +} + +static bool +convert_utf8_utf32 (iconv_t cd, const uchar *from, size_t flen, + struct _cpp_strbuf *to) +{ + return conversion_loop (one_utf8_to_utf32, cd, from, flen, to); +} + +static bool +convert_utf16_utf8 (iconv_t cd, const uchar *from, size_t flen, + struct _cpp_strbuf *to) +{ + return conversion_loop (one_utf16_to_utf8, cd, from, flen, to); +} + +static bool +convert_utf32_utf8 (iconv_t cd, const uchar *from, size_t flen, + struct _cpp_strbuf *to) +{ + return conversion_loop (one_utf32_to_utf8, cd, from, flen, to); +} + +/* Identity conversion, used when we have no alternative. */ +static bool +convert_no_conversion (iconv_t cd ATTRIBUTE_UNUSED, + const uchar *from, size_t flen, struct _cpp_strbuf *to) +{ + if (to->len + flen > to->asize) + { + to->asize = to->len + flen; + to->text = XRESIZEVEC (uchar, to->text, to->asize); + } + memcpy (to->text + to->len, from, flen); + to->len += flen; + return true; +} + +/* And this one uses the system iconv primitive. It's a little + different, since iconv's interface is a little different. */ +#if HAVE_ICONV + +#define CONVERT_ICONV_GROW_BUFFER \ + do { \ + outbytesleft += OUTBUF_BLOCK_SIZE; \ + to->asize += OUTBUF_BLOCK_SIZE; \ + to->text = XRESIZEVEC (uchar, to->text, to->asize); \ + outbuf = (char *)to->text + to->asize - outbytesleft; \ + } while (0) + +static bool +convert_using_iconv (iconv_t cd, const uchar *from, size_t flen, + struct _cpp_strbuf *to) +{ + ICONV_CONST char *inbuf; + char *outbuf; + size_t inbytesleft, outbytesleft; + + /* Reset conversion descriptor and check that it is valid. */ + if (iconv (cd, 0, 0, 0, 0) == (size_t)-1) + return false; + + inbuf = (ICONV_CONST char *)from; + inbytesleft = flen; + outbuf = (char *)to->text + to->len; + outbytesleft = to->asize - to->len; + + for (;;) + { + iconv (cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); + if (__builtin_expect (inbytesleft == 0, 1)) + { + /* Close out any shift states, returning to the initial state. */ + if (iconv (cd, 0, 0, &outbuf, &outbytesleft) == (size_t)-1) + { + if (errno != E2BIG) + return false; + + CONVERT_ICONV_GROW_BUFFER; + if (iconv (cd, 0, 0, &outbuf, &outbytesleft) == (size_t)-1) + return false; + } + + to->len = to->asize - outbytesleft; + return true; + } + if (errno != E2BIG) + return false; + + CONVERT_ICONV_GROW_BUFFER; + } +} +#else +#define convert_using_iconv 0 /* prevent undefined symbol error below */ +#endif + +/* Arrange for the above custom conversion logic to be used automatically + when conversion between a suitable pair of character sets is requested. */ + +#define APPLY_CONVERSION(CONVERTER, FROM, FLEN, TO) \ + CONVERTER.func (CONVERTER.cd, FROM, FLEN, TO) + +struct conversion +{ + const char *pair; + convert_f func; + iconv_t fake_cd; +}; +static const struct conversion conversion_tab[] = { + { "UTF-8/UTF-32LE", convert_utf8_utf32, (iconv_t)0 }, + { "UTF-8/UTF-32BE", convert_utf8_utf32, (iconv_t)1 }, + { "UTF-8/UTF-16LE", convert_utf8_utf16, (iconv_t)0 }, + { "UTF-8/UTF-16BE", convert_utf8_utf16, (iconv_t)1 }, + { "UTF-32LE/UTF-8", convert_utf32_utf8, (iconv_t)0 }, + { "UTF-32BE/UTF-8", convert_utf32_utf8, (iconv_t)1 }, + { "UTF-16LE/UTF-8", convert_utf16_utf8, (iconv_t)0 }, + { "UTF-16BE/UTF-8", convert_utf16_utf8, (iconv_t)1 }, +}; + +/* Subroutine of cpp_init_iconv: initialize and return a + cset_converter structure for conversion from FROM to TO. If + iconv_open() fails, issue an error and return an identity + converter. Silently return an identity converter if FROM and TO + are identical. */ +static struct cset_converter +init_iconv_desc (cpp_reader *pfile, const char *to, const char *from) +{ + struct cset_converter ret; + char *pair; + size_t i; + + if (!strcasecmp (to, from)) + { + ret.func = convert_no_conversion; + ret.cd = (iconv_t) -1; + ret.width = -1; + return ret; + } + + pair = (char *) alloca(strlen(to) + strlen(from) + 2); + + strcpy(pair, from); + strcat(pair, "/"); + strcat(pair, to); + for (i = 0; i < ARRAY_SIZE (conversion_tab); i++) + if (!strcasecmp (pair, conversion_tab[i].pair)) + { + ret.func = conversion_tab[i].func; + ret.cd = conversion_tab[i].fake_cd; + ret.width = -1; + return ret; + } + + /* No custom converter - try iconv. */ + if (HAVE_ICONV) + { + ret.func = convert_using_iconv; + ret.cd = iconv_open (to, from); + ret.width = -1; + + if (ret.cd == (iconv_t) -1) + { + if (errno == EINVAL) + cpp_error (pfile, CPP_DL_ERROR, /* FIXME should be DL_SORRY */ + "conversion from %s to %s not supported by iconv", + from, to); + else + cpp_errno (pfile, CPP_DL_ERROR, "iconv_open"); + + ret.func = convert_no_conversion; + } + } + else + { + cpp_error (pfile, CPP_DL_ERROR, /* FIXME: should be DL_SORRY */ + "no iconv implementation, cannot convert from %s to %s", + from, to); + ret.func = convert_no_conversion; + ret.cd = (iconv_t) -1; + ret.width = -1; + } + return ret; +} + +/* If charset conversion is requested, initialize iconv(3) descriptors + for conversion from the source character set to the execution + character sets. If iconv is not present in the C library, and + conversion is requested, issue an error. */ + +void +cpp_init_iconv (cpp_reader *pfile) +{ + const char *ncset = CPP_OPTION (pfile, narrow_charset); + const char *wcset = CPP_OPTION (pfile, wide_charset); + const char *default_wcset; + + bool be = CPP_OPTION (pfile, bytes_big_endian); + + if (CPP_OPTION (pfile, wchar_precision) >= 32) + default_wcset = be ? "UTF-32BE" : "UTF-32LE"; + else if (CPP_OPTION (pfile, wchar_precision) >= 16) + default_wcset = be ? "UTF-16BE" : "UTF-16LE"; + else + /* This effectively means that wide strings are not supported, + so don't do any conversion at all. */ + default_wcset = SOURCE_CHARSET; + + if (!ncset) + ncset = SOURCE_CHARSET; + if (!wcset) + wcset = default_wcset; + + pfile->narrow_cset_desc = init_iconv_desc (pfile, ncset, SOURCE_CHARSET); + pfile->narrow_cset_desc.width = CPP_OPTION (pfile, char_precision); + pfile->utf8_cset_desc = init_iconv_desc (pfile, "UTF-8", SOURCE_CHARSET); + pfile->utf8_cset_desc.width = CPP_OPTION (pfile, char_precision); + pfile->char16_cset_desc = init_iconv_desc (pfile, + be ? "UTF-16BE" : "UTF-16LE", + SOURCE_CHARSET); + pfile->char16_cset_desc.width = 16; + pfile->char32_cset_desc = init_iconv_desc (pfile, + be ? "UTF-32BE" : "UTF-32LE", + SOURCE_CHARSET); + pfile->char32_cset_desc.width = 32; + pfile->wide_cset_desc = init_iconv_desc (pfile, wcset, SOURCE_CHARSET); + pfile->wide_cset_desc.width = CPP_OPTION (pfile, wchar_precision); +} + +/* Destroy iconv(3) descriptors set up by cpp_init_iconv, if necessary. */ +void +_cpp_destroy_iconv (cpp_reader *pfile) +{ + if (HAVE_ICONV) + { + if (pfile->narrow_cset_desc.func == convert_using_iconv) + iconv_close (pfile->narrow_cset_desc.cd); + if (pfile->utf8_cset_desc.func == convert_using_iconv) + iconv_close (pfile->utf8_cset_desc.cd); + if (pfile->char16_cset_desc.func == convert_using_iconv) + iconv_close (pfile->char16_cset_desc.cd); + if (pfile->char32_cset_desc.func == convert_using_iconv) + iconv_close (pfile->char32_cset_desc.cd); + if (pfile->wide_cset_desc.func == convert_using_iconv) + iconv_close (pfile->wide_cset_desc.cd); + } +} + +/* Utility routine for use by a full compiler. C is a character taken + from the *basic* source character set, encoded in the host's + execution encoding. Convert it to (the target's) execution + encoding, and return that value. + + Issues an internal error if C's representation in the narrow + execution character set fails to be a single-byte value (C99 + 5.2.1p3: "The representation of each member of the source and + execution character sets shall fit in a byte.") May also issue an + internal error if C fails to be a member of the basic source + character set (testing this exactly is too hard, especially when + the host character set is EBCDIC). */ +cppchar_t +cpp_host_to_exec_charset (cpp_reader *pfile, cppchar_t c) +{ + uchar sbuf[1]; + struct _cpp_strbuf tbuf; + + /* This test is merely an approximation, but it suffices to catch + the most important thing, which is that we don't get handed a + character outside the unibyte range of the host character set. */ + if (c > LAST_POSSIBLY_BASIC_SOURCE_CHAR) + { + cpp_error (pfile, CPP_DL_ICE, + "character 0x%lx is not in the basic source character set\n", + (unsigned long)c); + return 0; + } + + /* Being a character in the unibyte range of the host character set, + we can safely splat it into a one-byte buffer and trust that that + is a well-formed string. */ + sbuf[0] = c; + + /* This should never need to reallocate, but just in case... */ + tbuf.asize = 1; + tbuf.text = XNEWVEC (uchar, tbuf.asize); + tbuf.len = 0; + + if (!APPLY_CONVERSION (pfile->narrow_cset_desc, sbuf, 1, &tbuf)) + { + cpp_errno (pfile, CPP_DL_ICE, "converting to execution character set"); + return 0; + } + if (tbuf.len != 1) + { + cpp_error (pfile, CPP_DL_ICE, + "character 0x%lx is not unibyte in execution character set", + (unsigned long)c); + return 0; + } + c = tbuf.text[0]; + free(tbuf.text); + return c; +} + + + +/* Utility routine that computes a mask of the form 0000...111... with + WIDTH 1-bits. */ +static inline size_t +width_to_mask (size_t width) +{ + width = MIN (width, BITS_PER_CPPCHAR_T); + if (width >= CHAR_BIT * sizeof (size_t)) + return ~(size_t) 0; + else + return ((size_t) 1 << width) - 1; +} + +/* A large table of unicode character information. */ +enum { + /* Valid in a C99 identifier? */ + C99 = 1, + /* Valid in a C99 identifier, but not as the first character? */ + DIG = 2, + /* Valid in a C++ identifier? */ + CXX = 4, + /* NFC representation is not valid in an identifier? */ + CID = 8, + /* Might be valid NFC form? */ + NFC = 16, + /* Might be valid NFKC form? */ + NKC = 32, + /* Certain preceding characters might make it not valid NFC/NKFC form? */ + CTX = 64 +}; + +static const struct { + /* Bitmap of flags above. */ + unsigned char flags; + /* Combining class of the character. */ + unsigned char combine; + /* Last character in the range described by this entry. */ + unsigned short end; +} ucnranges[] = { +#include "ucnid.h" +}; + +/* Returns 1 if C is valid in an identifier, 2 if C is valid except at + the start of an identifier, and 0 if C is not valid in an + identifier. We assume C has already gone through the checks of + _cpp_valid_ucn. Also update NST for C if returning nonzero. The + algorithm is a simple binary search on the table defined in + ucnid.h. */ + +static int +ucn_valid_in_identifier (cpp_reader *pfile, cppchar_t c, + struct normalize_state *nst) +{ + int mn, mx, md; + + if (c > 0xFFFF) + return 0; + + mn = 0; + mx = ARRAY_SIZE (ucnranges) - 1; + while (mx != mn) + { + md = (mn + mx) / 2; + if (c <= ucnranges[md].end) + mx = md; + else + mn = md + 1; + } + + /* When -pedantic, we require the character to have been listed by + the standard for the current language. Otherwise, we accept the + union of the acceptable sets for C++98 and C99. */ + if (! (ucnranges[mn].flags & (C99 | CXX))) + return 0; + + if (CPP_PEDANTIC (pfile) + && ((CPP_OPTION (pfile, c99) && !(ucnranges[mn].flags & C99)) + || (CPP_OPTION (pfile, cplusplus) + && !(ucnranges[mn].flags & CXX)))) + return 0; + + /* Update NST. */ + if (ucnranges[mn].combine != 0 && ucnranges[mn].combine < nst->prev_class) + nst->level = normalized_none; + else if (ucnranges[mn].flags & CTX) + { + bool safe; + cppchar_t p = nst->previous; + + /* Easy cases from Bengali, Oriya, Tamil, Jannada, and Malayalam. */ + if (c == 0x09BE) + safe = p != 0x09C7; /* Use 09CB instead of 09C7 09BE. */ + else if (c == 0x0B3E) + safe = p != 0x0B47; /* Use 0B4B instead of 0B47 0B3E. */ + else if (c == 0x0BBE) + safe = p != 0x0BC6 && p != 0x0BC7; /* Use 0BCA/0BCB instead. */ + else if (c == 0x0CC2) + safe = p != 0x0CC6; /* Use 0CCA instead of 0CC6 0CC2. */ + else if (c == 0x0D3E) + safe = p != 0x0D46 && p != 0x0D47; /* Use 0D4A/0D4B instead. */ + /* For Hangul, characters in the range AC00-D7A3 are NFC/NFKC, + and are combined algorithmically from a sequence of the form + 1100-1112 1161-1175 11A8-11C2 + (if the third is not present, it is treated as 11A7, which is not + really a valid character). + Unfortunately, C99 allows (only) the NFC form, but C++ allows + only the combining characters. */ + else if (c >= 0x1161 && c <= 0x1175) + safe = p < 0x1100 || p > 0x1112; + else if (c >= 0x11A8 && c <= 0x11C2) + safe = (p < 0xAC00 || p > 0xD7A3 || (p - 0xAC00) % 28 != 0); + else + { + /* Uh-oh, someone updated ucnid.h without updating this code. */ + cpp_error (pfile, CPP_DL_ICE, "Character %x might not be NFKC", c); + safe = true; + } + if (!safe && c < 0x1161) + nst->level = normalized_none; + else if (!safe) + nst->level = MAX (nst->level, normalized_identifier_C); + } + else if (ucnranges[mn].flags & NKC) + ; + else if (ucnranges[mn].flags & NFC) + nst->level = MAX (nst->level, normalized_C); + else if (ucnranges[mn].flags & CID) + nst->level = MAX (nst->level, normalized_identifier_C); + else + nst->level = normalized_none; + nst->previous = c; + nst->prev_class = ucnranges[mn].combine; + + /* In C99, UCN digits may not begin identifiers. */ + if (CPP_OPTION (pfile, c99) && (ucnranges[mn].flags & DIG)) + return 2; + + return 1; +} + +/* [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 corresponds to a surrogate code point + (in the range 0xD800-0xDFFF, inclusive), the program is ill-formed. + Additionally, if the hexadecimal value for a universal-character-name + outside a character or string literal corresponds to a control character + (in either of the ranges 0x00-0x1F or 0x7F-0x9F, both inclusive) or to a + character in the basic source character set, the program is ill-formed. + + C99 6.4.3: A universal character name shall not specify a character + whose short identifier is less than 00A0 other than 0024 ($), 0040 (@), + or 0060 (`), nor one in the range D800 through DFFF inclusive. + + *PSTR must be preceded by "\u" or "\U"; it is assumed that the + buffer end is delimited by a non-hex digit. Returns zero if the + UCN has not been consumed. + + Otherwise the nonzero value of the UCN, whether valid or invalid, + is returned. Diagnostics are emitted for invalid values. PSTR + is updated to point one beyond the UCN, or to the syntactically + invalid character. + + IDENTIFIER_POS is 0 when not in an identifier, 1 for the start of + an identifier, or 2 otherwise. */ + +cppchar_t +_cpp_valid_ucn (cpp_reader *pfile, const uchar **pstr, + const uchar *limit, int identifier_pos, + struct normalize_state *nst) +{ + cppchar_t result, c; + unsigned int length; + const uchar *str = *pstr; + const uchar *base = str - 2; + + if (!CPP_OPTION (pfile, cplusplus) && !CPP_OPTION (pfile, c99)) + cpp_error (pfile, CPP_DL_WARNING, + "universal character names are only valid in C++ and C99"); + else if (CPP_WTRADITIONAL (pfile) && identifier_pos == 0) + cpp_warning (pfile, CPP_W_TRADITIONAL, + "the meaning of '\\%c' is different in traditional C", + (int) str[-1]); + + if (str[-1] == 'u') + length = 4; + else if (str[-1] == 'U') + length = 8; + else + { + cpp_error (pfile, CPP_DL_ICE, "In _cpp_valid_ucn but not a UCN"); + length = 4; + } + + result = 0; + do + { + c = *str; + if (!ISXDIGIT (c)) + break; + str++; + result = (result << 4) + hex_value (c); + } + while (--length && str < limit); + + /* Partial UCNs are not valid in strings, but decompose into + multiple tokens in identifiers, so we can't give a helpful + error message in that case. */ + if (length && identifier_pos) + return 0; + + *pstr = str; + if (length) + { + cpp_error (pfile, CPP_DL_ERROR, + "incomplete universal character name %.*s", + (int) (str - base), base); + result = 1; + } + /* The C99 standard permits $, @ and ` to be specified as UCNs. We use + hex escapes so that this also works with EBCDIC hosts. + C++0x permits everything below 0xa0 within literals; + ucn_valid_in_identifier will complain about identifiers. */ + else if ((result < 0xa0 + && !CPP_OPTION (pfile, cplusplus) + && (result != 0x24 && result != 0x40 && result != 0x60)) + || (result & 0x80000000) + || (result >= 0xD800 && result <= 0xDFFF)) + { + cpp_error (pfile, CPP_DL_ERROR, + "%.*s is not a valid universal character", + (int) (str - base), base); + result = 1; + } + else if (identifier_pos && result == 0x24 + && CPP_OPTION (pfile, dollars_in_ident)) + { + if (CPP_OPTION (pfile, warn_dollars) && !pfile->state.skipping) + { + CPP_OPTION (pfile, warn_dollars) = 0; + cpp_error (pfile, CPP_DL_PEDWARN, "'$' in identifier or number"); + } + NORMALIZE_STATE_UPDATE_IDNUM (nst); + } + else if (identifier_pos) + { + int validity = ucn_valid_in_identifier (pfile, result, nst); + + if (validity == 0) + cpp_error (pfile, CPP_DL_ERROR, + "universal character %.*s is not valid in an identifier", + (int) (str - base), base); + else if (validity == 2 && identifier_pos == 1) + cpp_error (pfile, CPP_DL_ERROR, + "universal character %.*s is not valid at the start of an identifier", + (int) (str - base), base); + } + + if (result == 0) + result = 1; + + return result; +} + +/* Convert an UCN, pointed to by FROM, to UTF-8 encoding, then translate + it to the execution character set and write the result into TBUF. + An advanced pointer is returned. Issues all relevant diagnostics. */ +static const uchar * +convert_ucn (cpp_reader *pfile, const uchar *from, const uchar *limit, + struct _cpp_strbuf *tbuf, struct cset_converter cvt) +{ + cppchar_t ucn; + uchar buf[6]; + uchar *bufp = buf; + size_t bytesleft = 6; + int rval; + struct normalize_state nst = INITIAL_NORMALIZE_STATE; + + from++; /* Skip u/U. */ + ucn = _cpp_valid_ucn (pfile, &from, limit, 0, &nst); + + rval = one_cppchar_to_utf8 (ucn, &bufp, &bytesleft); + if (rval) + { + errno = rval; + cpp_errno (pfile, CPP_DL_ERROR, + "converting UCN to source character set"); + } + else if (!APPLY_CONVERSION (cvt, buf, 6 - bytesleft, tbuf)) + cpp_errno (pfile, CPP_DL_ERROR, + "converting UCN to execution character set"); + + return from; +} + +/* Subroutine of convert_hex and convert_oct. N is the representation + in the execution character set of a numeric escape; write it into the + string buffer TBUF and update the end-of-string pointer therein. WIDE + is true if it's a wide string that's being assembled in TBUF. This + function issues no diagnostics and never fails. */ +static void +emit_numeric_escape (cpp_reader *pfile, cppchar_t n, + struct _cpp_strbuf *tbuf, struct cset_converter cvt) +{ + size_t width = cvt.width; + + if (width != CPP_OPTION (pfile, char_precision)) + { + /* We have to render this into the target byte order, which may not + be our byte order. */ + bool bigend = CPP_OPTION (pfile, bytes_big_endian); + size_t cwidth = CPP_OPTION (pfile, char_precision); + size_t cmask = width_to_mask (cwidth); + size_t nbwc = width / cwidth; + size_t i; + size_t off = tbuf->len; + cppchar_t c; + + if (tbuf->len + nbwc > tbuf->asize) + { + tbuf->asize += OUTBUF_BLOCK_SIZE; + tbuf->text = XRESIZEVEC (uchar, tbuf->text, tbuf->asize); + } + + for (i = 0; i < nbwc; i++) + { + c = n & cmask; + n >>= cwidth; + tbuf->text[off + (bigend ? nbwc - i - 1 : i)] = c; + } + tbuf->len += nbwc; + } + else + { + /* Note: this code does not handle the case where the target + and host have a different number of bits in a byte. */ + if (tbuf->len + 1 > tbuf->asize) + { + tbuf->asize += OUTBUF_BLOCK_SIZE; + tbuf->text = XRESIZEVEC (uchar, tbuf->text, tbuf->asize); + } + tbuf->text[tbuf->len++] = n; + } +} + +/* Convert a hexadecimal escape, pointed to by FROM, to the execution + character set and write it into the string buffer TBUF. Returns an + advanced pointer, and issues diagnostics as necessary. + No character set translation occurs; this routine always produces the + execution-set character with numeric value equal to the given hex + number. You can, e.g. generate surrogate pairs this way. */ +static const uchar * +convert_hex (cpp_reader *pfile, const uchar *from, const uchar *limit, + struct _cpp_strbuf *tbuf, struct cset_converter cvt) +{ + cppchar_t c, n = 0, overflow = 0; + int digits_found = 0; + size_t width = cvt.width; + size_t mask = width_to_mask (width); + + if (CPP_WTRADITIONAL (pfile)) + cpp_warning (pfile, CPP_W_TRADITIONAL, + "the meaning of '\\x' is different in traditional C"); + + from++; /* Skip 'x'. */ + while (from < limit) + { + c = *from; + if (! hex_p (c)) + break; + from++; + overflow |= n ^ (n << 4 >> 4); + n = (n << 4) + hex_value (c); + digits_found = 1; + } + + if (!digits_found) + { + cpp_error (pfile, CPP_DL_ERROR, + "\\x used with no following hex digits"); + return from; + } + + if (overflow | (n != (n & mask))) + { + cpp_error (pfile, CPP_DL_PEDWARN, + "hex escape sequence out of range"); + n &= mask; + } + + emit_numeric_escape (pfile, n, tbuf, cvt); + + return from; +} + +/* Convert an octal escape, pointed to by FROM, to the execution + character set and write it into the string buffer TBUF. Returns an + advanced pointer, and issues diagnostics as necessary. + No character set translation occurs; this routine always produces the + execution-set character with numeric value equal to the given octal + number. */ +static const uchar * +convert_oct (cpp_reader *pfile, const uchar *from, const uchar *limit, + struct _cpp_strbuf *tbuf, struct cset_converter cvt) +{ + size_t count = 0; + cppchar_t c, n = 0; + size_t width = cvt.width; + size_t mask = width_to_mask (width); + bool overflow = false; + + while (from < limit && count++ < 3) + { + c = *from; + if (c < '0' || c > '7') + break; + from++; + overflow |= n ^ (n << 3 >> 3); + n = (n << 3) + c - '0'; + } + + if (n != (n & mask)) + { + cpp_error (pfile, CPP_DL_PEDWARN, + "octal escape sequence out of range"); + n &= mask; + } + + emit_numeric_escape (pfile, n, tbuf, cvt); + + return from; +} + +/* Convert an escape sequence (pointed to by FROM) to its value on + the target, and to the execution character set. Do not scan past + LIMIT. Write the converted value into TBUF. Returns an advanced + pointer. Handles all relevant diagnostics. */ +static const uchar * +convert_escape (cpp_reader *pfile, const uchar *from, const uchar *limit, + struct _cpp_strbuf *tbuf, struct cset_converter cvt) +{ + /* Values of \a \b \e \f \n \r \t \v respectively. */ +#if HOST_CHARSET == HOST_CHARSET_ASCII + static const uchar charconsts[] = { 7, 8, 27, 12, 10, 13, 9, 11 }; +#elif HOST_CHARSET == HOST_CHARSET_EBCDIC + static const uchar charconsts[] = { 47, 22, 39, 12, 21, 13, 5, 11 }; +#else +#error "unknown host character set" +#endif + + uchar c; + + c = *from; + switch (c) + { + /* UCNs, hex escapes, and octal escapes are processed separately. */ + case 'u': case 'U': + return convert_ucn (pfile, from, limit, tbuf, cvt); + + case 'x': + return convert_hex (pfile, from, limit, tbuf, cvt); + break; + + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + return convert_oct (pfile, from, limit, tbuf, cvt); + + /* Various letter escapes. Get the appropriate host-charset + value into C. */ + case '\\': case '\'': case '"': case '?': break; + + case '(': case '{': case '[': case '%': + /* '\(', etc, can be used at the beginning of a line in a long + string split onto multiple lines with \-newline, to prevent + Emacs or other text editors from getting confused. '\%' can + be used to prevent SCCS from mangling printf format strings. */ + if (CPP_PEDANTIC (pfile)) + goto unknown; + break; + + case 'b': c = charconsts[1]; break; + case 'f': c = charconsts[3]; break; + case 'n': c = charconsts[4]; break; + case 'r': c = charconsts[5]; break; + case 't': c = charconsts[6]; break; + case 'v': c = charconsts[7]; break; + + case 'a': + if (CPP_WTRADITIONAL (pfile)) + cpp_warning (pfile, CPP_W_TRADITIONAL, + "the meaning of '\\a' is different in traditional C"); + c = charconsts[0]; + break; + + case 'e': case 'E': + if (CPP_PEDANTIC (pfile)) + cpp_error (pfile, CPP_DL_PEDWARN, + "non-ISO-standard escape sequence, '\\%c'", (int) c); + c = charconsts[2]; + break; + + default: + unknown: + if (ISGRAPH (c)) + cpp_error (pfile, CPP_DL_PEDWARN, + "unknown escape sequence: '\\%c'", (int) c); + else + { + /* diagnostic.c does not support "%03o". When it does, this + code can use %03o directly in the diagnostic again. */ + char buf[32]; + sprintf(buf, "%03o", (int) c); + cpp_error (pfile, CPP_DL_PEDWARN, + "unknown escape sequence: '\\%s'", buf); + } + } + + /* Now convert what we have to the execution character set. */ + if (!APPLY_CONVERSION (cvt, &c, 1, tbuf)) + cpp_errno (pfile, CPP_DL_ERROR, + "converting escape sequence to execution character set"); + + return from + 1; +} + +/* TYPE is a token type. The return value is the conversion needed to + convert from source to execution character set for the given type. */ +static struct cset_converter +converter_for_type (cpp_reader *pfile, enum cpp_ttype type) +{ + switch (type) + { + default: + return pfile->narrow_cset_desc; + case CPP_UTF8STRING: + return pfile->utf8_cset_desc; + case CPP_CHAR16: + case CPP_STRING16: + return pfile->char16_cset_desc; + case CPP_CHAR32: + case CPP_STRING32: + return pfile->char32_cset_desc; + case CPP_WCHAR: + case CPP_WSTRING: + return pfile->wide_cset_desc; + } +} + +/* FROM is an array of cpp_string structures of length COUNT. These + are to be converted from the source to the execution character set, + escape sequences translated, and finally all are to be + concatenated. WIDE indicates whether or not to produce a wide + string. The result is written into TO. Returns true for success, + false for failure. */ +bool +cpp_interpret_string (cpp_reader *pfile, const cpp_string *from, size_t count, + cpp_string *to, enum cpp_ttype type) +{ + struct _cpp_strbuf tbuf; + const uchar *p, *base, *limit; + size_t i; + struct cset_converter cvt = converter_for_type (pfile, type); + + tbuf.asize = MAX (OUTBUF_BLOCK_SIZE, from->len); + tbuf.text = XNEWVEC (uchar, tbuf.asize); + tbuf.len = 0; + + for (i = 0; i < count; i++) + { + p = from[i].text; + if (*p == 'u') + { + if (*++p == '8') + p++; + } + else if (*p == 'L' || *p == 'U') p++; + if (*p == 'R') + { + const uchar *prefix; + + /* Skip over 'R"'. */ + p += 2; + prefix = p; + while (*p != '(') + p++; + p++; + limit = from[i].text + from[i].len; + if (limit >= p + (p - prefix) + 1) + limit -= (p - prefix) + 1; + + /* Raw strings are all normal characters; these can be fed + directly to convert_cset. */ + if (!APPLY_CONVERSION (cvt, p, limit - p, &tbuf)) + goto fail; + + continue; + } + + p++; /* Skip leading quote. */ + limit = from[i].text + from[i].len - 1; /* Skip trailing quote. */ + + for (;;) + { + base = p; + while (p < limit && *p != '\\') + p++; + if (p > base) + { + /* We have a run of normal characters; these can be fed + directly to convert_cset. */ + if (!APPLY_CONVERSION (cvt, base, p - base, &tbuf)) + goto fail; + } + if (p == limit) + break; + + p = convert_escape (pfile, p + 1, limit, &tbuf, cvt); + } + } + /* NUL-terminate the 'to' buffer and translate it to a cpp_string + structure. */ + emit_numeric_escape (pfile, 0, &tbuf, cvt); + tbuf.text = XRESIZEVEC (uchar, tbuf.text, tbuf.len); + to->text = tbuf.text; + to->len = tbuf.len; + return true; + + fail: + cpp_errno (pfile, CPP_DL_ERROR, "converting to execution character set"); + free (tbuf.text); + return false; +} + +/* Subroutine of do_line and do_linemarker. Convert escape sequences + in a string, but do not perform character set conversion. */ +bool +cpp_interpret_string_notranslate (cpp_reader *pfile, const cpp_string *from, + size_t count, cpp_string *to, + enum cpp_ttype type ATTRIBUTE_UNUSED) +{ + struct cset_converter save_narrow_cset_desc = pfile->narrow_cset_desc; + bool retval; + + pfile->narrow_cset_desc.func = convert_no_conversion; + pfile->narrow_cset_desc.cd = (iconv_t) -1; + pfile->narrow_cset_desc.width = CPP_OPTION (pfile, char_precision); + + retval = cpp_interpret_string (pfile, from, count, to, CPP_STRING); + + pfile->narrow_cset_desc = save_narrow_cset_desc; + return retval; +} + + +/* Subroutine of cpp_interpret_charconst which performs the conversion + to a number, for narrow strings. STR is the string structure returned + by cpp_interpret_string. PCHARS_SEEN and UNSIGNEDP are as for + cpp_interpret_charconst. */ +static cppchar_t +narrow_str_to_charconst (cpp_reader *pfile, cpp_string str, + unsigned int *pchars_seen, int *unsignedp) +{ + size_t width = CPP_OPTION (pfile, char_precision); + size_t max_chars = CPP_OPTION (pfile, int_precision) / width; + size_t mask = width_to_mask (width); + size_t i; + cppchar_t result, c; + bool unsigned_p; + + /* The value of a multi-character character constant, or a + single-character character constant whose representation in the + execution character set is more than one byte long, is + implementation defined. This implementation defines it to be the + number formed by interpreting the byte sequence in memory as a + big-endian binary number. If overflow occurs, the high bytes are + lost, and a warning is issued. + + We don't want to process the NUL terminator handed back by + cpp_interpret_string. */ + result = 0; + for (i = 0; i < str.len - 1; i++) + { + c = str.text[i] & mask; + if (width < BITS_PER_CPPCHAR_T) + result = (result << width) | c; + else + result = c; + } + + if (i > max_chars) + { + i = max_chars; + cpp_error (pfile, CPP_DL_WARNING, + "character constant too long for its type"); + } + else if (i > 1 && CPP_OPTION (pfile, warn_multichar)) + cpp_warning (pfile, CPP_W_MULTICHAR, "multi-character character constant"); + + /* Multichar constants are of type int and therefore signed. */ + if (i > 1) + unsigned_p = 0; + else + unsigned_p = CPP_OPTION (pfile, unsigned_char); + + /* Truncate the constant to its natural width, and simultaneously + sign- or zero-extend to the full width of cppchar_t. + For single-character constants, the value is WIDTH bits wide. + For multi-character constants, the value is INT_PRECISION bits wide. */ + if (i > 1) + width = CPP_OPTION (pfile, int_precision); + if (width < BITS_PER_CPPCHAR_T) + { + mask = ((cppchar_t) 1 << width) - 1; + if (unsigned_p || !(result & (1 << (width - 1)))) + result &= mask; + else + result |= ~mask; + } + *pchars_seen = i; + *unsignedp = unsigned_p; + return result; +} + +/* Subroutine of cpp_interpret_charconst which performs the conversion + to a number, for wide strings. STR is the string structure returned + by cpp_interpret_string. PCHARS_SEEN and UNSIGNEDP are as for + cpp_interpret_charconst. TYPE is the token type. */ +static cppchar_t +wide_str_to_charconst (cpp_reader *pfile, cpp_string str, + unsigned int *pchars_seen, int *unsignedp, + enum cpp_ttype type) +{ + bool bigend = CPP_OPTION (pfile, bytes_big_endian); + size_t width = converter_for_type (pfile, type).width; + size_t cwidth = CPP_OPTION (pfile, char_precision); + size_t mask = width_to_mask (width); + size_t cmask = width_to_mask (cwidth); + size_t nbwc = width / cwidth; + size_t off, i; + cppchar_t result = 0, c; + + /* This is finicky because the string is in the target's byte order, + which may not be our byte order. Only the last character, ignoring + the NUL terminator, is relevant. */ + off = str.len - (nbwc * 2); + result = 0; + for (i = 0; i < nbwc; i++) + { + c = bigend ? str.text[off + i] : str.text[off + nbwc - i - 1]; + result = (result << cwidth) | (c & cmask); + } + + /* Wide character constants have type wchar_t, and a single + character exactly fills a wchar_t, so a multi-character wide + character constant is guaranteed to overflow. */ + if (str.len > nbwc * 2) + cpp_error (pfile, CPP_DL_WARNING, + "character constant too long for its type"); + + /* Truncate the constant to its natural width, and simultaneously + sign- or zero-extend to the full width of cppchar_t. */ + if (width < BITS_PER_CPPCHAR_T) + { + if (type == CPP_CHAR16 || type == CPP_CHAR32 + || CPP_OPTION (pfile, unsigned_wchar) + || !(result & (1 << (width - 1)))) + result &= mask; + else + result |= ~mask; + } + + if (type == CPP_CHAR16 || type == CPP_CHAR32 + || CPP_OPTION (pfile, unsigned_wchar)) + *unsignedp = 1; + else + *unsignedp = 0; + + *pchars_seen = 1; + return result; +} + +/* Interpret a (possibly wide) character constant in TOKEN. + PCHARS_SEEN points to a variable that is filled in with the number + of characters seen, and UNSIGNEDP to a variable that indicates + whether the result has signed type. */ +cppchar_t +cpp_interpret_charconst (cpp_reader *pfile, const cpp_token *token, + unsigned int *pchars_seen, int *unsignedp) +{ + cpp_string str = { 0, 0 }; + bool wide = (token->type != CPP_CHAR); + cppchar_t result; + + /* an empty constant will appear as L'', u'', U'' or '' */ + if (token->val.str.len == (size_t) (2 + wide)) + { + cpp_error (pfile, CPP_DL_ERROR, "empty character constant"); + return 0; + } + else if (!cpp_interpret_string (pfile, &token->val.str, 1, &str, token->type)) + return 0; + + if (wide) + result = wide_str_to_charconst (pfile, str, pchars_seen, unsignedp, + token->type); + else + result = narrow_str_to_charconst (pfile, str, pchars_seen, unsignedp); + + if (str.text != token->val.str.text) + free ((void *)str.text); + + return result; +} + +/* Convert an identifier denoted by ID and LEN, which might contain + UCN escapes, to the source character set, either UTF-8 or + UTF-EBCDIC. Assumes that the identifier is actually a valid identifier. */ +cpp_hashnode * +_cpp_interpret_identifier (cpp_reader *pfile, const uchar *id, size_t len) +{ + /* It turns out that a UCN escape always turns into fewer characters + than the escape itself, so we can allocate a temporary in advance. */ + uchar * buf = (uchar *) alloca (len + 1); + uchar * bufp = buf; + size_t idp; + + for (idp = 0; idp < len; idp++) + if (id[idp] != '\\') + *bufp++ = id[idp]; + else + { + unsigned length = id[idp+1] == 'u' ? 4 : 8; + cppchar_t value = 0; + size_t bufleft = len - (bufp - buf); + int rval; + + idp += 2; + while (length && idp < len && ISXDIGIT (id[idp])) + { + value = (value << 4) + hex_value (id[idp]); + idp++; + length--; + } + idp--; + + /* Special case for EBCDIC: if the identifier contains + a '$' specified using a UCN, translate it to EBCDIC. */ + if (value == 0x24) + { + *bufp++ = '$'; + continue; + } + + rval = one_cppchar_to_utf8 (value, &bufp, &bufleft); + if (rval) + { + errno = rval; + cpp_errno (pfile, CPP_DL_ERROR, + "converting UCN to source character set"); + break; + } + } + + return CPP_HASHNODE (ht_lookup (pfile->hash_table, + buf, bufp - buf, HT_ALLOC)); +} + +/* Convert an input buffer (containing the complete contents of one + source file) from INPUT_CHARSET to the source character set. INPUT + points to the input buffer, SIZE is its allocated size, and LEN is + the length of the meaningful data within the buffer. The + translated buffer is returned, *ST_SIZE is set to the length of + the meaningful data within the translated buffer, and *BUFFER_START + is set to the start of the returned buffer. *BUFFER_START may + differ from the return value in the case of a BOM or other ignored + marker information. + + INPUT is expected to have been allocated with xmalloc. This + function will either set *BUFFER_START to INPUT, or free it and set + *BUFFER_START to a pointer to another xmalloc-allocated block of + memory. */ +uchar * +_cpp_convert_input (cpp_reader *pfile, const char *input_charset, + uchar *input, size_t size, size_t len, + const unsigned char **buffer_start, off_t *st_size) +{ + struct cset_converter input_cset; + struct _cpp_strbuf to; + unsigned char *buffer; + + input_cset = init_iconv_desc (pfile, SOURCE_CHARSET, input_charset); + if (input_cset.func == convert_no_conversion) + { + to.text = input; + to.asize = size; + to.len = len; + } + else + { + to.asize = MAX (65536, len); + to.text = XNEWVEC (uchar, to.asize); + to.len = 0; + + if (!APPLY_CONVERSION (input_cset, input, len, &to)) + cpp_error (pfile, CPP_DL_ERROR, + "failure to convert %s to %s", + CPP_OPTION (pfile, input_charset), SOURCE_CHARSET); + + free (input); + } + + /* Clean up the mess. */ + if (input_cset.func == convert_using_iconv) + iconv_close (input_cset.cd); + + /* Resize buffer if we allocated substantially too much, or if we + haven't enough space for the \n-terminator. */ + if (to.len + 4096 < to.asize || to.len >= to.asize) + to.text = XRESIZEVEC (uchar, to.text, to.len + 1); + + /* If the file is using old-school Mac line endings (\r only), + terminate with another \r, not an \n, so that we do not mistake + the \r\n sequence for a single DOS line ending and erroneously + issue the "No newline at end of file" diagnostic. */ + if (to.len && to.text[to.len - 1] == '\r') + to.text[to.len] = '\r'; + else + to.text[to.len] = '\n'; + + buffer = to.text; + *st_size = to.len; +#if HOST_CHARSET == HOST_CHARSET_ASCII + /* The HOST_CHARSET test just above ensures that the source charset + is UTF-8. So, ignore a UTF-8 BOM if we see one. Note that + glib'c UTF-8 iconv() provider (as of glibc 2.7) does not ignore a + BOM -- however, even if it did, we would still need this code due + to the 'convert_no_conversion' case. */ + if (to.len >= 3 && to.text[0] == 0xef && to.text[1] == 0xbb + && to.text[2] == 0xbf) + { + *st_size -= 3; + buffer += 3; + } +#endif + + *buffer_start = to.text; + return buffer; +} + +/* Decide on the default encoding to assume for input files. */ +const char * +_cpp_default_encoding (void) +{ + const char *current_encoding = NULL; + + /* We disable this because the default codeset is 7-bit ASCII on + most platforms, and this causes conversion failures on every + file in GCC that happens to have one of the upper 128 characters + in it -- most likely, as part of the name of a contributor. + We should definitely recognize in-band markers of file encoding, + like: + - the appropriate Unicode byte-order mark (FE FF) to recognize + UTF16 and UCS4 (in both big-endian and little-endian flavors) + and UTF8 + - a "#i", "#d", "/ *", "//", " #p" or "#p" (for #pragma) to + distinguish ASCII and EBCDIC. + - now we can parse something like "#pragma GCC encoding <xyz> + on the first line, or even Emacs/VIM's mode line tags (there's + a problem here in that VIM uses the last line, and Emacs has + its more elaborate "local variables" convention). + - investigate whether Java has another common convention, which + would be friendly to support. + (Zack Weinberg and Paolo Bonzini, May 20th 2004) */ +#if defined (HAVE_LOCALE_H) && defined (HAVE_LANGINFO_CODESET) && 0 + setlocale (LC_CTYPE, ""); + current_encoding = nl_langinfo (CODESET); +#endif + if (current_encoding == NULL || *current_encoding == '\0') + current_encoding = SOURCE_CHARSET; + + return current_encoding; +} diff --git a/support/cpp/libcpp/directives.c b/support/cpp/libcpp/directives.c new file mode 100644 index 0000000..f244ae5 --- /dev/null +++ b/support/cpp/libcpp/directives.c @@ -0,0 +1,2560 @@ +/* CPP Library. (Directive handling.) + Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + 1999, 2000, 2001, 2002, 2003, 2004, 2005, + 2007, 2008, 2009, 2010 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 3, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "cpplib.h" +#include "internal.h" +#include "mkdeps.h" +#include "obstack.h" + +/* Stack of conditionals currently in progress + (including both successful and failing conditionals). */ +struct if_stack +{ + struct if_stack *next; + linenum_type line; /* Line where condition started. */ + const cpp_hashnode *mi_cmacro;/* macro name for #ifndef around entire file */ + bool skip_elses; /* Can future #else / #elif be skipped? */ + bool was_skipping; /* If were skipping on entry. */ + int type; /* Most recent conditional for diagnostics. */ +}; + +/* Contains a registered pragma or pragma namespace. */ +typedef void (*pragma_cb) (cpp_reader *); +struct pragma_entry +{ + struct pragma_entry *next; + const cpp_hashnode *pragma; /* Name and length. */ + bool is_nspace; + bool is_internal; + bool is_deferred; + bool allow_expansion; + union { + pragma_cb handler; + struct pragma_entry *space; + unsigned int ident; + } u; +}; + +/* 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). + + EXPAND is set on directives that are always macro-expanded. */ +#define COND (1 << 0) +#define IF_COND (1 << 1) +#define INCL (1 << 2) +#define IN_I (1 << 3) +#define EXPAND (1 << 4) +#define DEPRECATED (1 << 5) + +/* Defines one #-directive, including how to handle it. */ +typedef void (*directive_handler) (cpp_reader *); +typedef struct directive directive; +struct directive +{ + directive_handler handler; /* Function to handle directive. */ + const uchar *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 (cpp_reader *); +static void check_eol (cpp_reader *, bool); +static void start_directive (cpp_reader *); +static void prepare_directive_trad (cpp_reader *); +static void end_directive (cpp_reader *, int); +static void directive_diagnostics (cpp_reader *, const directive *, int); +static void run_directive (cpp_reader *, int, const char *, size_t); +static char *glue_header_name (cpp_reader *); +static const char *parse_include (cpp_reader *, int *, const cpp_token ***, + source_location *); +static void push_conditional (cpp_reader *, int, int, const cpp_hashnode *); +static unsigned int read_flag (cpp_reader *, unsigned int); +static bool strtolinenum (const uchar *, size_t, linenum_type *, bool *); +static void do_diagnostic (cpp_reader *, int, int, int); +static cpp_hashnode *lex_macro_node (cpp_reader *, bool); +static int undefine_macros (cpp_reader *, cpp_hashnode *, void *); +static void do_include_common (cpp_reader *, enum include_type); +static struct pragma_entry *lookup_pragma_entry (struct pragma_entry *, + const cpp_hashnode *); +static int count_registered_pragmas (struct pragma_entry *); +static char ** save_registered_pragmas (struct pragma_entry *, char **); +static char ** restore_registered_pragmas (cpp_reader *, struct pragma_entry *, + char **); +static void do_pragma_once (cpp_reader *); +static void do_pragma_poison (cpp_reader *); +static void do_pragma_system_header (cpp_reader *); +static void do_pragma_dependency (cpp_reader *); +static void do_linemarker (cpp_reader *); +static const cpp_token *get_token_no_padding (cpp_reader *); +static const cpp_token *get__Pragma_string (cpp_reader *); +static void destringize_and_run (cpp_reader *, const cpp_string *); +static int parse_answer (cpp_reader *, struct answer **, int, source_location); +static cpp_hashnode *parse_assertion (cpp_reader *, struct answer **, int); +static struct answer ** find_answer (cpp_hashnode *, const struct answer *); +static void handle_assertion (cpp_reader *, const char *, int); +static void do_pragma_push_macro (cpp_reader *); +static void do_pragma_pop_macro (cpp_reader *); +static void cpp_pop_definition (cpp_reader *, struct def_pragma_macro *); + +/* 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, #include_next, + and #import 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 | EXPAND) /* 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 | EXPAND) /* 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, EXPAND) /* 2465 */ \ +D(elif, T_ELIF, STDC89, COND | EXPAND) /* 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 | EXPAND) /* 19 */ \ +D(ident, T_IDENT, EXTENSION, IN_I) /* 11 */ \ +D(import, T_IMPORT, EXTENSION, INCL | EXPAND) /* 0 ObjC */ \ +D(assert, T_ASSERT, EXTENSION, DEPRECATED) /* 0 SVR4 */ \ +D(unassert, T_UNASSERT, EXTENSION, DEPRECATED) /* 0 SVR4 */ \ +D(sccs, T_SCCS, EXTENSION, IN_I) /* 0 SVR4? */ + +/* #sccs is synonymous with #ident. */ +#define do_sccs do_ident + +/* Use the table to generate a series of prototypes, an enum for the + directive names, and an array of directive handlers. */ + +#define D(name, t, o, f) static void do_##name (cpp_reader *); +DIRECTIVE_TABLE +#undef D + +#define D(n, tag, o, f) tag, +enum +{ + DIRECTIVE_TABLE + N_DIRECTIVES +}; +#undef D + +#define D(name, t, origin, flags) \ +{ do_##name, (const uchar *) #name, \ + sizeof #name - 1, origin, flags }, +static const directive dtable[] = +{ +DIRECTIVE_TABLE +}; +#undef D +#undef DIRECTIVE_TABLE + +/* Wrapper struct directive for linemarkers. + The origin is more or less true - the original K+R cpp + did use this notation in its preprocessed output. */ +static const directive linemarker_dir = +{ + do_linemarker, UC"#", 1, KANDR, IN_I +}; + +#define SEEN_EOL() (pfile->cur_token[-1].type == CPP_EOF) + +/* Skip any remaining tokens in a directive. */ +static void +skip_rest_of_line (cpp_reader *pfile) +{ + /* Discard all stacked contexts. */ + while (pfile->context->prev) + _cpp_pop_context (pfile); + + /* Sweep up all tokens remaining on the line. */ + if (! SEEN_EOL ()) + while (_cpp_lex_token (pfile)->type != CPP_EOF) + ; +} + +/* Ensure there are no stray tokens at the end of a directive. If + EXPAND is true, tokens macro-expanding to nothing are allowed. */ +static void +check_eol (cpp_reader *pfile, bool expand) +{ + if (! SEEN_EOL () && (expand + ? cpp_get_token (pfile) + : _cpp_lex_token (pfile))->type != CPP_EOF) + cpp_error (pfile, CPP_DL_PEDWARN, "extra tokens at end of #%s directive", + pfile->directive->name); +} + +/* Ensure there are no stray tokens other than comments at the end of + a directive, and gather the comments. */ +static const cpp_token ** +check_eol_return_comments (cpp_reader *pfile) +{ + size_t c; + size_t capacity = 8; + const cpp_token **buf; + + buf = XNEWVEC (const cpp_token *, capacity); + c = 0; + if (! SEEN_EOL ()) + { + while (1) + { + const cpp_token *tok; + + tok = _cpp_lex_token (pfile); + if (tok->type == CPP_EOF) + break; + if (tok->type != CPP_COMMENT) + cpp_error (pfile, CPP_DL_PEDWARN, + "extra tokens at end of #%s directive", + pfile->directive->name); + else + { + if (c + 1 >= capacity) + { + capacity *= 2; + buf = XRESIZEVEC (const cpp_token *, buf, capacity); + } + buf[c] = tok; + ++c; + } + } + } + buf[c] = NULL; + return buf; +} + +/* Called when entering a directive, _Pragma or command-line directive. */ +static void +start_directive (cpp_reader *pfile) +{ + /* Setup in-directive state. */ + pfile->state.in_directive = 1; + pfile->state.save_comments = 0; + pfile->directive_result.type = CPP_PADDING; + + /* Some handlers need the position of the # for diagnostics. */ + pfile->directive_line = pfile->line_table->highest_line; +} + +/* Called when leaving a directive, _Pragma or command-line directive. */ +static void +end_directive (cpp_reader *pfile, int skip_line) +{ + if (CPP_OPTION (pfile, traditional)) + { + /* Revert change of prepare_directive_trad. */ + if (!pfile->state.in_deferred_pragma) + pfile->state.prevent_expansion--; + + if (pfile->directive != &dtable[T_DEFINE]) + _cpp_remove_overlay (pfile); + } + else if (pfile->state.in_deferred_pragma) + ; + /* We don't skip for an assembler #. */ + else if (skip_line) + { + skip_rest_of_line (pfile); + if (!pfile->keep_tokens) + { + pfile->cur_run = &pfile->base_run; + pfile->cur_token = pfile->base_run.base; + } + } + + /* Restore state. */ + pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments); + pfile->state.in_directive = 0; + pfile->state.in_expression = 0; + pfile->state.angled_headers = 0; + pfile->directive = 0; +} + +/* Prepare to handle the directive in pfile->directive. */ +static void +prepare_directive_trad (cpp_reader *pfile) +{ + if (pfile->directive != &dtable[T_DEFINE]) + { + bool no_expand = (pfile->directive + && ! (pfile->directive->flags & EXPAND)); + bool was_skipping = pfile->state.skipping; + + pfile->state.in_expression = (pfile->directive == &dtable[T_IF] + || pfile->directive == &dtable[T_ELIF]); + if (pfile->state.in_expression) + pfile->state.skipping = false; + + if (no_expand) + pfile->state.prevent_expansion++; + _cpp_scan_out_logical_line (pfile, NULL); + if (no_expand) + pfile->state.prevent_expansion--; + + pfile->state.skipping = was_skipping; + _cpp_overlay_buffer (pfile, pfile->out.base, + pfile->out.cur - pfile->out.base); + } + + /* Stop ISO C from expanding anything. */ + pfile->state.prevent_expansion++; +} + +/* Output diagnostics for a directive DIR. INDENTED is nonzero if + the '#' was indented. */ +static void +directive_diagnostics (cpp_reader *pfile, const directive *dir, int indented) +{ + /* Issue -pedantic or deprecated warnings for extensions. We let + -pedantic take precedence if both are applicable. */ + if (! pfile->state.skipping) + { + if (dir->origin == EXTENSION + && !(dir == &dtable[T_IMPORT] && CPP_OPTION (pfile, objc)) + && CPP_PEDANTIC (pfile)) + cpp_error (pfile, CPP_DL_PEDWARN, "#%s is a GCC extension", dir->name); + else if (((dir->flags & DEPRECATED) != 0 + || (dir == &dtable[T_IMPORT] && !CPP_OPTION (pfile, objc))) + && CPP_OPTION (pfile, cpp_warn_deprecated)) + cpp_warning (pfile, CPP_W_DEPRECATED, + "#%s is a deprecated GCC extension", dir->name); + } + + /* 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. #elif cannot be used at all. */ + if (CPP_WTRADITIONAL (pfile)) + { + if (dir == &dtable[T_ELIF]) + cpp_warning (pfile, CPP_W_TRADITIONAL, + "suggest not using #elif in traditional C"); + else if (indented && dir->origin == KANDR) + cpp_warning (pfile, CPP_W_TRADITIONAL, + "traditional C ignores #%s with the # indented", + dir->name); + else if (!indented && dir->origin != KANDR) + cpp_warning (pfile, CPP_W_TRADITIONAL, + "suggest hiding #%s from traditional C with an indented #", + dir->name); + } +} + +/* Check if we have a known directive. INDENTED is nonzero if the + '#' of the directive was indented. This function is in this file + to save unnecessarily exporting dtable etc. to lex.c. Returns + nonzero if the line of tokens has been handled, zero if we should + continue processing the line. */ +int +_cpp_handle_directive (cpp_reader *pfile, int indented) +{ + const directive *dir = 0; + const cpp_token *dname; + bool was_parsing_args = pfile->state.parsing_args; + bool was_discarding_output = pfile->state.discarding_output; + int skip = 1; + + if (was_discarding_output) + pfile->state.prevent_expansion = 0; + + if (was_parsing_args) + { + if (CPP_OPTION (pfile, cpp_pedantic)) + cpp_error (pfile, CPP_DL_PEDWARN, + "embedding a directive within macro arguments is not portable"); + pfile->state.parsing_args = 0; + pfile->state.prevent_expansion = 0; + } + start_directive (pfile); + dname = _cpp_lex_token (pfile); + + if (dname->type == CPP_NAME) + { + if (dname->val.node.node->is_directive) + dir = &dtable[dname->val.node.node->directive_index]; + } + /* We do not recognize the # followed by a number extension in + assembler code. */ + else if (dname->type == CPP_NUMBER && CPP_OPTION (pfile, lang) != CLK_ASM) + { + dir = &linemarker_dir; + if (CPP_PEDANTIC (pfile) && ! CPP_OPTION (pfile, preprocessed) + && ! pfile->state.skipping) + cpp_error (pfile, CPP_DL_PEDWARN, + "style of line directive is a GCC extension"); + } + + if (dir) + { + /* If we have a directive that is not an opening conditional, + invalidate any control macro. */ + if (! (dir->flags & IF_COND)) + pfile->mi_valid = false; + + /* 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. macro.c + puts a space in front of any '#' at the start of a macro. + + We exclude the -fdirectives-only case because macro expansion + has not been performed yet, and block comments can cause spaces + to preceed the directive. */ + if (CPP_OPTION (pfile, preprocessed) + && !CPP_OPTION (pfile, directives_only) + && (indented || !(dir->flags & IN_I))) + { + skip = 0; + dir = 0; + } + else + { + /* In failed conditional groups, all non-conditional + directives are ignored. Before doing that, whether + skipping or not, we should lex angle-bracketed headers + correctly, and maybe output some diagnostics. */ + pfile->state.angled_headers = dir->flags & INCL; + pfile->state.directive_wants_padding = dir->flags & INCL; + if (! CPP_OPTION (pfile, preprocessed)) + directive_diagnostics (pfile, dir, indented); + if (pfile->state.skipping && !(dir->flags & COND)) + dir = 0; + } + } + else if (dname->type == CPP_EOF) + ; /* CPP_EOF is the "null directive". */ + else + { + /* 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) + skip = 0; + else if (!pfile->state.skipping) + cpp_error (pfile, CPP_DL_ERROR, "invalid preprocessing directive #%s", + cpp_token_as_text (pfile, dname)); + } + + pfile->directive = dir; + if (CPP_OPTION (pfile, traditional)) + prepare_directive_trad (pfile); + + if (dir) + pfile->directive->handler (pfile); + else if (skip == 0) + _cpp_backup_tokens (pfile, 1); + + end_directive (pfile, skip); + if (was_parsing_args && !pfile->state.in_deferred_pragma) + { + /* Restore state when within macro args. */ + pfile->state.parsing_args = 2; + pfile->state.prevent_expansion = 1; + } + if (was_discarding_output) + pfile->state.prevent_expansion = 1; + return skip; +} + +/* Directive handler wrapper used by the command line option + processor. BUF is \n terminated. */ +static void +run_directive (cpp_reader *pfile, int dir_no, const char *buf, size_t count) +{ + cpp_push_buffer (pfile, (const uchar *) buf, count, + /* from_stage3 */ true); + start_directive (pfile); + + /* This is a short-term fix to prevent a leading '#' being + interpreted as a directive. */ + _cpp_clean_line (pfile); + + pfile->directive = &dtable[dir_no]; + if (CPP_OPTION (pfile, traditional)) + prepare_directive_trad (pfile); + pfile->directive->handler (pfile); + end_directive (pfile, 1); + _cpp_pop_buffer (pfile); +} + +/* Checks for validity the macro name in #define, #undef, #ifdef and + #ifndef directives. IS_DEF_OR_UNDEF is true if this call is + processing a #define or #undefine directive, and false + otherwise. */ +static cpp_hashnode * +lex_macro_node (cpp_reader *pfile, bool is_def_or_undef) +{ + const cpp_token *token = _cpp_lex_token (pfile); + + /* The token immediately after #define must be an identifier. That + identifier may not be "defined", per C99 6.10.8p4. + In C++, it may not be any of the "named operators" either, + per C++98 [lex.digraph], [lex.key]. + Finally, the identifier may not have been poisoned. (In that case + the lexer has issued the error message for us.) */ + + if (token->type == CPP_NAME) + { + cpp_hashnode *node = token->val.node.node; + + if (is_def_or_undef && node == pfile->spec_nodes.n_defined) + cpp_error (pfile, CPP_DL_ERROR, + "\"defined\" cannot be used as a macro name"); + else if (! (node->flags & NODE_POISONED)) + return node; + } + else if (token->flags & NAMED_OP) + cpp_error (pfile, CPP_DL_ERROR, + "\"%s\" cannot be used as a macro name as it is an operator in C++", + NODE_NAME (token->val.node.node)); + else if (token->type == CPP_EOF) + cpp_error (pfile, CPP_DL_ERROR, "no macro name given in #%s directive", + pfile->directive->name); + else + cpp_error (pfile, CPP_DL_ERROR, "macro names must be identifiers"); + + return NULL; +} + +/* Process a #define directive. Most work is done in macro.c. */ +static void +do_define (cpp_reader *pfile) +{ + cpp_hashnode *node = lex_macro_node (pfile, true); + + if (node) + { + /* If we have been requested to expand comments into macros, + then re-enable saving of comments. */ + pfile->state.save_comments = + ! CPP_OPTION (pfile, discard_comments_in_macro_exp); + + if (pfile->cb.before_define) + pfile->cb.before_define (pfile); + + if (_cpp_create_definition (pfile, node)) + if (pfile->cb.define) + pfile->cb.define (pfile, pfile->directive_line, node); + + node->flags &= ~NODE_USED; + } +} + +/* Handle #undef. Mark the identifier NT_VOID in the hash table. */ +static void +do_undef (cpp_reader *pfile) +{ + cpp_hashnode *node = lex_macro_node (pfile, true); + + if (node) + { + if (pfile->cb.before_define) + pfile->cb.before_define (pfile); + + if (pfile->cb.undef) + pfile->cb.undef (pfile, pfile->directive_line, node); + + /* 6.10.3.5 paragraph 2: [#undef] is ignored if the specified + identifier is not currently defined as a macro name. */ + if (node->type == NT_MACRO) + { + if (node->flags & NODE_WARN) + cpp_error (pfile, CPP_DL_WARNING, + "undefining \"%s\"", NODE_NAME (node)); + + if (CPP_OPTION (pfile, warn_unused_macros)) + _cpp_warn_if_unused_macro (pfile, node, NULL); + + _cpp_free_definition (node); + } + } + + check_eol (pfile, false); +} + +/* Undefine a single macro/assertion/whatever. */ + +static int +undefine_macros (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *h, + void *data_p ATTRIBUTE_UNUSED) +{ + /* Body of _cpp_free_definition inlined here for speed. + Macros and assertions no longer have anything to free. */ + h->type = NT_VOID; + h->flags &= ~(NODE_POISONED|NODE_BUILTIN|NODE_DISABLED|NODE_USED); + return 1; +} + +/* Undefine all macros and assertions. */ + +void +cpp_undef_all (cpp_reader *pfile) +{ + cpp_forall_identifiers (pfile, undefine_macros, NULL); +} + + +/* 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 a malloced filename. */ +static char * +glue_header_name (cpp_reader *pfile) +{ + const cpp_token *token; + char *buffer; + 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 = XNEWVEC (char, capacity); + for (;;) + { + token = get_token_no_padding (pfile); + + if (token->type == CPP_GREATER) + break; + if (token->type == CPP_EOF) + { + cpp_error (pfile, CPP_DL_ERROR, "missing terminating > character"); + break; + } + + len = cpp_token_len (token) + 2; /* Leading space, terminating \0. */ + if (total_len + len > capacity) + { + capacity = (capacity + len) * 2; + buffer = XRESIZEVEC (char, buffer, capacity); + } + + if (token->flags & PREV_WHITE) + buffer[total_len++] = ' '; + + total_len = (cpp_spell_token (pfile, token, (uchar *) &buffer[total_len], + true) + - (uchar *) buffer); + } + + buffer[total_len] = '\0'; + return buffer; +} + +/* Returns the file name of #include, #include_next, #import and + #pragma dependency. The string is malloced and the caller should + free it. Returns NULL on error. LOCATION is the source location + of the file name. */ + +static const char * +parse_include (cpp_reader *pfile, int *pangle_brackets, + const cpp_token ***buf, source_location *location) +{ + char *fname; + const cpp_token *header; + + /* Allow macro expansion. */ + header = get_token_no_padding (pfile); + *location = header->src_loc; + if ((header->type == CPP_STRING && header->val.str.text[0] != 'R') + || header->type == CPP_HEADER_NAME) + { + fname = XNEWVEC (char, header->val.str.len - 1); + memcpy (fname, header->val.str.text + 1, header->val.str.len - 2); + fname[header->val.str.len - 2] = '\0'; + *pangle_brackets = header->type == CPP_HEADER_NAME; + } + else if (header->type == CPP_LESS) + { + fname = glue_header_name (pfile); + *pangle_brackets = 1; + } + else + { + const unsigned char *dir; + + if (pfile->directive == &dtable[T_PRAGMA]) + dir = UC"pragma dependency"; + else + dir = pfile->directive->name; + cpp_error (pfile, CPP_DL_ERROR, "#%s expects \"FILENAME\" or <FILENAME>", + dir); + + return NULL; + } + + if (pfile->directive == &dtable[T_PRAGMA]) + { + /* This pragma allows extra tokens after the file name. */ + } + else if (buf == NULL || CPP_OPTION (pfile, discard_comments)) + check_eol (pfile, true); + else + { + /* If we are not discarding comments, then gather them while + doing the eol check. */ + *buf = check_eol_return_comments (pfile); + } + + return fname; +} + +/* Handle #include, #include_next and #import. */ +static void +do_include_common (cpp_reader *pfile, enum include_type type) +{ + const char *fname; + int angle_brackets; + const cpp_token **buf = NULL; + source_location location; + + /* Re-enable saving of comments if requested, so that the include + callback can dump comments which follow #include. */ + pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments); + + fname = parse_include (pfile, &angle_brackets, &buf, &location); + if (!fname) + { + if (buf) + XDELETEVEC (buf); + return; + } + + if (!*fname) + { + cpp_error_with_line (pfile, CPP_DL_ERROR, location, 0, + "empty filename in #%s", + pfile->directive->name); + XDELETEVEC (fname); + if (buf) + XDELETEVEC (buf); + return; + } + + /* Prevent #include recursion. */ + if (pfile->line_table->depth >= CPP_STACK_MAX) + cpp_error (pfile, CPP_DL_ERROR, "#include nested too deeply"); + else + { + /* Get out of macro context, if we are. */ + skip_rest_of_line (pfile); + + if (pfile->cb.include) + pfile->cb.include (pfile, pfile->directive_line, + pfile->directive->name, fname, angle_brackets, + buf); + + _cpp_stack_include (pfile, fname, angle_brackets, type); + } + + XDELETEVEC (fname); + if (buf) + XDELETEVEC (buf); +} + +static void +do_include (cpp_reader *pfile) +{ + do_include_common (pfile, IT_INCLUDE); +} + +static void +do_import (cpp_reader *pfile) +{ + do_include_common (pfile, IT_IMPORT); +} + +static void +do_include_next (cpp_reader *pfile) +{ + enum include_type type = IT_INCLUDE_NEXT; + + /* If this is the primary source file, warn and use the normal + search logic. */ + if (cpp_in_primary_file (pfile)) + { + cpp_error (pfile, CPP_DL_WARNING, + "#include_next in primary source file"); + type = IT_INCLUDE; + } + do_include_common (pfile, type); +} + +/* Subroutine of do_linemarker. 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 (cpp_reader *pfile, unsigned int last) +{ + const cpp_token *token = _cpp_lex_token (pfile); + + 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, CPP_DL_ERROR, "invalid flag \"%s\" in line directive", + cpp_token_as_text (pfile, token)); + return 0; +} + +/* Subroutine of do_line and do_linemarker. Convert a number in STR, + of length LEN, to binary; store it in NUMP, and return false if the + number was well-formed, true if not. WRAPPED is set to true if the + number did not fit into 'unsigned long'. */ +static bool +strtolinenum (const uchar *str, size_t len, linenum_type *nump, bool *wrapped) +{ + linenum_type reg = 0; + linenum_type reg_prev = 0; + + uchar c; + *wrapped = false; + while (len--) + { + c = *str++; + if (!ISDIGIT (c)) + return true; + reg *= 10; + reg += c - '0'; + if (reg < reg_prev) + *wrapped = true; + reg_prev = reg; + } + *nump = reg; + return false; +} + +/* Interpret #line command. + Note that the filename string (if any) is a true string constant + (escapes are interpreted), unlike in #line. */ +static void +do_line (cpp_reader *pfile) +{ + const struct line_maps *line_table = pfile->line_table; + const struct line_map *map = &line_table->maps[line_table->used - 1]; + + /* skip_rest_of_line() may cause line table to be realloc()ed so note down + sysp right now. */ + + unsigned char map_sysp = map->sysp; + const cpp_token *token; + const char *new_file = map->to_file; + linenum_type new_lineno; + + /* C99 raised the minimum limit on #line numbers. */ + linenum_type cap = CPP_OPTION (pfile, c99) ? 2147483647 : 32767; + bool wrapped; + + /* #line commands expand macros. */ + token = cpp_get_token (pfile); + if (token->type != CPP_NUMBER + || strtolinenum (token->val.str.text, token->val.str.len, + &new_lineno, &wrapped)) + { + if (token->type == CPP_EOF) + cpp_error (pfile, CPP_DL_ERROR, "unexpected end of file after #line"); + else + cpp_error (pfile, CPP_DL_ERROR, + "\"%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 || wrapped)) + cpp_error (pfile, CPP_DL_PEDWARN, "line number out of range"); + else if (wrapped) + cpp_error (pfile, CPP_DL_WARNING, "line number out of range"); + + token = cpp_get_token (pfile); + if (token->type == CPP_STRING) + { + cpp_string s = { 0, 0 }; + if (cpp_interpret_string_notranslate (pfile, &token->val.str, 1, + &s, CPP_STRING)) + new_file = (const char *)s.text; + check_eol (pfile, true); + } + else if (token->type != CPP_EOF) + { + cpp_error (pfile, CPP_DL_ERROR, "\"%s\" is not a valid filename", + cpp_token_as_text (pfile, token)); + return; + } + + skip_rest_of_line (pfile); + _cpp_do_file_change (pfile, LC_RENAME_VERBATIM, new_file, new_lineno, + map_sysp); +} + +/* Interpret the # 44 "file" [flags] notation, which has slightly + different syntax and semantics from #line: Flags are allowed, + and we never complain about the line number being too big. */ +static void +do_linemarker (cpp_reader *pfile) +{ + const struct line_maps *line_table = pfile->line_table; + const struct line_map *map = &line_table->maps[line_table->used - 1]; + const cpp_token *token; + const char *new_file = map->to_file; + linenum_type new_lineno; + unsigned int new_sysp = map->sysp; + enum lc_reason reason = LC_RENAME_VERBATIM; + int flag; + bool wrapped; + + /* Back up so we can get the number again. Putting this in + _cpp_handle_directive risks two calls to _cpp_backup_tokens in + some circumstances, which can segfault. */ + _cpp_backup_tokens (pfile, 1); + + /* #line commands expand macros. */ + token = cpp_get_token (pfile); + if (token->type != CPP_NUMBER + || strtolinenum (token->val.str.text, token->val.str.len, + &new_lineno, &wrapped)) + { + /* Unlike #line, there does not seem to be a way to get an EOF + here. So, it should be safe to always spell the token. */ + cpp_error (pfile, CPP_DL_ERROR, + "\"%s\" after # is not a positive integer", + cpp_token_as_text (pfile, token)); + return; + } + + token = cpp_get_token (pfile); + if (token->type == CPP_STRING) + { + cpp_string s = { 0, 0 }; + if (cpp_interpret_string_notranslate (pfile, &token->val.str, + 1, &s, CPP_STRING)) + new_file = (const char *)s.text; + + new_sysp = 0; + flag = read_flag (pfile, 0); + if (flag == 1) + { + reason = LC_ENTER; + /* Fake an include for cpp_included (). */ + _cpp_fake_include (pfile, new_file); + flag = read_flag (pfile, flag); + } + else if (flag == 2) + { + reason = LC_LEAVE; + flag = read_flag (pfile, flag); + } + if (flag == 3) + { + new_sysp = 1; + flag = read_flag (pfile, flag); + if (flag == 4) + new_sysp = 2; + } + pfile->buffer->sysp = new_sysp; + + check_eol (pfile, false); + } + else if (token->type != CPP_EOF) + { + cpp_error (pfile, CPP_DL_ERROR, "\"%s\" is not a valid filename", + cpp_token_as_text (pfile, token)); + return; + } + + skip_rest_of_line (pfile); + + /* Compensate for the increment in linemap_add that occurs in + _cpp_do_file_change. We're currently at the start of the line + *following* the #line directive. A separate source_location for this + location makes no sense (until we do the LC_LEAVE), and + complicates LAST_SOURCE_LINE_LOCATION. */ + pfile->line_table->highest_location--; + + _cpp_do_file_change (pfile, reason, new_file, new_lineno, new_sysp); +} + +/* Arrange the file_change callback. pfile->line has changed to + FILE_LINE of TO_FILE, for reason REASON. SYSP is 1 for a system + header, 2 for a system header that needs to be extern "C" protected, + and zero otherwise. */ +void +_cpp_do_file_change (cpp_reader *pfile, enum lc_reason reason, + const char *to_file, linenum_type file_line, + unsigned int sysp) +{ + const struct line_map *map = linemap_add (pfile->line_table, reason, sysp, + to_file, file_line); + if (map != NULL) + linemap_line_start (pfile->line_table, map->to_line, 127); + + if (pfile->cb.file_change) + pfile->cb.file_change (pfile, map); +} + +/* 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 (cpp_reader *pfile, int code, int reason, int print_dir) +{ + const unsigned char *dir_name; + unsigned char *line; + source_location src_loc = pfile->cur_token[-1].src_loc; + + if (print_dir) + dir_name = pfile->directive->name; + else + dir_name = NULL; + pfile->state.prevent_expansion++; + line = cpp_output_line_to_string (pfile, dir_name); + pfile->state.prevent_expansion--; + + if (code == CPP_DL_WARNING_SYSHDR && reason) + cpp_warning_with_line_syshdr (pfile, reason, src_loc, 0, "%s", line); + else if (code == CPP_DL_WARNING && reason) + cpp_warning_with_line (pfile, reason, src_loc, 0, "%s", line); + else + cpp_error_with_line (pfile, code, src_loc, 0, "%s", line); + free (line); +} + +static void +do_error (cpp_reader *pfile) +{ + do_diagnostic (pfile, CPP_DL_ERROR, 0, 1); +} + +static void +do_warning (cpp_reader *pfile) +{ + /* We want #warning diagnostics to be emitted in system headers too. */ + do_diagnostic (pfile, CPP_DL_WARNING_SYSHDR, CPP_W_WARNING_DIRECTIVE, 1); +} + +/* Report program identification. */ +static void +do_ident (cpp_reader *pfile) +{ + const cpp_token *str = cpp_get_token (pfile); + + if (str->type != CPP_STRING) + cpp_error (pfile, CPP_DL_ERROR, "invalid #%s directive", + pfile->directive->name); + else if (pfile->cb.ident) + pfile->cb.ident (pfile, pfile->directive_line, &str->val.str); + + check_eol (pfile, false); +} + +/* Lookup a PRAGMA name in a singly-linked CHAIN. Returns the + matching entry, or NULL if none is found. The returned entry could + be the start of a namespace chain, or a pragma. */ +static struct pragma_entry * +lookup_pragma_entry (struct pragma_entry *chain, const cpp_hashnode *pragma) +{ + while (chain && chain->pragma != pragma) + chain = chain->next; + + return chain; +} + +/* Create and insert a blank pragma entry at the beginning of a + singly-linked CHAIN. */ +static struct pragma_entry * +new_pragma_entry (cpp_reader *pfile, struct pragma_entry **chain) +{ + struct pragma_entry *new_entry; + + new_entry = (struct pragma_entry *) + _cpp_aligned_alloc (pfile, sizeof (struct pragma_entry)); + + memset (new_entry, 0, sizeof (struct pragma_entry)); + new_entry->next = *chain; + + *chain = new_entry; + return new_entry; +} + +/* Register a pragma NAME in namespace SPACE. If SPACE is null, it + goes in the global namespace. */ +static struct pragma_entry * +register_pragma_1 (cpp_reader *pfile, const char *space, const char *name, + bool allow_name_expansion) +{ + struct pragma_entry **chain = &pfile->pragmas; + struct pragma_entry *entry; + const cpp_hashnode *node; + + if (space) + { + node = cpp_lookup (pfile, UC space, strlen (space)); + entry = lookup_pragma_entry (*chain, node); + if (!entry) + { + entry = new_pragma_entry (pfile, chain); + entry->pragma = node; + entry->is_nspace = true; + entry->allow_expansion = allow_name_expansion; + } + else if (!entry->is_nspace) + goto clash; + else if (entry->allow_expansion != allow_name_expansion) + { + cpp_error (pfile, CPP_DL_ICE, + "registering pragmas in namespace \"%s\" with mismatched " + "name expansion", space); + return NULL; + } + chain = &entry->u.space; + } + else if (allow_name_expansion) + { + cpp_error (pfile, CPP_DL_ICE, + "registering pragma \"%s\" with name expansion " + "and no namespace", name); + return NULL; + } + + /* Check for duplicates. */ + node = cpp_lookup (pfile, UC name, strlen (name)); + entry = lookup_pragma_entry (*chain, node); + if (entry == NULL) + { + entry = new_pragma_entry (pfile, chain); + entry->pragma = node; + return entry; + } + + if (entry->is_nspace) + clash: + cpp_error (pfile, CPP_DL_ICE, + "registering \"%s\" as both a pragma and a pragma namespace", + NODE_NAME (node)); + else if (space) + cpp_error (pfile, CPP_DL_ICE, "#pragma %s %s is already registered", + space, name); + else + cpp_error (pfile, CPP_DL_ICE, "#pragma %s is already registered", name); + + return NULL; +} + +/* Register a cpplib internal pragma SPACE NAME with HANDLER. */ +static void +register_pragma_internal (cpp_reader *pfile, const char *space, + const char *name, pragma_cb handler) +{ + struct pragma_entry *entry; + + entry = register_pragma_1 (pfile, space, name, false); + entry->is_internal = true; + entry->u.handler = handler; +} + +/* Register a pragma NAME in namespace SPACE. If SPACE is null, it + goes in the global namespace. HANDLER is the handler it will call, + which must be non-NULL. If ALLOW_EXPANSION is set, allow macro + expansion while parsing pragma NAME. This function is exported + from libcpp. */ +void +cpp_register_pragma (cpp_reader *pfile, const char *space, const char *name, + pragma_cb handler, bool allow_expansion) +{ + struct pragma_entry *entry; + + if (!handler) + { + cpp_error (pfile, CPP_DL_ICE, "registering pragma with NULL handler"); + return; + } + + entry = register_pragma_1 (pfile, space, name, false); + if (entry) + { + entry->allow_expansion = allow_expansion; + entry->u.handler = handler; + } +} + +/* Similarly, but create mark the pragma for deferred processing. + When found, a CPP_PRAGMA token will be insertted into the stream + with IDENT in the token->u.pragma slot. */ +void +cpp_register_deferred_pragma (cpp_reader *pfile, const char *space, + const char *name, unsigned int ident, + bool allow_expansion, bool allow_name_expansion) +{ + struct pragma_entry *entry; + + entry = register_pragma_1 (pfile, space, name, allow_name_expansion); + if (entry) + { + entry->is_deferred = true; + entry->allow_expansion = allow_expansion; + entry->u.ident = ident; + } +} + +/* Register the pragmas the preprocessor itself handles. */ +void +_cpp_init_internal_pragmas (cpp_reader *pfile) +{ + /* Pragmas in the global namespace. */ + register_pragma_internal (pfile, 0, "once", do_pragma_once); + register_pragma_internal (pfile, 0, "push_macro", do_pragma_push_macro); + register_pragma_internal (pfile, 0, "pop_macro", do_pragma_pop_macro); + + /* New GCC-specific pragmas should be put in the GCC namespace. */ + register_pragma_internal (pfile, "GCC", "poison", do_pragma_poison); + register_pragma_internal (pfile, "GCC", "system_header", + do_pragma_system_header); + register_pragma_internal (pfile, "GCC", "dependency", do_pragma_dependency); +} + +/* Return the number of registered pragmas in PE. */ + +static int +count_registered_pragmas (struct pragma_entry *pe) +{ + int ct = 0; + for (; pe != NULL; pe = pe->next) + { + if (pe->is_nspace) + ct += count_registered_pragmas (pe->u.space); + ct++; + } + return ct; +} + +/* Save into SD the names of the registered pragmas referenced by PE, + and return a pointer to the next free space in SD. */ + +static char ** +save_registered_pragmas (struct pragma_entry *pe, char **sd) +{ + for (; pe != NULL; pe = pe->next) + { + if (pe->is_nspace) + sd = save_registered_pragmas (pe->u.space, sd); + *sd++ = (char *) xmemdup (HT_STR (&pe->pragma->ident), + HT_LEN (&pe->pragma->ident), + HT_LEN (&pe->pragma->ident) + 1); + } + return sd; +} + +/* Return a newly-allocated array which saves the names of the + registered pragmas. */ + +char ** +_cpp_save_pragma_names (cpp_reader *pfile) +{ + int ct = count_registered_pragmas (pfile->pragmas); + char **result = XNEWVEC (char *, ct); + (void) save_registered_pragmas (pfile->pragmas, result); + return result; +} + +/* Restore from SD the names of the registered pragmas referenced by PE, + and return a pointer to the next unused name in SD. */ + +static char ** +restore_registered_pragmas (cpp_reader *pfile, struct pragma_entry *pe, + char **sd) +{ + for (; pe != NULL; pe = pe->next) + { + if (pe->is_nspace) + sd = restore_registered_pragmas (pfile, pe->u.space, sd); + pe->pragma = cpp_lookup (pfile, UC *sd, strlen (*sd)); + free (*sd); + sd++; + } + return sd; +} + +/* Restore the names of the registered pragmas from SAVED. */ + +void +_cpp_restore_pragma_names (cpp_reader *pfile, char **saved) +{ + (void) restore_registered_pragmas (pfile, pfile->pragmas, saved); + free (saved); +} + +/* Pragmata handling. We handle some, 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 allows for a mix of both, since GCC did not + traditionally macro expand its (few) pragmas, whereas OpenMP + specifies that macro expansion should happen. */ +static void +do_pragma (cpp_reader *pfile) +{ + const struct pragma_entry *p = NULL; + const cpp_token *token, *pragma_token = pfile->cur_token; + cpp_token ns_token; + unsigned int count = 1; + + pfile->state.prevent_expansion++; + + token = cpp_get_token (pfile); + ns_token = *token; + if (token->type == CPP_NAME) + { + p = lookup_pragma_entry (pfile->pragmas, token->val.node.node); + if (p && p->is_nspace) + { + bool allow_name_expansion = p->allow_expansion; + if (allow_name_expansion) + pfile->state.prevent_expansion--; + token = cpp_get_token (pfile); + if (token->type == CPP_NAME) + p = lookup_pragma_entry (p->u.space, token->val.node.node); + else + p = NULL; + if (allow_name_expansion) + pfile->state.prevent_expansion++; + count = 2; + } + } + + if (p) + { + if (p->is_deferred) + { + pfile->directive_result.src_loc = pragma_token->src_loc; + pfile->directive_result.type = CPP_PRAGMA; + pfile->directive_result.flags = pragma_token->flags; + pfile->directive_result.val.pragma = p->u.ident; + pfile->state.in_deferred_pragma = true; + pfile->state.pragma_allow_expansion = p->allow_expansion; + if (!p->allow_expansion) + pfile->state.prevent_expansion++; + } + else + { + /* Since the handler below doesn't get the line number, that + it might need for diagnostics, make sure it has the right + numbers in place. */ + if (pfile->cb.line_change) + (*pfile->cb.line_change) (pfile, pragma_token, false); + if (p->allow_expansion) + pfile->state.prevent_expansion--; + (*p->u.handler) (pfile); + if (p->allow_expansion) + pfile->state.prevent_expansion++; + } + } + else if (pfile->cb.def_pragma) + { + if (count == 1 || pfile->context->prev == NULL) + _cpp_backup_tokens (pfile, count); + else + { + /* Invalid name comes from macro expansion, _cpp_backup_tokens + won't allow backing 2 tokens. */ + /* ??? The token buffer is leaked. Perhaps if def_pragma hook + reads both tokens, we could perhaps free it, but if it doesn't, + we don't know the exact lifespan. */ + cpp_token *toks = XNEWVEC (cpp_token, 2); + toks[0] = ns_token; + toks[0].flags |= NO_EXPAND; + toks[1] = *token; + toks[1].flags |= NO_EXPAND; + _cpp_push_token_context (pfile, NULL, toks, 2); + } + pfile->cb.def_pragma (pfile, pfile->directive_line); + } + + pfile->state.prevent_expansion--; +} + +/* Handle #pragma once. */ +static void +do_pragma_once (cpp_reader *pfile) +{ + if (cpp_in_primary_file (pfile)) + cpp_error (pfile, CPP_DL_WARNING, "#pragma once in main file"); + + check_eol (pfile, false); + _cpp_mark_file_once_only (pfile, pfile->buffer->file); +} + +/* Handle #pragma push_macro(STRING). */ +static void +do_pragma_push_macro (cpp_reader *pfile) +{ + cpp_hashnode *node; + size_t defnlen; + const uchar *defn = NULL; + char *macroname, *dest; + const char *limit, *src; + const cpp_token *txt; + struct def_pragma_macro *c; + + txt = get__Pragma_string (pfile); + if (!txt) + { + source_location src_loc = pfile->cur_token[-1].src_loc; + cpp_error_with_line (pfile, CPP_DL_ERROR, src_loc, 0, + "invalid #pragma push_macro directive"); + check_eol (pfile, false); + skip_rest_of_line (pfile); + return; + } + dest = macroname = (char *) alloca (txt->val.str.len + 2); + src = (const char *) (txt->val.str.text + 1 + (txt->val.str.text[0] == 'L')); + limit = (const char *) (txt->val.str.text + txt->val.str.len - 1); + while (src < limit) + { + /* We know there is a character following the backslash. */ + if (*src == '\\' && (src[1] == '\\' || src[1] == '"')) + src++; + *dest++ = *src++; + } + *dest = 0; + check_eol (pfile, false); + skip_rest_of_line (pfile); + c = XNEW (struct def_pragma_macro); + memset (c, 0, sizeof (struct def_pragma_macro)); + c->name = XNEWVAR (char, strlen (macroname) + 1); + strcpy (c->name, macroname); + c->next = pfile->pushed_macros; + node = _cpp_lex_identifier (pfile, c->name); + if (node->type == NT_VOID) + c->is_undef = 1; + else + { + defn = cpp_macro_definition (pfile, node); + defnlen = ustrlen (defn); + c->definition = XNEWVEC (uchar, defnlen + 2); + c->definition[defnlen] = '\n'; + c->definition[defnlen + 1] = 0; + c->line = node->value.macro->line; + c->syshdr = node->value.macro->syshdr; + c->used = node->value.macro->used; + memcpy (c->definition, defn, defnlen); + } + + pfile->pushed_macros = c; +} + +/* Handle #pragma pop_macro(STRING). */ +static void +do_pragma_pop_macro (cpp_reader *pfile) +{ + char *macroname, *dest; + const char *limit, *src; + const cpp_token *txt; + struct def_pragma_macro *l = NULL, *c = pfile->pushed_macros; + txt = get__Pragma_string (pfile); + if (!txt) + { + source_location src_loc = pfile->cur_token[-1].src_loc; + cpp_error_with_line (pfile, CPP_DL_ERROR, src_loc, 0, + "invalid #pragma pop_macro directive"); + check_eol (pfile, false); + skip_rest_of_line (pfile); + return; + } + dest = macroname = (char *) alloca (txt->val.str.len + 2); + src = (const char *) (txt->val.str.text + 1 + (txt->val.str.text[0] == 'L')); + limit = (const char *) (txt->val.str.text + txt->val.str.len - 1); + while (src < limit) + { + /* We know there is a character following the backslash. */ + if (*src == '\\' && (src[1] == '\\' || src[1] == '"')) + src++; + *dest++ = *src++; + } + *dest = 0; + check_eol (pfile, false); + skip_rest_of_line (pfile); + + while (c != NULL) + { + if (!strcmp (c->name, macroname)) + { + if (!l) + pfile->pushed_macros = c->next; + else + l->next = c->next; + cpp_pop_definition (pfile, c); + free (c->definition); + free (c->name); + free (c); + break; + } + l = c; + c = c->next; + } +} + +/* Handle #pragma GCC poison, to poison one or more identifiers so + that the lexer produces a hard error for each subsequent usage. */ +static void +do_pragma_poison (cpp_reader *pfile) +{ + const cpp_token *tok; + cpp_hashnode *hp; + + pfile->state.poisoned_ok = 1; + for (;;) + { + tok = _cpp_lex_token (pfile); + if (tok->type == CPP_EOF) + break; + if (tok->type != CPP_NAME) + { + cpp_error (pfile, CPP_DL_ERROR, + "invalid #pragma GCC poison directive"); + break; + } + + hp = tok->val.node.node; + if (hp->flags & NODE_POISONED) + continue; + + if (hp->type == NT_MACRO) + cpp_error (pfile, CPP_DL_WARNING, "poisoning existing macro \"%s\"", + NODE_NAME (hp)); + _cpp_free_definition (hp); + hp->flags |= NODE_POISONED | NODE_DIAGNOSTIC; + } + pfile->state.poisoned_ok = 0; +} + +/* 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 (cpp_reader *pfile) +{ + if (cpp_in_primary_file (pfile)) + cpp_error (pfile, CPP_DL_WARNING, + "#pragma system_header ignored outside include file"); + else + { + check_eol (pfile, false); + skip_rest_of_line (pfile); + cpp_make_system_header (pfile, 1, 0); + } +} + +/* 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 (cpp_reader *pfile) +{ + const char *fname; + int angle_brackets, ordering; + source_location location; + + fname = parse_include (pfile, &angle_brackets, NULL, &location); + if (!fname) + return; + + ordering = _cpp_compare_file_date (pfile, fname, angle_brackets); + if (ordering < 0) + cpp_error (pfile, CPP_DL_WARNING, "cannot find source file %s", fname); + else if (ordering > 0) + { + cpp_error (pfile, CPP_DL_WARNING, + "current file is older than %s", fname); + if (cpp_get_token (pfile)->type != CPP_EOF) + { + _cpp_backup_tokens (pfile, 1); + do_diagnostic (pfile, CPP_DL_WARNING, 0, 0); + } + } + + free ((void *) fname); +} + +/* Get a token but skip padding. */ +static const cpp_token * +get_token_no_padding (cpp_reader *pfile) +{ + for (;;) + { + const cpp_token *result = cpp_get_token (pfile); + if (result->type != CPP_PADDING) + return result; + } +} + +/* Check syntax is "(string-literal)". Returns the string on success, + or NULL on failure. */ +static const cpp_token * +get__Pragma_string (cpp_reader *pfile) +{ + const cpp_token *string; + const cpp_token *paren; + + paren = get_token_no_padding (pfile); + if (paren->type == CPP_EOF) + _cpp_backup_tokens (pfile, 1); + if (paren->type != CPP_OPEN_PAREN) + return NULL; + + string = get_token_no_padding (pfile); + if (string->type == CPP_EOF) + _cpp_backup_tokens (pfile, 1); + if (string->type != CPP_STRING && string->type != CPP_WSTRING + && string->type != CPP_STRING32 && string->type != CPP_STRING16 + && string->type != CPP_UTF8STRING) + return NULL; + + paren = get_token_no_padding (pfile); + if (paren->type == CPP_EOF) + _cpp_backup_tokens (pfile, 1); + if (paren->type != CPP_CLOSE_PAREN) + return NULL; + + return string; +} + +/* Destringize IN into a temporary buffer, by removing the first \ of + \" and \\ sequences, and process the result as a #pragma directive. */ +static void +destringize_and_run (cpp_reader *pfile, const cpp_string *in) +{ + const unsigned char *src, *limit; + char *dest, *result; + cpp_context *saved_context; + cpp_token *saved_cur_token; + tokenrun *saved_cur_run; + cpp_token *toks; + int count; + const struct directive *save_directive; + + dest = result = (char *) alloca (in->len - 1); + src = in->text + 1 + (in->text[0] == 'L'); + limit = in->text + in->len - 1; + while (src < limit) + { + /* We know there is a character following the backslash. */ + if (*src == '\\' && (src[1] == '\\' || src[1] == '"')) + src++; + *dest++ = *src++; + } + *dest = '\n'; + + /* Ugh; an awful kludge. We are really not set up to be lexing + tokens when in the middle of a macro expansion. Use a new + context to force cpp_get_token to lex, and so skip_rest_of_line + doesn't go beyond the end of the text. Also, remember the + current lexing position so we can return to it later. + + Something like line-at-a-time lexing should remove the need for + this. */ + saved_context = pfile->context; + saved_cur_token = pfile->cur_token; + saved_cur_run = pfile->cur_run; + + pfile->context = XNEW (cpp_context); + pfile->context->macro = 0; + pfile->context->prev = 0; + pfile->context->next = 0; + + /* Inline run_directive, since we need to delay the _cpp_pop_buffer + until we've read all of the tokens that we want. */ + cpp_push_buffer (pfile, (const uchar *) result, dest - result, + /* from_stage3 */ true); + /* ??? Antique Disgusting Hack. What does this do? */ + if (pfile->buffer->prev) + pfile->buffer->file = pfile->buffer->prev->file; + + start_directive (pfile); + _cpp_clean_line (pfile); + save_directive = pfile->directive; + pfile->directive = &dtable[T_PRAGMA]; + do_pragma (pfile); + end_directive (pfile, 1); + pfile->directive = save_directive; + + /* We always insert at least one token, the directive result. It'll + either be a CPP_PADDING or a CPP_PRAGMA. In the later case, we + need to insert *all* of the tokens, including the CPP_PRAGMA_EOL. */ + + /* If we're not handling the pragma internally, read all of the tokens from + the string buffer now, while the string buffer is still installed. */ + /* ??? Note that the token buffer allocated here is leaked. It's not clear + to me what the true lifespan of the tokens are. It would appear that + the lifespan is the entire parse of the main input stream, in which case + this may not be wrong. */ + if (pfile->directive_result.type == CPP_PRAGMA) + { + int maxcount; + + count = 1; + maxcount = 50; + toks = XNEWVEC (cpp_token, maxcount); + toks[0] = pfile->directive_result; + + do + { + if (count == maxcount) + { + maxcount = maxcount * 3 / 2; + toks = XRESIZEVEC (cpp_token, toks, maxcount); + } + toks[count] = *cpp_get_token (pfile); + /* Macros have been already expanded by cpp_get_token + if the pragma allowed expansion. */ + toks[count++].flags |= NO_EXPAND; + } + while (toks[count-1].type != CPP_PRAGMA_EOL); + } + else + { + count = 1; + toks = XNEW (cpp_token); + toks[0] = pfile->directive_result; + + /* If we handled the entire pragma internally, make sure we get the + line number correct for the next token. */ + if (pfile->cb.line_change) + pfile->cb.line_change (pfile, pfile->cur_token, false); + } + + /* Finish inlining run_directive. */ + pfile->buffer->file = NULL; + _cpp_pop_buffer (pfile); + + /* Reset the old macro state before ... */ + XDELETE (pfile->context); + pfile->context = saved_context; + pfile->cur_token = saved_cur_token; + pfile->cur_run = saved_cur_run; + + /* ... inserting the new tokens we collected. */ + _cpp_push_token_context (pfile, NULL, toks, count); +} + +/* Handle the _Pragma operator. Return 0 on error, 1 if ok. */ +int +_cpp_do__Pragma (cpp_reader *pfile) +{ + const cpp_token *string = get__Pragma_string (pfile); + pfile->directive_result.type = CPP_PADDING; + + if (string) + { + destringize_and_run (pfile, &string->val.str); + return 1; + } + cpp_error (pfile, CPP_DL_ERROR, + "_Pragma takes a parenthesized string literal"); + return 0; +} + +/* Handle #ifdef. */ +static void +do_ifdef (cpp_reader *pfile) +{ + int skip = 1; + + if (! pfile->state.skipping) + { + cpp_hashnode *node = lex_macro_node (pfile, false); + + if (node) + { + /* Do not treat conditional macros as being defined. This is due to + the powerpc and spu ports using conditional macros for 'vector', + 'bool', and 'pixel' to act as conditional keywords. This messes + up tests like #ifndef bool. */ + skip = (node->type != NT_MACRO + || ((node->flags & NODE_CONDITIONAL) != 0)); + _cpp_mark_macro_used (node); + if (!(node->flags & NODE_USED)) + { + node->flags |= NODE_USED; + if (node->type == NT_MACRO) + { + if ((node->flags & NODE_BUILTIN) + && pfile->cb.user_builtin_macro) + pfile->cb.user_builtin_macro (pfile, node); + if (pfile->cb.used_define) + pfile->cb.used_define (pfile, pfile->directive_line, node); + } + else + { + if (pfile->cb.used_undef) + pfile->cb.used_undef (pfile, pfile->directive_line, node); + } + } + if (pfile->cb.used) + pfile->cb.used (pfile, pfile->directive_line, node); + check_eol (pfile, false); + } + } + + push_conditional (pfile, skip, T_IFDEF, 0); +} + +/* Handle #ifndef. */ +static void +do_ifndef (cpp_reader *pfile) +{ + int skip = 1; + cpp_hashnode *node = 0; + + if (! pfile->state.skipping) + { + node = lex_macro_node (pfile, false); + + if (node) + { + /* Do not treat conditional macros as being defined. This is due to + the powerpc and spu ports using conditional macros for 'vector', + 'bool', and 'pixel' to act as conditional keywords. This messes + up tests like #ifndef bool. */ + skip = (node->type == NT_MACRO + && ((node->flags & NODE_CONDITIONAL) == 0)); + _cpp_mark_macro_used (node); + if (!(node->flags & NODE_USED)) + { + node->flags |= NODE_USED; + if (node->type == NT_MACRO) + { + if ((node->flags & NODE_BUILTIN) + && pfile->cb.user_builtin_macro) + pfile->cb.user_builtin_macro (pfile, node); + if (pfile->cb.used_define) + pfile->cb.used_define (pfile, pfile->directive_line, node); + } + else + { + if (pfile->cb.used_undef) + pfile->cb.used_undef (pfile, pfile->directive_line, node); + } + } + if (pfile->cb.used) + pfile->cb.used (pfile, pfile->directive_line, node); + check_eol (pfile, false); + } + } + + push_conditional (pfile, skip, T_IFNDEF, node); +} + +/* _cpp_parse_expr puts a macro in a "#if !defined ()" expression in + pfile->mi_ind_cmacro so we can handle multiple-include + optimizations. If macro expansion occurs in the expression, we + cannot treat it as a controlling conditional, since the expansion + could change in the future. That is handled by cpp_get_token. */ +static void +do_if (cpp_reader *pfile) +{ + int skip = 1; + + if (! pfile->state.skipping) + skip = _cpp_parse_expr (pfile, true) == false; + + push_conditional (pfile, skip, T_IF, pfile->mi_ind_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 (cpp_reader *pfile) +{ + cpp_buffer *buffer = pfile->buffer; + struct if_stack *ifs = buffer->if_stack; + + if (ifs == NULL) + cpp_error (pfile, CPP_DL_ERROR, "#else without #if"); + else + { + if (ifs->type == T_ELSE) + { + cpp_error (pfile, CPP_DL_ERROR, "#else after #else"); + cpp_error_with_line (pfile, CPP_DL_ERROR, ifs->line, 0, + "the conditional began here"); + } + ifs->type = T_ELSE; + + /* Skip any future (erroneous) #elses or #elifs. */ + pfile->state.skipping = ifs->skip_elses; + ifs->skip_elses = true; + + /* Invalidate any controlling macro. */ + ifs->mi_cmacro = 0; + + /* Only check EOL if was not originally skipping. */ + if (!ifs->was_skipping && CPP_OPTION (pfile, warn_endif_labels)) + check_eol (pfile, false); + } +} + +/* Handle a #elif directive by not changing if_stack either. See the + comment above do_else. */ +static void +do_elif (cpp_reader *pfile) +{ + cpp_buffer *buffer = pfile->buffer; + struct if_stack *ifs = buffer->if_stack; + + if (ifs == NULL) + cpp_error (pfile, CPP_DL_ERROR, "#elif without #if"); + else + { + if (ifs->type == T_ELSE) + { + cpp_error (pfile, CPP_DL_ERROR, "#elif after #else"); + cpp_error_with_line (pfile, CPP_DL_ERROR, ifs->line, 0, + "the conditional began here"); + } + ifs->type = T_ELIF; + + if (! ifs->was_skipping) + { + bool value; + /* The standard mandates that the expression be parsed even + if we are skipping elses at this point -- the lexical + restrictions on #elif only apply to skipped groups, but + this group is not being skipped. Temporarily set + skipping to false to get lexer warnings. */ + pfile->state.skipping = 0; + value = _cpp_parse_expr (pfile, false); + if (ifs->skip_elses) + pfile->state.skipping = 1; + else + { + pfile->state.skipping = ! value; + ifs->skip_elses = value; + } + } + + /* Invalidate any controlling macro. */ + ifs->mi_cmacro = 0; + } +} + +/* #endif pops the if stack and resets pfile->state.skipping. */ +static void +do_endif (cpp_reader *pfile) +{ + cpp_buffer *buffer = pfile->buffer; + struct if_stack *ifs = buffer->if_stack; + + if (ifs == NULL) + cpp_error (pfile, CPP_DL_ERROR, "#endif without #if"); + else + { + /* Only check EOL if was not originally skipping. */ + if (!ifs->was_skipping && CPP_OPTION (pfile, warn_endif_labels)) + check_eol (pfile, false); + + /* If potential control macro, we go back outside again. */ + if (ifs->next == 0 && ifs->mi_cmacro) + { + pfile->mi_valid = true; + pfile->mi_cmacro = ifs->mi_cmacro; + } + + buffer->if_stack = ifs->next; + pfile->state.skipping = ifs->was_skipping; + obstack_free (&pfile->buffer_ob, ifs); + } +} + +/* Push an if_stack entry for a preprocessor conditional, and set + pfile->state.skipping to SKIP. If TYPE indicates the conditional + is #if or #ifndef, CMACRO is a potentially controlling macro, and + we need to check here that we are at the top of the file. */ +static void +push_conditional (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->line = pfile->directive_line; + ifs->next = buffer->if_stack; + ifs->skip_elses = pfile->state.skipping || !skip; + ifs->was_skipping = pfile->state.skipping; + ifs->type = type; + /* This condition is effectively a test for top-of-file. */ + if (pfile->mi_valid && pfile->mi_cmacro == 0) + ifs->mi_cmacro = cmacro; + else + ifs->mi_cmacro = 0; + + pfile->state.skipping = skip; + buffer->if_stack = ifs; +} + +/* Read the tokens of the answer into the macro pool, in a directive + of type TYPE. Only commit the memory if we intend it as permanent + storage, i.e. the #assert case. Returns 0 on success, and sets + ANSWERP to point to the answer. PRED_LOC is the location of the + predicate. */ +static int +parse_answer (cpp_reader *pfile, struct answer **answerp, int type, + source_location pred_loc) +{ + const cpp_token *paren; + struct answer *answer; + unsigned int acount; + + /* In a conditional, it is legal to not have an open paren. We + should save the following token in this case. */ + paren = cpp_get_token (pfile); + + /* 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) + { + _cpp_backup_tokens (pfile, 1); + return 0; + } + + /* #unassert with no answer is valid - it removes all answers. */ + if (type == T_UNASSERT && paren->type == CPP_EOF) + return 0; + + cpp_error_with_line (pfile, CPP_DL_ERROR, pred_loc, 0, + "missing '(' after predicate"); + return 1; + } + + for (acount = 0;; acount++) + { + size_t room_needed; + const cpp_token *token = cpp_get_token (pfile); + cpp_token *dest; + + if (token->type == CPP_CLOSE_PAREN) + break; + + if (token->type == CPP_EOF) + { + cpp_error (pfile, CPP_DL_ERROR, "missing ')' to complete answer"); + return 1; + } + + /* struct answer includes the space for one token. */ + room_needed = (sizeof (struct answer) + acount * sizeof (cpp_token)); + + if (BUFF_ROOM (pfile->a_buff) < room_needed) + _cpp_extend_buff (pfile, &pfile->a_buff, sizeof (struct answer)); + + dest = &((struct answer *) BUFF_FRONT (pfile->a_buff))->first[acount]; + *dest = *token; + + /* Drop whitespace at start, for answer equivalence purposes. */ + if (acount == 0) + dest->flags &= ~PREV_WHITE; + } + + if (acount == 0) + { + cpp_error (pfile, CPP_DL_ERROR, "predicate's answer is empty"); + return 1; + } + + answer = (struct answer *) BUFF_FRONT (pfile->a_buff); + answer->count = acount; + answer->next = NULL; + *answerp = answer; + + return 0; +} + +/* Parses an assertion directive of type TYPE, 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 (cpp_reader *pfile, struct answer **answerp, int type) +{ + cpp_hashnode *result = 0; + const cpp_token *predicate; + + /* We don't expand predicates or answers. */ + pfile->state.prevent_expansion++; + + *answerp = 0; + predicate = cpp_get_token (pfile); + if (predicate->type == CPP_EOF) + cpp_error (pfile, CPP_DL_ERROR, "assertion without predicate"); + else if (predicate->type != CPP_NAME) + cpp_error_with_line (pfile, CPP_DL_ERROR, predicate->src_loc, 0, + "predicate must be an identifier"); + else if (parse_answer (pfile, answerp, type, predicate->src_loc) == 0) + { + unsigned int len = NODE_LEN (predicate->val.node.node); + unsigned char *sym = (unsigned char *) alloca (len + 1); + + /* Prefix '#' to get it out of macro namespace. */ + sym[0] = '#'; + memcpy (sym + 1, NODE_NAME (predicate->val.node.node), len); + result = cpp_lookup (pfile, sym, len + 1); + } + + pfile->state.prevent_expansion--; + return result; +} + +/* Returns a pointer to the pointer to CANDIDATE in the answer chain, + or a pointer to NULL if the answer is not in the chain. */ +static struct answer ** +find_answer (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 + nonzero on failure, zero on success. On success, the result of + the test is written into VALUE, otherwise the value 0. */ +int +_cpp_test_assertion (cpp_reader *pfile, unsigned int *value) +{ + struct answer *answer; + cpp_hashnode *node; + + node = parse_assertion (pfile, &answer, T_IF); + + /* For recovery, an erroneous assertion expression is handled as a + failing assertion. */ + *value = 0; + + if (node) + *value = (node->type == NT_ASSERTION && + (answer == 0 || *find_answer (node, answer) != 0)); + else if (pfile->cur_token[-1].type == CPP_EOF) + _cpp_backup_tokens (pfile, 1); + + /* We don't commit the memory for the answer - it's temporary only. */ + return node == 0; +} + +/* Handle #assert. */ +static void +do_assert (cpp_reader *pfile) +{ + struct answer *new_answer; + cpp_hashnode *node; + + node = parse_assertion (pfile, &new_answer, T_ASSERT); + if (node) + { + size_t answer_size; + + /* 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_error (pfile, CPP_DL_WARNING, "\"%s\" re-asserted", + NODE_NAME (node) + 1); + return; + } + new_answer->next = node->value.answers; + } + + answer_size = sizeof (struct answer) + ((new_answer->count - 1) + * sizeof (cpp_token)); + /* Commit or allocate storage for the object. */ + if (pfile->hash_table->alloc_subobject) + { + struct answer *temp_answer = new_answer; + new_answer = (struct answer *) pfile->hash_table->alloc_subobject + (answer_size); + memcpy (new_answer, temp_answer, answer_size); + } + else + BUFF_FRONT (pfile->a_buff) += answer_size; + + node->type = NT_ASSERTION; + node->value.answers = new_answer; + check_eol (pfile, false); + } +} + +/* Handle #unassert. */ +static void +do_unassert (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; + + check_eol (pfile, false); + } + 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 (cpp_reader *pfile, const char *str) +{ + char *buf; + const char *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. */ + + count = strlen (str); + buf = (char *) alloca (count + 3); + memcpy (buf, str, count); + + p = strchr (str, '='); + if (p) + buf[p - str] = ' '; + else + { + buf[count++] = ' '; + buf[count++] = '1'; + } + buf[count] = '\n'; + + run_directive (pfile, T_DEFINE, buf, count); +} + + +/* Use to build macros to be run through cpp_define() as + described above. + Example: cpp_define_formatted (pfile, "MACRO=%d", value); */ + +void +cpp_define_formatted (cpp_reader *pfile, const char *fmt, ...) +{ + char *ptr = NULL; + + va_list ap; + va_start (ap, fmt); + vasprintf (&ptr, fmt, ap); + va_end (ap); + + cpp_define (pfile, ptr); + free (ptr); +} + + +/* Slight variant of the above for use by initialize_builtins. */ +void +_cpp_define_builtin (cpp_reader *pfile, const char *str) +{ + size_t len = strlen (str); + char *buf = (char *) alloca (len + 1); + memcpy (buf, str, len); + buf[len] = '\n'; + run_directive (pfile, T_DEFINE, buf, len); +} + +/* Process MACRO as if it appeared as the body of an #undef. */ +void +cpp_undef (cpp_reader *pfile, const char *macro) +{ + size_t len = strlen (macro); + char *buf = (char *) alloca (len + 1); + memcpy (buf, macro, len); + buf[len] = '\n'; + run_directive (pfile, T_UNDEF, buf, len); +} + +/* Replace a previous definition DEF of the macro STR. If DEF is NULL, + or first element is zero, then the macro should be undefined. */ +static void +cpp_pop_definition (cpp_reader *pfile, struct def_pragma_macro *c) +{ + cpp_hashnode *node = _cpp_lex_identifier (pfile, c->name); + if (node == NULL) + return; + + if (pfile->cb.before_define) + pfile->cb.before_define (pfile); + + if (node->type == NT_MACRO) + { + if (pfile->cb.undef) + pfile->cb.undef (pfile, pfile->directive_line, node); + if (CPP_OPTION (pfile, warn_unused_macros)) + _cpp_warn_if_unused_macro (pfile, node, NULL); + } + if (node->type != NT_VOID) + _cpp_free_definition (node); + + if (c->is_undef) + return; + { + size_t namelen; + const uchar *dn; + cpp_hashnode *h = NULL; + cpp_buffer *nbuf; + + namelen = ustrcspn (c->definition, "( \n"); + h = cpp_lookup (pfile, c->definition, namelen); + dn = c->definition + namelen; + + h->type = NT_VOID; + h->flags &= ~(NODE_POISONED|NODE_BUILTIN|NODE_DISABLED|NODE_USED); + nbuf = cpp_push_buffer (pfile, dn, ustrchr (dn, '\n') - dn, true); + if (nbuf != NULL) + { + _cpp_clean_line (pfile); + nbuf->sysp = 1; + if (!_cpp_create_definition (pfile, h)) + abort (); + _cpp_pop_buffer (pfile); + } + else + abort (); + h->value.macro->line = c->line; + h->value.macro->syshdr = c->syshdr; + h->value.macro->used = c->used; + } +} + +/* Process the string STR as if it appeared as the body of a #assert. */ +void +cpp_assert (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 (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 (cpp_reader *pfile, const char *str, int type) +{ + size_t count = strlen (str); + const char *p = strchr (str, '='); + + /* 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 + 2); + + memcpy (buf, str, count); + if (p) + { + buf[p - str] = '('; + buf[count++] = ')'; + } + buf[count] = '\n'; + str = buf; + + run_directive (pfile, type, str, count); +} + +/* The options structure. */ +cpp_options * +cpp_get_options (cpp_reader *pfile) +{ + return &pfile->opts; +} + +/* The callbacks structure. */ +cpp_callbacks * +cpp_get_callbacks (cpp_reader *pfile) +{ + return &pfile->cb; +} + +/* Copy the given callbacks structure to our own. */ +void +cpp_set_callbacks (cpp_reader *pfile, cpp_callbacks *cb) +{ + pfile->cb = *cb; +} + +/* The dependencies structure. (Creates one if it hasn't already been.) */ +struct deps * +cpp_get_deps (cpp_reader *pfile) +{ + if (!pfile->deps) + pfile->deps = deps_init (); + return pfile->deps; +} + +/* 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 (cpp_reader *pfile, const uchar *buffer, size_t len, + int from_stage3) +{ + cpp_buffer *new_buffer = XOBNEW (&pfile->buffer_ob, cpp_buffer); + + /* Clears, amongst other things, if_stack and mi_cmacro. */ + memset (new_buffer, 0, sizeof (cpp_buffer)); + + new_buffer->next_line = new_buffer->buf = buffer; + new_buffer->rlimit = buffer + len; + new_buffer->from_stage3 = from_stage3; + new_buffer->prev = pfile->buffer; + new_buffer->need_line = true; + + pfile->buffer = new_buffer; + + return new_buffer; +} + +/* Pops a single buffer, with a file change call-back if appropriate. + Then pushes the next -include file, if any remain. */ +void +_cpp_pop_buffer (cpp_reader *pfile) +{ + cpp_buffer *buffer = pfile->buffer; + struct _cpp_file *inc = buffer->file; + struct if_stack *ifs; + + /* 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, CPP_DL_ERROR, ifs->line, 0, + "unterminated #%s", dtable[ifs->type].name); + + /* In case of a missing #endif. */ + pfile->state.skipping = 0; + + /* _cpp_do_file_change expects pfile->buffer to be the new one. */ + pfile->buffer = buffer->prev; + + free (buffer->notes); + + /* Free the buffer object now; we may want to push a new buffer + in _cpp_push_next_include_file. */ + obstack_free (&pfile->buffer_ob, buffer); + + if (inc) + { + _cpp_pop_file_buffer (pfile, inc); + + _cpp_do_file_change (pfile, LC_LEAVE, 0, 0, 0); + } +} + +/* Enter all recognized directives in the hash table. */ +void +_cpp_init_directives (cpp_reader *pfile) +{ + unsigned int i; + cpp_hashnode *node; + + for (i = 0; i < (unsigned int) N_DIRECTIVES; i++) + { + node = cpp_lookup (pfile, dtable[i].name, dtable[i].length); + node->is_directive = 1; + node->directive_index = i; + } +} diff --git a/support/cpp/libcpp/errors.c b/support/cpp/libcpp/errors.c new file mode 100644 index 0000000..c586749 --- /dev/null +++ b/support/cpp/libcpp/errors.c @@ -0,0 +1,238 @@ +/* Default error handlers for CPP Library. + Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1998, 1999, 2000, + 2001, 2002, 2004, 2008, 2009, 2010 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 3, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. + + 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 "internal.h" + +/* Print a diagnostic at the location of the previously lexed token. */ + +ATTRIBUTE_FPTR_PRINTF(4,0) +static bool +cpp_diagnostic (cpp_reader * pfile, int level, int reason, + const char *msgid, va_list *ap) +{ + source_location src_loc; + bool ret; + + if (CPP_OPTION (pfile, traditional)) + { + if (pfile->state.in_directive) + src_loc = pfile->directive_line; + else + src_loc = pfile->line_table->highest_line; + } + /* We don't want to refer to a token before the beginning of the + current run -- that is invalid. */ + else if (pfile->cur_token == pfile->cur_run->base) + { + if (pfile->cur_run->prev != NULL) + src_loc = pfile->cur_run->prev->limit->src_loc; + else + src_loc = 0; + } + else + { + src_loc = pfile->cur_token[-1].src_loc; + } + + if (!pfile->cb.error) + abort (); + ret = pfile->cb.error (pfile, level, reason, src_loc, 0, _(msgid), ap); + + return ret; +} + +/* Print a warning or error, depending on the value of LEVEL. */ + +bool +cpp_error (cpp_reader * pfile, int level, const char *msgid, ...) +{ + va_list ap; + bool ret; + + va_start (ap, msgid); + + ret = cpp_diagnostic (pfile, level, CPP_W_NONE, msgid, &ap); + + va_end (ap); + return ret; +} + +/* Print a warning. The warning reason may be given in REASON. */ + +bool +cpp_warning (cpp_reader * pfile, int reason, const char *msgid, ...) +{ + va_list ap; + bool ret; + + va_start (ap, msgid); + + ret = cpp_diagnostic (pfile, CPP_DL_WARNING, reason, msgid, &ap); + + va_end (ap); + return ret; +} + +/* Print a pedantic warning. The warning reason may be given in REASON. */ + +bool +cpp_pedwarning (cpp_reader * pfile, int reason, const char *msgid, ...) +{ + va_list ap; + bool ret; + + va_start (ap, msgid); + + ret = cpp_diagnostic (pfile, CPP_DL_PEDWARN, reason, msgid, &ap); + + va_end (ap); + return ret; +} + +/* Print a warning, including system headers. The warning reason may be + given in REASON. */ + +bool +cpp_warning_syshdr (cpp_reader * pfile, int reason, const char *msgid, ...) +{ + va_list ap; + bool ret; + + va_start (ap, msgid); + + ret = cpp_diagnostic (pfile, CPP_DL_WARNING_SYSHDR, reason, msgid, &ap); + + va_end (ap); + return ret; +} + +/* Print a diagnostic at a specific location. */ + +ATTRIBUTE_FPTR_PRINTF(6,0) +static bool +cpp_diagnostic_with_line (cpp_reader * pfile, int level, int reason, + source_location src_loc, unsigned int column, + const char *msgid, va_list *ap) +{ + bool ret; + + if (!pfile->cb.error) + abort (); + ret = pfile->cb.error (pfile, level, reason, src_loc, column, _(msgid), ap); + + return ret; +} + +/* Print a warning or error, depending on the value of LEVEL. */ + +bool +cpp_error_with_line (cpp_reader *pfile, int level, + source_location src_loc, unsigned int column, + const char *msgid, ...) +{ + va_list ap; + bool ret; + + va_start (ap, msgid); + + ret = cpp_diagnostic_with_line (pfile, level, CPP_W_NONE, src_loc, + column, msgid, &ap); + + va_end (ap); + return ret; +} + +/* Print a warning. The warning reason may be given in REASON. */ + +bool +cpp_warning_with_line (cpp_reader *pfile, int reason, + source_location src_loc, unsigned int column, + const char *msgid, ...) +{ + va_list ap; + bool ret; + + va_start (ap, msgid); + + ret = cpp_diagnostic_with_line (pfile, CPP_DL_WARNING, reason, src_loc, + column, msgid, &ap); + + va_end (ap); + return ret; +} + +/* Print a pedantic warning. The warning reason may be given in REASON. */ + +bool +cpp_pedwarning_with_line (cpp_reader *pfile, int reason, + source_location src_loc, unsigned int column, + const char *msgid, ...) +{ + va_list ap; + bool ret; + + va_start (ap, msgid); + + ret = cpp_diagnostic_with_line (pfile, CPP_DL_PEDWARN, reason, src_loc, + column, msgid, &ap); + + va_end (ap); + return ret; +} + +/* Print a warning, including system headers. The warning reason may be + given in REASON. */ + +bool +cpp_warning_with_line_syshdr (cpp_reader *pfile, int reason, + source_location src_loc, unsigned int column, + const char *msgid, ...) +{ + va_list ap; + bool ret; + + va_start (ap, msgid); + + ret = cpp_diagnostic_with_line (pfile, CPP_DL_WARNING_SYSHDR, reason, src_loc, + column, msgid, &ap); + + va_end (ap); + return ret; +} + +/* Print a warning or error, depending on the value of LEVEL. Include + information from errno. */ + +bool +cpp_errno (cpp_reader *pfile, int level, const char *msgid) +{ + if (msgid[0] == '\0') + msgid = _("stdout"); + + return cpp_error (pfile, level, "%s: %s", msgid, xstrerror (errno)); +} diff --git a/support/cpp/libcpp/expr.c b/support/cpp/libcpp/expr.c new file mode 100644 index 0000000..d9bae17 --- /dev/null +++ b/support/cpp/libcpp/expr.c @@ -0,0 +1,1793 @@ +/* Parse C expressions for cpplib. + Copyright (C) 1987, 1992, 1994, 1995, 1997, 1998, 1999, 2000, 2001, + 2002, 2004, 2008, 2009, 2010 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 3, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "cpplib.h" +#include "internal.h" + +#define PART_PRECISION (sizeof (cpp_num_part) * CHAR_BIT) +#define HALF_MASK (~(cpp_num_part) 0 >> (PART_PRECISION / 2)) +#define LOW_PART(num_part) (num_part & HALF_MASK) +#define HIGH_PART(num_part) (num_part >> (PART_PRECISION / 2)) + +struct op +{ + const cpp_token *token; /* The token forming op (for diagnostics). */ + cpp_num value; /* The value logically "right" of op. */ + source_location loc; /* The location of this value. */ + enum cpp_ttype op; +}; + +/* Some simple utility routines on double integers. */ +#define num_zerop(num) ((num.low | num.high) == 0) +#define num_eq(num1, num2) (num1.low == num2.low && num1.high == num2.high) +static bool num_positive (cpp_num, size_t); +static bool num_greater_eq (cpp_num, cpp_num, size_t); +static cpp_num num_trim (cpp_num, size_t); +static cpp_num num_part_mul (cpp_num_part, cpp_num_part); + +static cpp_num num_unary_op (cpp_reader *, cpp_num, enum cpp_ttype); +static cpp_num num_binary_op (cpp_reader *, cpp_num, cpp_num, enum cpp_ttype); +static cpp_num num_negate (cpp_num, size_t); +static cpp_num num_bitwise_op (cpp_reader *, cpp_num, cpp_num, enum cpp_ttype); +static cpp_num num_inequality_op (cpp_reader *, cpp_num, cpp_num, + enum cpp_ttype); +static cpp_num num_equality_op (cpp_reader *, cpp_num, cpp_num, + enum cpp_ttype); +static cpp_num num_mul (cpp_reader *, cpp_num, cpp_num); +static cpp_num num_div_op (cpp_reader *, cpp_num, cpp_num, enum cpp_ttype, + source_location); +static cpp_num num_lshift (cpp_num, size_t, size_t); +static cpp_num num_rshift (cpp_num, size_t, size_t); + +static cpp_num append_digit (cpp_num, int, int, size_t); +static cpp_num parse_defined (cpp_reader *); +static cpp_num eval_token (cpp_reader *, const cpp_token *); +static struct op *reduce (cpp_reader *, struct op *, enum cpp_ttype); +static unsigned int interpret_float_suffix (const uchar *, size_t); +static unsigned int interpret_int_suffix (const uchar *, size_t); +static void check_promotion (cpp_reader *, const struct op *); + +/* Token type abuse to create unary plus and minus operators. */ +#define CPP_UPLUS ((enum cpp_ttype) (CPP_LAST_CPP_OP + 1)) +#define CPP_UMINUS ((enum cpp_ttype) (CPP_LAST_CPP_OP + 2)) + +/* With -O2, gcc appears to produce nice code, moving the error + message load and subsequent jump completely out of the main path. */ +#define SYNTAX_ERROR(msgid) \ + do { cpp_error (pfile, CPP_DL_ERROR, msgid); goto syntax_error; } while(0) +#define SYNTAX_ERROR2(msgid, arg) \ + do { cpp_error (pfile, CPP_DL_ERROR, msgid, arg); goto syntax_error; } \ + while(0) + +/* Subroutine of cpp_classify_number. S points to a float suffix of + length LEN, possibly zero. Returns 0 for an invalid suffix, or a + flag vector describing the suffix. */ +static unsigned int +interpret_float_suffix (const uchar *s, size_t len) +{ + size_t flags; + size_t f, d, l, w, q, i; + + flags = 0; + f = d = l = w = q = i = 0; + + /* Process decimal float suffixes, which are two letters starting + with d or D. Order and case are significant. */ + if (len == 2 && (*s == 'd' || *s == 'D')) + { + bool uppercase = (*s == 'D'); + switch (s[1]) + { + case 'f': return (!uppercase ? (CPP_N_DFLOAT | CPP_N_SMALL): 0); break; + case 'F': return (uppercase ? (CPP_N_DFLOAT | CPP_N_SMALL) : 0); break; + case 'd': return (!uppercase ? (CPP_N_DFLOAT | CPP_N_MEDIUM): 0); break; + case 'D': return (uppercase ? (CPP_N_DFLOAT | CPP_N_MEDIUM) : 0); break; + case 'l': return (!uppercase ? (CPP_N_DFLOAT | CPP_N_LARGE) : 0); break; + case 'L': return (uppercase ? (CPP_N_DFLOAT | CPP_N_LARGE) : 0); break; + default: + /* Additional two-character suffixes beginning with D are not + for decimal float constants. */ + break; + } + } + + /* Recognize a fixed-point suffix. */ + switch (s[len-1]) + { + case 'k': case 'K': flags = CPP_N_ACCUM; break; + case 'r': case 'R': flags = CPP_N_FRACT; break; + default: break; + } + + /* Continue processing a fixed-point suffix. The suffix is case + insensitive except for ll or LL. Order is significant. */ + if (flags) + { + if (len == 1) + return flags; + len--; + + if (*s == 'u' || *s == 'U') + { + flags |= CPP_N_UNSIGNED; + if (len == 1) + return flags; + len--; + s++; + } + + switch (*s) + { + case 'h': case 'H': + if (len == 1) + return flags |= CPP_N_SMALL; + break; + case 'l': + if (len == 1) + return flags |= CPP_N_MEDIUM; + if (len == 2 && s[1] == 'l') + return flags |= CPP_N_LARGE; + break; + case 'L': + if (len == 1) + return flags |= CPP_N_MEDIUM; + if (len == 2 && s[1] == 'L') + return flags |= CPP_N_LARGE; + break; + default: + break; + } + /* Anything left at this point is invalid. */ + return 0; + } + + /* In any remaining valid suffix, the case and order don't matter. */ + while (len--) + switch (s[len]) + { + case 'f': case 'F': f++; break; + case 'd': case 'D': d++; break; + case 'l': case 'L': l++; break; + case 'w': case 'W': w++; break; + case 'q': case 'Q': q++; break; + case 'i': case 'I': + case 'j': case 'J': i++; break; + default: + return 0; + } + + if (f + d + l + w + q > 1 || i > 1) + return 0; + + return ((i ? CPP_N_IMAGINARY : 0) + | (f ? CPP_N_SMALL : + d ? CPP_N_MEDIUM : + l ? CPP_N_LARGE : + w ? CPP_N_MD_W : + q ? CPP_N_MD_Q : CPP_N_DEFAULT)); +} + +/* Subroutine of cpp_classify_number. S points to an integer suffix + of length LEN, possibly zero. Returns 0 for an invalid suffix, or a + flag vector describing the suffix. */ +static unsigned int +interpret_int_suffix (const uchar *s, size_t len) +{ + size_t u, l, i; + + u = l = i = 0; + + while (len--) + switch (s[len]) + { + case 'u': case 'U': u++; break; + case 'i': case 'I': + case 'j': case 'J': i++; break; + case 'l': case 'L': l++; + /* If there are two Ls, they must be adjacent and the same case. */ + if (l == 2 && s[len] != s[len + 1]) + return 0; + break; + default: + return 0; + } + + if (l > 2 || u > 1 || i > 1) + return 0; + + return ((i ? CPP_N_IMAGINARY : 0) + | (u ? CPP_N_UNSIGNED : 0) + | ((l == 0) ? CPP_N_SMALL + : (l == 1) ? CPP_N_MEDIUM : CPP_N_LARGE)); +} + +/* Categorize numeric constants according to their field (integer, + floating point, or invalid), radix (decimal, octal, hexadecimal), + and type suffixes. */ +unsigned int +cpp_classify_number (cpp_reader *pfile, const cpp_token *token) +{ + const uchar *str = token->val.str.text; + const uchar *limit; + unsigned int max_digit, result, radix; + enum {NOT_FLOAT = 0, AFTER_POINT, AFTER_EXPON} float_flag; + bool seen_digit; + + /* If the lexer has done its job, length one can only be a single + digit. Fast-path this very common case. */ + if (token->val.str.len == 1) + return CPP_N_INTEGER | CPP_N_SMALL | CPP_N_DECIMAL; + + limit = str + token->val.str.len; + float_flag = NOT_FLOAT; + max_digit = 0; + radix = 10; + seen_digit = false; + + /* First, interpret the radix. */ + if (*str == '0') + { + radix = 8; + str++; + + /* Require at least one hex digit to classify it as hex. */ + if ((*str == 'x' || *str == 'X') + && (str[1] == '.' || ISXDIGIT (str[1]))) + { + radix = 16; + str++; + } + else if ((*str == 'b' || *str == 'B') && (str[1] == '0' || str[1] == '1')) + { + radix = 2; + str++; + } + } + + /* Now scan for a well-formed integer or float. */ + for (;;) + { + unsigned int c = *str++; + + if (ISDIGIT (c) || (ISXDIGIT (c) && radix == 16)) + { + seen_digit = true; + c = hex_value (c); + if (c > max_digit) + max_digit = c; + } + else if (c == '.') + { + if (float_flag == NOT_FLOAT) + float_flag = AFTER_POINT; + else + SYNTAX_ERROR ("too many decimal points in number"); + } + else if ((radix <= 10 && (c == 'e' || c == 'E')) + || (radix == 16 && (c == 'p' || c == 'P'))) + { + float_flag = AFTER_EXPON; + break; + } + else + { + /* Start of suffix. */ + str--; + break; + } + } + + /* The suffix may be for decimal fixed-point constants without exponent. */ + if (radix != 16 && float_flag == NOT_FLOAT) + { + result = interpret_float_suffix (str, limit - str); + if ((result & CPP_N_FRACT) || (result & CPP_N_ACCUM)) + { + result |= CPP_N_FLOATING; + /* We need to restore the radix to 10, if the radix is 8. */ + if (radix == 8) + radix = 10; + + if (CPP_PEDANTIC (pfile)) + cpp_error (pfile, CPP_DL_PEDWARN, + "fixed-point constants are a GCC extension"); + goto syntax_ok; + } + else + result = 0; + } + + if (float_flag != NOT_FLOAT && radix == 8) + radix = 10; + + if (max_digit >= radix) + { + if (radix == 2) + SYNTAX_ERROR2 ("invalid digit \"%c\" in binary constant", '0' + max_digit); + else + SYNTAX_ERROR2 ("invalid digit \"%c\" in octal constant", '0' + max_digit); + } + + if (float_flag != NOT_FLOAT) + { + if (radix == 2) + { + cpp_error (pfile, CPP_DL_ERROR, + "invalid prefix \"0b\" for floating constant"); + return CPP_N_INVALID; + } + + if (radix == 16 && !seen_digit) + SYNTAX_ERROR ("no digits in hexadecimal floating constant"); + + if (radix == 16 && CPP_PEDANTIC (pfile) && !CPP_OPTION (pfile, c99)) + cpp_error (pfile, CPP_DL_PEDWARN, + "use of C99 hexadecimal floating constant"); + + if (float_flag == AFTER_EXPON) + { + if (*str == '+' || *str == '-') + str++; + + /* Exponent is decimal, even if string is a hex float. */ + if (!ISDIGIT (*str)) + SYNTAX_ERROR ("exponent has no digits"); + + do + str++; + while (ISDIGIT (*str)); + } + else if (radix == 16) + SYNTAX_ERROR ("hexadecimal floating constants require an exponent"); + + result = interpret_float_suffix (str, limit - str); + if (result == 0) + { + cpp_error (pfile, CPP_DL_ERROR, + "invalid suffix \"%.*s\" on floating constant", + (int) (limit - str), str); + return CPP_N_INVALID; + } + + /* Traditional C didn't accept any floating suffixes. */ + if (limit != str + && CPP_WTRADITIONAL (pfile) + && ! cpp_sys_macro_p (pfile)) + cpp_warning (pfile, CPP_W_TRADITIONAL, + "traditional C rejects the \"%.*s\" suffix", + (int) (limit - str), str); + + /* A suffix for double is a GCC extension via decimal float support. + If the suffix also specifies an imaginary value we'll catch that + later. */ + if ((result == CPP_N_MEDIUM) && CPP_PEDANTIC (pfile)) + cpp_error (pfile, CPP_DL_PEDWARN, + "suffix for double constant is a GCC extension"); + + /* Radix must be 10 for decimal floats. */ + if ((result & CPP_N_DFLOAT) && radix != 10) + { + cpp_error (pfile, CPP_DL_ERROR, + "invalid suffix \"%.*s\" with hexadecimal floating constant", + (int) (limit - str), str); + return CPP_N_INVALID; + } + + if ((result & (CPP_N_FRACT | CPP_N_ACCUM)) && CPP_PEDANTIC (pfile)) + cpp_error (pfile, CPP_DL_PEDWARN, + "fixed-point constants are a GCC extension"); + + if ((result & CPP_N_DFLOAT) && CPP_PEDANTIC (pfile)) + cpp_error (pfile, CPP_DL_PEDWARN, + "decimal float constants are a GCC extension"); + + result |= CPP_N_FLOATING; + } + else + { + result = interpret_int_suffix (str, limit - str); + if (result == 0) + { + cpp_error (pfile, CPP_DL_ERROR, + "invalid suffix \"%.*s\" on integer constant", + (int) (limit - str), str); + return CPP_N_INVALID; + } + + /* Traditional C only accepted the 'L' suffix. + Suppress warning about 'LL' with -Wno-long-long. */ + if (CPP_WTRADITIONAL (pfile) && ! cpp_sys_macro_p (pfile)) + { + int u_or_i = (result & (CPP_N_UNSIGNED|CPP_N_IMAGINARY)); + int large = (result & CPP_N_WIDTH) == CPP_N_LARGE + && CPP_OPTION (pfile, cpp_warn_long_long); + + if (u_or_i || large) + cpp_warning (pfile, large ? CPP_W_LONG_LONG : CPP_W_TRADITIONAL, + "traditional C rejects the \"%.*s\" suffix", + (int) (limit - str), str); + } + + if ((result & CPP_N_WIDTH) == CPP_N_LARGE + && CPP_OPTION (pfile, cpp_warn_long_long)) + { + const char *message = CPP_OPTION (pfile, cplusplus) + ? N_("use of C++0x long long integer constant") + : N_("use of C99 long long integer constant"); + + if (CPP_OPTION (pfile, c99)) + cpp_warning (pfile, CPP_W_LONG_LONG, "%s", message); + else + cpp_pedwarning (pfile, CPP_W_LONG_LONG, "%s", message); + } + + result |= CPP_N_INTEGER; + } + + syntax_ok: + if ((result & CPP_N_IMAGINARY) && CPP_PEDANTIC (pfile)) + cpp_error (pfile, CPP_DL_PEDWARN, + "imaginary constants are a GCC extension"); + if (radix == 2 && CPP_PEDANTIC (pfile)) + cpp_error (pfile, CPP_DL_PEDWARN, + "binary constants are a GCC extension"); + + if (radix == 10) + result |= CPP_N_DECIMAL; + else if (radix == 16) + result |= CPP_N_HEX; + else if (radix == 2) + result |= CPP_N_BINARY; + else + result |= CPP_N_OCTAL; + + return result; + + syntax_error: + return CPP_N_INVALID; +} + +/* cpp_interpret_integer converts an integer constant into a cpp_num, + of precision options->precision. + + We do not provide any interface for decimal->float conversion, + because the preprocessor doesn't need it and we don't want to + drag in GCC's floating point emulator. */ +cpp_num +cpp_interpret_integer (cpp_reader *pfile, const cpp_token *token, + unsigned int type) +{ + const uchar *p, *end; + cpp_num result; + + result.low = 0; + result.high = 0; + result.unsignedp = !!(type & CPP_N_UNSIGNED); + result.overflow = false; + + p = token->val.str.text; + end = p + token->val.str.len; + + /* Common case of a single digit. */ + if (token->val.str.len == 1) + result.low = p[0] - '0'; + else + { + cpp_num_part max; + size_t precision = CPP_OPTION (pfile, precision); + unsigned int base = 10, c = 0; + bool overflow = false; + + if ((type & CPP_N_RADIX) == CPP_N_OCTAL) + { + base = 8; + p++; + } + else if ((type & CPP_N_RADIX) == CPP_N_HEX) + { + base = 16; + p += 2; + } + else if ((type & CPP_N_RADIX) == CPP_N_BINARY) + { + base = 2; + p += 2; + } + + /* We can add a digit to numbers strictly less than this without + needing the precision and slowness of double integers. */ + max = ~(cpp_num_part) 0; + if (precision < PART_PRECISION) + max >>= PART_PRECISION - precision; + max = (max - base + 1) / base + 1; + + for (; p < end; p++) + { + c = *p; + + if (ISDIGIT (c) || (base == 16 && ISXDIGIT (c))) + c = hex_value (c); + else + break; + + /* Strict inequality for when max is set to zero. */ + if (result.low < max) + result.low = result.low * base + c; + else + { + result = append_digit (result, c, base, precision); + overflow |= result.overflow; + max = 0; + } + } + + if (overflow) + cpp_error (pfile, CPP_DL_PEDWARN, + "integer constant is too large for its type"); + /* If too big to be signed, consider it unsigned. Only warn for + decimal numbers. Traditional numbers were always signed (but + we still honor an explicit U suffix); but we only have + traditional semantics in directives. */ + else if (!result.unsignedp + && !(CPP_OPTION (pfile, traditional) + && pfile->state.in_directive) + && !num_positive (result, precision)) + { + /* This is for constants within the range of uintmax_t but + not that of intmax_t. For such decimal constants, a + diagnostic is required for C99 as the selected type must + be signed and not having a type is a constraint violation + (DR#298, TC3), so this must be a pedwarn. For C90, + unsigned long is specified to be used for a constant that + does not fit in signed long; if uintmax_t has the same + range as unsigned long this means only a warning is + appropriate here. C90 permits the preprocessor to use a + wider range than unsigned long in the compiler, so if + uintmax_t is wider than unsigned long no diagnostic is + required for such constants in preprocessor #if + expressions and the compiler will pedwarn for such + constants outside the range of unsigned long that reach + the compiler so a diagnostic is not required there + either; thus, pedwarn for C99 but use a plain warning for + C90. */ + if (base == 10) + cpp_error (pfile, (CPP_OPTION (pfile, c99) + ? CPP_DL_PEDWARN + : CPP_DL_WARNING), + "integer constant is so large that it is unsigned"); + result.unsignedp = true; + } + } + + return result; +} + +/* Append DIGIT to NUM, a number of PRECISION bits being read in base BASE. */ +static cpp_num +append_digit (cpp_num num, int digit, int base, size_t precision) +{ + cpp_num result; + unsigned int shift; + bool overflow; + cpp_num_part add_high, add_low; + + /* Multiply by 2, 8 or 16. Catching this overflow here means we don't + need to worry about add_high overflowing. */ + switch (base) + { + case 2: + shift = 1; + break; + + case 16: + shift = 4; + break; + + default: + shift = 3; + } + overflow = !!(num.high >> (PART_PRECISION - shift)); + result.high = num.high << shift; + result.low = num.low << shift; + result.high |= num.low >> (PART_PRECISION - shift); + result.unsignedp = num.unsignedp; + + if (base == 10) + { + add_low = num.low << 1; + add_high = (num.high << 1) + (num.low >> (PART_PRECISION - 1)); + } + else + add_high = add_low = 0; + + if (add_low + digit < add_low) + add_high++; + add_low += digit; + + if (result.low + add_low < result.low) + add_high++; + if (result.high + add_high < result.high) + overflow = true; + + result.low += add_low; + result.high += add_high; + result.overflow = overflow; + + /* The above code catches overflow of a cpp_num type. This catches + overflow of the (possibly shorter) target precision. */ + num.low = result.low; + num.high = result.high; + result = num_trim (result, precision); + if (!num_eq (result, num)) + result.overflow = true; + + return result; +} + +/* Handle meeting "defined" in a preprocessor expression. */ +static cpp_num +parse_defined (cpp_reader *pfile) +{ + cpp_num result; + int paren = 0; + cpp_hashnode *node = 0; + const cpp_token *token; + cpp_context *initial_context = pfile->context; + + /* Don't expand macros. */ + pfile->state.prevent_expansion++; + + token = cpp_get_token (pfile); + if (token->type == CPP_OPEN_PAREN) + { + paren = 1; + token = cpp_get_token (pfile); + } + + if (token->type == CPP_NAME) + { + node = token->val.node.node; + if (paren && cpp_get_token (pfile)->type != CPP_CLOSE_PAREN) + { + cpp_error (pfile, CPP_DL_ERROR, "missing ')' after \"defined\""); + node = 0; + } + } + else + { + cpp_error (pfile, CPP_DL_ERROR, + "operator \"defined\" requires an identifier"); + if (token->flags & NAMED_OP) + { + cpp_token op; + + op.flags = 0; + op.type = token->type; + cpp_error (pfile, CPP_DL_ERROR, + "(\"%s\" is an alternative token for \"%s\" in C++)", + cpp_token_as_text (pfile, token), + cpp_token_as_text (pfile, &op)); + } + } + + if (node) + { + if (pfile->context != initial_context && CPP_PEDANTIC (pfile)) + cpp_error (pfile, CPP_DL_WARNING, + "this use of \"defined\" may not be portable"); + + _cpp_mark_macro_used (node); + if (!(node->flags & NODE_USED)) + { + node->flags |= NODE_USED; + if (node->type == NT_MACRO) + { + if ((node->flags & NODE_BUILTIN) + && pfile->cb.user_builtin_macro) + pfile->cb.user_builtin_macro (pfile, node); + if (pfile->cb.used_define) + pfile->cb.used_define (pfile, pfile->directive_line, node); + } + else + { + if (pfile->cb.used_undef) + pfile->cb.used_undef (pfile, pfile->directive_line, node); + } + } + + /* A possible controlling macro of the form #if !defined (). + _cpp_parse_expr checks there was no other junk on the line. */ + pfile->mi_ind_cmacro = node; + } + + pfile->state.prevent_expansion--; + + /* Do not treat conditional macros as being defined. This is due to the + powerpc and spu ports using conditional macros for 'vector', 'bool', and + 'pixel' to act as conditional keywords. This messes up tests like #ifndef + bool. */ + result.unsignedp = false; + result.high = 0; + result.overflow = false; + result.low = (node && node->type == NT_MACRO + && (node->flags & NODE_CONDITIONAL) == 0); + return result; +} + +/* Convert a token into a CPP_NUMBER (an interpreted preprocessing + number or character constant, or the result of the "defined" or "#" + operators). */ +static cpp_num +eval_token (cpp_reader *pfile, const cpp_token *token) +{ + cpp_num result; + unsigned int temp; + int unsignedp = 0; + + result.unsignedp = false; + result.overflow = false; + + switch (token->type) + { + case CPP_NUMBER: + temp = cpp_classify_number (pfile, token); + switch (temp & CPP_N_CATEGORY) + { + case CPP_N_FLOATING: + cpp_error (pfile, CPP_DL_ERROR, + "floating constant in preprocessor expression"); + break; + case CPP_N_INTEGER: + if (!(temp & CPP_N_IMAGINARY)) + return cpp_interpret_integer (pfile, token, temp); + cpp_error (pfile, CPP_DL_ERROR, + "imaginary number in preprocessor expression"); + break; + + case CPP_N_INVALID: + /* Error already issued. */ + break; + } + result.high = result.low = 0; + break; + + case CPP_WCHAR: + case CPP_CHAR: + case CPP_CHAR16: + case CPP_CHAR32: + { + cppchar_t cc = cpp_interpret_charconst (pfile, token, + &temp, &unsignedp); + + result.high = 0; + result.low = cc; + /* Sign-extend the result if necessary. */ + if (!unsignedp && (cppchar_signed_t) cc < 0) + { + if (PART_PRECISION > BITS_PER_CPPCHAR_T) + result.low |= ~(~(cpp_num_part) 0 + >> (PART_PRECISION - BITS_PER_CPPCHAR_T)); + result.high = ~(cpp_num_part) 0; + result = num_trim (result, CPP_OPTION (pfile, precision)); + } + } + break; + + case CPP_NAME: + if (token->val.node.node == pfile->spec_nodes.n_defined) + return parse_defined (pfile); + else if (CPP_OPTION (pfile, cplusplus) + && (token->val.node.node == pfile->spec_nodes.n_true + || token->val.node.node == pfile->spec_nodes.n_false)) + { + result.high = 0; + result.low = (token->val.node.node == pfile->spec_nodes.n_true); + } + else + { + result.high = 0; + result.low = 0; + if (CPP_OPTION (pfile, warn_undef) && !pfile->state.skip_eval) + cpp_warning (pfile, CPP_W_UNDEF, "\"%s\" is not defined", + NODE_NAME (token->val.node.node)); + } + break; + + case CPP_HASH: + if (!pfile->state.skipping) + { + /* A pedantic warning takes precedence over a deprecated + warning here. */ + if (CPP_PEDANTIC (pfile)) + cpp_error (pfile, CPP_DL_PEDWARN, + "assertions are a GCC extension"); + else if (CPP_OPTION (pfile, cpp_warn_deprecated)) + cpp_warning (pfile, CPP_W_DEPRECATED, + "assertions are a deprecated extension"); + } + _cpp_test_assertion (pfile, &temp); + result.high = 0; + result.low = temp; + break; + + default: + abort (); + } + + result.unsignedp = !!unsignedp; + return result; +} + +/* Operator precedence and flags table. + +After an operator is returned from the lexer, if it has priority less +than the operator on the top of the stack, we reduce the stack by one +operator and repeat the test. Since equal priorities do not reduce, +this is naturally right-associative. + +We handle left-associative operators by decrementing the priority of +just-lexed operators by one, but retaining the priority of operators +already on the stack. + +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 +parenthesized expression. If there is a matching '(', the routine +reduce() exits immediately. If the normal exit route sees a ')', then +there cannot have been a matching '(' and an error message is output. + +The parser assumes all shifted operators require a left operand unless +the flag NO_L_OPERAND is set. These semantics are automatic; any +extra semantics need to be handled with operator-specific code. */ + +/* Flags. If CHECK_PROMOTION, we warn if the effective sign of an + operand changes because of integer promotions. */ +#define NO_L_OPERAND (1 << 0) +#define LEFT_ASSOC (1 << 1) +#define CHECK_PROMOTION (1 << 2) + +/* Operator to priority map. Must be in the same order as the first + N entries of enum cpp_ttype. */ +static const struct cpp_operator +{ + uchar prio; + uchar flags; +} optab[] = +{ + /* EQ */ {0, 0}, /* Shouldn't happen. */ + /* NOT */ {16, NO_L_OPERAND}, + /* GREATER */ {12, LEFT_ASSOC | CHECK_PROMOTION}, + /* LESS */ {12, LEFT_ASSOC | CHECK_PROMOTION}, + /* PLUS */ {14, LEFT_ASSOC | CHECK_PROMOTION}, + /* MINUS */ {14, LEFT_ASSOC | CHECK_PROMOTION}, + /* MULT */ {15, LEFT_ASSOC | CHECK_PROMOTION}, + /* DIV */ {15, LEFT_ASSOC | CHECK_PROMOTION}, + /* MOD */ {15, LEFT_ASSOC | CHECK_PROMOTION}, + /* AND */ {9, LEFT_ASSOC | CHECK_PROMOTION}, + /* OR */ {7, LEFT_ASSOC | CHECK_PROMOTION}, + /* XOR */ {8, LEFT_ASSOC | CHECK_PROMOTION}, + /* RSHIFT */ {13, LEFT_ASSOC}, + /* LSHIFT */ {13, LEFT_ASSOC}, + + /* COMPL */ {16, NO_L_OPERAND}, + /* AND_AND */ {6, LEFT_ASSOC}, + /* OR_OR */ {5, LEFT_ASSOC}, + /* Note that QUERY, COLON, and COMMA must have the same precedence. + However, there are some special cases for these in reduce(). */ + /* QUERY */ {4, 0}, + /* COLON */ {4, LEFT_ASSOC | CHECK_PROMOTION}, + /* COMMA */ {4, LEFT_ASSOC}, + /* OPEN_PAREN */ {1, NO_L_OPERAND}, + /* CLOSE_PAREN */ {0, 0}, + /* EOF */ {0, 0}, + /* EQ_EQ */ {11, LEFT_ASSOC}, + /* NOT_EQ */ {11, LEFT_ASSOC}, + /* GREATER_EQ */ {12, LEFT_ASSOC | CHECK_PROMOTION}, + /* LESS_EQ */ {12, LEFT_ASSOC | CHECK_PROMOTION}, + /* UPLUS */ {16, NO_L_OPERAND}, + /* UMINUS */ {16, NO_L_OPERAND} +}; + +/* Parse and evaluate a C expression, reading from PFILE. + Returns the truth value of the expression. + + 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 op_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. */ +bool +_cpp_parse_expr (cpp_reader *pfile, bool is_if) +{ + struct op *top = pfile->op_stack; + unsigned int lex_count; + bool saw_leading_not, want_value = true; + + pfile->state.skip_eval = 0; + + /* Set up detection of #if ! defined(). */ + pfile->mi_ind_cmacro = 0; + saw_leading_not = false; + lex_count = 0; + + /* Lowest priority operator prevents further reductions. */ + top->op = CPP_EOF; + + for (;;) + { + struct op op; + + lex_count++; + op.token = cpp_get_token (pfile); + op.op = op.token->type; + op.loc = op.token->src_loc; + + switch (op.op) + { + /* These tokens convert into values. */ + case CPP_NUMBER: + case CPP_CHAR: + case CPP_WCHAR: + case CPP_CHAR16: + case CPP_CHAR32: + case CPP_NAME: + case CPP_HASH: + if (!want_value) + SYNTAX_ERROR2 ("missing binary operator before token \"%s\"", + cpp_token_as_text (pfile, op.token)); + want_value = false; + top->value = eval_token (pfile, op.token); + continue; + + case CPP_NOT: + saw_leading_not = lex_count == 1; + break; + case CPP_PLUS: + if (want_value) + op.op = CPP_UPLUS; + break; + case CPP_MINUS: + if (want_value) + op.op = CPP_UMINUS; + break; + + default: + if ((int) op.op <= (int) CPP_EQ || (int) op.op >= (int) CPP_PLUS_EQ) + SYNTAX_ERROR2 ("token \"%s\" is not valid in preprocessor expressions", + cpp_token_as_text (pfile, op.token)); + break; + } + + /* Check we have a value or operator as appropriate. */ + if (optab[op.op].flags & NO_L_OPERAND) + { + if (!want_value) + SYNTAX_ERROR2 ("missing binary operator before token \"%s\"", + cpp_token_as_text (pfile, op.token)); + } + else if (want_value) + { + /* We want a number (or expression) and haven't got one. + Try to emit a specific diagnostic. */ + if (op.op == CPP_CLOSE_PAREN && top->op == CPP_OPEN_PAREN) + SYNTAX_ERROR ("missing expression between '(' and ')'"); + + if (op.op == CPP_EOF && top->op == CPP_EOF) + SYNTAX_ERROR2 ("%s with no expression", is_if ? "#if" : "#elif"); + + if (top->op != CPP_EOF && top->op != CPP_OPEN_PAREN) + SYNTAX_ERROR2 ("operator '%s' has no right operand", + cpp_token_as_text (pfile, top->token)); + else if (op.op == CPP_CLOSE_PAREN || op.op == CPP_EOF) + /* Complain about missing paren during reduction. */; + else + SYNTAX_ERROR2 ("operator '%s' has no left operand", + cpp_token_as_text (pfile, op.token)); + } + + top = reduce (pfile, top, op.op); + if (!top) + goto syntax_error; + + if (op.op == CPP_EOF) + break; + + switch (op.op) + { + case CPP_CLOSE_PAREN: + continue; + case CPP_OR_OR: + if (!num_zerop (top->value)) + pfile->state.skip_eval++; + break; + case CPP_AND_AND: + case CPP_QUERY: + if (num_zerop (top->value)) + pfile->state.skip_eval++; + break; + case CPP_COLON: + if (top->op != CPP_QUERY) + SYNTAX_ERROR (" ':' without preceding '?'"); + if (!num_zerop (top[-1].value)) /* Was '?' condition true? */ + pfile->state.skip_eval++; + else + pfile->state.skip_eval--; + default: + break; + } + + want_value = true; + + /* Check for and handle stack overflow. */ + if (++top == pfile->op_limit) + top = _cpp_expand_op_stack (pfile); + + top->op = op.op; + top->token = op.token; + top->loc = op.token->src_loc; + } + + /* The controlling macro expression is only valid if we called lex 3 + times: <!> <defined expression> and <EOF>. push_conditional () + checks that we are at top-of-file. */ + if (pfile->mi_ind_cmacro && !(saw_leading_not && lex_count == 3)) + pfile->mi_ind_cmacro = 0; + + if (top != pfile->op_stack) + { + cpp_error (pfile, CPP_DL_ICE, "unbalanced stack in %s", + is_if ? "#if" : "#elif"); + syntax_error: + return false; /* Return false on syntax error. */ + } + + return !num_zerop (top->value); +} + +/* Reduce the operator / value stack if possible, in preparation for + pushing operator OP. Returns NULL on error, otherwise the top of + the stack. */ +static struct op * +reduce (cpp_reader *pfile, struct op *top, enum cpp_ttype op) +{ + unsigned int prio; + + if (top->op <= CPP_EQ || top->op > CPP_LAST_CPP_OP + 2) + { + bad_op: + cpp_error (pfile, CPP_DL_ICE, "impossible operator '%u'", top->op); + return 0; + } + + if (op == CPP_OPEN_PAREN) + return top; + + /* Decrement the priority of left-associative operators to force a + reduction with operators of otherwise equal priority. */ + prio = optab[op].prio - ((optab[op].flags & LEFT_ASSOC) != 0); + while (prio < optab[top->op].prio) + { + if (CPP_OPTION (pfile, warn_num_sign_change) + && optab[top->op].flags & CHECK_PROMOTION) + check_promotion (pfile, top); + + switch (top->op) + { + case CPP_UPLUS: + case CPP_UMINUS: + case CPP_NOT: + case CPP_COMPL: + top[-1].value = num_unary_op (pfile, top->value, top->op); + top[-1].loc = top->loc; + break; + + case CPP_PLUS: + case CPP_MINUS: + case CPP_RSHIFT: + case CPP_LSHIFT: + case CPP_COMMA: + top[-1].value = num_binary_op (pfile, top[-1].value, + top->value, top->op); + top[-1].loc = top->loc; + break; + + case CPP_GREATER: + case CPP_LESS: + case CPP_GREATER_EQ: + case CPP_LESS_EQ: + top[-1].value + = num_inequality_op (pfile, top[-1].value, top->value, top->op); + top[-1].loc = top->loc; + break; + + case CPP_EQ_EQ: + case CPP_NOT_EQ: + top[-1].value + = num_equality_op (pfile, top[-1].value, top->value, top->op); + top[-1].loc = top->loc; + break; + + case CPP_AND: + case CPP_OR: + case CPP_XOR: + top[-1].value + = num_bitwise_op (pfile, top[-1].value, top->value, top->op); + top[-1].loc = top->loc; + break; + + case CPP_MULT: + top[-1].value = num_mul (pfile, top[-1].value, top->value); + top[-1].loc = top->loc; + break; + + case CPP_DIV: + case CPP_MOD: + top[-1].value = num_div_op (pfile, top[-1].value, + top->value, top->op, top->loc); + top[-1].loc = top->loc; + break; + + case CPP_OR_OR: + top--; + if (!num_zerop (top->value)) + pfile->state.skip_eval--; + top->value.low = (!num_zerop (top->value) + || !num_zerop (top[1].value)); + top->value.high = 0; + top->value.unsignedp = false; + top->value.overflow = false; + top->loc = top[1].loc; + continue; + + case CPP_AND_AND: + top--; + if (num_zerop (top->value)) + pfile->state.skip_eval--; + top->value.low = (!num_zerop (top->value) + && !num_zerop (top[1].value)); + top->value.high = 0; + top->value.unsignedp = false; + top->value.overflow = false; + top->loc = top[1].loc; + continue; + + case CPP_OPEN_PAREN: + if (op != CPP_CLOSE_PAREN) + { + cpp_error_with_line (pfile, CPP_DL_ERROR, + top->token->src_loc, + 0, "missing ')' in expression"); + return 0; + } + top--; + top->value = top[1].value; + top->loc = top[1].loc; + return top; + + case CPP_COLON: + top -= 2; + if (!num_zerop (top->value)) + { + pfile->state.skip_eval--; + top->value = top[1].value; + top->loc = top[1].loc; + } + else + { + top->value = top[2].value; + top->loc = top[2].loc; + } + top->value.unsignedp = (top[1].value.unsignedp + || top[2].value.unsignedp); + continue; + + case CPP_QUERY: + /* COMMA and COLON should not reduce a QUERY operator. */ + if (op == CPP_COMMA || op == CPP_COLON) + return top; + cpp_error (pfile, CPP_DL_ERROR, "'?' without following ':'"); + return 0; + + default: + goto bad_op; + } + + top--; + if (top->value.overflow && !pfile->state.skip_eval) + cpp_error (pfile, CPP_DL_PEDWARN, + "integer overflow in preprocessor expression"); + } + + if (op == CPP_CLOSE_PAREN) + { + cpp_error (pfile, CPP_DL_ERROR, "missing '(' in expression"); + return 0; + } + + return top; +} + +/* Returns the position of the old top of stack after expansion. */ +struct op * +_cpp_expand_op_stack (cpp_reader *pfile) +{ + size_t old_size = (size_t) (pfile->op_limit - pfile->op_stack); + size_t new_size = old_size * 2 + 20; + + pfile->op_stack = XRESIZEVEC (struct op, pfile->op_stack, new_size); + pfile->op_limit = pfile->op_stack + new_size; + + return pfile->op_stack + old_size; +} + +/* Emits a warning if the effective sign of either operand of OP + changes because of integer promotions. */ +static void +check_promotion (cpp_reader *pfile, const struct op *op) +{ + if (op->value.unsignedp == op[-1].value.unsignedp) + return; + + if (op->value.unsignedp) + { + if (!num_positive (op[-1].value, CPP_OPTION (pfile, precision))) + cpp_error_with_line (pfile, CPP_DL_WARNING, op[-1].loc, 0, + "the left operand of \"%s\" changes sign when promoted", + cpp_token_as_text (pfile, op->token)); + } + else if (!num_positive (op->value, CPP_OPTION (pfile, precision))) + cpp_error_with_line (pfile, CPP_DL_WARNING, op->loc, 0, + "the right operand of \"%s\" changes sign when promoted", + cpp_token_as_text (pfile, op->token)); +} + +/* Clears the unused high order bits of the number pointed to by PNUM. */ +static cpp_num +num_trim (cpp_num num, size_t precision) +{ + if (precision > PART_PRECISION) + { + precision -= PART_PRECISION; + if (precision < PART_PRECISION) + num.high &= ((cpp_num_part) 1 << precision) - 1; + } + else + { + if (precision < PART_PRECISION) + num.low &= ((cpp_num_part) 1 << precision) - 1; + num.high = 0; + } + + return num; +} + +/* True iff A (presumed signed) >= 0. */ +static bool +num_positive (cpp_num num, size_t precision) +{ + if (precision > PART_PRECISION) + { + precision -= PART_PRECISION; + return (num.high & (cpp_num_part) 1 << (precision - 1)) == 0; + } + + return (num.low & (cpp_num_part) 1 << (precision - 1)) == 0; +} + +/* Sign extend a number, with PRECISION significant bits and all + others assumed clear, to fill out a cpp_num structure. */ +cpp_num +cpp_num_sign_extend (cpp_num num, size_t precision) +{ + if (!num.unsignedp) + { + if (precision > PART_PRECISION) + { + precision -= PART_PRECISION; + if (precision < PART_PRECISION + && (num.high & (cpp_num_part) 1 << (precision - 1))) + num.high |= ~(~(cpp_num_part) 0 >> (PART_PRECISION - precision)); + } + else if (num.low & (cpp_num_part) 1 << (precision - 1)) + { + if (precision < PART_PRECISION) + num.low |= ~(~(cpp_num_part) 0 >> (PART_PRECISION - precision)); + num.high = ~(cpp_num_part) 0; + } + } + + return num; +} + +/* Returns the negative of NUM. */ +static cpp_num +num_negate (cpp_num num, size_t precision) +{ + cpp_num copy; + + copy = num; + num.high = ~num.high; + num.low = ~num.low; + if (++num.low == 0) + num.high++; + num = num_trim (num, precision); + num.overflow = (!num.unsignedp && num_eq (num, copy) && !num_zerop (num)); + + return num; +} + +/* Returns true if A >= B. */ +static bool +num_greater_eq (cpp_num pa, cpp_num pb, size_t precision) +{ + bool unsignedp; + + unsignedp = pa.unsignedp || pb.unsignedp; + + if (!unsignedp) + { + /* Both numbers have signed type. If they are of different + sign, the answer is the sign of A. */ + unsignedp = num_positive (pa, precision); + + if (unsignedp != num_positive (pb, precision)) + return unsignedp; + + /* Otherwise we can do an unsigned comparison. */ + } + + return (pa.high > pb.high) || (pa.high == pb.high && pa.low >= pb.low); +} + +/* Returns LHS OP RHS, where OP is a bit-wise operation. */ +static cpp_num +num_bitwise_op (cpp_reader *pfile ATTRIBUTE_UNUSED, + cpp_num lhs, cpp_num rhs, enum cpp_ttype op) +{ + lhs.overflow = false; + lhs.unsignedp = lhs.unsignedp || rhs.unsignedp; + + /* As excess precision is zeroed, there is no need to num_trim () as + these operations cannot introduce a set bit there. */ + if (op == CPP_AND) + { + lhs.low &= rhs.low; + lhs.high &= rhs.high; + } + else if (op == CPP_OR) + { + lhs.low |= rhs.low; + lhs.high |= rhs.high; + } + else + { + lhs.low ^= rhs.low; + lhs.high ^= rhs.high; + } + + return lhs; +} + +/* Returns LHS OP RHS, where OP is an inequality. */ +static cpp_num +num_inequality_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, + enum cpp_ttype op) +{ + bool gte = num_greater_eq (lhs, rhs, CPP_OPTION (pfile, precision)); + + if (op == CPP_GREATER_EQ) + lhs.low = gte; + else if (op == CPP_LESS) + lhs.low = !gte; + else if (op == CPP_GREATER) + lhs.low = gte && !num_eq (lhs, rhs); + else /* CPP_LESS_EQ. */ + lhs.low = !gte || num_eq (lhs, rhs); + + lhs.high = 0; + lhs.overflow = false; + lhs.unsignedp = false; + return lhs; +} + +/* Returns LHS OP RHS, where OP is == or !=. */ +static cpp_num +num_equality_op (cpp_reader *pfile ATTRIBUTE_UNUSED, + cpp_num lhs, cpp_num rhs, enum cpp_ttype op) +{ + /* Work around a 3.0.4 bug; see PR 6950. */ + bool eq = num_eq (lhs, rhs); + if (op == CPP_NOT_EQ) + eq = !eq; + lhs.low = eq; + lhs.high = 0; + lhs.overflow = false; + lhs.unsignedp = false; + return lhs; +} + +/* Shift NUM, of width PRECISION, right by N bits. */ +static cpp_num +num_rshift (cpp_num num, size_t precision, size_t n) +{ + cpp_num_part sign_mask; + bool x = num_positive (num, precision); + + if (num.unsignedp || x) + sign_mask = 0; + else + sign_mask = ~(cpp_num_part) 0; + + if (n >= precision) + num.high = num.low = sign_mask; + else + { + /* Sign-extend. */ + if (precision < PART_PRECISION) + num.high = sign_mask, num.low |= sign_mask << precision; + else if (precision < 2 * PART_PRECISION) + num.high |= sign_mask << (precision - PART_PRECISION); + + if (n >= PART_PRECISION) + { + n -= PART_PRECISION; + num.low = num.high; + num.high = sign_mask; + } + + if (n) + { + num.low = (num.low >> n) | (num.high << (PART_PRECISION - n)); + num.high = (num.high >> n) | (sign_mask << (PART_PRECISION - n)); + } + } + + num = num_trim (num, precision); + num.overflow = false; + return num; +} + +/* Shift NUM, of width PRECISION, left by N bits. */ +static cpp_num +num_lshift (cpp_num num, size_t precision, size_t n) +{ + if (n >= precision) + { + num.overflow = !num.unsignedp && !num_zerop (num); + num.high = num.low = 0; + } + else + { + cpp_num orig, maybe_orig; + size_t m = n; + + orig = num; + if (m >= PART_PRECISION) + { + m -= PART_PRECISION; + num.high = num.low; + num.low = 0; + } + if (m) + { + num.high = (num.high << m) | (num.low >> (PART_PRECISION - m)); + num.low <<= m; + } + num = num_trim (num, precision); + + if (num.unsignedp) + num.overflow = false; + else + { + maybe_orig = num_rshift (num, precision, n); + num.overflow = !num_eq (orig, maybe_orig); + } + } + + return num; +} + +/* The four unary operators: +, -, ! and ~. */ +static cpp_num +num_unary_op (cpp_reader *pfile, cpp_num num, enum cpp_ttype op) +{ + switch (op) + { + case CPP_UPLUS: + if (CPP_WTRADITIONAL (pfile) && !pfile->state.skip_eval) + cpp_warning (pfile, CPP_W_TRADITIONAL, + "traditional C rejects the unary plus operator"); + num.overflow = false; + break; + + case CPP_UMINUS: + num = num_negate (num, CPP_OPTION (pfile, precision)); + break; + + case CPP_COMPL: + num.high = ~num.high; + num.low = ~num.low; + num = num_trim (num, CPP_OPTION (pfile, precision)); + num.overflow = false; + break; + + default: /* case CPP_NOT: */ + num.low = num_zerop (num); + num.high = 0; + num.overflow = false; + num.unsignedp = false; + break; + } + + return num; +} + +/* The various binary operators. */ +static cpp_num +num_binary_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op) +{ + cpp_num result; + size_t precision = CPP_OPTION (pfile, precision); + size_t n; + + switch (op) + { + /* Shifts. */ + case CPP_LSHIFT: + case CPP_RSHIFT: + if (!rhs.unsignedp && !num_positive (rhs, precision)) + { + /* A negative shift is a positive shift the other way. */ + if (op == CPP_LSHIFT) + op = CPP_RSHIFT; + else + op = CPP_LSHIFT; + rhs = num_negate (rhs, precision); + } + if (rhs.high) + n = ~0; /* Maximal. */ + else + n = rhs.low; + if (op == CPP_LSHIFT) + lhs = num_lshift (lhs, precision, n); + else + lhs = num_rshift (lhs, precision, n); + break; + + /* Arithmetic. */ + case CPP_MINUS: + rhs = num_negate (rhs, precision); + case CPP_PLUS: + result.low = lhs.low + rhs.low; + result.high = lhs.high + rhs.high; + if (result.low < lhs.low) + result.high++; + result.unsignedp = lhs.unsignedp || rhs.unsignedp; + result.overflow = false; + + result = num_trim (result, precision); + if (!result.unsignedp) + { + bool lhsp = num_positive (lhs, precision); + result.overflow = (lhsp == num_positive (rhs, precision) + && lhsp != num_positive (result, precision)); + } + return result; + + /* Comma. */ + default: /* case CPP_COMMA: */ + if (CPP_PEDANTIC (pfile) && (!CPP_OPTION (pfile, c99) + || !pfile->state.skip_eval)) + cpp_error (pfile, CPP_DL_PEDWARN, + "comma operator in operand of #if"); + lhs = rhs; + break; + } + + return lhs; +} + +/* Multiplies two unsigned cpp_num_parts to give a cpp_num. This + cannot overflow. */ +static cpp_num +num_part_mul (cpp_num_part lhs, cpp_num_part rhs) +{ + cpp_num result; + cpp_num_part middle[2], temp; + + result.low = LOW_PART (lhs) * LOW_PART (rhs); + result.high = HIGH_PART (lhs) * HIGH_PART (rhs); + + middle[0] = LOW_PART (lhs) * HIGH_PART (rhs); + middle[1] = HIGH_PART (lhs) * LOW_PART (rhs); + + temp = result.low; + result.low += LOW_PART (middle[0]) << (PART_PRECISION / 2); + if (result.low < temp) + result.high++; + + temp = result.low; + result.low += LOW_PART (middle[1]) << (PART_PRECISION / 2); + if (result.low < temp) + result.high++; + + result.high += HIGH_PART (middle[0]); + result.high += HIGH_PART (middle[1]); + result.unsignedp = true; + result.overflow = false; + + return result; +} + +/* Multiply two preprocessing numbers. */ +static cpp_num +num_mul (cpp_reader *pfile, cpp_num lhs, cpp_num rhs) +{ + cpp_num result, temp; + bool unsignedp = lhs.unsignedp || rhs.unsignedp; + bool overflow, negate = false; + size_t precision = CPP_OPTION (pfile, precision); + + /* Prepare for unsigned multiplication. */ + if (!unsignedp) + { + if (!num_positive (lhs, precision)) + negate = !negate, lhs = num_negate (lhs, precision); + if (!num_positive (rhs, precision)) + negate = !negate, rhs = num_negate (rhs, precision); + } + + overflow = lhs.high && rhs.high; + result = num_part_mul (lhs.low, rhs.low); + + temp = num_part_mul (lhs.high, rhs.low); + result.high += temp.low; + if (temp.high) + overflow = true; + + temp = num_part_mul (lhs.low, rhs.high); + result.high += temp.low; + if (temp.high) + overflow = true; + + temp.low = result.low, temp.high = result.high; + result = num_trim (result, precision); + if (!num_eq (result, temp)) + overflow = true; + + if (negate) + result = num_negate (result, precision); + + if (unsignedp) + result.overflow = false; + else + result.overflow = overflow || (num_positive (result, precision) ^ !negate + && !num_zerop (result)); + result.unsignedp = unsignedp; + + return result; +} + +/* Divide two preprocessing numbers, LHS and RHS, returning the answer + or the remainder depending upon OP. LOCATION is the source location + of this operator (for diagnostics). */ + +static cpp_num +num_div_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op, + source_location location) +{ + cpp_num result, sub; + cpp_num_part mask; + bool unsignedp = lhs.unsignedp || rhs.unsignedp; + bool negate = false, lhs_neg = false; + size_t i, precision = CPP_OPTION (pfile, precision); + + /* Prepare for unsigned division. */ + if (!unsignedp) + { + if (!num_positive (lhs, precision)) + negate = !negate, lhs_neg = true, lhs = num_negate (lhs, precision); + if (!num_positive (rhs, precision)) + negate = !negate, rhs = num_negate (rhs, precision); + } + + /* Find the high bit. */ + if (rhs.high) + { + i = precision - 1; + mask = (cpp_num_part) 1 << (i - PART_PRECISION); + for (; ; i--, mask >>= 1) + if (rhs.high & mask) + break; + } + else if (rhs.low) + { + if (precision > PART_PRECISION) + i = precision - PART_PRECISION - 1; + else + i = precision - 1; + mask = (cpp_num_part) 1 << i; + for (; ; i--, mask >>= 1) + if (rhs.low & mask) + break; + } + else + { + if (!pfile->state.skip_eval) + cpp_error_with_line (pfile, CPP_DL_ERROR, location, 0, + "division by zero in #if"); + return lhs; + } + + /* First nonzero bit of RHS is bit I. Do naive division by + shifting the RHS fully left, and subtracting from LHS if LHS is + at least as big, and then repeating but with one less shift. + This is not very efficient, but is easy to understand. */ + + rhs.unsignedp = true; + lhs.unsignedp = true; + i = precision - i - 1; + sub = num_lshift (rhs, precision, i); + + result.high = result.low = 0; + for (;;) + { + if (num_greater_eq (lhs, sub, precision)) + { + lhs = num_binary_op (pfile, lhs, sub, CPP_MINUS); + if (i >= PART_PRECISION) + result.high |= (cpp_num_part) 1 << (i - PART_PRECISION); + else + result.low |= (cpp_num_part) 1 << i; + } + if (i-- == 0) + break; + sub.low = (sub.low >> 1) | (sub.high << (PART_PRECISION - 1)); + sub.high >>= 1; + } + + /* We divide so that the remainder has the sign of the LHS. */ + if (op == CPP_DIV) + { + result.unsignedp = unsignedp; + result.overflow = false; + if (!unsignedp) + { + if (negate) + result = num_negate (result, precision); + result.overflow = (num_positive (result, precision) ^ !negate + && !num_zerop (result)); + } + + return result; + } + + /* CPP_MOD. */ + lhs.unsignedp = unsignedp; + lhs.overflow = false; + if (lhs_neg) + lhs = num_negate (lhs, precision); + + return lhs; +} diff --git a/support/cpp/libcpp/files.c b/support/cpp/libcpp/files.c new file mode 100644 index 0000000..6484be5 --- /dev/null +++ b/support/cpp/libcpp/files.c @@ -0,0 +1,1827 @@ +/* Part of CPP library. File handling. + Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1998, + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 + 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 + Reimplemented, Neil Booth, Jul 2003 + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "cpplib.h" +#include "internal.h" +#include "mkdeps.h" +#include "obstack.h" +#include "hashtab.h" +#include "md5.h" +#include <dirent.h> + +/* Variable length record files on VMS will have a stat size that includes + record control characters that won't be included in the read size. */ +#ifdef VMS +# define FAB_C_VAR 2 /* variable length records (see Starlet fabdef.h) */ +# define STAT_SIZE_RELIABLE(ST) ((ST).st_fab_rfm != FAB_C_VAR) +#else +# define STAT_SIZE_RELIABLE(ST) true +#endif + +#ifdef __DJGPP__ +#include <io.h> + /* For DJGPP redirected input is opened in text mode. */ +# define set_stdin_to_binary_mode() \ + if (! isatty (0)) setmode (0, O_BINARY) +#else +# define set_stdin_to_binary_mode() /* Nothing */ +#endif + +/* This structure represents a file searched for by CPP, whether it + exists or not. An instance may be pointed to by more than one + file_hash_entry; at present no reference count is kept. */ +struct _cpp_file +{ + /* Filename as given to #include or command line switch. */ + const char *name; + + /* The full path used to find the file. */ + const char *path; + + /* The full path of the pch file. */ + const char *pchname; + + /* The file's path with the basename stripped. NULL if it hasn't + been calculated yet. */ + const char *dir_name; + + /* Chain through all files. */ + struct _cpp_file *next_file; + + /* The contents of NAME after calling read_file(). */ + const uchar *buffer; + + /* Pointer to the real start of BUFFER. read_file() might increment + BUFFER; when freeing, this this pointer must be used instead. */ + const uchar *buffer_start; + + /* The macro, if any, preventing re-inclusion. */ + const cpp_hashnode *cmacro; + + /* The directory in the search path where FILE was found. Used for + #include_next and determining whether a header is a system + header. */ + cpp_dir *dir; + + /* As filled in by stat(2) for the file. */ + struct stat st; + + /* File descriptor. Invalid if -1, otherwise open. */ + int fd; + + /* Zero if this file was successfully opened and stat()-ed, + otherwise errno obtained from failure. */ + int err_no; + + /* Number of times the file has been stacked for preprocessing. */ + unsigned short stack_count; + + /* If opened with #import or contains #pragma once. */ + bool once_only; + + /* If read() failed before. */ + bool dont_read; + + /* If this file is the main file. */ + bool main_file; + + /* If BUFFER above contains the true contents of the file. */ + bool buffer_valid; +}; + +/* A singly-linked list for all searches for a given file name, with + its head pointed to by a slot in FILE_HASH. The file name is what + appeared between the quotes in a #include directive; it can be + determined implicitly from the hash table location or explicitly + from FILE->name. + + FILE is a structure containing details about the file that was + found with that search, or details of how the search failed. + + START_DIR is the starting location of the search in the include + chain. The current directories for "" includes are also hashed in + the hash table and therefore unique. Files that are looked up + without using a search path, such as absolute filenames and file + names from the command line share a special starting directory so + they don't cause cache hits with normal include-chain lookups. + + If START_DIR is NULL then the entry is for a directory, not a file, + and the directory is in DIR. Since the starting point in a file + lookup chain is never NULL, this means that simple pointer + comparisons against START_DIR can be made to determine cache hits + in file lookups. + + If a cache lookup fails because of e.g. an extra "./" in the path, + then nothing will break. It is just less efficient as CPP will + have to do more work re-preprocessing the file, and/or comparing + its contents against earlier once-only files. +*/ +struct file_hash_entry +{ + struct file_hash_entry *next; + cpp_dir *start_dir; + source_location location; + union + { + _cpp_file *file; + cpp_dir *dir; + } u; +}; + +/* Number of entries to put in a file_hash_entry pool. */ +#define FILE_HASH_POOL_SIZE 127 + +/* A file hash entry pool. We allocate file_hash_entry object from + one of these. */ +struct file_hash_entry_pool +{ + /* Number of entries used from this pool. */ + unsigned int file_hash_entries_used; + /* Next pool in the chain; used when freeing. */ + struct file_hash_entry_pool *next; + /* The memory pool. */ + struct file_hash_entry pool[FILE_HASH_POOL_SIZE]; +}; + +static bool open_file (_cpp_file *file); +static bool pch_open_file (cpp_reader *pfile, _cpp_file *file, + bool *invalid_pch); +static bool find_file_in_dir (cpp_reader *pfile, _cpp_file *file, + bool *invalid_pch); +static bool read_file_guts (cpp_reader *pfile, _cpp_file *file); +static bool read_file (cpp_reader *pfile, _cpp_file *file); +static bool should_stack_file (cpp_reader *, _cpp_file *file, bool import); +static struct cpp_dir *search_path_head (cpp_reader *, const char *fname, + int angle_brackets, enum include_type); +static const char *dir_name_of_file (_cpp_file *file); +static void open_file_failed (cpp_reader *pfile, _cpp_file *file, int); +static struct file_hash_entry *search_cache (struct file_hash_entry *head, + const cpp_dir *start_dir); +static _cpp_file *make_cpp_file (cpp_reader *, cpp_dir *, const char *fname); +static void destroy_cpp_file (_cpp_file *); +static cpp_dir *make_cpp_dir (cpp_reader *, const char *dir_name, int sysp); +static void allocate_file_hash_entries (cpp_reader *pfile); +static struct file_hash_entry *new_file_hash_entry (cpp_reader *pfile); +static int report_missing_guard (void **slot, void *b); +static hashval_t file_hash_hash (const void *p); +static int file_hash_eq (const void *p, const void *q); +static char *read_filename_string (int ch, FILE *f); +static void read_name_map (cpp_dir *dir); +static char *remap_filename (cpp_reader *pfile, _cpp_file *file); +static char *append_file_to_dir (const char *fname, cpp_dir *dir); +static bool validate_pch (cpp_reader *, _cpp_file *file, const char *pchname); +static int pchf_save_compare (const void *e1, const void *e2); +static int pchf_compare (const void *d_p, const void *e_p); +static bool check_file_against_entries (cpp_reader *, _cpp_file *, bool); + +/* Given a filename in FILE->PATH, with the empty string interpreted + as <stdin>, open it. + + On success FILE contains an open file descriptor and stat + information for the file. On failure the file descriptor is -1 and + the appropriate errno is also stored in FILE. Returns TRUE iff + successful. + + 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. */ +static bool +open_file (_cpp_file *file) +{ + if (file->path[0] == '\0') + { + file->fd = 0; + set_stdin_to_binary_mode (); + } + else + file->fd = open (file->path, O_RDONLY | O_NOCTTY | O_BINARY, 0666); + + if (file->fd != -1) + { + if (fstat (file->fd, &file->st) == 0) + { + if (!S_ISDIR (file->st.st_mode)) + { + file->err_no = 0; + return true; + } + + /* Ignore a directory and continue the search. The file we're + looking for may be elsewhere in the search path. */ + errno = ENOENT; + } + + close (file->fd); + file->fd = -1; + } +#if defined(_WIN32) && !defined(__CYGWIN__) + else if (errno == EACCES) + { + /* On most UNIX systems, open succeeds on a directory. Above, + we check if we have opened a directory and if so, set errno + to ENOENT. However, on Windows, opening a directory + fails with EACCES. We want to return ENOENT in that + case too. */ + if (stat (file->path, &file->st) == 0 + && S_ISDIR (file->st.st_mode)) + errno = ENOENT; + else + /* The call to stat may have reset errno. */ + errno = EACCES; + } +#endif + else if (errno == ENOTDIR) + errno = ENOENT; + + file->err_no = errno; + + return false; +} + +/* Temporary PCH intercept of opening a file. Try to find a PCH file + based on FILE->name and FILE->dir, and test those found for + validity using PFILE->cb.valid_pch. Return true iff a valid file is + found. Set *INVALID_PCH if a PCH file is found but wasn't valid. */ + +static bool +pch_open_file (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch) +{ + static const char extension[] = ".gch"; + const char *path = file->path; + size_t len, flen; + char *pchname; + struct stat st; + bool valid = false; + + /* No PCH on <stdin> or if not requested. */ + if (file->name[0] == '\0' || !pfile->cb.valid_pch) + return false; + + /* If the file is not included as first include from either the toplevel + file or the command-line it is not a valid use of PCH. */ + if (pfile->all_files + && pfile->all_files->next_file) + return false; + + flen = strlen (path); + len = flen + sizeof (extension); + pchname = XNEWVEC (char, len); + memcpy (pchname, path, flen); + memcpy (pchname + flen, extension, sizeof (extension)); + + if (stat (pchname, &st) == 0) + { + DIR *pchdir; + struct dirent *d; + size_t dlen, plen = len; + + if (!S_ISDIR (st.st_mode)) + valid = validate_pch (pfile, file, pchname); + else if ((pchdir = opendir (pchname)) != NULL) + { + pchname[plen - 1] = '/'; + while ((d = readdir (pchdir)) != NULL) + { + dlen = strlen (d->d_name) + 1; + if ((strcmp (d->d_name, ".") == 0) + || (strcmp (d->d_name, "..") == 0)) + continue; + if (dlen + plen > len) + { + len += dlen + 64; + pchname = XRESIZEVEC (char, pchname, len); + } + memcpy (pchname + plen, d->d_name, dlen); + valid = validate_pch (pfile, file, pchname); + if (valid) + break; + } + closedir (pchdir); + } + if (!valid) + *invalid_pch = true; + } + + if (valid) + file->pchname = pchname; + else + free (pchname); + + return valid; +} + +/* Try to open the path FILE->name appended to FILE->dir. This is + where remap and PCH intercept the file lookup process. Return true + if the file was found, whether or not the open was successful. + Set *INVALID_PCH to true if a PCH file is found but wasn't valid. */ + +static bool +find_file_in_dir (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch) +{ + char *path; + + if (CPP_OPTION (pfile, remap) && (path = remap_filename (pfile, file))) + ; + else + if (file->dir->construct) + path = file->dir->construct (file->name, file->dir); + else + path = append_file_to_dir (file->name, file->dir); + + if (path) + { + hashval_t hv = htab_hash_string (path); + char *copy; + void **pp; + + if (htab_find_with_hash (pfile->nonexistent_file_hash, path, hv) != NULL) + { + file->err_no = ENOENT; + return false; + } + + file->path = path; + if (pch_open_file (pfile, file, invalid_pch)) + return true; + + if (open_file (file)) + return true; + + if (file->err_no != ENOENT) + { + open_file_failed (pfile, file, 0); + return true; + } + + /* We copy the path name onto an obstack partly so that we don't + leak the memory, but mostly so that we don't fragment the + heap. */ + copy = (char *) obstack_copy0 (&pfile->nonexistent_file_ob, path, + strlen (path)); + free (path); + pp = htab_find_slot_with_hash (pfile->nonexistent_file_hash, + copy, hv, INSERT); + *pp = copy; + + file->path = file->name; + } + else + { + file->err_no = ENOENT; + file->path = NULL; + } + + return false; +} + +/* Return tue iff the missing_header callback found the given HEADER. */ +static bool +search_path_exhausted (cpp_reader *pfile, const char *header, _cpp_file *file) +{ + missing_header_cb func = pfile->cb.missing_header; + + /* When the regular search path doesn't work, try context dependent + headers search paths. */ + if (func + && file->dir == NULL) + { + if ((file->path = func (pfile, header, &file->dir)) != NULL) + { + if (open_file (file)) + return true; + free ((void *)file->path); + } + file->path = file->name; + } + + return false; +} + +bool +_cpp_find_failed (_cpp_file *file) +{ + return file->err_no != 0; +} + +/* Given a filename FNAME search for such a file in the include path + starting from START_DIR. If FNAME is the empty string it is + interpreted as STDIN if START_DIR is PFILE->no_search_path. + + If the file is not found in the file cache fall back to the O/S and + add the result to our cache. + + If the file was not found in the filesystem, or there was an error + opening it, then ERR_NO is nonzero and FD is -1. If the file was + found, then ERR_NO is zero and FD could be -1 or an open file + descriptor. FD can be -1 if the file was found in the cache and + had previously been closed. To open it again pass the return value + to open_file(). +*/ +_cpp_file * +_cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool fake, int angle_brackets) +{ + struct file_hash_entry *entry, **hash_slot; + _cpp_file *file; + bool invalid_pch = false; + bool saw_bracket_include = false; + bool saw_quote_include = false; + struct cpp_dir *found_in_cache = NULL; + + /* Ensure we get no confusion between cached files and directories. */ + if (start_dir == NULL) + cpp_error (pfile, CPP_DL_ICE, "NULL directory in find_file"); + + hash_slot = (struct file_hash_entry **) + htab_find_slot_with_hash (pfile->file_hash, fname, + htab_hash_string (fname), + INSERT); + + /* First check the cache before we resort to memory allocation. */ + entry = search_cache (*hash_slot, start_dir); + if (entry) + return entry->u.file; + + file = make_cpp_file (pfile, start_dir, fname); + + /* Try each path in the include chain. */ + for (; !fake ;) + { + if (find_file_in_dir (pfile, file, &invalid_pch)) + break; + + file->dir = file->dir->next; + if (file->dir == NULL) + { + if (search_path_exhausted (pfile, fname, file)) + { + /* Although this file must not go in the cache, because + the file found might depend on things (like the current file) + that aren't represented in the cache, it still has to go in + the list of all files so that #import works. */ + file->next_file = pfile->all_files; + pfile->all_files = file; + return file; + } + + if (invalid_pch) + { + cpp_error (pfile, CPP_DL_ERROR, + "one or more PCH files were found, but they were invalid"); + if (!cpp_get_options (pfile)->warn_invalid_pch) + cpp_error (pfile, CPP_DL_ERROR, + "use -Winvalid-pch for more information"); + } + open_file_failed (pfile, file, angle_brackets); + break; + } + + /* Only check the cache for the starting location (done above) + and the quote and bracket chain heads because there are no + other possible starting points for searches. */ + if (file->dir == pfile->bracket_include) + saw_bracket_include = true; + else if (file->dir == pfile->quote_include) + saw_quote_include = true; + else + continue; + + entry = search_cache (*hash_slot, file->dir); + if (entry) + { + found_in_cache = file->dir; + break; + } + } + + if (entry) + { + /* Cache for START_DIR too, sharing the _cpp_file structure. */ + free ((char *) file->name); + free (file); + file = entry->u.file; + } + else + { + /* This is a new file; put it in the list. */ + file->next_file = pfile->all_files; + pfile->all_files = file; + } + + /* Store this new result in the hash table. */ + entry = new_file_hash_entry (pfile); + entry->next = *hash_slot; + entry->start_dir = start_dir; + entry->location = pfile->line_table->highest_location; + entry->u.file = file; + *hash_slot = entry; + + /* If we passed the quote or bracket chain heads, cache them also. + This speeds up processing if there are lots of -I options. */ + if (saw_bracket_include + && pfile->bracket_include != start_dir + && found_in_cache != pfile->bracket_include) + { + entry = new_file_hash_entry (pfile); + entry->next = *hash_slot; + entry->start_dir = pfile->bracket_include; + entry->location = pfile->line_table->highest_location; + entry->u.file = file; + *hash_slot = entry; + } + if (saw_quote_include + && pfile->quote_include != start_dir + && found_in_cache != pfile->quote_include) + { + entry = new_file_hash_entry (pfile); + entry->next = *hash_slot; + entry->start_dir = pfile->quote_include; + entry->location = pfile->line_table->highest_location; + entry->u.file = file; + *hash_slot = entry; + } + + return file; +} + +/* Read a file into FILE->buffer, returning true on success. + + If FILE->fd is something weird, like a block device, we don't want + to read it at all. Don't even try to figure out what something is, + except for plain files and block devices, since there is no + reliable portable way of doing this. + + FIXME: Flush file cache and try again if we run out of memory. */ +static bool +read_file_guts (cpp_reader *pfile, _cpp_file *file) +{ + ssize_t size, total, count; + uchar *buf; + bool regular; + + if (S_ISBLK (file->st.st_mode)) + { + cpp_error (pfile, CPP_DL_ERROR, "%s is a block device", file->path); + return false; + } + + regular = S_ISREG (file->st.st_mode); + if (regular) + { + /* 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 (file->st.st_size > INTTYPE_MAXIMUM (ssize_t)) + { + cpp_error (pfile, CPP_DL_ERROR, "%s is too large", file->path); + return false; + } + + size = file->st.st_size; + } + 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 = XNEWVEC (uchar, size + 1); + total = 0; + while ((count = read (file->fd, buf + total, size - total)) > 0) + { + total += count; + + if (total == size) + { + if (regular) + break; + size *= 2; + buf = XRESIZEVEC (uchar, buf, size + 1); + } + } + + if (count < 0) + { + cpp_errno (pfile, CPP_DL_ERROR, file->path); + return false; + } + + if (regular && total != size && STAT_SIZE_RELIABLE (file->st)) + cpp_error (pfile, CPP_DL_WARNING, + "%s is shorter than expected", file->path); + + file->buffer = _cpp_convert_input (pfile, + CPP_OPTION (pfile, input_charset), + buf, size, total, + &file->buffer_start, + &file->st.st_size); + file->buffer_valid = true; + + return true; +} + +/* Convenience wrapper around read_file_guts that opens the file if + necessary and closes the file descriptor after reading. FILE must + have been passed through find_file() at some stage. */ +static bool +read_file (cpp_reader *pfile, _cpp_file *file) +{ + /* If we already have its contents in memory, succeed immediately. */ + if (file->buffer_valid) + return true; + + /* If an earlier read failed for some reason don't try again. */ + if (file->dont_read || file->err_no) + return false; + + if (file->fd == -1 && !open_file (file)) + { + open_file_failed (pfile, file, 0); + return false; + } + + file->dont_read = !read_file_guts (pfile, file); + close (file->fd); + file->fd = -1; + + return !file->dont_read; +} + +/* Returns TRUE if FILE's contents have been successfully placed in + FILE->buffer and the file should be stacked, otherwise false. */ +static bool +should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import) +{ + _cpp_file *f; + + /* Skip once-only files. */ + if (file->once_only) + return false; + + /* We must mark the file once-only if #import now, before header + guard checks. Otherwise, undefining the header guard might + cause the file to be re-stacked. */ + if (import) + { + _cpp_mark_file_once_only (pfile, file); + + /* Don't stack files that have been stacked before. */ + if (file->stack_count) + return false; + } + + /* Skip if the file had a header guard and the macro is defined. + PCH relies on this appearing before the PCH handler below. */ + if (file->cmacro && file->cmacro->type == NT_MACRO) + return false; + + /* Handle PCH files immediately; don't stack them. */ + if (file->pchname) + { + pfile->cb.read_pch (pfile, file->pchname, file->fd, file->path); + file->fd = -1; + free ((void *) file->pchname); + file->pchname = NULL; + return false; + } + + if (!read_file (pfile, file)) + return false; + + /* Check the file against the PCH file. This is done before + checking against files we've already seen, since it may save on + I/O. */ + if (check_file_against_entries (pfile, file, import)) + { + /* If this isn't a #import, but yet we can't include the file, + that means that it was #import-ed in the PCH file, + so we can never include it again. */ + if (! import) + _cpp_mark_file_once_only (pfile, file); + return false; + } + + /* Now we've read the file's contents, we can stack it if there + are no once-only files. */ + if (!pfile->seen_once_only) + return true; + + /* We may have read the file under a different name. Look + for likely candidates and compare file contents to be sure. */ + for (f = pfile->all_files; f; f = f->next_file) + { + if (f == file) + continue; + + if ((import || f->once_only) + && f->err_no == 0 + && f->st.st_mtime == file->st.st_mtime + && f->st.st_size == file->st.st_size) + { + _cpp_file *ref_file; + bool same_file_p = false; + + if (f->buffer && !f->buffer_valid) + { + /* We already have a buffer but it is not valid, because + the file is still stacked. Make a new one. */ + ref_file = make_cpp_file (pfile, f->dir, f->name); + ref_file->path = f->path; + } + else + /* The file is not stacked anymore. We can reuse it. */ + ref_file = f; + + same_file_p = read_file (pfile, ref_file) + /* Size might have changed in read_file(). */ + && ref_file->st.st_size == file->st.st_size + && !memcmp (ref_file->buffer, + file->buffer, + file->st.st_size); + + if (f->buffer && !f->buffer_valid) + { + ref_file->path = 0; + destroy_cpp_file (ref_file); + } + + if (same_file_p) + break; + } + } + + return f == NULL; +} + +/* Place the file referenced by FILE into a new buffer on the buffer + stack if possible. IMPORT is true if this stacking attempt is + because of a #import directive. Returns true if a buffer is + stacked. */ +bool +_cpp_stack_file (cpp_reader *pfile, _cpp_file *file, bool import) +{ + cpp_buffer *buffer; + int sysp; + + if (!should_stack_file (pfile, file, import)) + return false; + + if (pfile->buffer == NULL || file->dir == NULL) + sysp = 0; + else + sysp = MAX (pfile->buffer->sysp, file->dir->sysp); + + /* Add the file to the dependencies on its first inclusion. */ + if (CPP_OPTION (pfile, deps.style) > !!sysp && !file->stack_count) + { + if (!file->main_file || !CPP_OPTION (pfile, deps.ignore_main_file)) + deps_add_dep (pfile->deps, file->path); + } + + /* Clear buffer_valid since _cpp_clean_line messes it up. */ + file->buffer_valid = false; + file->stack_count++; + + /* Stack the buffer. */ + buffer = cpp_push_buffer (pfile, file->buffer, file->st.st_size, + CPP_OPTION (pfile, preprocessed) + && !CPP_OPTION (pfile, directives_only)); + buffer->file = file; + buffer->sysp = sysp; + + /* Initialize controlling macro state. */ + pfile->mi_valid = true; + pfile->mi_cmacro = 0; + + /* Generate the call back. */ + _cpp_do_file_change (pfile, LC_ENTER, file->path, 1, sysp); + + return true; +} + +/* Mark FILE to be included once only. */ +void +_cpp_mark_file_once_only (cpp_reader *pfile, _cpp_file *file) +{ + pfile->seen_once_only = true; + file->once_only = true; +} + +/* Return the directory from which searching for FNAME should start, + considering the directive TYPE and ANGLE_BRACKETS. If there is + nothing left in the path, returns NULL. */ +static struct cpp_dir * +search_path_head (cpp_reader *pfile, const char *fname, int angle_brackets, + enum include_type type) +{ + cpp_dir *dir; + _cpp_file *file; + + if (IS_ABSOLUTE_PATH (fname)) + return &pfile->no_search_path; + + /* pfile->buffer is NULL when processing an -include command-line flag. */ + file = pfile->buffer == NULL ? pfile->main_file : pfile->buffer->file; + + /* 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 && file->dir + && file->dir != &pfile->no_search_path) + dir = file->dir->next; + else if (angle_brackets) + dir = pfile->bracket_include; + else if (type == IT_CMDLINE) + /* -include and -imacros use the #include "" chain with the + preprocessor's cwd prepended. */ + return make_cpp_dir (pfile, "./", false); + else if (pfile->quote_ignores_source_dir) + dir = pfile->quote_include; + else + return make_cpp_dir (pfile, dir_name_of_file (file), + pfile->buffer ? pfile->buffer->sysp : 0); + + if (dir == NULL) + cpp_error (pfile, CPP_DL_ERROR, + "no include path in which to search for %s", fname); + + return dir; +} + +/* Strip the basename from the file's path. It ends with a slash if + of nonzero length. Note that this procedure also works for + <stdin>, which is represented by the empty string. */ +static const char * +dir_name_of_file (_cpp_file *file) +{ + if (!file->dir_name) + { + size_t len = lbasename (file->path) - file->path; + char *dir_name = XNEWVEC (char, len + 1); + + memcpy (dir_name, file->path, len); + dir_name[len] = '\0'; + file->dir_name = dir_name; + } + + return file->dir_name; +} + +/* Handles #include-family directives (distinguished by TYPE), + including HEADER, and the command line -imacros and -include. + Returns true if a buffer was stacked. */ +bool +_cpp_stack_include (cpp_reader *pfile, const char *fname, int angle_brackets, + enum include_type type) +{ + struct cpp_dir *dir; + _cpp_file *file; + + dir = search_path_head (pfile, fname, angle_brackets, type); + if (!dir) + return false; + + file = _cpp_find_file (pfile, fname, dir, false, angle_brackets); + + /* Compensate for the increment in linemap_add that occurs in + _cpp_stack_file. In the case of a normal #include, we're + currently at the start of the line *following* the #include. A + separate source_location for this location makes no sense (until + we do the LC_LEAVE), and complicates LAST_SOURCE_LINE_LOCATION. + This does not apply if we found a PCH file (in which case + linemap_add is not called) or we were included from the + command-line. */ + if (file->pchname == NULL && file->err_no == 0 && type != IT_CMDLINE) + pfile->line_table->highest_location--; + + return _cpp_stack_file (pfile, file, type == IT_IMPORT); +} + +/* Could not open FILE. The complication is dependency output. */ +static void +open_file_failed (cpp_reader *pfile, _cpp_file *file, int angle_brackets) +{ + int sysp = pfile->line_table->highest_line > 1 && pfile->buffer ? pfile->buffer->sysp : 0; + bool print_dep = CPP_OPTION (pfile, deps.style) > (angle_brackets || !!sysp); + + errno = file->err_no; + if (print_dep && CPP_OPTION (pfile, deps.missing_files) && errno == ENOENT) + { + deps_add_dep (pfile->deps, file->name); + /* If the preprocessor output (other than dependency information) is + being used, we must also flag an error. */ + if (CPP_OPTION (pfile, deps.need_preprocessor_output)) + cpp_errno (pfile, CPP_DL_FATAL, file->path); + } + else + { + /* If we are not outputting dependencies, or if we are and dependencies + were requested for this file, or if preprocessor output is needed + in addition to dependency information, this is an error. + + Otherwise (outputting dependencies but not for this file, and not + using the preprocessor output), we can still produce correct output + so it's only a warning. */ + if (CPP_OPTION (pfile, deps.style) == DEPS_NONE + || print_dep + || CPP_OPTION (pfile, deps.need_preprocessor_output)) + cpp_errno (pfile, CPP_DL_FATAL, file->path); + else + cpp_errno (pfile, CPP_DL_WARNING, file->path); + } +} + +/* Search in the chain beginning at HEAD for a file whose search path + started at START_DIR != NULL. */ +static struct file_hash_entry * +search_cache (struct file_hash_entry *head, const cpp_dir *start_dir) +{ + while (head && head->start_dir != start_dir) + head = head->next; + + return head; +} + +/* Allocate a new _cpp_file structure. */ +static _cpp_file * +make_cpp_file (cpp_reader *pfile, cpp_dir *dir, const char *fname) +{ + _cpp_file *file; + + file = XCNEW (_cpp_file); + file->main_file = !pfile->buffer; + file->fd = -1; + file->dir = dir; + file->name = xstrdup (fname); + + return file; +} + +/* Release a _cpp_file structure. */ +static void +destroy_cpp_file (_cpp_file *file) +{ + if (file->buffer_start) + free ((void *) file->buffer_start); + free ((void *) file->name); + free (file); +} + +/* Release all the files allocated by this reader. */ +static void +destroy_all_cpp_files (cpp_reader *pfile) +{ + _cpp_file *iter = pfile->all_files; + while (iter) + { + _cpp_file *next = iter->next_file; + destroy_cpp_file (iter); + iter = next; + } +} + +/* A hash of directory names. The directory names are the path names + of files which contain a #include "", the included file name is + appended to this directories. + + To avoid duplicate entries we follow the convention that all + non-empty directory names should end in a '/'. DIR_NAME must be + stored in permanently allocated memory. */ +static cpp_dir * +make_cpp_dir (cpp_reader *pfile, const char *dir_name, int sysp) +{ + struct file_hash_entry *entry, **hash_slot; + cpp_dir *dir; + + hash_slot = (struct file_hash_entry **) + htab_find_slot_with_hash (pfile->dir_hash, dir_name, + htab_hash_string (dir_name), + INSERT); + + /* Have we already hashed this directory? */ + for (entry = *hash_slot; entry; entry = entry->next) + if (entry->start_dir == NULL) + return entry->u.dir; + + dir = XCNEW (cpp_dir); + dir->next = pfile->quote_include; + dir->name = (char *) dir_name; + dir->len = strlen (dir_name); + dir->sysp = sysp; + dir->construct = 0; + + /* Store this new result in the hash table. */ + entry = new_file_hash_entry (pfile); + entry->next = *hash_slot; + entry->start_dir = NULL; + entry->location = pfile->line_table->highest_location; + entry->u.dir = dir; + *hash_slot = entry; + + return dir; +} + +/* Create a new block of memory for file hash entries. */ +static void +allocate_file_hash_entries (cpp_reader *pfile) +{ + struct file_hash_entry_pool *pool = XNEW (struct file_hash_entry_pool); + pool->file_hash_entries_used = 0; + pool->next = pfile->file_hash_entries; + pfile->file_hash_entries = pool; +} + +/* Return a new file hash entry. */ +static struct file_hash_entry * +new_file_hash_entry (cpp_reader *pfile) +{ + unsigned int idx; + if (pfile->file_hash_entries->file_hash_entries_used == FILE_HASH_POOL_SIZE) + allocate_file_hash_entries (pfile); + + idx = pfile->file_hash_entries->file_hash_entries_used++; + return &pfile->file_hash_entries->pool[idx]; +} + +/* Free the file hash entry pools. */ +static void +free_file_hash_entries (cpp_reader *pfile) +{ + struct file_hash_entry_pool *iter = pfile->file_hash_entries; + while (iter) + { + struct file_hash_entry_pool *next = iter->next; + free (iter); + iter = next; + } +} + +/* Returns TRUE if a file FNAME has ever been successfully opened. + This routine is not intended to correctly handle filenames aliased + by links or redundant . or .. traversals etc. */ +bool +cpp_included (cpp_reader *pfile, const char *fname) +{ + struct file_hash_entry *entry; + + entry = (struct file_hash_entry *) + htab_find_with_hash (pfile->file_hash, fname, htab_hash_string (fname)); + + while (entry && (entry->start_dir == NULL || entry->u.file->err_no)) + entry = entry->next; + + return entry != NULL; +} + +/* Returns TRUE if a file FNAME has ever been successfully opened + before LOCATION. This routine is not intended to correctly handle + filenames aliased by links or redundant . or .. traversals etc. */ +bool +cpp_included_before (cpp_reader *pfile, const char *fname, + source_location location) +{ + struct file_hash_entry *entry; + + entry = (struct file_hash_entry *) + htab_find_with_hash (pfile->file_hash, fname, htab_hash_string (fname)); + + while (entry && (entry->start_dir == NULL || entry->u.file->err_no + || entry->location > location)) + entry = entry->next; + + return entry != NULL; +} + +/* Calculate the hash value of a file hash entry P. */ + +static hashval_t +file_hash_hash (const void *p) +{ + struct file_hash_entry *entry = (struct file_hash_entry *) p; + const char *hname; + if (entry->start_dir) + hname = entry->u.file->name; + else + hname = entry->u.dir->name; + + return htab_hash_string (hname); +} + +/* Compare a string Q against a file hash entry P. */ +static int +file_hash_eq (const void *p, const void *q) +{ + struct file_hash_entry *entry = (struct file_hash_entry *) p; + const char *fname = (const char *) q; + const char *hname; + + if (entry->start_dir) + hname = entry->u.file->name; + else + hname = entry->u.dir->name; + + return strcmp (hname, fname) == 0; +} + +/* Compare entries in the nonexistent file hash table. These are just + strings. */ +static int +nonexistent_file_hash_eq (const void *p, const void *q) +{ + return strcmp ((const char *) p, (const char *) q) == 0; +} + +/* Initialize everything in this source file. */ +void +_cpp_init_files (cpp_reader *pfile) +{ + pfile->file_hash = htab_create_alloc (127, file_hash_hash, file_hash_eq, + NULL, xcalloc, free); + pfile->dir_hash = htab_create_alloc (127, file_hash_hash, file_hash_eq, + NULL, xcalloc, free); + allocate_file_hash_entries (pfile); + pfile->nonexistent_file_hash = htab_create_alloc (127, htab_hash_string, + nonexistent_file_hash_eq, + NULL, xcalloc, free); + _obstack_begin (&pfile->nonexistent_file_ob, 0, 0, + (void *(*) (size_t)) xmalloc, + (void (*) (void *)) free); +} + +/* Finalize everything in this source file. */ +void +_cpp_cleanup_files (cpp_reader *pfile) +{ + htab_delete (pfile->file_hash); + htab_delete (pfile->dir_hash); + htab_delete (pfile->nonexistent_file_hash); + obstack_free (&pfile->nonexistent_file_ob, 0); + free_file_hash_entries (pfile); + destroy_all_cpp_files (pfile); +} + +/* Make the parser forget about files it has seen. This can be useful + for resetting the parser to start another run. */ +void +cpp_clear_file_cache (cpp_reader *pfile) +{ + _cpp_cleanup_files (pfile); + pfile->file_hash_entries = NULL; + pfile->all_files = NULL; + _cpp_init_files (pfile); +} + +/* Enter a file name in the hash for the sake of cpp_included. */ +void +_cpp_fake_include (cpp_reader *pfile, const char *fname) +{ + _cpp_find_file (pfile, fname, pfile->buffer->file->dir, true, 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 (cpp_reader *pfile, int syshdr, int externc) +{ + int flags = 0; + const struct line_maps *line_table = pfile->line_table; + const struct line_map *map = &line_table->maps[line_table->used-1]; + + /* 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, LC_RENAME, map->to_file, + SOURCE_LINE (map, pfile->line_table->highest_line), flags); +} + +/* Allow the client to change the current file. Used by the front end + to achieve pseudo-file names like <built-in>. + If REASON is LC_LEAVE, then NEW_NAME must be NULL. */ +void +cpp_change_file (cpp_reader *pfile, enum lc_reason reason, + const char *new_name) +{ + _cpp_do_file_change (pfile, reason, new_name, 1, 0); +} + +struct report_missing_guard_data +{ + const char **paths; + size_t count; +}; + +/* Callback function for htab_traverse. */ +static int +report_missing_guard (void **slot, void *d) +{ + struct file_hash_entry *entry = (struct file_hash_entry *) *slot; + struct report_missing_guard_data *data + = (struct report_missing_guard_data *) d; + + /* Skip directories. */ + if (entry->start_dir != NULL) + { + _cpp_file *file = entry->u.file; + + /* We don't want MI guard advice for the main file. */ + if (!file->once_only && file->cmacro == NULL + && file->stack_count == 1 && !file->main_file) + { + if (data->paths == NULL) + { + data->paths = XCNEWVEC (const char *, data->count); + data->count = 0; + } + + data->paths[data->count++] = file->path; + } + } + + /* Keep traversing the hash table. */ + return 1; +} + +/* Comparison function for qsort. */ +static int +report_missing_guard_cmp (const void *p1, const void *p2) +{ + return strcmp (*(const char *const *) p1, *(const char *const *) p2); +} + +/* Report on all files that might benefit from a multiple include guard. + Triggered by -H. */ +void +_cpp_report_missing_guards (cpp_reader *pfile) +{ + struct report_missing_guard_data data; + + data.paths = NULL; + data.count = htab_elements (pfile->file_hash); + htab_traverse (pfile->file_hash, report_missing_guard, &data); + + if (data.paths != NULL) + { + size_t i; + + /* Sort the paths to avoid outputting them in hash table + order. */ + qsort (data.paths, data.count, sizeof (const char *), + report_missing_guard_cmp); + fputs (_("Multiple include guards may be useful for:\n"), + stderr); + for (i = 0; i < data.count; i++) + { + fputs (data.paths[i], stderr); + putc ('\n', stderr); + } + free (data.paths); + } +} + +/* 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, return 1, otherwise 0. */ +int +_cpp_compare_file_date (cpp_reader *pfile, const char *fname, + int angle_brackets) +{ + _cpp_file *file; + struct cpp_dir *dir; + + dir = search_path_head (pfile, fname, angle_brackets, IT_INCLUDE); + if (!dir) + return -1; + + file = _cpp_find_file (pfile, fname, dir, false, angle_brackets); + if (file->err_no) + return -1; + + if (file->fd != -1) + { + close (file->fd); + file->fd = -1; + } + + return file->st.st_mtime > pfile->buffer->file->st.st_mtime; +} + +/* Pushes the given file onto the buffer stack. Returns nonzero if + successful. */ +bool +cpp_push_include (cpp_reader *pfile, const char *fname) +{ + return _cpp_stack_include (pfile, fname, false, IT_CMDLINE); +} + +/* Do appropriate cleanup when a file INC's buffer is popped off the + input stack. */ +void +_cpp_pop_file_buffer (cpp_reader *pfile, _cpp_file *file) +{ + /* Record the inclusion-preventing macro, which could be NULL + meaning no controlling macro. */ + if (pfile->mi_valid && file->cmacro == NULL) + file->cmacro = pfile->mi_cmacro; + + /* Invalidate control macros in the #including file. */ + pfile->mi_valid = false; + + if (file->buffer_start) + { + free ((void *) file->buffer_start); + file->buffer_start = NULL; + file->buffer = NULL; + file->buffer_valid = false; + } +} + +/* Inteface to file statistics record in _cpp_file structure. */ +struct stat * +_cpp_get_file_stat (_cpp_file *file) +{ + return &file->st; +} + +/* Set the include chain for "" to QUOTE, for <> to BRACKET. If + QUOTE_IGNORES_SOURCE_DIR, then "" includes do not look in the + directory of the including file. + + If BRACKET does not lie in the QUOTE chain, it is set to QUOTE. */ +void +cpp_set_include_chains (cpp_reader *pfile, cpp_dir *quote, cpp_dir *bracket, + int quote_ignores_source_dir) +{ + pfile->quote_include = quote; + pfile->bracket_include = quote; + pfile->quote_ignores_source_dir = quote_ignores_source_dir; + + for (; quote; quote = quote->next) + { + quote->name_map = NULL; + quote->len = strlen (quote->name); + if (quote == bracket) + pfile->bracket_include = bracket; + } +} + +/* Append the file name to the directory to create the path, but don't + turn / into // or // into ///; // may be a namespace escape. */ +static char * +append_file_to_dir (const char *fname, cpp_dir *dir) +{ + size_t dlen, flen; + char *path; + + dlen = dir->len; + flen = strlen (fname); + path = XNEWVEC (char, dlen + 1 + flen + 1); + memcpy (path, dir->name, dlen); + if (dlen && path[dlen - 1] != '/') + path[dlen++] = '/'; + memcpy (&path[dlen], fname, flen + 1); + + return path; +} + +/* Read a space delimited string of unlimited length from a stdio + file F. */ +static char * +read_filename_string (int ch, FILE *f) +{ + char *alloc, *set; + int len; + + len = 20; + set = alloc = XNEWVEC (char, len + 1); + if (! is_space (ch)) + { + *set++ = ch; + while ((ch = getc (f)) != EOF && ! is_space (ch)) + { + if (set - alloc == len) + { + len *= 2; + alloc = XRESIZEVEC (char, alloc, len + 1); + set = alloc + len / 2; + } + *set++ = ch; + } + } + *set = '\0'; + ungetc (ch, f); + return alloc; +} + +/* Read the file name map file for DIR. */ +static void +read_name_map (cpp_dir *dir) +{ + static const char FILE_NAME_MAP_FILE[] = "header.gcc"; + char *name; + FILE *f; + size_t len, count = 0, room = 9; + + len = dir->len; + name = (char *) alloca (len + sizeof (FILE_NAME_MAP_FILE) + 1); + memcpy (name, dir->name, len); + if (len && name[len - 1] != '/') + name[len++] = '/'; + strcpy (name + len, FILE_NAME_MAP_FILE); + f = fopen (name, "r"); + + dir->name_map = XNEWVEC (const char *, room); + + /* Silently return NULL if we cannot open. */ + if (f) + { + int ch; + + while ((ch = getc (f)) != EOF) + { + char *to; + + if (is_space (ch)) + continue; + + if (count + 2 > room) + { + room += 8; + dir->name_map = XRESIZEVEC (const char *, dir->name_map, room); + } + + dir->name_map[count] = read_filename_string (ch, f); + while ((ch = getc (f)) != EOF && is_hspace (ch)) + ; + + to = read_filename_string (ch, f); + if (IS_ABSOLUTE_PATH (to)) + dir->name_map[count + 1] = to; + else + { + dir->name_map[count + 1] = append_file_to_dir (to, dir); + free (to); + } + + count += 2; + while ((ch = getc (f)) != '\n') + if (ch == EOF) + break; + } + + fclose (f); + } + + /* Terminate the list of maps. */ + dir->name_map[count] = NULL; +} + +/* Remap a FILE's name based on the file_name_map, if any, for + FILE->dir. If the file name has any directory separators, + recursively check those directories too. */ +static char * +remap_filename (cpp_reader *pfile, _cpp_file *file) +{ + const char *fname, *p; + char *new_dir; + cpp_dir *dir; + size_t index, len; + + dir = file->dir; + fname = file->name; + + for (;;) + { + if (!dir->name_map) + read_name_map (dir); + + for (index = 0; dir->name_map[index]; index += 2) + if (!strcmp (dir->name_map[index], fname)) + return xstrdup (dir->name_map[index + 1]); + + p = strchr (fname, '/'); + if (!p || p == fname) + return NULL; + + len = dir->len + (p - fname + 1); + new_dir = XNEWVEC (char, len + 1); + memcpy (new_dir, dir->name, dir->len); + memcpy (new_dir + dir->len, fname, p - fname + 1); + new_dir[len] = '\0'; + + dir = make_cpp_dir (pfile, new_dir, dir->sysp); + fname = p + 1; + } +} + +/* Returns true if PCHNAME is a valid PCH file for FILE. */ +static bool +validate_pch (cpp_reader *pfile, _cpp_file *file, const char *pchname) +{ + const char *saved_path = file->path; + bool valid = false; + + file->path = pchname; + if (open_file (file)) + { + valid = 1 & pfile->cb.valid_pch (pfile, pchname, file->fd); + + if (!valid) + { + close (file->fd); + file->fd = -1; + } + + if (CPP_OPTION (pfile, print_include_names)) + { + unsigned int i; + for (i = 1; i < pfile->line_table->depth; i++) + putc ('.', stderr); + fprintf (stderr, "%c %s\n", + valid ? '!' : 'x', pchname); + } + } + + file->path = saved_path; + return valid; +} + +/* Get the path associated with the _cpp_file F. The path includes + the base name from the include directive and the directory it was + found in via the search path. */ + +const char * +cpp_get_path (struct _cpp_file *f) +{ + return f->path; +} + +/* Get the directory associated with the _cpp_file F. */ + +cpp_dir * +cpp_get_dir (struct _cpp_file *f) +{ + return f->dir; +} + +/* Get the cpp_buffer currently associated with the cpp_reader + PFILE. */ + +cpp_buffer * +cpp_get_buffer (cpp_reader *pfile) +{ + return pfile->buffer; +} + +/* Get the _cpp_file associated with the cpp_buffer B. */ + +_cpp_file * +cpp_get_file (cpp_buffer *b) +{ + return b->file; +} + +/* Get the previous cpp_buffer given a cpp_buffer B. The previous + buffer is the buffer that included the given buffer. */ + +cpp_buffer * +cpp_get_prev (cpp_buffer *b) +{ + return b->prev; +} + +/* This data structure holds the list of header files that were seen + while the PCH was being built. The 'entries' field is kept sorted + in memcmp() order; yes, this means that on little-endian systems, + it's sorted initially by the least-significant byte of 'size', but + that's OK. The code does rely on having entries with the same size + next to each other. */ + +struct pchf_entry { + /* The size of this file. This is used to save running a MD5 checksum + if the sizes don't match. */ + off_t size; + /* The MD5 checksum of this file. */ + unsigned char sum[16]; + /* Is this file to be included only once? */ + bool once_only; +}; + +struct pchf_data { + /* Number of pchf_entry structures. */ + size_t count; + + /* Are there any values with once_only set? + This is used as an optimisation, it means we don't have to search + the structure if we're processing a regular #include. */ + bool have_once_only; + + struct pchf_entry entries[1]; +}; + +static struct pchf_data *pchf; + +/* A qsort ordering function for pchf_entry structures. */ + +static int +pchf_save_compare (const void *e1, const void *e2) +{ + return memcmp (e1, e2, sizeof (struct pchf_entry)); +} + +/* Create and write to F a pchf_data structure. */ + +bool +_cpp_save_file_entries (cpp_reader *pfile, FILE *fp) +{ + size_t count = 0; + struct pchf_data *result; + size_t result_size; + _cpp_file *f; + + for (f = pfile->all_files; f; f = f->next_file) + ++count; + + result_size = (sizeof (struct pchf_data) + + sizeof (struct pchf_entry) * (count - 1)); + result = XCNEWVAR (struct pchf_data, result_size); + + result->count = 0; + result->have_once_only = false; + + for (f = pfile->all_files; f; f = f->next_file) + { + size_t count; + + /* This should probably never happen, since if a read error occurred + the PCH file shouldn't be written... */ + if (f->dont_read || f->err_no) + continue; + + if (f->stack_count == 0) + continue; + + count = result->count++; + + result->entries[count].once_only = f->once_only; + /* |= is avoided in the next line because of an HP C compiler bug */ + result->have_once_only = result->have_once_only | f->once_only; + if (f->buffer_valid) + md5_buffer ((const char *)f->buffer, + f->st.st_size, result->entries[count].sum); + else + { + FILE *ff; + int oldfd = f->fd; + + if (!open_file (f)) + { + open_file_failed (pfile, f, 0); + return false; + } + ff = fdopen (f->fd, "rb"); + md5_stream (ff, result->entries[count].sum); + fclose (ff); + f->fd = oldfd; + } + result->entries[count].size = f->st.st_size; + } + + result_size = (sizeof (struct pchf_data) + + sizeof (struct pchf_entry) * (result->count - 1)); + + qsort (result->entries, result->count, sizeof (struct pchf_entry), + pchf_save_compare); + + return fwrite (result, result_size, 1, fp) == 1; +} + +/* Read the pchf_data structure from F. */ + +bool +_cpp_read_file_entries (cpp_reader *pfile ATTRIBUTE_UNUSED, FILE *f) +{ + struct pchf_data d; + + if (fread (&d, sizeof (struct pchf_data) - sizeof (struct pchf_entry), 1, f) + != 1) + return false; + + pchf = XNEWVAR (struct pchf_data, sizeof (struct pchf_data) + + sizeof (struct pchf_entry) * (d.count - 1)); + memcpy (pchf, &d, sizeof (struct pchf_data) - sizeof (struct pchf_entry)); + if (fread (pchf->entries, sizeof (struct pchf_entry), d.count, f) + != d.count) + return false; + return true; +} + +/* The parameters for pchf_compare. */ + +struct pchf_compare_data +{ + /* The size of the file we're looking for. */ + off_t size; + + /* The MD5 checksum of the file, if it's been computed. */ + unsigned char sum[16]; + + /* Is SUM valid? */ + bool sum_computed; + + /* Do we need to worry about entries that don't have ONCE_ONLY set? */ + bool check_included; + + /* The file that we're searching for. */ + _cpp_file *f; +}; + +/* bsearch comparison function; look for D_P in E_P. */ + +static int +pchf_compare (const void *d_p, const void *e_p) +{ + const struct pchf_entry *e = (const struct pchf_entry *)e_p; + struct pchf_compare_data *d = (struct pchf_compare_data *)d_p; + int result; + + result = memcmp (&d->size, &e->size, sizeof (off_t)); + if (result != 0) + return result; + + if (! d->sum_computed) + { + _cpp_file *const f = d->f; + + md5_buffer ((const char *)f->buffer, f->st.st_size, d->sum); + d->sum_computed = true; + } + + result = memcmp (d->sum, e->sum, 16); + if (result != 0) + return result; + + if (d->check_included || e->once_only) + return 0; + else + return 1; +} + +/* Check that F is not in a list read from a PCH file (if any). + Assumes that f->buffer_valid is true. Return TRUE if the file + should not be read. */ + +static bool +check_file_against_entries (cpp_reader *pfile ATTRIBUTE_UNUSED, + _cpp_file *f, + bool check_included) +{ + struct pchf_compare_data d; + + if (pchf == NULL + || (! check_included && ! pchf->have_once_only)) + return false; + + d.size = f->st.st_size; + d.sum_computed = false; + d.f = f; + d.check_included = check_included; + return bsearch (&d, pchf->entries, pchf->count, sizeof (struct pchf_entry), + pchf_compare) != NULL; +} diff --git a/support/cpp/libcpp/identifiers.c b/support/cpp/libcpp/identifiers.c new file mode 100644 index 0000000..67378df --- /dev/null +++ b/support/cpp/libcpp/identifiers.c @@ -0,0 +1,121 @@ +/* Hash tables for the CPP library. + Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1998, + 1999, 2000, 2001, 2002, 2007, 2009 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 3, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. + + 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 "internal.h" + +static hashnode alloc_node (hash_table *); + +/* Return an identifier node for hashtable.c. Used by cpplib except + when integrated with the C front ends. */ +static hashnode +alloc_node (hash_table *table) +{ + cpp_hashnode *node; + + node = XOBNEW (&table->pfile->hash_ob, cpp_hashnode); + memset (node, 0, sizeof (cpp_hashnode)); + return HT_NODE (node); +} + +/* Set up the identifier hash table. Use TABLE if non-null, otherwise + create our own. */ +void +_cpp_init_hashtable (cpp_reader *pfile, hash_table *table) +{ + struct spec_nodes *s; + + if (table == NULL) + { + pfile->our_hashtable = 1; + table = ht_create (13); /* 8K (=2^13) entries. */ + table->alloc_node = alloc_node; + + _obstack_begin (&pfile->hash_ob, 0, 0, + (void *(*) (size_t)) xmalloc, + (void (*) (void *)) free); + } + + table->pfile = pfile; + pfile->hash_table = table; + + /* Now we can initialize things that use the hash table. */ + _cpp_init_directives (pfile); + _cpp_init_internal_pragmas (pfile); + + s = &pfile->spec_nodes; + 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__VA_ARGS__ = cpp_lookup (pfile, DSC("__VA_ARGS__")); + s->n__VA_ARGS__->flags |= NODE_DIAGNOSTIC; +} + +/* Tear down the identifier hash table. */ +void +_cpp_destroy_hashtable (cpp_reader *pfile) +{ + if (pfile->our_hashtable) + { + ht_destroy (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 (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 (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; +} + +/* We don't need a proxy since the hash table's identifier comes first + in cpp_hashnode. However, in case this is ever changed, we have a + static assertion for it. */ +extern char proxy_assertion_broken[offsetof (struct cpp_hashnode, ident) == 0 ? 1 : -1]; + +/* For all nodes in the hashtable, callback CB with parameters PFILE, + the node, and V. */ +void +cpp_forall_identifiers (cpp_reader *pfile, cpp_cb cb, void *v) +{ + ht_forall (pfile->hash_table, (ht_cb) cb, v); +} diff --git a/support/cpp/libcpp/include/cpp-id-data.h b/support/cpp/libcpp/include/cpp-id-data.h new file mode 100644 index 0000000..a57edad --- /dev/null +++ b/support/cpp/libcpp/include/cpp-id-data.h @@ -0,0 +1,81 @@ +/* Structures that hang off cpp_identifier, for PCH. + Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + 1999, 2000, 2001, 2002, 2003, 2004, 2009 Free Software Foundation, Inc. + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "cpplib.h" + +#if !defined (HAVE_UCHAR) && !defined (IN_GCC) +typedef unsigned char uchar; +#endif + +#define UC (const unsigned char *) /* Intended use: UC"string" */ + +/* Chained list of answers to an assertion. */ +struct GTY(()) answer { + struct answer *next; + unsigned int count; + cpp_token GTY ((length ("%h.count"))) first[1]; +}; + +/* Each macro definition is recorded in a cpp_macro structure. + Variadic macros cannot occur with traditional cpp. */ +struct GTY(()) cpp_macro { + /* Parameters, if any. */ + cpp_hashnode ** GTY ((nested_ptr (union tree_node, + "%h ? CPP_HASHNODE (GCC_IDENT_TO_HT_IDENT (%h)) : NULL", + "%h ? HT_IDENT_TO_GCC_IDENT (HT_NODE (%h)) : NULL"), + length ("%h.paramc"))) + params; + + /* Replacement tokens (ISO) or replacement text (traditional). See + comment at top of cpptrad.c for how traditional function-like + macros are encoded. */ + union cpp_macro_u + { + cpp_token * GTY ((tag ("0"), length ("%0.count"))) tokens; + const unsigned char * GTY ((tag ("1"))) text; + } GTY ((desc ("%1.traditional"))) exp; + + /* Definition line number. */ + source_location line; + + /* Number of tokens in expansion, or bytes for traditional macros. */ + unsigned int count; + + /* Number of parameters. */ + unsigned short paramc; + + /* If a function-like macro. */ + unsigned int fun_like : 1; + + /* If a variadic macro. */ + unsigned int variadic : 1; + + /* If macro defined in system header. */ + unsigned int syshdr : 1; + + /* Nonzero if it has been expanded or had its existence tested. */ + unsigned int used : 1; + + /* Indicate which field of 'exp' is in use. */ + unsigned int traditional : 1; + + /* Indicate whether the tokens include extra CPP_PASTE tokens at the + end to track invalid redefinitions with consecutive CPP_PASTE + tokens. */ + unsigned int extra_tokens : 1; +}; diff --git a/support/cpp/libcpp/include/cpplib.h b/support/cpp/libcpp/include/cpplib.h new file mode 100644 index 0000000..6882514 --- /dev/null +++ b/support/cpp/libcpp/include/cpplib.h @@ -0,0 +1,1012 @@ +/* Definitions for CPP library. + Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, + 2004, 2005, 2007, 2008, 2009, 2010 + 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 3, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. + + 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 LIBCPP_CPPLIB_H +#define LIBCPP_CPPLIB_H + +#include <sys/types.h> +#include "symtab.h" +#include "line-map.h" + +typedef struct cpp_reader cpp_reader; +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_callbacks cpp_callbacks; +typedef struct cpp_dir cpp_dir; + +struct answer; +struct _cpp_file; + +/* The first three groups, apart from '=', can appear in preprocessor + expressions (+= and -= are used to indicate unary + and - resp.). + 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 ">>". + + See the cpp_operator table optab in expr.c if you change the order or + add or remove anything in the first group. */ + +#define TTYPE_TABLE \ + OP(EQ, "=") \ + OP(NOT, "!") \ + OP(GREATER, ">") /* compare */ \ + OP(LESS, "<") \ + OP(PLUS, "+") /* math */ \ + OP(MINUS, "-") \ + OP(MULT, "*") \ + OP(DIV, "/") \ + OP(MOD, "%") \ + OP(AND, "&") /* bit ops */ \ + OP(OR, "|") \ + OP(XOR, "^") \ + OP(RSHIFT, ">>") \ + OP(LSHIFT, "<<") \ + \ + OP(COMPL, "~") \ + OP(AND_AND, "&&") /* logical */ \ + OP(OR_OR, "||") \ + OP(QUERY, "?") \ + OP(COLON, ":") \ + OP(COMMA, ",") /* grouping */ \ + OP(OPEN_PAREN, "(") \ + OP(CLOSE_PAREN, ")") \ + TK(EOF, NONE) \ + OP(EQ_EQ, "==") /* compare */ \ + OP(NOT_EQ, "!=") \ + OP(GREATER_EQ, ">=") \ + OP(LESS_EQ, "<=") \ + \ + /* These two are unary + / - in preprocessor expressions. */ \ + OP(PLUS_EQ, "+=") /* math */ \ + OP(MINUS_EQ, "-=") \ + \ + OP(MULT_EQ, "*=") \ + OP(DIV_EQ, "/=") \ + OP(MOD_EQ, "%=") \ + OP(AND_EQ, "&=") /* bit ops */ \ + OP(OR_EQ, "|=") \ + OP(XOR_EQ, "^=") \ + OP(RSHIFT_EQ, ">>=") \ + OP(LSHIFT_EQ, "<<=") \ + /* Digraphs together, beginning with CPP_FIRST_DIGRAPH. */ \ + OP(HASH, "#") /* digraphs */ \ + OP(PASTE, "##") \ + OP(OPEN_SQUARE, "[") \ + OP(CLOSE_SQUARE, "]") \ + OP(OPEN_BRACE, "{") \ + OP(CLOSE_BRACE, "}") \ + /* The remainder of the punctuation. Order is not significant. */ \ + OP(SEMICOLON, ";") /* structure */ \ + OP(ELLIPSIS, "...") \ + OP(PLUS_PLUS, "++") /* increment */ \ + OP(MINUS_MINUS, "--") \ + OP(DEREF, "->") /* accessors */ \ + OP(DOT, ".") \ + OP(SCOPE, "::") \ + OP(DEREF_STAR, "->*") \ + OP(DOT_STAR, ".*") \ + OP(ATSIGN, "@") /* used in Objective-C */ \ + \ + TK(NAME, IDENT) /* word */ \ + TK(AT_NAME, IDENT) /* @word - Objective-C */ \ + TK(NUMBER, LITERAL) /* 34_be+ta */ \ + \ + TK(CHAR, LITERAL) /* 'char' */ \ + TK(WCHAR, LITERAL) /* L'char' */ \ + TK(CHAR16, LITERAL) /* u'char' */ \ + TK(CHAR32, LITERAL) /* U'char' */ \ + TK(OTHER, LITERAL) /* stray punctuation */ \ + \ + TK(STRING, LITERAL) /* "string" */ \ + TK(WSTRING, LITERAL) /* L"string" */ \ + TK(STRING16, LITERAL) /* u"string" */ \ + TK(STRING32, LITERAL) /* U"string" */ \ + TK(UTF8STRING, LITERAL) /* u8"string" */ \ + TK(OBJC_STRING, LITERAL) /* @"string" - Objective-C */ \ + TK(HEADER_NAME, LITERAL) /* <stdio.h> in #include */ \ + \ + TK(COMMENT, LITERAL) /* Only if output comments. */ \ + /* SPELL_LITERAL happens to DTRT. */ \ + TK(MACRO_ARG, NONE) /* Macro argument. */ \ + TK(PRAGMA, NONE) /* Only for deferred pragmas. */ \ + TK(PRAGMA_EOL, NONE) /* End-of-line for deferred pragmas. */ \ + TK(PADDING, NONE) /* Whitespace for -E. */ \ +\ + /* SDCC _asm specific */ \ + TK(ASM, LITERAL) /* _asm ... _endasm ; */ + +#define OP(e, s) CPP_ ## e, +#define TK(e, s) CPP_ ## e, +enum cpp_ttype +{ + TTYPE_TABLE + N_TTYPES, + + /* Positions in the table. */ + CPP_LAST_EQ = CPP_LSHIFT, + CPP_FIRST_DIGRAPH = CPP_HASH, + CPP_LAST_PUNCTUATOR= CPP_ATSIGN, + CPP_LAST_CPP_OP = CPP_LESS_EQ +}; +#undef OP +#undef TK + +/* C language kind, used when calling cpp_create_reader. */ +enum c_lang {CLK_GNUC89 = 0, CLK_GNUC99, CLK_GNUC1X, + CLK_STDC89, CLK_STDC94, CLK_STDC99, CLK_STDC1X, + CLK_GNUCXX, CLK_CXX98, CLK_GNUCXX0X, CLK_CXX0X, CLK_ASM}; + +/* Payload of a NUMBER, STRING, CHAR or COMMENT token. */ +struct GTY(()) 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 BOL (1 << 6) /* Token at beginning of line. */ +#define PURE_ZERO (1 << 7) /* Single 0 digit, used by the C++ frontend, + set in c-lex.c. */ +#define SP_DIGRAPH (1 << 8) /* # or ## token was a digraph. */ +#define SP_PREV_WHITE (1 << 9) /* If whitespace before a ## + operator, or before this token + after a # operator. */ +#define PREV_NL (1 <<11) /* If a newline before this token. */ +#define ENTER_ASM (1 <<12) /* enter an __asm __endasm pair. */ +#define EXIT_ASM (1 <<13) /* exit an __asm __endasm pair. */ + +/* Specify which field, if any, of the cpp_token union is used. */ + +enum cpp_token_fld_kind { + CPP_TOKEN_FLD_NODE, + CPP_TOKEN_FLD_SOURCE, + CPP_TOKEN_FLD_STR, + CPP_TOKEN_FLD_ARG_NO, + CPP_TOKEN_FLD_TOKEN_NO, + CPP_TOKEN_FLD_PRAGMA, + CPP_TOKEN_FLD_NONE +}; + +/* A macro argument in the cpp_token union. */ +struct GTY(()) cpp_macro_arg { + /* Argument number. */ + unsigned int arg_no; +}; + +/* An identifier in the cpp_token union. */ +struct GTY(()) cpp_identifier { + /* The canonical (UTF-8) spelling of the identifier. */ + cpp_hashnode * + GTY ((nested_ptr (union tree_node, + "%h ? CPP_HASHNODE (GCC_IDENT_TO_HT_IDENT (%h)) : NULL", + "%h ? HT_IDENT_TO_GCC_IDENT (HT_NODE (%h)) : NULL"))) + node; +}; + +/* A preprocessing token. This has been carefully packed and should + occupy 16 bytes on 32-bit hosts and 24 bytes on 64-bit hosts. */ +struct GTY(()) cpp_token { + source_location src_loc; /* Location of first char of token. */ + ENUM_BITFIELD(cpp_ttype) type : CHAR_BIT; /* token type */ + unsigned short flags; /* flags - see above */ + + union cpp_token_u + { + /* An identifier. */ + struct cpp_identifier GTY ((tag ("CPP_TOKEN_FLD_NODE"))) node; + + /* Inherit padding from this token. */ + cpp_token * GTY ((tag ("CPP_TOKEN_FLD_SOURCE"))) source; + + /* A string, or number. */ + struct cpp_string GTY ((tag ("CPP_TOKEN_FLD_STR"))) str; + + /* Argument no. for a CPP_MACRO_ARG. */ + struct cpp_macro_arg GTY ((tag ("CPP_TOKEN_FLD_ARG_NO"))) macro_arg; + + /* Original token no. for a CPP_PASTE (from a sequence of + consecutive paste tokens in a macro expansion). */ + unsigned int GTY ((tag ("CPP_TOKEN_FLD_TOKEN_NO"))) token_no; + + /* Caller-supplied identifier for a CPP_PRAGMA. */ + unsigned int GTY ((tag ("CPP_TOKEN_FLD_PRAGMA"))) pragma; + } GTY ((desc ("cpp_token_val_index (&%1)"))) val; +}; + +/* Say which field is in use. */ +extern enum cpp_token_fld_kind cpp_token_val_index (cpp_token *tok); + +/* A type wide enough to hold any multibyte source character. + cpplib's character constant interpreter requires an unsigned type. + Also, a typedef for the signed equivalent. + The width of this type is capped at 32 bits; there do exist targets + where wchar_t is 64 bits, but only in a non-default mode, and there + would be no meaningful interpretation for a wchar_t value greater + than 2^32 anyway -- the widest wide-character encoding around is + ISO 10646, which stops at 2^31. */ +#if CHAR_BIT * SIZEOF_INT >= 32 +# define CPPCHAR_SIGNED_T int +#elif CHAR_BIT * SIZEOF_LONG >= 32 +# define CPPCHAR_SIGNED_T long +#else +# error "Cannot find a least-32-bit signed integer type" +#endif +typedef unsigned CPPCHAR_SIGNED_T cppchar_t; +typedef CPPCHAR_SIGNED_T cppchar_signed_t; + +/* Style of header dependencies to generate. */ +enum cpp_deps_style { DEPS_NONE = 0, DEPS_USER, DEPS_SYSTEM }; + +/* The possible normalization levels, from most restrictive to least. */ +enum cpp_normalize_level { + /* In NFKC. */ + normalized_KC = 0, + /* In NFC. */ + normalized_C, + /* In NFC, except for subsequences where being in NFC would make + the identifier invalid. */ + normalized_identifier_C, + /* Not normalized at all. */ + normalized_none +}; + +/* This structure is nested inside struct cpp_reader, and + carries all the options visible to the command line. */ +struct cpp_options +{ + /* Characters between tab stops. */ + unsigned int tabstop; + + /* The language we're preprocessing. */ + enum c_lang lang; + + /* Nonzero means use extra default include directories for C++. */ + unsigned char cplusplus; + + /* Nonzero means handle cplusplus style comments. */ + unsigned char cplusplus_comments; + + /* Nonzero means define __OBJC__, treat @ as a special token, use + the OBJC[PLUS]_INCLUDE_PATH environment variable, and allow + "#import". */ + unsigned char objc; + + /* Nonzero means don't copy comments into the output file. */ + unsigned char discard_comments; + + /* Nonzero means don't copy comments into the output file during + macro expansion. */ + unsigned char discard_comments_in_macro_exp; + + /* 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 process u/U prefix literals (UTF-16/32). */ + unsigned char uliterals; + + /* Nonzero means print names of header files (-H). */ + unsigned char print_include_names; + + /* Nonzero means complain about deprecated features. */ + unsigned char cpp_warn_deprecated; + + /* Nonzero means warn if slash-star appears in a comment. */ + unsigned char warn_comments; + + /* Nonzero means warn if a user-supplied include directory does not + exist. */ + unsigned char warn_missing_include_dirs; + + /* Nonzero means warn if there are any trigraphs. */ + unsigned char warn_trigraphs; + + /* Nonzero means warn about multicharacter charconsts. */ + unsigned char warn_multichar; + + /* Nonzero means warn about various incompatibilities with + traditional C. */ + unsigned char cpp_warn_traditional; + + /* Nonzero means warn about long long numeric constants. */ + unsigned char cpp_warn_long_long; + + /* Nonzero means warn about text after an #endif (or #else). */ + unsigned char warn_endif_labels; + + /* Nonzero means warn about implicit sign changes owing to integer + promotions. */ + unsigned char warn_num_sign_change; + + /* Zero means don't warn about __VA_ARGS__ usage in c89 pedantic mode. + Presumably the usage is protected by the appropriate #ifdef. */ + unsigned char warn_variadic_macros; + + /* Nonzero means warn about builtin macros that are redefined or + explicitly undefined. */ + unsigned char warn_builtin_macro_redefined; + + /* Nonzero means we should look for header.gcc files that remap file + names. */ + unsigned char remap; + + /* Zero means dollar signs are punctuation. */ + unsigned char dollars_in_ident; + + /* Nonzero means UCNs are accepted in identifiers. */ + unsigned char extended_identifiers; + + /* True if we should warn about dollars in identifiers or numbers + for this translation unit. */ + unsigned char warn_dollars; + + /* Nonzero means warn if undefined identifiers are evaluated in an #if. */ + unsigned char warn_undef; + + /* Nonzero means warn of unused macros from the main file. */ + unsigned char warn_unused_macros; + + /* Nonzero for the 1999 C Standard, including corrigenda and amendments. */ + unsigned char c99; + + /* Nonzero if we are conforming to a specific C or C++ standard. */ + unsigned char std; + + /* Nonzero means give all the error messages the ANSI standard requires. */ + unsigned char cpp_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 means handle C++ alternate operator names. */ + unsigned char operator_names; + + /* Nonzero means warn about use of C++ alternate operator names. */ + unsigned char warn_cxx_operator_names; + + /* True for traditional preprocessing. */ + unsigned char traditional; + + /* Holds the name of the target (execution) character set. */ + const char *narrow_charset; + + /* Holds the name of the target wide character set. */ + const char *wide_charset; + + /* Holds the name of the input character set. */ + const char *input_charset; + + /* The minimum permitted level of normalization before a warning + is generated. */ + enum cpp_normalize_level warn_normalize; + + /* True to warn about precompiled header files we couldn't use. */ + bool warn_invalid_pch; + + /* True if dependencies should be restored from a precompiled header. */ + bool restore_pch_deps; + + /* SDCC abuse by Kevin: allow naked '#' characters in expanded macros + * (see _cpp_create_definition in cppmacro.c) + */ + unsigned char allow_naked_hash; + + /* SDCC _asm specific + switch _asm block preprocessing on / off */ + unsigned char preproc_asm; + + /* SDCC specific + object file exetnsion */ + const char *obj_ext; + + /* SDCC specific + pedantic_parse_number */ + unsigned char pedantic_parse_number; + + /* Dependency generation. */ + struct + { + /* Style of header dependencies to generate. */ + enum cpp_deps_style style; + + /* Assume missing files are generated files. */ + bool missing_files; + + /* Generate phony targets for each dependency apart from the first + one. */ + bool phony_targets; + + /* If true, no dependency is generated on the main file. */ + bool ignore_main_file; + + /* If true, intend to use the preprocessor output (e.g., for compilation) + in addition to the dependency info. */ + bool need_preprocessor_output; + } deps; + + /* Target-specific features set by the front end or client. */ + + /* Precision for target CPP arithmetic, target characters, target + ints and target wide characters, respectively. */ + size_t precision, char_precision, int_precision, wchar_precision; + + /* True means chars (wide chars) are unsigned. */ + bool unsigned_char, unsigned_wchar; + + /* True if the most significant byte in a word has the lowest + address in memory. */ + bool bytes_big_endian; + + /* Nonzero means __STDC__ should have the value 0 in system headers. */ + unsigned char stdc_0_in_system_headers; + + /* True disables tokenization outside of preprocessing directives. */ + bool directives_only; +}; + +/* Callback for header lookup for HEADER, which is the name of a + source file. It is used as a method of last resort to find headers + that are not otherwise found during the normal include processing. + The return value is the malloced name of a header to try and open, + if any, or NULL otherwise. This callback is called only if the + header is otherwise unfound. */ +typedef const char *(*missing_header_cb)(cpp_reader *, const char *header, cpp_dir **); + +/* Call backs to cpplib client. */ +struct cpp_callbacks +{ + /* Called when a new line of preprocessed output is started. */ + void (*line_change) (cpp_reader *, const cpp_token *, int); + + /* Called when switching to/from a new file. + The line_map is for the new file. It is NULL if there is no new file. + (In C this happens when done with <built-in>+<command line> and also + when done with a main file.) This can be used for resource cleanup. */ + void (*file_change) (cpp_reader *, const struct line_map *); + + void (*dir_change) (cpp_reader *, const char *); + void (*include) (cpp_reader *, unsigned int, const unsigned char *, + const char *, int, const cpp_token **); + void (*define) (cpp_reader *, unsigned int, cpp_hashnode *); + void (*undef) (cpp_reader *, unsigned int, cpp_hashnode *); + void (*ident) (cpp_reader *, unsigned int, const cpp_string *); + void (*def_pragma) (cpp_reader *, unsigned int); + int (*valid_pch) (cpp_reader *, const char *, int); + void (*read_pch) (cpp_reader *, const char *, int, const char *); + missing_header_cb missing_header; + + /* Context-sensitive macro support. Returns macro (if any) that should + be expanded. */ + cpp_hashnode * (*macro_to_expand) (cpp_reader *, const cpp_token *); + + /* Called to emit a diagnostic. This callback receives the + translated message. */ + bool (*error) (cpp_reader *, int, int, source_location, unsigned int, + const char *, va_list *) + ATTRIBUTE_FPTR_PRINTF(6,0); + + /* Callbacks for when a macro is expanded, or tested (whether + defined or not at the time) in #ifdef, #ifndef or "defined". */ + void (*used_define) (cpp_reader *, unsigned int, cpp_hashnode *); + void (*used_undef) (cpp_reader *, unsigned int, cpp_hashnode *); + /* Called before #define and #undef or other macro definition + changes are processed. */ + void (*before_define) (cpp_reader *); + /* Called whenever a macro is expanded or tested. + Second argument is the location of the start of the current expansion. */ + void (*used) (cpp_reader *, source_location, cpp_hashnode *); + + /* Callback that can change a user builtin into normal macro. */ + bool (*user_builtin_macro) (cpp_reader *, cpp_hashnode *); +}; + +#ifdef VMS +#define INO_T_CPP ino_t ino[3] +#else +#define INO_T_CPP ino_t ino +#endif + +/* Chain of directories to look for include files in. */ +struct cpp_dir +{ + /* NULL-terminated singly-linked list. */ + struct cpp_dir *next; + + /* NAME of the directory, NUL-terminated. */ + char *name; + unsigned int len; + + /* One if a system header, two if a system header that has extern + "C" guards for C++. */ + unsigned char sysp; + + /* Is this a user-supplied directory? */ + bool user_supplied_p; + + /* The canonicalized NAME as determined by lrealpath. This field + is only used by hosts that lack reliable inode numbers. */ + char *canonical_name; + + /* Mapping of file names for this directory for MS-DOS and related + platforms. A NULL-terminated array of (from, to) pairs. */ + const char **name_map; + + /* Routine to construct pathname, given the search path name and the + HEADER we are trying to find, return a constructed pathname to + try and open. If this is NULL, the constructed pathname is as + constructed by append_file_to_dir. */ + char *(*construct) (const char *header, cpp_dir *dir); + + /* The C front end uses these to recognize duplicated + directories in the search path. */ + INO_T_CPP; + dev_t dev; +}; + +/* 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. Poisoned 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__, poisoned identifiers, and -Wc++-compat + warnings about NODE_OPERATOR. */ + +/* 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. */ +#define NODE_DISABLED (1 << 5) /* A disabled macro. */ +#define NODE_MACRO_ARG (1 << 6) /* Used during #define processing. */ +#define NODE_USED (1 << 7) /* Dumped with -dU. */ +#define NODE_CONDITIONAL (1 << 8) /* Conditional macro */ +#define NODE_WARN_OPERATOR (1 << 9) /* Warn about C++ named operator. */ + +/* 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. _Pragma is an operator, but we + handle it with the builtin code for efficiency reasons. */ +enum cpp_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__' */ + BT_PRAGMA, /* `_Pragma' operator */ + BT_TIMESTAMP, /* `__TIMESTAMP__' */ + BT_COUNTER, /* `__COUNTER__' */ + BT_FUNCTION, /* `__func__' */ + BT_FIRST_USER, /* User defined builtin macros. */ + BT_LAST_USER = BT_FIRST_USER + 31 +}; + +#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) + +/* Specify which field, if any, of the union is used. */ + +enum { + NTV_MACRO, + NTV_ANSWER, + NTV_BUILTIN, + NTV_ARGUMENT, + NTV_NONE +}; + +#define CPP_HASHNODE_VALUE_IDX(HNODE) \ + ((HNODE.flags & NODE_MACRO_ARG) ? NTV_ARGUMENT \ + : HNODE.type == NT_MACRO ? ((HNODE.flags & NODE_BUILTIN) \ + ? NTV_BUILTIN : NTV_MACRO) \ + : HNODE.type == NT_ASSERTION ? NTV_ANSWER \ + : NTV_NONE) + +/* 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. */ + +union GTY(()) _cpp_hashnode_value { + /* If a macro. */ + cpp_macro * GTY((tag ("NTV_MACRO"))) macro; + /* Answers to an assertion. */ + struct answer * GTY ((tag ("NTV_ANSWER"))) answers; + /* Code for a builtin macro. */ + enum cpp_builtin_type GTY ((tag ("NTV_BUILTIN"))) builtin; + /* Macro argument index. */ + unsigned short GTY ((tag ("NTV_ARGUMENT"))) arg_index; +}; + +struct GTY(()) cpp_hashnode { + struct ht_identifier ident; + unsigned int is_directive : 1; + unsigned int directive_index : 7; /* If is_directive, + then index into directive table. + Otherwise, a NODE_OPERATOR. */ + unsigned char rid_code; /* Rid code - for front ends. */ + ENUM_BITFIELD(node_type) type : 6; /* CPP node type. */ + unsigned int flags : 10; /* CPP flags. */ + + union _cpp_hashnode_value GTY ((desc ("CPP_HASHNODE_VALUE_IDX (%1)"))) 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. Otherwise you should pass in an initialized hash table + that cpplib will share; this technique is used by the C front + ends. */ +extern cpp_reader *cpp_create_reader (enum c_lang, struct ht *, + struct line_maps *); + +/* Reset the cpp_reader's line_map. This is only used after reading a + PCH file. */ +extern void cpp_set_line_map (cpp_reader *, struct line_maps *); + +/* Call this to change the selected language standard (e.g. because of + command line options). */ +extern void cpp_set_lang (cpp_reader *, enum c_lang); + +/* Set the include paths. */ +extern void cpp_set_include_chains (cpp_reader *, cpp_dir *, cpp_dir *, int); + +/* Call these to get pointers to the options, callback, and deps + 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 (cpp_reader *); +extern cpp_callbacks *cpp_get_callbacks (cpp_reader *); +extern void cpp_set_callbacks (cpp_reader *, cpp_callbacks *); +extern struct deps *cpp_get_deps (cpp_reader *); + +/* This function reads the file, but does not start preprocessing. It + returns the name of the original file; this is the same as the + input file, except for preprocessed input. This will generate at + least one file change callback, and possibly a line change callback + too. If there was an error opening the file, it returns NULL. */ +extern const char *cpp_read_main_file (cpp_reader *, const char *); + +/* Set up built-ins with special behavior. Use cpp_init_builtins() + instead unless your know what you are doing. */ +extern void cpp_init_special_builtins (cpp_reader *); + +/* Set up built-ins like __FILE__. */ +extern void cpp_init_builtins (cpp_reader *, int); + +/* This is called after options have been parsed, and partially + processed. */ +extern void cpp_post_options (cpp_reader *); + +/* Set up translation to the target character set. */ +extern void cpp_init_iconv (cpp_reader *); + +/* Call this to finish preprocessing. If you requested dependency + generation, pass an open stream to write the information to, + otherwise NULL. It is your responsibility to close the stream. */ +extern void cpp_finish (cpp_reader *, FILE *deps_stream); + +/* Call this to release the handle at the end of preprocessing. Any + use of the handle after this function returns is invalid. */ +extern void cpp_destroy (cpp_reader *); + +extern unsigned int cpp_token_len (const cpp_token *); +extern unsigned char *cpp_token_as_text (cpp_reader *, const cpp_token *); +extern unsigned char *cpp_spell_token (cpp_reader *, const cpp_token *, + unsigned char *, bool); +extern void cpp_register_pragma (cpp_reader *, const char *, const char *, + void (*) (cpp_reader *), bool); +extern void cpp_register_deferred_pragma (cpp_reader *, const char *, + const char *, unsigned, bool, bool); +extern int cpp_avoid_paste (cpp_reader *, const cpp_token *, + const cpp_token *); +extern const cpp_token *cpp_get_token (cpp_reader *); +extern const cpp_token *cpp_get_token_with_location (cpp_reader *, + source_location *); +extern const unsigned char *cpp_macro_definition (cpp_reader *, + cpp_hashnode *); +extern void _cpp_backup_tokens (cpp_reader *, unsigned int); +extern const cpp_token *cpp_peek_token (cpp_reader *, int); + +/* Evaluate a CPP_*CHAR* token. */ +extern cppchar_t cpp_interpret_charconst (cpp_reader *, const cpp_token *, + unsigned int *, int *); +/* Evaluate a vector of CPP_*STRING* tokens. */ +extern bool cpp_interpret_string (cpp_reader *, + const cpp_string *, size_t, + cpp_string *, enum cpp_ttype); +extern bool cpp_interpret_string_notranslate (cpp_reader *, + const cpp_string *, size_t, + cpp_string *, enum cpp_ttype); + +/* Convert a host character constant to the execution character set. */ +extern cppchar_t cpp_host_to_exec_charset (cpp_reader *, cppchar_t); + +/* Used to register macros and assertions, perhaps from the command line. + The text is the same as the command line argument. */ +extern void cpp_define (cpp_reader *, const char *); +extern void cpp_define_formatted (cpp_reader *pfile, + const char *fmt, ...) ATTRIBUTE_PRINTF_2; +extern void cpp_assert (cpp_reader *, const char *); +extern void cpp_undef (cpp_reader *, const char *); +extern void cpp_unassert (cpp_reader *, const char *); + +/* Undefine all macros and assertions. */ +extern void cpp_undef_all (cpp_reader *); + +extern cpp_buffer *cpp_push_buffer (cpp_reader *, const unsigned char *, + size_t, int); +extern int cpp_defined (cpp_reader *, const unsigned char *, int); + +/* A preprocessing number. Code assumes that any unused high bits of + the double integer are set to zero. */ +typedef unsigned HOST_WIDE_INT cpp_num_part; +typedef struct cpp_num cpp_num; +struct cpp_num +{ + cpp_num_part high; + cpp_num_part low; + bool unsignedp; /* True if value should be treated as unsigned. */ + bool overflow; /* True if the most recent calculation overflowed. */ +}; + +/* cpplib provides two interfaces for interpretation of preprocessing + numbers. + + cpp_classify_number categorizes numeric constants according to + their field (integer, floating point, or invalid), radix (decimal, + octal, hexadecimal), and type suffixes. */ + +#define CPP_N_CATEGORY 0x000F +#define CPP_N_INVALID 0x0000 +#define CPP_N_INTEGER 0x0001 +#define CPP_N_FLOATING 0x0002 + +#define CPP_N_WIDTH 0x00F0 +#define CPP_N_SMALL 0x0010 /* int, float, shrot _Fract/Accum */ +#define CPP_N_MEDIUM 0x0020 /* long, double, long _Fract/_Accum. */ +#define CPP_N_LARGE 0x0040 /* long long, long double, + long long _Fract/Accum. */ + +#define CPP_N_WIDTH_MD 0xF0000 /* machine defined. */ +#define CPP_N_MD_W 0x10000 +#define CPP_N_MD_Q 0x20000 + +#define CPP_N_RADIX 0x0F00 +#define CPP_N_DECIMAL 0x0100 +#define CPP_N_HEX 0x0200 +#define CPP_N_OCTAL 0x0400 +#define CPP_N_BINARY 0x0800 + +#define CPP_N_UNSIGNED 0x1000 /* Properties. */ +#define CPP_N_IMAGINARY 0x2000 +#define CPP_N_DFLOAT 0x4000 +#define CPP_N_DEFAULT 0x8000 + +#define CPP_N_FRACT 0x100000 /* Fract types. */ +#define CPP_N_ACCUM 0x200000 /* Accum types. */ + +/* Classify a CPP_NUMBER token. The return value is a combination of + the flags from the above sets. */ +extern unsigned cpp_classify_number (cpp_reader *, const cpp_token *); + +/* Evaluate a token classified as category CPP_N_INTEGER. */ +extern cpp_num cpp_interpret_integer (cpp_reader *, const cpp_token *, + unsigned int type); + +/* Sign extend a number, with PRECISION significant bits and all + others assumed clear, to fill out a cpp_num structure. */ +cpp_num cpp_num_sign_extend (cpp_num, size_t); + +/* Diagnostic levels. To get a diagnostic without associating a + position in the translation unit with it, use cpp_error_with_line + with a line number of zero. */ + +enum { + /* Warning, an error with -Werror. */ + CPP_DL_WARNING = 0, + /* Same as CPP_DL_WARNING, except it is not suppressed in system headers. */ + CPP_DL_WARNING_SYSHDR, + /* Warning, an error with -pedantic-errors or -Werror. */ + CPP_DL_PEDWARN, + /* An error. */ + CPP_DL_ERROR, + /* An internal consistency check failed. Prints "internal error: ", + otherwise the same as CPP_DL_ERROR. */ + CPP_DL_ICE, + /* An informative note following a warning. */ + CPP_DL_NOTE, + /* A fatal error. */ + CPP_DL_FATAL +}; + +/* Warning reason codes. Use a reason code of zero for unclassified warnings + and errors that are not warnings. */ +enum { + CPP_W_NONE = 0, + CPP_W_DEPRECATED, + CPP_W_COMMENTS, + CPP_W_MISSING_INCLUDE_DIRS, + CPP_W_TRIGRAPHS, + CPP_W_MULTICHAR, + CPP_W_TRADITIONAL, + CPP_W_LONG_LONG, + CPP_W_ENDIF_LABELS, + CPP_W_NUM_SIGN_CHANGE, + CPP_W_VARIADIC_MACROS, + CPP_W_BUILTIN_MACRO_REDEFINED, + CPP_W_DOLLARS, + CPP_W_UNDEF, + CPP_W_UNUSED_MACROS, + CPP_W_CXX_OPERATOR_NAMES, + CPP_W_NORMALIZE, + CPP_W_INVALID_PCH, + CPP_W_WARNING_DIRECTIVE +}; + +/* Output a diagnostic of some kind. */ +extern bool cpp_error (cpp_reader *, int, const char *msgid, ...) + ATTRIBUTE_PRINTF_3; +extern bool cpp_warning (cpp_reader *, int, const char *msgid, ...) + ATTRIBUTE_PRINTF_3; +extern bool cpp_pedwarning (cpp_reader *, int, const char *msgid, ...) + ATTRIBUTE_PRINTF_3; +extern bool cpp_warning_syshdr (cpp_reader *, int, const char *msgid, ...) + ATTRIBUTE_PRINTF_3; + +/* Output a diagnostic with "MSGID: " preceding the + error string of errno. No location is printed. */ +extern bool cpp_errno (cpp_reader *, int, const char *msgid); + +/* Same as cpp_error, except additionally specifies a position as a + (translation unit) physical line and physical column. If the line is + zero, then no location is printed. */ +extern bool cpp_error_with_line (cpp_reader *, int, source_location, + unsigned, const char *msgid, ...) + ATTRIBUTE_PRINTF_5; +extern bool cpp_warning_with_line (cpp_reader *, int, source_location, + unsigned, const char *msgid, ...) + ATTRIBUTE_PRINTF_5; +extern bool cpp_pedwarning_with_line (cpp_reader *, int, source_location, + unsigned, const char *msgid, ...) + ATTRIBUTE_PRINTF_5; +extern bool cpp_warning_with_line_syshdr (cpp_reader *, int, source_location, + unsigned, const char *msgid, ...) + ATTRIBUTE_PRINTF_5; + +/* In lex.c */ +extern int cpp_ideq (const cpp_token *, const char *); +extern void cpp_output_line (cpp_reader *, FILE *); +extern unsigned char *cpp_output_line_to_string (cpp_reader *, + const unsigned char *); +extern void cpp_output_token (const cpp_token *, FILE *); +extern const char *cpp_type2name (enum cpp_ttype, unsigned char flags); +/* Returns the value of an escape sequence, truncated to the correct + target precision. PSTR points to the input pointer, which is just + after the backslash. LIMIT is how much text we have. WIDE is true + if the escape sequence is part of a wide character constant or + string literal. Handles all relevant diagnostics. */ +extern cppchar_t cpp_parse_escape (cpp_reader *, const unsigned char ** pstr, + const unsigned char *limit, int wide); + +/* Structure used to hold a comment block at a given location in the + source code. */ + +typedef struct +{ + /* Text of the comment including the terminators. */ + char *comment; + + /* source location for the given comment. */ + source_location sloc; +} cpp_comment; + +/* Structure holding all comments for a given cpp_reader. */ + +typedef struct +{ + /* table of comment entries. */ + cpp_comment *entries; + + /* number of actual entries entered in the table. */ + int count; + + /* number of entries allocated currently. */ + int allocated; +} cpp_comment_table; + +/* Returns the table of comments encountered by the preprocessor. This + table is only populated when pfile->state.save_comments is true. */ +extern cpp_comment_table *cpp_get_comments (cpp_reader *); + +/* In hash.c */ + +/* Lookup an identifier in the hashtable. Puts the identifier in the + table if it is not already there. */ +extern cpp_hashnode *cpp_lookup (cpp_reader *, const unsigned char *, + unsigned int); + +typedef int (*cpp_cb) (cpp_reader *, cpp_hashnode *, void *); +extern void cpp_forall_identifiers (cpp_reader *, cpp_cb, void *); + +/* In macro.c */ +extern void cpp_scan_nooutput (cpp_reader *); +extern int cpp_sys_macro_p (cpp_reader *); +extern unsigned char *cpp_quote_string (unsigned char *, const unsigned char *, + unsigned int); + +/* In files.c */ +extern bool cpp_included (cpp_reader *, const char *); +extern bool cpp_included_before (cpp_reader *, const char *, source_location); +extern void cpp_make_system_header (cpp_reader *, int, int); +extern bool cpp_push_include (cpp_reader *, const char *); +extern void cpp_change_file (cpp_reader *, enum lc_reason, const char *); +extern const char *cpp_get_path (struct _cpp_file *); +extern cpp_dir *cpp_get_dir (struct _cpp_file *); +extern cpp_buffer *cpp_get_buffer (cpp_reader *); +extern struct _cpp_file *cpp_get_file (cpp_buffer *); +extern cpp_buffer *cpp_get_prev (cpp_buffer *); +extern void cpp_clear_file_cache (cpp_reader *); + +/* In pch.c */ +struct save_macro_data; +extern int cpp_save_state (cpp_reader *, FILE *); +extern int cpp_write_pch_deps (cpp_reader *, FILE *); +extern int cpp_write_pch_state (cpp_reader *, FILE *); +extern int cpp_valid_state (cpp_reader *, const char *, int); +extern void cpp_prepare_state (cpp_reader *, struct save_macro_data **); +extern int cpp_read_state (cpp_reader *, const char *, FILE *, + struct save_macro_data *); + +#endif /* ! LIBCPP_CPPLIB_H */ diff --git a/support/cpp/libcpp/include/line-map.h b/support/cpp/libcpp/include/line-map.h new file mode 100644 index 0000000..3234423 --- /dev/null +++ b/support/cpp/libcpp/include/line-map.h @@ -0,0 +1,193 @@ +/* Map logical line numbers to (source file, line number) pairs. + Copyright (C) 2001, 2003, 2004, 2007, 2008, 2009, 2010 + Free Software Foundation, Inc. + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. + + 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 LIBCPP_LINE_MAP_H +#define LIBCPP_LINE_MAP_H + +#ifndef GTY +#define GTY(x) /* nothing */ +#endif + +/* Reason for adding a line change with add_line_map (). LC_ENTER is + when including a new file, e.g. a #include directive in C. + LC_LEAVE is when reaching a file's end. LC_RENAME is when a file + name or line number changes for neither of the above reasons + (e.g. a #line directive in C); LC_RENAME_VERBATIM is like LC_RENAME + but a filename of "" is not specially interpreted as standard input. */ +enum lc_reason {LC_ENTER = 0, LC_LEAVE, LC_RENAME, LC_RENAME_VERBATIM}; + +/* The type of line numbers. */ +typedef unsigned int linenum_type; + +/* A logical line/column number, i.e. an "index" into a line_map. */ +typedef unsigned int source_location; + +/* Memory allocation function typedef. Works like xrealloc. */ +typedef void *(*line_map_realloc) (void *, size_t); + +/* Physical source file TO_FILE at line TO_LINE at column 0 is represented + by the logical START_LOCATION. TO_LINE+L at column C is represented by + START_LOCATION+(L*(1<<column_bits))+C, as long as C<(1<<column_bits), + and the result_location is less than the next line_map's start_location. + (The top line is line 1 and the leftmost column is column 1; line/column 0 + means "entire file/line" or "unknown line/column" or "not applicable".) + INCLUDED_FROM is an index into the set that gives the line mapping + at whose end the current one was included. File(s) at the bottom + of the include stack have this set to -1. REASON is the reason for + creation of this line map, SYSP is one for a system header, two for + a C system header file that therefore needs to be extern "C" + protected in C++, and zero otherwise. */ +struct GTY(()) line_map { + const char *to_file; + linenum_type to_line; + source_location start_location; + int included_from; + ENUM_BITFIELD (lc_reason) reason : CHAR_BIT; + /* The sysp field isn't really needed now that it's in cpp_buffer. */ + unsigned char sysp; + /* Number of the low-order source_location bits used for a column number. */ + unsigned int column_bits : 8; +}; + +/* A set of chronological line_map structures. */ +struct GTY(()) line_maps { + struct line_map * GTY ((length ("%h.used"))) maps; + unsigned int allocated; + unsigned int used; + + unsigned int cache; + + /* The most recently listed include stack, if any, starts with + LAST_LISTED as the topmost including file. -1 indicates nothing + has been listed yet. */ + int last_listed; + + /* Depth of the include stack, including the current file. */ + unsigned int depth; + + /* If true, prints an include trace a la -H. */ + bool trace_includes; + + /* Highest source_location "given out". */ + source_location highest_location; + + /* Start of line of highest source_location "given out". */ + source_location highest_line; + + /* The maximum column number we can quickly allocate. Higher numbers + may require allocating a new line_map. */ + unsigned int max_column_hint; + + /* If non-null, the allocator to use when resizing 'maps'. If null, + xrealloc is used. */ + line_map_realloc reallocator; +}; + +/* Initialize a line map set. */ +extern void linemap_init (struct line_maps *); + +/* Free a line map set. */ +extern void linemap_free (struct line_maps *); + +/* Check for and warn about line_maps entered but not exited. */ + +extern void linemap_check_files_exited (struct line_maps *); + +/* Return a source_location for the start (i.e. column==0) of + (physical) line TO_LINE in the current source file (as in the + most recent linemap_add). MAX_COLUMN_HINT is the highest column + number we expect to use in this line (but it does not change + the highest_location). */ + +extern source_location linemap_line_start +(struct line_maps *set, linenum_type to_line, unsigned int max_column_hint); + +/* Add a mapping of logical source line to physical source file and + line number. + + The text pointed to by TO_FILE must have a lifetime + at least as long as the final call to lookup_line (). An empty + TO_FILE means standard input. If reason is LC_LEAVE, and + TO_FILE is NULL, then TO_FILE, TO_LINE and SYSP are given their + natural values considering the file we are returning to. + + A call to this function can relocate the previous set of + maps, so any stored line_map pointers should not be used. */ +extern const struct line_map *linemap_add + (struct line_maps *, enum lc_reason, unsigned int sysp, + const char *to_file, linenum_type to_line); + +/* Given a logical line, returns the map from which the corresponding + (source file, line) pair can be deduced. */ +extern const struct line_map *linemap_lookup + (struct line_maps *, source_location); + +/* source_location values from 0 to RESERVED_LOCATION_COUNT-1 will + be reserved for libcpp user as special values, no token from libcpp + will contain any of those locations. */ +#define RESERVED_LOCATION_COUNT 2 + +/* Converts a map and a source_location to source line. */ +#define SOURCE_LINE(MAP, LOC) \ + ((((LOC) - (MAP)->start_location) >> (MAP)->column_bits) + (MAP)->to_line) + +#define SOURCE_COLUMN(MAP, LOC) \ + (((LOC) - (MAP)->start_location) & ((1 << (MAP)->column_bits) - 1)) + +/* Returns the last source line within a map. This is the (last) line + of the #include, or other directive, that caused a map change. */ +#define LAST_SOURCE_LINE(MAP) \ + SOURCE_LINE (MAP, LAST_SOURCE_LINE_LOCATION (MAP)) +#define LAST_SOURCE_COLUMN(MAP) \ + SOURCE_COLUMN (MAP, LAST_SOURCE_LINE_LOCATION (MAP)) +#define LAST_SOURCE_LINE_LOCATION(MAP) \ + ((((MAP)[1].start_location - 1 - (MAP)->start_location) \ + & ~((1 << (MAP)->column_bits) - 1)) \ + + (MAP)->start_location) + +/* Returns the map a given map was included from. */ +#define INCLUDED_FROM(SET, MAP) (&(SET)->maps[(MAP)->included_from]) + +/* Nonzero if the map is at the bottom of the include stack. */ +#define MAIN_FILE_P(MAP) ((MAP)->included_from < 0) + +/* Set LOC to a source position that is the same line as the most recent + linemap_line_start, but with the specified TO_COLUMN column number. */ + +#define LINEMAP_POSITION_FOR_COLUMN(LOC, SET, TO_COLUMN) do { \ + unsigned int to_column = (TO_COLUMN); \ + struct line_maps *set = (SET); \ + if (__builtin_expect (to_column >= set->max_column_hint, 0)) \ + (LOC) = linemap_position_for_column (set, to_column); \ + else { \ + source_location r = set->highest_line; \ + r = r + to_column; \ + if (r >= set->highest_location) \ + set->highest_location = r; \ + (LOC) = r; \ + }} while (0) + + +extern source_location +linemap_position_for_column (struct line_maps *set, unsigned int to_column); + +#endif /* !LIBCPP_LINE_MAP_H */ diff --git a/support/cpp/libcpp/include/mkdeps.h b/support/cpp/libcpp/include/mkdeps.h new file mode 100644 index 0000000..f743ee7 --- /dev/null +++ b/support/cpp/libcpp/include/mkdeps.h @@ -0,0 +1,80 @@ +/* Dependency generator for Makefile fragments. + Copyright (C) 2000, 2001, 2003, 2009 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 3, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. + + 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 LIBCPP_MKDEPS_H +#define LIBCPP_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; +struct cpp_reader; + +/* Create a deps buffer. */ +extern struct deps *deps_init (void); + +/* Destroy a deps buffer. */ +extern void deps_free (struct deps *); + +/* Add a set of "vpath" directories. The second argument is a colon- + separated list of pathnames, like you would set Make's VPATH + variable to. If a dependency or target name begins with any of + these pathnames (and the next path element is not "..") that + pathname is stripped off. */ +extern void deps_add_vpath (struct deps *, const char *); + +/* 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 (struct deps *, const char *, int); + +/* Sets the default target if none has been given already. An empty + string as the default target is interpreted as stdin. */ +extern void deps_add_default_target (struct cpp_reader *, 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 (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 (const struct deps *, FILE *, unsigned int); + +/* Write out a deps buffer to a file, in a form that can be read back + with deps_restore. Returns nonzero on error, in which case the + error number will be in errno. */ +extern int deps_save (struct deps *, FILE *); + +/* Read back dependency information written with deps_save into + the deps buffer. The third argument may be NULL, in which case + the dependency information is just skipped, or it may be a filename, + in which case that filename is skipped. */ +extern int deps_restore (struct deps *, FILE *, const char *); + +/* 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 (const struct deps *, FILE *); + +#endif /* ! LIBCPP_MKDEPS_H */ diff --git a/support/cpp/libcpp/include/symtab.h b/support/cpp/libcpp/include/symtab.h new file mode 100644 index 0000000..4107a6f --- /dev/null +++ b/support/cpp/libcpp/include/symtab.h @@ -0,0 +1,104 @@ +/* Hash tables. + Copyright (C) 2000, 2001, 2003, 2004, 2007, 2008, 2009, 2010 + Free Software Foundation, Inc. + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#ifndef LIBCPP_SYMTAB_H +#define LIBCPP_SYMTAB_H + +#include "obstack.h" + +#ifndef GTY +#define GTY(x) /* nothing */ +#endif + +/* This is what each hash table entry points to. It may be embedded + deeply within another object. */ +typedef struct ht_identifier ht_identifier; +typedef struct ht_identifier *ht_identifier_ptr; +struct GTY(()) ht_identifier { + const unsigned char *str; + unsigned int len; + unsigned int hash_value; +}; + +#define HT_LEN(NODE) ((NODE)->len) +#define HT_STR(NODE) ((NODE)->str) + +typedef struct ht hash_table; +typedef struct ht_identifier *hashnode; + +enum ht_lookup_option {HT_NO_INSERT = 0, HT_ALLOC}; + +/* An identifier hash table for cpplib and the front ends. */ +struct ht +{ + /* Identifiers are allocated from here. */ + struct obstack stack; + + hashnode *entries; + /* Call back, allocate a node. */ + hashnode (*alloc_node) (hash_table *); + /* Call back, allocate something that hangs off a node like a cpp_macro. + NULL means use the usual allocator. */ + void * (*alloc_subobject) (size_t); + + 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; + + /* Should 'entries' be freed when it is no longer needed? */ + bool entries_owned; +}; + +/* Initialize the hashtable with 2 ^ order entries. */ +extern hash_table *ht_create (unsigned int order); + +/* Frees all memory associated with a hash table. */ +extern void ht_destroy (hash_table *); + +extern hashnode ht_lookup (hash_table *, const unsigned char *, + size_t, enum ht_lookup_option); +extern hashnode ht_lookup_with_hash (hash_table *, const unsigned char *, + size_t, unsigned int, + enum ht_lookup_option); +#define HT_HASHSTEP(r, c) ((r) * 67 + ((c) - 113)); +#define HT_HASHFINISH(r, len) ((r) + (len)) + +/* 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) (struct cpp_reader *, hashnode, const void *); +extern void ht_forall (hash_table *, ht_cb, const void *); + +/* For all nodes in TABLE, call the callback. If the callback returns + a nonzero value, the node is removed from the table. */ +extern void ht_purge (hash_table *, ht_cb, const void *); + +/* Restore the hash table. */ +extern void ht_load (hash_table *ht, hashnode *entries, + unsigned int nslots, unsigned int nelements, bool own); + +/* Dump allocation statistics to stderr. */ +extern void ht_dump_statistics (hash_table *); + +#endif /* LIBCPP_SYMTAB_H */ diff --git a/support/cpp/libcpp/init.c b/support/cpp/libcpp/init.c new file mode 100644 index 0000000..a884f46 --- /dev/null +++ b/support/cpp/libcpp/init.c @@ -0,0 +1,721 @@ +/* CPP Library. + Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, + 2009, 2010 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 3, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "cpplib.h" +#include "internal.h" +#include "mkdeps.h" +#ifdef ENABLE_NLS +#include "localedir.h" +#endif + +static void init_library (void); +static void mark_named_operators (cpp_reader *, int); +static void read_original_filename (cpp_reader *); +static void read_original_directory (cpp_reader *); +static void post_options (cpp_reader *); + +/* 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 uchar _cpp_trigraph_map[UCHAR_MAX + 1] = { + +#define END }; +#define s(p, v) [p] = v, + +#else + +#define TRIGRAPH_MAP uchar _cpp_trigraph_map[UCHAR_MAX + 1] = { 0 }; \ + static void init_trigraph_map (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 + +/* A set of booleans indicating what CPP features each source language + requires. */ +struct lang_flags +{ + char c99; + char cplusplus; + char extended_numbers; + char extended_identifiers; + char std; + char cplusplus_comments; + char digraphs; + char uliterals; +}; + +static const struct lang_flags lang_defaults[] = +{ /* c99 c++ xnum xid std // digr ulit */ + /* GNUC89 */ { 0, 0, 1, 0, 0, 1, 1, 0 }, + /* GNUC99 */ { 1, 0, 1, 0, 0, 1, 1, 1 }, + /* GNUC1X */ { 1, 0, 1, 0, 0, 1, 1, 1 }, + /* STDC89 */ { 0, 0, 0, 0, 1, 0, 0, 0 }, + /* STDC94 */ { 0, 0, 0, 0, 1, 0, 1, 0 }, + /* STDC99 */ { 1, 0, 1, 0, 1, 1, 1, 0 }, + /* STDC1X */ { 1, 0, 1, 0, 1, 1, 1, 0 }, + /* GNUCXX */ { 0, 1, 1, 0, 0, 1, 1, 0 }, + /* CXX98 */ { 0, 1, 1, 0, 1, 1, 1, 0 }, + /* GNUCXX0X */ { 1, 1, 1, 0, 0, 1, 1, 1 }, + /* CXX0X */ { 1, 1, 1, 0, 1, 1, 1, 1 }, + /* ASM */ { 0, 0, 1, 0, 0, 1, 0, 0 } + /* xid should be 1 for GNUC99, STDC99, GNUCXX, CXX98, GNUCXX0X, and + CXX0X when no longer experimental (when all uses of identifiers + in the compiler have been audited for correct handling of + extended identifiers). */ +}; + +/* Sets internal flags correctly for a given language. */ +void +cpp_set_lang (cpp_reader *pfile, enum c_lang lang) +{ + const struct lang_flags *l = &lang_defaults[(int) lang]; + + CPP_OPTION (pfile, lang) = lang; + + CPP_OPTION (pfile, c99) = l->c99; + CPP_OPTION (pfile, cplusplus) = l->cplusplus; + CPP_OPTION (pfile, extended_numbers) = l->extended_numbers; + CPP_OPTION (pfile, extended_identifiers) = l->extended_identifiers; + CPP_OPTION (pfile, std) = l->std; + /* Trigraphs processing is always enabled in sdcpp */ + CPP_OPTION (pfile, trigraphs) = 1; + CPP_OPTION (pfile, cplusplus_comments) = l->cplusplus_comments; + CPP_OPTION (pfile, digraphs) = l->digraphs; + CPP_OPTION (pfile, uliterals) = l->uliterals; +} + +/* Initialize library global state. */ +static void +init_library (void) +{ + static int initialized = 0; + + if (! initialized) + { + initialized = 1; + + /* 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 (); + +#ifdef ENABLE_NLS + (void) bindtextdomain (PACKAGE, LOCALEDIR); +#endif + } +} + +/* Initialize a cpp_reader structure. */ +cpp_reader * +cpp_create_reader (enum c_lang lang, hash_table *table, + struct line_maps *line_table) +{ + cpp_reader *pfile; + + /* Initialize this instance of the library if it hasn't been already. */ + init_library (); + + pfile = XCNEW (cpp_reader); + + cpp_set_lang (pfile, lang); + CPP_OPTION (pfile, warn_multichar) = 1; + CPP_OPTION (pfile, discard_comments) = 1; + CPP_OPTION (pfile, discard_comments_in_macro_exp) = 1; + CPP_OPTION (pfile, tabstop) = 8; + CPP_OPTION (pfile, operator_names) = 1; + /* Trigraphs wrning is always enabled in sdcpp */ + CPP_OPTION (pfile, warn_trigraphs) = 1; + CPP_OPTION (pfile, warn_endif_labels) = 1; + CPP_OPTION (pfile, cpp_warn_deprecated) = 1; + CPP_OPTION (pfile, cpp_warn_long_long) = 0; + CPP_OPTION (pfile, dollars_in_ident) = 1; + CPP_OPTION (pfile, warn_dollars) = 1; + CPP_OPTION (pfile, warn_variadic_macros) = 1; + CPP_OPTION (pfile, warn_builtin_macro_redefined) = 1; + CPP_OPTION (pfile, warn_normalize) = normalized_C; + + /* Default CPP arithmetic to something sensible for the host for the + benefit of dumb users like fix-header. */ + CPP_OPTION (pfile, precision) = CHAR_BIT * sizeof (long); + CPP_OPTION (pfile, char_precision) = CHAR_BIT; + CPP_OPTION (pfile, wchar_precision) = CHAR_BIT * sizeof (int); + CPP_OPTION (pfile, int_precision) = CHAR_BIT * sizeof (int); + CPP_OPTION (pfile, unsigned_char) = 0; + CPP_OPTION (pfile, unsigned_wchar) = 1; + CPP_OPTION (pfile, bytes_big_endian) = 1; /* does not matter */ + + /* Default to no charset conversion. */ + CPP_OPTION (pfile, narrow_charset) = _cpp_default_encoding (); + CPP_OPTION (pfile, wide_charset) = 0; + + /* Default the input character set to UTF-8. */ + CPP_OPTION (pfile, input_charset) = _cpp_default_encoding (); + + /* A fake empty "directory" used as the starting point for files + looked up without a search path. Name cannot be '/' because we + don't want to prepend anything at all to filenames using it. All + other entries are correct zero-initialized. */ + pfile->no_search_path.name = (char *) ""; + + /* Initialize the line map. */ + pfile->line_table = line_table; + + /* Initialize lexer state. */ + pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments); + + /* Set up static tokens. */ + pfile->avoid_paste.type = CPP_PADDING; + pfile->avoid_paste.val.source = NULL; + pfile->eof.type = CPP_EOF; + pfile->eof.flags = 0; + + /* Create a token buffer for the lexer. */ + _cpp_init_tokenrun (&pfile->base_run, 250); + pfile->cur_run = &pfile->base_run; + pfile->cur_token = pfile->base_run.base; + + /* Initialize the base context. */ + pfile->context = &pfile->base_context; + pfile->base_context.macro = 0; + pfile->base_context.prev = pfile->base_context.next = 0; + + /* Aligned and unaligned storage. */ + pfile->a_buff = _cpp_get_buff (pfile, 0); + pfile->u_buff = _cpp_get_buff (pfile, 0); + + /* Initialize table for push_macro/pop_macro. */ + pfile->pushed_macros = 0; + + /* The expression parser stack. */ + _cpp_expand_op_stack (pfile); + + /* Initialize the buffer obstack. */ + _obstack_begin (&pfile->buffer_ob, 0, 0, + (void *(*) (size_t)) xmalloc, + (void (*) (void *)) free); + + _cpp_init_files (pfile); + + _cpp_init_hashtable (pfile, table); + + return pfile; +} + +/* Set the line_table entry in PFILE. This is called after reading a + PCH file, as the old line_table will be incorrect. */ +void +cpp_set_line_map (cpp_reader *pfile, struct line_maps *line_table) +{ + pfile->line_table = line_table; +} + +/* Free resources used by PFILE. Accessing PFILE after this function + returns leads to undefined behavior. Returns the error count. */ +void +cpp_destroy (cpp_reader *pfile) +{ + cpp_context *context, *contextn; + struct def_pragma_macro *pmacro; + tokenrun *run, *runn; + int i; + + free (pfile->op_stack); + + while (CPP_BUFFER (pfile) != NULL) + _cpp_pop_buffer (pfile); + + if (pfile->out.base) + free (pfile->out.base); + + if (pfile->macro_buffer) + { + free (pfile->macro_buffer); + pfile->macro_buffer = NULL; + pfile->macro_buffer_len = 0; + } + + if (pfile->deps) + deps_free (pfile->deps); + obstack_free (&pfile->buffer_ob, 0); + + _cpp_destroy_hashtable (pfile); + _cpp_cleanup_files (pfile); + _cpp_destroy_iconv (pfile); + + _cpp_free_buff (pfile->a_buff); + _cpp_free_buff (pfile->u_buff); + _cpp_free_buff (pfile->free_buffs); + + for (run = &pfile->base_run; run; run = runn) + { + runn = run->next; + free (run->base); + if (run != &pfile->base_run) + free (run); + } + + for (context = pfile->base_context.next; context; context = contextn) + { + contextn = context->next; + free (context); + } + + if (pfile->comments.entries) + { + for (i = 0; i < pfile->comments.count; i++) + free (pfile->comments.entries[i].comment); + + free (pfile->comments.entries); + } + if (pfile->pushed_macros) + { + do + { + pmacro = pfile->pushed_macros; + pfile->pushed_macros = pmacro->next; + free (pmacro->name); + free (pmacro); + } + while (pfile->pushed_macros); + } + + free (pfile); +} + +/* This structure defines one built-in identifier. A node will be + entered in the hash table under the name NAME, with value VALUE. + + There are two tables of these. builtin_array holds all the + "builtin" macros: these are handled by builtin_macro() in + macro.c. Builtin is somewhat of a misnomer -- the property of + interest is that these macros require special code to compute their + expansions. The value is a "cpp_builtin_type" enumerator. + + operator_array holds the C++ named operators. These are keywords + which act as aliases for punctuators. In C++, they cannot be + altered through #define, and #if recognizes them as operators. In + C, these are not entered into the hash table at all (but see + <iso646.h>). The value is a token-type enumerator. */ +struct builtin_macro +{ + const uchar *const name; + const unsigned short len; + const unsigned short value; + const bool always_warn_if_redefined; +}; + +#define B(n, t, f) { DSC(n), t, f } +static const struct builtin_macro builtin_array[] = +{ + B("__TIMESTAMP__", BT_TIMESTAMP, false), + B("__TIME__", BT_TIME, false), + B("__DATE__", BT_DATE, false), + B("__FILE__", BT_FILE, false), + B("__func__", BT_FUNCTION, false), + B("__BASE_FILE__", BT_BASE_FILE, false), + B("__LINE__", BT_SPECLINE, true), + B("__INCLUDE_LEVEL__", BT_INCLUDE_LEVEL, true), + B("__COUNTER__", BT_COUNTER, true), + /* Keep builtins not used for -traditional-cpp at the end, and + update init_builtins() if any more are added. */ + B("_Pragma", BT_PRAGMA, true), + B("__STDC__", BT_STDC, true), +}; +#undef B + +struct builtin_operator +{ + const uchar *const name; + const unsigned short len; + const unsigned short value; +}; + +#define B(n, t) { DSC(n), t } +static const struct builtin_operator operator_array[] = +{ + B("and", CPP_AND_AND), + B("and_eq", CPP_AND_EQ), + B("bitand", CPP_AND), + B("bitor", CPP_OR), + B("compl", CPP_COMPL), + B("not", CPP_NOT), + B("not_eq", CPP_NOT_EQ), + B("or", CPP_OR_OR), + B("or_eq", CPP_OR_EQ), + B("xor", CPP_XOR), + B("xor_eq", CPP_XOR_EQ) +}; +#undef B + +/* Mark the C++ named operators in the hash table. */ +static void +mark_named_operators (cpp_reader *pfile, int flags) +{ + const struct builtin_operator *b; + + for (b = operator_array; + b < (operator_array + ARRAY_SIZE (operator_array)); + b++) + { + cpp_hashnode *hp = cpp_lookup (pfile, b->name, b->len); + hp->flags |= flags; + hp->is_directive = 0; + hp->directive_index = b->value; + } +} + +/* Helper function of cpp_type2name. Return the string associated with + named operator TYPE. */ +const char * +cpp_named_operator2name (enum cpp_ttype type) +{ + const struct builtin_operator *b; + + for (b = operator_array; + b < (operator_array + ARRAY_SIZE (operator_array)); + b++) + { + if (type == b->value) + return (const char *) b->name; + } + + return NULL; +} + +void +cpp_init_special_builtins (cpp_reader *pfile) +{ + const struct builtin_macro *b; + size_t n = ARRAY_SIZE (builtin_array); + + if (CPP_OPTION (pfile, traditional)) + n -= 2; + else if (! CPP_OPTION (pfile, stdc_0_in_system_headers) + || CPP_OPTION (pfile, std)) + n--; + + for (b = builtin_array; b < builtin_array + n; b++) + { + cpp_hashnode *hp = cpp_lookup (pfile, b->name, b->len); + hp->type = NT_MACRO; + hp->flags |= NODE_BUILTIN; + if (b->always_warn_if_redefined + || CPP_OPTION (pfile, warn_builtin_macro_redefined)) + hp->flags |= NODE_WARN; + hp->value.builtin = (enum cpp_builtin_type) b->value; + } +} + +/* Read the builtins table above and enter them, and language-specific + macros, into the hash table. HOSTED is true if this is a hosted + environment. */ +void +cpp_init_builtins (cpp_reader *pfile, int hosted) +{ + cpp_init_special_builtins (pfile); + + if (!CPP_OPTION (pfile, traditional) + && (! CPP_OPTION (pfile, stdc_0_in_system_headers) + || CPP_OPTION (pfile, std))) + _cpp_define_builtin (pfile, "__STDC__ 1"); + + if (CPP_OPTION (pfile, cplusplus)) + _cpp_define_builtin (pfile, "__cplusplus 1"); + else if (CPP_OPTION (pfile, lang) == CLK_ASM) + _cpp_define_builtin (pfile, "__ASSEMBLER__ 1"); + else if (CPP_OPTION (pfile, lang) == CLK_STDC94) + _cpp_define_builtin (pfile, "__STDC_VERSION__ 199409L"); + else if (CPP_OPTION (pfile, lang) == CLK_STDC1X + || CPP_OPTION (pfile, lang) == CLK_GNUC1X) + _cpp_define_builtin (pfile, "__STDC_VERSION__ 201112L"); + else if (CPP_OPTION (pfile, c99)) + _cpp_define_builtin (pfile, "__STDC_VERSION__ 199901L"); + + if (hosted) + _cpp_define_builtin (pfile, "__STDC_HOSTED__ 1"); + else + _cpp_define_builtin (pfile, "__STDC_HOSTED__ 0"); + + if (CPP_OPTION (pfile, objc)) + _cpp_define_builtin (pfile, "__OBJC__ 1"); +} + +/* Sanity-checks are dependent on command-line options, so it is + called as a subroutine of cpp_read_main_file (). */ +#if ENABLE_CHECKING +static void sanity_checks (cpp_reader *); +static void sanity_checks (cpp_reader *pfile) +{ + cppchar_t test = 0; + size_t max_precision = 2 * CHAR_BIT * sizeof (cpp_num_part); + + /* Sanity checks for assumptions about CPP arithmetic and target + type precisions made by cpplib. */ + test--; + if (test < 1) + cpp_error (pfile, CPP_DL_ICE, "cppchar_t must be an unsigned type"); + + if (CPP_OPTION (pfile, precision) > max_precision) + cpp_error (pfile, CPP_DL_ICE, + "preprocessor arithmetic has maximum precision of %lu bits;" + " target requires %lu bits", + (unsigned long) max_precision, + (unsigned long) CPP_OPTION (pfile, precision)); + + if (CPP_OPTION (pfile, precision) < CPP_OPTION (pfile, int_precision)) + cpp_error (pfile, CPP_DL_ICE, + "CPP arithmetic must be at least as precise as a target int"); + + if (CPP_OPTION (pfile, char_precision) < 8) + cpp_error (pfile, CPP_DL_ICE, "target char is less than 8 bits wide"); + + if (CPP_OPTION (pfile, wchar_precision) < CPP_OPTION (pfile, char_precision)) + cpp_error (pfile, CPP_DL_ICE, + "target wchar_t is narrower than target char"); + + if (CPP_OPTION (pfile, int_precision) < CPP_OPTION (pfile, char_precision)) + cpp_error (pfile, CPP_DL_ICE, + "target int is narrower than target char"); + + /* This is assumed in eval_token() and could be fixed if necessary. */ + if (sizeof (cppchar_t) > sizeof (cpp_num_part)) + cpp_error (pfile, CPP_DL_ICE, + "CPP half-integer narrower than CPP character"); + + if (CPP_OPTION (pfile, wchar_precision) > BITS_PER_CPPCHAR_T) + cpp_error (pfile, CPP_DL_ICE, + "CPP on this host cannot handle wide character constants over" + " %lu bits, but the target requires %lu bits", + (unsigned long) BITS_PER_CPPCHAR_T, + (unsigned long) CPP_OPTION (pfile, wchar_precision)); +} +#else +# define sanity_checks(PFILE) +#endif + +/* This is called after options have been parsed, and partially + processed. */ +void +cpp_post_options (cpp_reader *pfile) +{ + int flags; + + sanity_checks (pfile); + + post_options (pfile); + + /* Mark named operators before handling command line macros. */ + flags = 0; + if (CPP_OPTION (pfile, cplusplus) && CPP_OPTION (pfile, operator_names)) + flags |= NODE_OPERATOR; + if (CPP_OPTION (pfile, warn_cxx_operator_names)) + flags |= NODE_DIAGNOSTIC | NODE_WARN_OPERATOR; + if (flags != 0) + mark_named_operators (pfile, flags); +} + +/* Setup for processing input from the file named FNAME, or stdin if + it is the empty string. Return the original filename + on success (e.g. foo.i->foo.c), or NULL on failure. */ +const char * +cpp_read_main_file (cpp_reader *pfile, const char *fname) +{ + if (CPP_OPTION (pfile, deps.style) != DEPS_NONE) + { + if (!pfile->deps) + pfile->deps = deps_init (); + + /* Set the default target (if there is none already). */ + deps_add_default_target (pfile, fname); + } + + pfile->main_file + = _cpp_find_file (pfile, fname, &pfile->no_search_path, false, 0); + if (_cpp_find_failed (pfile->main_file)) + return NULL; + + _cpp_stack_file (pfile, pfile->main_file, false); + + /* For foo.i, read the original filename foo.c now, for the benefit + of the front ends. */ + if (CPP_OPTION (pfile, preprocessed)) + { + read_original_filename (pfile); + fname = pfile->line_table->maps[pfile->line_table->used-1].to_file; + } + return fname; +} + +/* For preprocessed files, if the first tokens are of the form # NUM. + handle the directive so we know the original file name. This will + generate file_change callbacks, which the front ends must handle + appropriately given their state of initialization. */ +static void +read_original_filename (cpp_reader *pfile) +{ + const cpp_token *token, *token1; + + /* Lex ahead; if the first tokens are of the form # NUM, then + process the directive, otherwise back up. */ + token = _cpp_lex_direct (pfile); + if (token->type == CPP_HASH) + { + pfile->state.in_directive = 1; + token1 = _cpp_lex_direct (pfile); + _cpp_backup_tokens (pfile, 1); + pfile->state.in_directive = 0; + + /* If it's a #line directive, handle it. */ + if (token1->type == CPP_NUMBER + && _cpp_handle_directive (pfile, token->flags & PREV_WHITE)) + { + read_original_directory (pfile); + return; + } + } + + /* Backup as if nothing happened. */ + _cpp_backup_tokens (pfile, 1); +} + +/* For preprocessed files, if the tokens following the first filename + line is of the form # <line> "/path/name//", handle the + directive so we know the original current directory. */ +static void +read_original_directory (cpp_reader *pfile) +{ + const cpp_token *hash, *token; + + /* Lex ahead; if the first tokens are of the form # NUM, then + process the directive, otherwise back up. */ + hash = _cpp_lex_direct (pfile); + if (hash->type != CPP_HASH) + { + _cpp_backup_tokens (pfile, 1); + return; + } + + token = _cpp_lex_direct (pfile); + + if (token->type != CPP_NUMBER) + { + _cpp_backup_tokens (pfile, 2); + return; + } + + token = _cpp_lex_direct (pfile); + + if (token->type != CPP_STRING + || ! (token->val.str.len >= 5 + && token->val.str.text[token->val.str.len-2] == '/' + && token->val.str.text[token->val.str.len-3] == '/')) + { + _cpp_backup_tokens (pfile, 3); + return; + } + + if (pfile->cb.dir_change) + { + char *debugdir = (char *) alloca (token->val.str.len - 3); + + memcpy (debugdir, (const char *) token->val.str.text + 1, + token->val.str.len - 4); + debugdir[token->val.str.len - 4] = '\0'; + + pfile->cb.dir_change (pfile, debugdir); + } +} + +/* This is called at the end of preprocessing. It pops the last + buffer and writes dependency output. + + Maybe it should also reset state, such that you could call + cpp_start_read with a new filename to restart processing. */ +void +cpp_finish (cpp_reader *pfile, FILE *deps_stream) +{ + /* Warn about unused macros before popping the final buffer. */ + if (CPP_OPTION (pfile, warn_unused_macros)) + cpp_forall_identifiers (pfile, _cpp_warn_if_unused_macro, NULL); + + /* lex.c leaves the final buffer on the stack. This it so that + it returns an unending stream of CPP_EOFs to the client. If we + popped the buffer, we'd dereference a NULL buffer pointer and + segfault. It's nice to allow the client to do worry-free excess + cpp_get_token calls. */ + while (pfile->buffer) + _cpp_pop_buffer (pfile); + + if (CPP_OPTION (pfile, deps.style) != DEPS_NONE + && deps_stream) + { + deps_write (pfile->deps, deps_stream, 72); + + if (CPP_OPTION (pfile, deps.phony_targets)) + deps_phony_targets (pfile->deps, deps_stream); + } + + /* Report on headers that could use multiple include guards. */ + if (CPP_OPTION (pfile, print_include_names)) + _cpp_report_missing_guards (pfile); +} + +static void +post_options (cpp_reader *pfile) +{ + /* -Wtraditional is not useful in C++ mode. */ + if (CPP_OPTION (pfile, cplusplus)) + CPP_OPTION (pfile, cpp_warn_traditional) = 0; + + /* Permanently disable macro expansion if we are rescanning + preprocessed text. Read preprocesed source in ISO mode. */ + if (CPP_OPTION (pfile, preprocessed)) + { + if (!CPP_OPTION (pfile, directives_only)) + pfile->state.prevent_expansion = 1; + CPP_OPTION (pfile, traditional) = 0; + } + + if (CPP_OPTION (pfile, traditional)) + { + CPP_OPTION (pfile, cplusplus_comments) = 0; + } +} diff --git a/support/cpp/libcpp/internal.h b/support/cpp/libcpp/internal.h new file mode 100644 index 0000000..eeed29d --- /dev/null +++ b/support/cpp/libcpp/internal.h @@ -0,0 +1,745 @@ +/* Part of CPP library. + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, + 2008, 2009, 2010 Free Software Foundation, Inc. + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +/* This header defines all the internal data structures and functions + that need to be visible across files. It should not be used outside + cpplib. */ + +#ifndef LIBCPP_INTERNAL_H +#define LIBCPP_INTERNAL_H + +#include "symtab.h" +#include "cpp-id-data.h" + +#if HAVE_ICONV +#include <iconv.h> +#else +#define HAVE_ICONV 0 +typedef int iconv_t; /* dummy */ +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +struct directive; /* Deliberately incomplete. */ +struct pending_option; +struct op; +struct _cpp_strbuf; + +typedef bool (*convert_f) (iconv_t, const unsigned char *, size_t, + struct _cpp_strbuf *); +struct cset_converter +{ + convert_f func; + iconv_t cd; + int width; +}; + +#define BITS_PER_CPPCHAR_T (CHAR_BIT * sizeof (cppchar_t)) + +/* 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_COLUMN(BUF, CUR) ((CUR) - (BUF)->line_base) +#define CPP_BUF_COL(BUF) CPP_BUF_COLUMN(BUF, (BUF)->cur) + +#define CPP_INCREMENT_LINE(PFILE, COLS_HINT) do { \ + const struct line_maps *line_table = PFILE->line_table; \ + const struct line_map *map = &line_table->maps[line_table->used-1]; \ + linenum_type line = SOURCE_LINE (map, line_table->highest_line); \ + linemap_line_start (PFILE->line_table, line + 1, COLS_HINT); \ + } while (0) + +/* Maximum nesting of cpp_buffers. We use a static limit, partly for + efficiency, and partly to limit runaway recursion. */ +#define CPP_STACK_MAX 200 + +/* Host alignment handling. */ +struct dummy +{ + char c; + union + { + double d; + int *p; + } u; +}; + +#define DEFAULT_ALIGNMENT offsetof (struct dummy, u) +#define CPP_ALIGN2(size, align) (((size) + ((align) - 1)) & ~((align) - 1)) +#define CPP_ALIGN(size) CPP_ALIGN2 (size, DEFAULT_ALIGNMENT) + +#define _cpp_mark_macro_used(NODE) do { \ + if ((NODE)->type == NT_MACRO && !((NODE)->flags & NODE_BUILTIN)) \ + (NODE)->value.macro->used = 1; } while (0) + +/* A generic memory buffer, and operations on it. */ +typedef struct _cpp_buff _cpp_buff; +struct _cpp_buff +{ + struct _cpp_buff *next; + unsigned char *base, *cur, *limit; +}; + +extern _cpp_buff *_cpp_get_buff (cpp_reader *, size_t); +extern void _cpp_release_buff (cpp_reader *, _cpp_buff *); +extern void _cpp_extend_buff (cpp_reader *, _cpp_buff **, size_t); +extern _cpp_buff *_cpp_append_extend_buff (cpp_reader *, _cpp_buff *, size_t); +extern void _cpp_free_buff (_cpp_buff *); +extern unsigned char *_cpp_aligned_alloc (cpp_reader *, size_t); +extern unsigned char *_cpp_unaligned_alloc (cpp_reader *, size_t); + +#define BUFF_ROOM(BUFF) (size_t) ((BUFF)->limit - (BUFF)->cur) +#define BUFF_FRONT(BUFF) ((BUFF)->cur) +#define BUFF_LIMIT(BUFF) ((BUFF)->limit) + +/* #include types. */ +enum include_type {IT_INCLUDE, IT_INCLUDE_NEXT, IT_IMPORT, IT_CMDLINE}; + +union utoken +{ + const cpp_token *token; + const cpp_token **ptoken; +}; + +/* A "run" of tokens; part of a chain of runs. */ +typedef struct tokenrun tokenrun; +struct tokenrun +{ + tokenrun *next, *prev; + cpp_token *base, *limit; +}; + +/* Accessor macros for struct cpp_context. */ +#define FIRST(c) ((c)->u.iso.first) +#define LAST(c) ((c)->u.iso.last) +#define CUR(c) ((c)->u.trad.cur) +#define RLIMIT(c) ((c)->u.trad.rlimit) + +typedef struct cpp_context cpp_context; +struct cpp_context +{ + /* Doubly-linked list. */ + cpp_context *next, *prev; + + union + { + /* For ISO macro expansion. Contexts other than the base context + are contiguous tokens. e.g. macro expansions, expanded + argument tokens. */ + struct + { + union utoken first; + union utoken last; + } iso; + + /* For traditional macro expansion. */ + struct + { + const unsigned char *cur; + const unsigned char *rlimit; + } trad; + } u; + + /* If non-NULL, a buffer used for storage related to this context. + When the context is popped, the buffer is released. */ + _cpp_buff *buff; + + /* For a macro context, the macro node, otherwise NULL. */ + cpp_hashnode *macro; + + /* True if utoken element is token, else ptoken. */ + bool direct_p; +}; + +struct lexer_state +{ + /* Nonzero if first token on line is CPP_HASH. */ + unsigned char in_directive; + + /* Nonzero if in a directive that will handle padding tokens itself. + #include needs this to avoid problems with computed include and + spacing between tokens. */ + unsigned char directive_wants_padding; + + /* True if we are skipping a failed conditional group. */ + unsigned char skipping; + + /* Nonzero if in a directive that takes angle-bracketed headers. */ + unsigned char angled_headers; + + /* Nonzero if in a #if or #elif directive. */ + unsigned char in_expression; + + /* Nonzero to save comments. Turned off if discard_comments, and in + all directives apart from #define. */ + unsigned char save_comments; + + /* 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 if prevent_expansion is true only because output is + being discarded. */ + unsigned char discarding_output; + + /* Nonzero to skip evaluating part of an expression. */ + unsigned int skip_eval; + + /* Nonzero when handling a deferred pragma. */ + unsigned char in_deferred_pragma; + + /* Nonzero if the deferred pragma being handled allows macro expansion. */ + unsigned char pragma_allow_expansion; +}; + +/* Special nodes - identifiers with predefined significance. */ +struct spec_nodes +{ + cpp_hashnode *n_defined; /* defined operator */ + cpp_hashnode *n_true; /* C++ keyword true */ + cpp_hashnode *n_false; /* C++ keyword false */ + cpp_hashnode *n__VA_ARGS__; /* C99 vararg macros */ + /* SDCC _asm specific */ + cpp_hashnode *n__asm; /* __asm ... __endasm ; */ + cpp_hashnode *n__endasm; /* __asm ... __endasm ; */ +}; + +typedef struct _cpp_line_note _cpp_line_note; +struct _cpp_line_note +{ + /* Location in the clean line the note refers to. */ + const unsigned char *pos; + + /* Type of note. The 9 'from' trigraph characters represent those + trigraphs, '\\' an escaped newline, ' ' an escaped newline with + intervening space, 0 represents a note that has already been handled, + and anything else is invalid. */ + unsigned int type; +}; + +/* Represents the contents of a file cpplib has read in. */ +struct cpp_buffer +{ + const unsigned char *cur; /* Current location. */ + const unsigned char *line_base; /* Start of current physical line. */ + const unsigned char *next_line; /* Start of to-be-cleaned logical line. */ + + const unsigned char *buf; /* Entire character buffer. */ + const unsigned char *rlimit; /* Writable byte at end of file. */ + + _cpp_line_note *notes; /* Array of notes. */ + unsigned int cur_note; /* Next note to process. */ + unsigned int notes_used; /* Number of notes. */ + unsigned int notes_cap; /* Size of allocated array. */ + + struct cpp_buffer *prev; + + /* Pointer into the file table; non-NULL if this is a file buffer. + Used for include_next and to record control macros. */ + struct _cpp_file *file; + + /* Saved value of __TIMESTAMP__ macro - date and time of last modification + of the assotiated file. */ + const unsigned char *timestamp; + + /* Value of if_stack at start of this file. + Used to prohibit unmatched #endif (etc) in an include file. */ + struct if_stack *if_stack; + + /* True if we need to get the next clean line. */ + bool need_line; + + /* 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 int warned_cplusplus_comments : 1; + + /* True if we don't process trigraphs and escaped newlines. True + for preprocessed input, command line directives, and _Pragma + buffers. */ + unsigned int from_stage3 : 1; + + /* At EOF, a buffer is automatically popped. If RETURN_AT_EOF is + true, a CPP_EOF token is then returned. Otherwise, the next + token from the enclosing buffer is returned. */ + unsigned int return_at_eof : 1; + + /* One for a system header, two for a C system header file that therefore + needs to be extern "C" protected in C++, and zero otherwise. */ + unsigned char sysp; + + /* 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 cpp_dir dir; + + /* Descriptor for converting from the input character set to the + source character set. */ + struct cset_converter input_cset_desc; +}; + +/* The list of saved macros by push_macro pragma. */ +struct def_pragma_macro { + /* Chain element to previous saved macro. */ + struct def_pragma_macro *next; + /* Name of the macro. */ + char *name; + /* The stored macro content. */ + unsigned char *definition; + + /* Definition line number. */ + source_location line; + /* If macro defined in system header. */ + unsigned int syshdr : 1; + /* Nonzero if it has been expanded or had its existence tested. */ + unsigned int used : 1; + + /* Mark if we save an undefined macro. */ + unsigned int is_undef : 1; +}; + +/* 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; + + /* Overlaid buffer (can be different after processing #include). */ + cpp_buffer *overlaid_buffer; + + /* Lexer state. */ + struct lexer_state state; + + /* Source line tracking. */ + struct line_maps *line_table; + + /* The line of the '#' of the current directive. */ + source_location directive_line; + + /* Memory buffers. */ + _cpp_buff *a_buff; /* Aligned permanent storage. */ + _cpp_buff *u_buff; /* Unaligned permanent storage. */ + _cpp_buff *free_buffs; /* Free buffer chain. */ + + /* Context stack. */ + struct cpp_context base_context; + struct cpp_context *context; + + /* If in_directive, the directive if known. */ + const struct directive *directive; + + /* Token generated while handling a directive, if any. */ + cpp_token directive_result; + + /* When expanding a macro at top-level, this is the location of the + macro invocation. */ + source_location invocation_location; + + /* True if this call to cpp_get_token should consider setting + invocation_location. */ + bool set_invocation_location; + + /* Search paths for include files. */ + struct cpp_dir *quote_include; /* "" */ + struct cpp_dir *bracket_include; /* <> */ + struct cpp_dir no_search_path; /* No path. */ + + /* Chain of all hashed _cpp_file instances. */ + struct _cpp_file *all_files; + + struct _cpp_file *main_file; + + /* File and directory hash table. */ + struct htab *file_hash; + struct htab *dir_hash; + struct file_hash_entry_pool *file_hash_entries; + + /* Negative path lookup hash table. */ + struct htab *nonexistent_file_hash; + struct obstack nonexistent_file_ob; + + /* Nonzero means don't look for #include "foo" the source-file + directory. */ + bool quote_ignores_source_dir; + + /* Nonzero if any file has contained #pragma once or #import has + been used. */ + bool seen_once_only; + + /* Multiple include optimization. */ + const cpp_hashnode *mi_cmacro; + const cpp_hashnode *mi_ind_cmacro; + bool mi_valid; + + /* Lexing. */ + cpp_token *cur_token; + tokenrun base_run, *cur_run; + unsigned int lookaheads; + + /* Nonzero prevents the lexer from re-using the token runs. */ + unsigned int keep_tokens; + + /* Buffer to hold macro definition string. */ + unsigned char *macro_buffer; + unsigned int macro_buffer_len; + + /* Descriptor for converting from the source character set to the + execution character set. */ + struct cset_converter narrow_cset_desc; + + /* Descriptor for converting from the source character set to the + UTF-8 execution character set. */ + struct cset_converter utf8_cset_desc; + + /* Descriptor for converting from the source character set to the + UTF-16 execution character set. */ + struct cset_converter char16_cset_desc; + + /* Descriptor for converting from the source character set to the + UTF-32 execution character set. */ + struct cset_converter char32_cset_desc; + + /* Descriptor for converting from the source character set to the + wide execution character set. */ + struct cset_converter wide_cset_desc; + + /* Date and time text. Calculated together if either is requested. */ + const unsigned char *date; + const unsigned char *time; + + /* EOF token, and a token forcing paste avoidance. */ + cpp_token avoid_paste; + cpp_token eof; + + /* Opaque handle to the dependencies of mkdeps.c. */ + struct deps *deps; + + /* Obstack holding all macro hash nodes. This never shrinks. + See identifiers.c */ + struct obstack hash_ob; + + /* Obstack holding buffer and conditional structures. This is a + real stack. See directives.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 to cpplib client. */ + struct cpp_callbacks cb; + + /* Identifier hash table. */ + struct ht *hash_table; + + /* Expression parser stack. */ + struct op *op_stack, *op_limit; + + /* User visible options. */ + struct cpp_options opts; + + /* Special nodes - identifiers with predefined significance to the + preprocessor. */ + struct spec_nodes spec_nodes; + + /* Whether cpplib owns the hashtable. */ + bool our_hashtable; + + /* Traditional preprocessing output buffer (a logical line). */ + struct + { + unsigned char *base; + unsigned char *limit; + unsigned char *cur; + source_location first_line; + } out; + + /* Used for buffer overlays by traditional.c. */ + const unsigned char *saved_cur, *saved_rlimit, *saved_line_base; + + /* A saved list of the defined macros, for dependency checking + of precompiled headers. */ + struct cpp_savedstate *savedstate; + + /* Next value of __COUNTER__ macro. */ + unsigned int counter; + + /* Table of comments, when state.save_comments is true. */ + cpp_comment_table comments; + + /* List of saved macros by push_macro. */ + struct def_pragma_macro *pushed_macros; +}; + +/* 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 lex.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. */ + +static inline int cpp_in_system_header (cpp_reader *); +static inline int +cpp_in_system_header (cpp_reader *pfile) +{ + return pfile->buffer ? pfile->buffer->sysp : 0; +} +#define CPP_PEDANTIC(PF) CPP_OPTION (PF, cpp_pedantic) +#define CPP_WTRADITIONAL(PF) CPP_OPTION (PF, cpp_warn_traditional) + +static inline int cpp_in_primary_file (cpp_reader *); +static inline int +cpp_in_primary_file (cpp_reader *pfile) +{ + return pfile->line_table->depth == 1; +} + +/* In macro.c */ +extern void _cpp_free_definition (cpp_hashnode *); +extern bool _cpp_create_definition (cpp_reader *, cpp_hashnode *); +extern void _cpp_pop_context (cpp_reader *); +extern void _cpp_push_text_context (cpp_reader *, cpp_hashnode *, + const unsigned char *, size_t); +extern bool _cpp_save_parameter (cpp_reader *, cpp_macro *, cpp_hashnode *); +extern bool _cpp_arguments_ok (cpp_reader *, cpp_macro *, const cpp_hashnode *, + unsigned int); +extern const unsigned char *_cpp_builtin_macro_text (cpp_reader *, + cpp_hashnode *); +extern int _cpp_warn_if_unused_macro (cpp_reader *, cpp_hashnode *, void *); +extern void _cpp_push_token_context (cpp_reader *, cpp_hashnode *, + const cpp_token *, unsigned int); +extern void _cpp_backup_tokens_direct (cpp_reader *, unsigned int); + +/* In identifiers.c */ +extern void _cpp_init_hashtable (cpp_reader *, hash_table *); +extern void _cpp_destroy_hashtable (cpp_reader *); + +/* In files.c */ +typedef struct _cpp_file _cpp_file; +extern _cpp_file *_cpp_find_file (cpp_reader *, const char *, cpp_dir *, + bool, int); +extern bool _cpp_find_failed (_cpp_file *); +extern void _cpp_mark_file_once_only (cpp_reader *, struct _cpp_file *); +extern void _cpp_fake_include (cpp_reader *, const char *); +extern bool _cpp_stack_file (cpp_reader *, _cpp_file*, bool); +extern bool _cpp_stack_include (cpp_reader *, const char *, int, + enum include_type); +extern int _cpp_compare_file_date (cpp_reader *, const char *, int); +extern void _cpp_report_missing_guards (cpp_reader *); +extern void _cpp_init_files (cpp_reader *); +extern void _cpp_cleanup_files (cpp_reader *); +extern void _cpp_pop_file_buffer (cpp_reader *, struct _cpp_file *); +extern bool _cpp_save_file_entries (cpp_reader *pfile, FILE *f); +extern bool _cpp_read_file_entries (cpp_reader *, FILE *); +extern struct stat *_cpp_get_file_stat (_cpp_file *); + +/* In expr.c */ +extern bool _cpp_parse_expr (cpp_reader *, bool); +extern struct op *_cpp_expand_op_stack (cpp_reader *); + +/* In lex.c */ +extern int _cpp_process_line_notes (cpp_reader *, int); +extern void _cpp_clean_line (cpp_reader *); +extern bool _cpp_get_fresh_line (cpp_reader *); +extern bool _cpp_skip_block_comment (cpp_reader *); +extern cpp_token *_cpp_temp_token (cpp_reader *); +extern const cpp_token *_cpp_lex_token (cpp_reader *); +extern cpp_token *_cpp_lex_direct (cpp_reader *); +extern int _cpp_equiv_tokens (const cpp_token *, const cpp_token *); +extern void _cpp_init_tokenrun (tokenrun *, unsigned int); +extern cpp_hashnode *_cpp_lex_identifier (cpp_reader *, const char *); + +/* In init.c. */ +extern void _cpp_maybe_push_include_file (cpp_reader *); +extern const char *cpp_named_operator2name (enum cpp_ttype type); + +/* In directives.c */ +extern int _cpp_test_assertion (cpp_reader *, unsigned int *); +extern int _cpp_handle_directive (cpp_reader *, int); +extern void _cpp_define_builtin (cpp_reader *, const char *); +extern char ** _cpp_save_pragma_names (cpp_reader *); +extern void _cpp_restore_pragma_names (cpp_reader *, char **); +extern int _cpp_do__Pragma (cpp_reader *); +extern void _cpp_init_directives (cpp_reader *); +extern void _cpp_init_internal_pragmas (cpp_reader *); +extern void _cpp_do_file_change (cpp_reader *, enum lc_reason, const char *, + linenum_type, unsigned int); +extern void _cpp_pop_buffer (cpp_reader *); + +/* In directives.c */ +struct _cpp_dir_only_callbacks +{ + /* Called to print a block of lines. */ + void (*print_lines) (int, const void *, size_t); + void (*maybe_print_line) (source_location); +}; + +extern void _cpp_preprocess_dir_only (cpp_reader *, + const struct _cpp_dir_only_callbacks *); + +/* In traditional.c. */ +extern bool _cpp_scan_out_logical_line (cpp_reader *, cpp_macro *); +extern bool _cpp_read_logical_line_trad (cpp_reader *); +extern void _cpp_overlay_buffer (cpp_reader *pfile, const unsigned char *, + size_t); +extern void _cpp_remove_overlay (cpp_reader *); +extern bool _cpp_create_trad_definition (cpp_reader *, cpp_macro *); +extern bool _cpp_expansions_different_trad (const cpp_macro *, + const cpp_macro *); +extern unsigned char *_cpp_copy_replacement_text (const cpp_macro *, + unsigned char *); +extern size_t _cpp_replacement_text_len (const cpp_macro *); + +/* In charset.c. */ + +/* The normalization state at this point in the sequence. + It starts initialized to all zeros, and at the end + 'level' is the normalization level of the sequence. */ + +struct normalize_state +{ + /* The previous character. */ + cppchar_t previous; + /* The combining class of the previous character. */ + unsigned char prev_class; + /* The lowest normalization level so far. */ + enum cpp_normalize_level level; +}; +#define INITIAL_NORMALIZE_STATE { 0, 0, normalized_KC } +#define NORMALIZE_STATE_RESULT(st) ((st)->level) + +/* We saw a character that matches ISIDNUM(), update a + normalize_state appropriately. */ +#define NORMALIZE_STATE_UPDATE_IDNUM(st) \ + ((st)->previous = 0, (st)->prev_class = 0) + +extern cppchar_t _cpp_valid_ucn (cpp_reader *, const unsigned char **, + const unsigned char *, int, + struct normalize_state *state); +extern void _cpp_destroy_iconv (cpp_reader *); +extern unsigned char *_cpp_convert_input (cpp_reader *, const char *, + unsigned char *, size_t, size_t, + const unsigned char **, off_t *); +extern const char *_cpp_default_encoding (void); +extern cpp_hashnode * _cpp_interpret_identifier (cpp_reader *pfile, + const unsigned char *id, + size_t len); + +/* Utility routines and macros. */ +#define DSC(str) (const unsigned char *)str, sizeof str - 1 + +/* These are inline functions instead of macros so we can get type + checking. */ +static inline int ustrcmp (const unsigned char *, const unsigned char *); +static inline int ustrncmp (const unsigned char *, const unsigned char *, + size_t); +static inline size_t ustrlen (const unsigned char *); +static inline unsigned char *uxstrdup (const unsigned char *); +static inline unsigned char *ustrchr (const unsigned char *, int); +static inline int ufputs (const unsigned char *, FILE *); + +/* Use a const char for the second parameter since it is usually a literal. */ +static inline int ustrcspn (const unsigned char *, const char *); + +static inline int +ustrcmp (const unsigned char *s1, const unsigned char *s2) +{ + return strcmp ((const char *)s1, (const char *)s2); +} + +static inline int +ustrncmp (const unsigned char *s1, const unsigned char *s2, size_t n) +{ + return strncmp ((const char *)s1, (const char *)s2, n); +} + +static inline int +ustrcspn (const unsigned char *s1, const char *s2) +{ + return strcspn ((const char *)s1, s2); +} + +static inline size_t +ustrlen (const unsigned char *s1) +{ + return strlen ((const char *)s1); +} + +static inline unsigned char * +uxstrdup (const unsigned char *s1) +{ + return (unsigned char *) xstrdup ((const char *)s1); +} + +static inline unsigned char * +ustrchr (const unsigned char *s1, int c) +{ + return (unsigned char *) strchr ((const char *)s1, c); +} + +static inline int +ufputs (const unsigned char *s, FILE *f) +{ + return fputs ((const char *)s, f); +} + +#ifdef __cplusplus +} +#endif + +#endif /* ! LIBCPP_INTERNAL_H */ diff --git a/support/cpp/libcpp/lex.c b/support/cpp/libcpp/lex.c new file mode 100644 index 0000000..ccb4b0f --- /dev/null +++ b/support/cpp/libcpp/lex.c @@ -0,0 +1,2906 @@ +/* CPP Library - lexical analysis. + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010 + 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 + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "cpplib.h" +#include "internal.h" +#include <assert.h> + +enum spell_type +{ + SPELL_OPERATOR = 0, + SPELL_IDENT, + SPELL_LITERAL, + SPELL_NONE +}; + +struct token_spelling +{ + enum spell_type category; + const unsigned char *name; +}; + +static const unsigned char *const digraph_spellings[] = +{ UC"%:", UC"%:%:", UC"<:", UC":>", UC"<%", UC"%>" }; + +#define OP(e, s) { SPELL_OPERATOR, UC s }, +#define TK(e, s) { SPELL_ ## s, UC #e }, +static 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 void add_line_note (cpp_buffer *, const uchar *, unsigned int); +static int skip_line_comment (cpp_reader *); +static void skip_whitespace (cpp_reader *, cppchar_t); +static void lex_string (cpp_reader *, cpp_token *, const uchar *); +static void save_comment (cpp_reader *, cpp_token *, const uchar *, cppchar_t); +static void store_comment (cpp_reader *, cpp_token *); +static void create_literal (cpp_reader *, cpp_token *, const uchar *, + unsigned int, enum cpp_ttype); +static bool warn_in_comment (cpp_reader *, _cpp_line_note *); +static int name_p (cpp_reader *, const cpp_string *); +static tokenrun *next_tokenrun (tokenrun *); + +static _cpp_buff *new_buff (size_t); + +int in_asm = 0; + +/* 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 (const cpp_token *token, const char *string) +{ + if (token->type != CPP_NAME) + return 0; + + return !ustrcmp (NODE_NAME (token->val.node.node), (const uchar *) string); +} + +/* Record a note TYPE at byte POS into the current cleaned logical + line. */ +static void +add_line_note (cpp_buffer *buffer, const uchar *pos, unsigned int type) +{ + if (buffer->notes_used == buffer->notes_cap) + { + buffer->notes_cap = buffer->notes_cap * 2 + 200; + buffer->notes = XRESIZEVEC (_cpp_line_note, buffer->notes, + buffer->notes_cap); + } + + buffer->notes[buffer->notes_used].pos = pos; + buffer->notes[buffer->notes_used].type = type; + buffer->notes_used++; +} + + +/* Fast path to find line special characters using optimized character + scanning algorithms. Anything complicated falls back to the slow + path below. Since this loop is very hot it's worth doing these kinds + of optimizations. + + One of the paths through the ifdefs should provide + + const uchar *search_line_fast (const uchar *s, const uchar *end); + + Between S and END, search for \n, \r, \\, ?. Return a pointer to + the found character. + + Note that the last character of the buffer is *always* a newline, + as forced by _cpp_convert_input. This fact can be used to avoid + explicitly looking for the end of the buffer. */ + +/* Configure gives us an ifdef test. */ +#ifndef WORDS_BIGENDIAN +#define WORDS_BIGENDIAN 0 +#endif + +/* We'd like the largest integer that fits into a register. There's nothing + in <stdint.h> that gives us that. For most hosts this is unsigned long, + but MS decided on an LLP64 model. Thankfully when building with GCC we + can get the "real" word size. */ +#ifdef __GNUC__ +typedef unsigned int word_type __attribute__((__mode__(__word__))); +#else +typedef unsigned long word_type; +#endif + +/* The code below is only expecting sizes 4 or 8. + Die at compile-time if this expectation is violated. */ +typedef char check_word_type_size + [(sizeof(word_type) == 8 || sizeof(word_type) == 4) * 2 - 1]; + +/* Return X with the first N bytes forced to values that won't match one + of the interesting characters. Note that NUL is not interesting. */ + +static inline word_type +acc_char_mask_misalign (word_type val, unsigned int n) +{ + word_type mask = -1; + if (WORDS_BIGENDIAN) + mask >>= n * 8; + else + mask <<= n * 8; + return val & mask; +} + +/* Return X replicated to all byte positions within WORD_TYPE. */ + +static inline word_type +acc_char_replicate (uchar x) +{ + word_type ret; + + ret = (x << 24) | (x << 16) | (x << 8) | x; + if (sizeof(word_type) == 8) + ret = (ret << 16 << 16) | ret; + return ret; +} + +/* Return non-zero if some byte of VAL is (probably) C. */ + +static inline word_type +acc_char_cmp (word_type val, word_type c) +{ +#if defined(__GNUC__) && defined(__alpha__) + /* We can get exact results using a compare-bytes instruction. + Get (val == c) via (0 >= (val ^ c)). */ + return __builtin_alpha_cmpbge (0, val ^ c); +#else + word_type magic = 0x7efefefeU; + if (sizeof(word_type) == 8) + magic = (magic << 16 << 16) | 0xfefefefeU; + magic |= 1; + + val ^= c; + return ((val + magic) ^ ~val) & ~magic; +#endif +} + +/* Given the result of acc_char_cmp is non-zero, return the index of + the found character. If this was a false positive, return -1. */ + +static inline int +acc_char_index (word_type cmp ATTRIBUTE_UNUSED, + word_type val ATTRIBUTE_UNUSED) +{ +#if defined(__GNUC__) && defined(__alpha__) && !WORDS_BIGENDIAN + /* The cmpbge instruction sets *bits* of the result corresponding to + matches in the bytes with no false positives. */ + return __builtin_ctzl (cmp); +#else + unsigned int i; + + /* ??? It would be nice to force unrolling here, + and have all of these constants folded. */ + for (i = 0; i < sizeof(word_type); ++i) + { + uchar c; + if (WORDS_BIGENDIAN) + c = (val >> (sizeof(word_type) - i - 1) * 8) & 0xff; + else + c = (val >> i * 8) & 0xff; + + if (c == '\n' || c == '\r' || c == '\\' || c == '?') + return i; + } + + return -1; +#endif +} + +/* A version of the fast scanner using bit fiddling techniques. + + For 32-bit words, one would normally perform 16 comparisons and + 16 branches. With this algorithm one performs 24 arithmetic + operations and one branch. Whether this is faster with a 32-bit + word size is going to be somewhat system dependent. + + For 64-bit words, we eliminate twice the number of comparisons + and branches without increasing the number of arithmetic operations. + It's almost certainly going to be a win with 64-bit word size. */ + +static const uchar * search_line_acc_char (const uchar *, const uchar *) + ATTRIBUTE_UNUSED; + +static const uchar * +search_line_acc_char (const uchar *s, const uchar *end ATTRIBUTE_UNUSED) +{ + const word_type repl_nl = acc_char_replicate ('\n'); + const word_type repl_cr = acc_char_replicate ('\r'); + const word_type repl_bs = acc_char_replicate ('\\'); + const word_type repl_qm = acc_char_replicate ('?'); + + unsigned int misalign; + const word_type *p; + word_type val, t; + + /* Align the buffer. Mask out any bytes from before the beginning. */ + p = (word_type *)((uintptr_t)s & -sizeof(word_type)); + val = *p; + misalign = (uintptr_t)s & (sizeof(word_type) - 1); + if (misalign) + val = acc_char_mask_misalign (val, misalign); + + /* Main loop. */ + while (1) + { + t = acc_char_cmp (val, repl_nl); + t |= acc_char_cmp (val, repl_cr); + t |= acc_char_cmp (val, repl_bs); + t |= acc_char_cmp (val, repl_qm); + + if (__builtin_expect (t != 0, 0)) + { + int i = acc_char_index (t, val); + if (i >= 0) + return (const uchar *)p + i; + } + + val = *++p; + } +} + +#define search_line_fast search_line_acc_char + +/* Returns with a logical line that contains no escaped newlines or + trigraphs. This is a time-critical inner loop. */ +void +_cpp_clean_line (cpp_reader *pfile) +{ + cpp_buffer *buffer; + const uchar *s; + uchar c, *d, *p; + + buffer = pfile->buffer; + buffer->cur_note = buffer->notes_used = 0; + buffer->cur = buffer->line_base = buffer->next_line; + buffer->need_line = false; + s = buffer->next_line; + + if (!buffer->from_stage3) + { + const uchar *pbackslash = NULL; + + /* Fast path. This is the common case of an un-escaped line with + no trigraphs. The primary win here is by not writing any + data back to memory until we have to. */ + while (1) + { + /* Perform an optimized search for \n, \r, \\, ?. */ + s = search_line_fast (s, buffer->rlimit); + + c = *s; + if (c == '\\') + { + /* Record the location of the backslash and continue. */ + pbackslash = s++; + } + else if (__builtin_expect (c == '?', 0)) + { + if (__builtin_expect (s[1] == '?', false) + && _cpp_trigraph_map[s[2]]) + { + /* Have a trigraph. We may or may not have to convert + it. Add a line note regardless, for -Wtrigraphs. */ + add_line_note (buffer, s, s[2]); + if (CPP_OPTION (pfile, trigraphs)) + { + /* We do, and that means we have to switch to the + slow path. */ + d = (uchar *) s; + *d = _cpp_trigraph_map[s[2]]; + s += 2; + goto slow_path; + } + } + /* Not a trigraph. Continue on fast-path. */ + s++; + } + else + break; + } + + /* This must be \r or \n. We're either done, or we'll be forced + to write back to the buffer and continue on the slow path. */ + d = (uchar *) s; + + if (__builtin_expect (s == buffer->rlimit, false)) + goto done; + + /* DOS line ending? */ + if (__builtin_expect (c == '\r', false) && s[1] == '\n') + { + s++; + if (s == buffer->rlimit) + goto done; + } + + if (__builtin_expect (pbackslash == NULL, true)) + goto done; + + /* Check for escaped newline. */ + p = d; + while (is_nvspace (p[-1])) + p--; + if (p - 1 != pbackslash) + goto done; + + /* Have an escaped newline; process it and proceed to + the slow path. */ + add_line_note (buffer, p - 1, p != d ? ' ' : '\\'); + d = p - 2; + buffer->next_line = p - 1; + + slow_path: + while (1) + { + c = *++s; + *++d = c; + + if (c == '\n' || c == '\r') + { + /* Handle DOS line endings. */ + if (c == '\r' && s != buffer->rlimit && s[1] == '\n') + s++; + if (s == buffer->rlimit) + break; + + /* Escaped? */ + p = d; + while (p != buffer->next_line && is_nvspace (p[-1])) + p--; + if (p == buffer->next_line || p[-1] != '\\') + break; + + add_line_note (buffer, p - 1, p != d ? ' ': '\\'); + d = p - 2; + buffer->next_line = p - 1; + } + else if (c == '?' && s[1] == '?' && _cpp_trigraph_map[s[2]]) + { + /* Add a note regardless, for the benefit of -Wtrigraphs. */ + add_line_note (buffer, d, s[2]); + if (CPP_OPTION (pfile, trigraphs)) + { + *d = _cpp_trigraph_map[s[2]]; + s += 2; + } + } + } + } + else + { + while (*s != '\n' && *s != '\r') + s++; + d = (uchar *) s; + + /* Handle DOS line endings. */ + if (*s == '\r' && s != buffer->rlimit && s[1] == '\n') + s++; + } + + done: + *d = '\n'; + /* A sentinel note that should never be processed. */ + add_line_note (buffer, d + 1, '\n'); + buffer->next_line = s + 1; +} + +/* Return true if the trigraph indicated by NOTE should be warned + about in a comment. */ +static bool +warn_in_comment (cpp_reader *pfile, _cpp_line_note *note) +{ + const uchar *p; + + /* Within comments we don't warn about trigraphs, unless the + trigraph forms an escaped newline, as that may change + behavior. */ + if (note->type != '/') + return false; + + /* If -trigraphs, then this was an escaped newline iff the next note + is coincident. */ + if (CPP_OPTION (pfile, trigraphs)) + return note[1].pos == note->pos; + + /* Otherwise, see if this forms an escaped newline. */ + p = note->pos + 3; + while (is_nvspace (*p)) + p++; + + /* There might have been escaped newlines between the trigraph and the + newline we found. Hence the position test. */ + return (*p == '\n' && p < note[1].pos); +} + +/* Process the notes created by add_line_note as far as the current + location. */ +int +_cpp_process_line_notes (cpp_reader *pfile, int in_comment) +{ + int ret = 0; + cpp_buffer *buffer = pfile->buffer; + + for (;;) + { + _cpp_line_note *note = &buffer->notes[buffer->cur_note]; + unsigned int col; + + if (note->pos > buffer->cur) + break; + + buffer->cur_note++; + col = CPP_BUF_COLUMN (buffer, note->pos + 1); + + if (note->type == '\\' || note->type == ' ') + { + if (note->type == ' ' && !in_comment) + cpp_error_with_line (pfile, CPP_DL_WARNING, pfile->line_table->highest_line, col, + "backslash and newline separated by space"); + + if (buffer->next_line > buffer->rlimit) + { + cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line_table->highest_line, col, + "backslash-newline at end of file"); + /* Prevent "no newline at end of file" warning. */ + buffer->next_line = buffer->rlimit; + } + + ret = PREV_NL; + + buffer->line_base = note->pos; + CPP_INCREMENT_LINE (pfile, 0); + } + else if (_cpp_trigraph_map[note->type]) + { + if (CPP_OPTION (pfile, warn_trigraphs) + && (!in_comment || warn_in_comment (pfile, note))) + { + if (CPP_OPTION (pfile, trigraphs)) + cpp_warning_with_line (pfile, CPP_W_TRIGRAPHS, + pfile->line_table->highest_line, col, + "trigraph ??%c converted to %c", + note->type, + (int) _cpp_trigraph_map[note->type]); + else + { + cpp_warning_with_line + (pfile, CPP_W_TRIGRAPHS, + pfile->line_table->highest_line, col, + "trigraph ??%c ignored, use -trigraphs to enable", + note->type); + } + } + } + else if (note->type == 0) + /* Already processed in lex_raw_string. */; + else + abort (); + } + return ret; +} + +/* SDCC __asm specific */ +/* Skip an __asm ... __endasm block. We find the end of the comment by + seeing __endasm. Returns non-zero if _asm terminated by EOF, zero + otherwise. */ +static int +_sdcpp_skip_asm_block (cpp_reader *pfile) +{ +#define ENDASM_STR "endasm" +#define ENDASM_LEN ((sizeof ENDASM_STR) - 1) + + cpp_buffer *buffer = pfile->buffer; + uchar c = EOF; + int prev_space = false; + + while (buffer->cur != buffer->rlimit) + { + prev_space = is_space(c); + c = *buffer->cur++; + + if (prev_space && c == '_' && *buffer->cur == '_') + { + /* check if it is __endasm */ + ++buffer->cur; + if (buffer->cur + ENDASM_LEN <= buffer->rlimit && + strncmp((const char *)buffer->cur, ENDASM_STR, ENDASM_LEN) == 0) + { + buffer->cur += ENDASM_LEN; + break; + } + } + else if (c == '\n') + { + unsigned int cols; + --buffer->cur; + _cpp_process_line_notes (pfile, true); + if (buffer->next_line >= buffer->rlimit) + return true; + _cpp_clean_line (pfile); + + cols = buffer->next_line - buffer->line_base; + CPP_INCREMENT_LINE (pfile, cols); + } + } + + _cpp_process_line_notes (pfile, true); + return false; +} + +/* Skip a C-style block comment. We find the end of the comment by + seeing if an asterisk is before every '/' we encounter. Returns + nonzero if comment terminated by EOF, zero otherwise. + + Buffer->cur points to the initial asterisk of the comment. */ +bool +_cpp_skip_block_comment (cpp_reader *pfile) +{ + cpp_buffer *buffer = pfile->buffer; + const uchar *cur = buffer->cur; + uchar c; + + cur++; + if (*cur == '/') + cur++; + + for (;;) + { + /* People like decorating comments with '*', so check for '/' + instead for efficiency. */ + c = *cur++; + + if (c == '/') + { + if (cur[-2] == '*') + break; + + /* Warn about potential nested comments, but not if the '/' + comes immediately before the true comment delimiter. + Don't bother to get it right across escaped newlines. */ + if (CPP_OPTION (pfile, warn_comments) + && cur[0] == '*' && cur[1] != '/') + { + buffer->cur = cur; + cpp_warning_with_line (pfile, CPP_W_COMMENTS, + pfile->line_table->highest_line, + CPP_BUF_COL (buffer), + "\"/*\" within comment"); + } + } + else if (c == '\n') + { + unsigned int cols; + buffer->cur = cur - 1; + _cpp_process_line_notes (pfile, true); + if (buffer->next_line >= buffer->rlimit) + return true; + _cpp_clean_line (pfile); + + cols = buffer->next_line - buffer->line_base; + CPP_INCREMENT_LINE (pfile, cols); + + cur = buffer->cur; + } + } + + buffer->cur = cur; + _cpp_process_line_notes (pfile, true); + return false; +} + +/* Skip a C++ line comment, leaving buffer->cur pointing to the + terminating newline. Handles escaped newlines. Returns nonzero + if a multiline comment. */ +static int +skip_line_comment (cpp_reader *pfile) +{ + cpp_buffer *buffer = pfile->buffer; + source_location orig_line = pfile->line_table->highest_line; + + while (*buffer->cur != '\n') + buffer->cur++; + + _cpp_process_line_notes (pfile, true); + return orig_line != pfile->line_table->highest_line; +} + +/* Skips whitespace, saving the next non-whitespace character. */ +static void +skip_whitespace (cpp_reader *pfile, cppchar_t c) +{ + cpp_buffer *buffer = pfile->buffer; + bool saw_NUL = false; + + do + { + /* Horizontal space always OK. */ + if (c == ' ' || c == '\t') + ; + /* Just \f \v or \0 left. */ + else if (c == '\0') + saw_NUL = true; + else if (pfile->state.in_directive && CPP_PEDANTIC (pfile)) + cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line_table->highest_line, + CPP_BUF_COL (buffer), + "%s in preprocessing directive", + c == '\f' ? "form feed" : "vertical tab"); + + c = *buffer->cur++; + } + /* We only want non-vertical space, i.e. ' ' \t \f \v \0. */ + while (is_nvspace (c)); + + if (saw_NUL) + cpp_error (pfile, CPP_DL_WARNING, "null character(s) ignored"); + + buffer->cur--; +} + +/* See if the characters of a number token are valid in a name (no + '.', '+' or '-'). */ +static int +name_p (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; +} + +/* After parsing an identifier or other sequence, produce a warning about + sequences not in NFC/NFKC. */ +static void +warn_about_normalization (cpp_reader *pfile, + const cpp_token *token, + const struct normalize_state *s) +{ + if (CPP_OPTION (pfile, warn_normalize) < NORMALIZE_STATE_RESULT (s) + && !pfile->state.skipping) + { + /* Make sure that the token is printed using UCNs, even + if we'd otherwise happily print UTF-8. */ + unsigned char *buf = XNEWVEC (unsigned char, cpp_token_len (token)); + size_t sz; + + sz = cpp_spell_token (pfile, token, buf, false) - buf; + if (NORMALIZE_STATE_RESULT (s) == normalized_C) + cpp_warning_with_line (pfile, CPP_W_NORMALIZE, token->src_loc, 0, + "`%.*s' is not in NFKC", (int) sz, buf); + else + cpp_warning_with_line (pfile, CPP_W_NORMALIZE, token->src_loc, 0, + "`%.*s' is not in NFC", (int) sz, buf); + } +} + +/* Returns TRUE if the sequence starting at buffer->cur is invalid in + an identifier. FIRST is TRUE if this starts an identifier. */ +static bool +forms_identifier_p (cpp_reader *pfile, int first, + struct normalize_state *state) +{ + cpp_buffer *buffer = pfile->buffer; + + if (*buffer->cur == '$') + { + if (!CPP_OPTION (pfile, dollars_in_ident)) + return false; + + buffer->cur++; + if (CPP_OPTION (pfile, warn_dollars) && !pfile->state.skipping) + { + CPP_OPTION (pfile, warn_dollars) = 0; + cpp_error (pfile, CPP_DL_PEDWARN, "'$' in identifier or number"); + } + + return true; + } + + /* Is this a syntactically valid UCN? */ + if (CPP_OPTION (pfile, extended_identifiers) + && *buffer->cur == '\\' + && (buffer->cur[1] == 'u' || buffer->cur[1] == 'U')) + { + buffer->cur += 2; + if (_cpp_valid_ucn (pfile, &buffer->cur, buffer->rlimit, 1 + !first, + state)) + return true; + buffer->cur -= 2; + } + + return false; +} + +/* Helper function to get the cpp_hashnode of the identifier BASE. */ +static cpp_hashnode * +lex_identifier_intern (cpp_reader *pfile, const uchar *base) +{ + cpp_hashnode *result; + const uchar *cur; + unsigned int len; + unsigned int hash = HT_HASHSTEP (0, *base); + + cur = base + 1; + while (ISIDNUM (*cur)) + { + hash = HT_HASHSTEP (hash, *cur); + cur++; + } + len = cur - base; + hash = HT_HASHFINISH (hash, len); + result = CPP_HASHNODE (ht_lookup_with_hash (pfile->hash_table, + base, len, hash, HT_ALLOC)); + + /* Rarely, identifiers require diagnostics when lexed. */ + if (__builtin_expect ((result->flags & NODE_DIAGNOSTIC) + && !pfile->state.skipping, 0)) + { + /* It is allowed to poison the same identifier twice. */ + if ((result->flags & NODE_POISONED) && !pfile->state.poisoned_ok) + cpp_error (pfile, CPP_DL_ERROR, "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_error (pfile, CPP_DL_PEDWARN, + "__VA_ARGS__ can only appear in the expansion" + " of a C99 variadic macro"); + + /* For -Wc++-compat, warn about use of C++ named operators. */ + if (result->flags & NODE_WARN_OPERATOR) + cpp_warning (pfile, CPP_W_CXX_OPERATOR_NAMES, + "identifier \"%s\" is a special operator name in C++", + NODE_NAME (result)); + } + + return result; +} + +/* Get the cpp_hashnode of an identifier specified by NAME in + the current cpp_reader object. If none is found, NULL is returned. */ +cpp_hashnode * +_cpp_lex_identifier (cpp_reader *pfile, const char *name) +{ + cpp_hashnode *result; + result = lex_identifier_intern (pfile, (uchar *) name); + return result; +} + +/* Lex an identifier starting at BUFFER->CUR - 1. */ +static cpp_hashnode * +lex_identifier (cpp_reader *pfile, const uchar *base, bool starts_ucn, + struct normalize_state *nst) +{ + cpp_hashnode *result; + const uchar *cur; + unsigned int len; + unsigned int hash = HT_HASHSTEP (0, *base); + + cur = pfile->buffer->cur; + if (! starts_ucn) + while (ISIDNUM (*cur)) + { + hash = HT_HASHSTEP (hash, *cur); + cur++; + } + pfile->buffer->cur = cur; + if (starts_ucn || forms_identifier_p (pfile, false, nst)) + { + /* Slower version for identifiers containing UCNs (or $). */ + do { + while (ISIDNUM (*pfile->buffer->cur)) + { + pfile->buffer->cur++; + NORMALIZE_STATE_UPDATE_IDNUM (nst); + } + } while (forms_identifier_p (pfile, false, nst)); + result = _cpp_interpret_identifier (pfile, base, + pfile->buffer->cur - base); + } + else + { + len = cur - base; + hash = HT_HASHFINISH (hash, len); + + result = CPP_HASHNODE (ht_lookup_with_hash (pfile->hash_table, + base, len, hash, HT_ALLOC)); + } + + /* Rarely, identifiers require diagnostics when lexed. */ + if (__builtin_expect ((result->flags & NODE_DIAGNOSTIC) + && !pfile->state.skipping, 0)) + { + /* It is allowed to poison the same identifier twice. */ + if ((result->flags & NODE_POISONED) && !pfile->state.poisoned_ok) + cpp_error (pfile, CPP_DL_ERROR, "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_error (pfile, CPP_DL_PEDWARN, + "__VA_ARGS__ can only appear in the expansion" + " of a C99 variadic macro"); + + /* For -Wc++-compat, warn about use of C++ named operators. */ + if (result->flags & NODE_WARN_OPERATOR) + cpp_warning (pfile, CPP_W_CXX_OPERATOR_NAMES, + "identifier \"%s\" is a special operator name in C++", + NODE_NAME (result)); + } + + return result; +} + +/* sdpcc specific */ +/* Pedantic parse a number, beginning with character C, skipping embedded + backslash-newlines. LEADING_PERIOD is nonzero if there was a "." + before C. Place the result in NUMBER. */ +static void +pedantic_lex_number (cpp_reader *pfile, cpp_string *number) +{ +#define get_effective_char(pfile) (*pfile->buffer->cur++) +#define BACKUP() (--pfile->buffer->cur) + + enum num_type_e { NT_DEC, NT_HEX, NT_BIN } num_type = NT_DEC; + enum num_part_e { NP_WHOLE, NP_FRACT, NP_EXP, NP_INT_SUFFIX, NP_FLOAT_SUFFIX } num_part = NP_WHOLE; + + uchar c = *(pfile->buffer->cur - 1); + struct obstack *stack = &pfile->hash_table->stack; + int len = 0; + int has_whole = 0; + int has_fract = 0; + + if ('.' == c) + { + num_part = NP_FRACT; + ++len; + obstack_1grow (stack, '.'); + c = get_effective_char (pfile); + } + else + { + if ('0' == c) + { + has_whole = 1; + ++len; + obstack_1grow (stack, c); + c = get_effective_char (pfile); + + switch (c) + { + case 'X': + case 'x': + num_type = NT_HEX; + ++len; + obstack_1grow (stack, c); + c = get_effective_char (pfile); + break; + + case 'B': + case 'b': + if (!CPP_OPTION (pfile, std)) + { + num_type = NT_BIN; + ++len; + obstack_1grow (stack, c); + c = get_effective_char (pfile); + } + break; + + case '.': + num_part = NP_FRACT; + ++len; + obstack_1grow (stack, c); + c = get_effective_char (pfile); + break; + } + } + } + + for (; ; ) + { + switch (num_part) + { + case NP_WHOLE: + if (NT_DEC == num_type) + { + while (ISDIGIT (c)) + { + has_whole = 1; + ++len; + obstack_1grow (stack, c); + c = get_effective_char (pfile); + } + + if ('.' == c) + { + num_part = NP_FRACT; + ++len; + obstack_1grow (stack, c); + c = get_effective_char (pfile); + continue; + } + else if ('E' == c || 'e' == c) + { + if (has_whole || has_fract) + { + num_part = NP_EXP; + ++len; + obstack_1grow (stack, c); + c = get_effective_char (pfile); + continue; + } + else + break; + } + } + else if (NT_HEX == num_type) + { + while (ISXDIGIT (c)) + { + has_whole = 1; + ++len; + obstack_1grow (stack, c); + c = get_effective_char (pfile); + } + + if ('.' == c) + { + num_part = NP_FRACT; + ++len; + obstack_1grow (stack, c); + c = get_effective_char (pfile); + continue; + } + else if ('P' == c || 'p' == c) + { + if (has_whole || has_fract) + { + num_part = NP_EXP; + ++len; + obstack_1grow (stack, c); + c = get_effective_char (pfile); + continue; + } + else + break; + } + } + else /* (NT_BIN == num_type) */ + { + while ((c=='0') || (c=='1')) + { + has_whole = 1; + ++len; + obstack_1grow (stack, c); + c = get_effective_char (pfile); + } + + if ('.' == c) + { + num_part = NP_FRACT; + ++len; + obstack_1grow (stack, c); + c = get_effective_char (pfile); + continue; + } + else if ('P' == c || 'p' == c) + { + if (has_whole || has_fract) + { + num_part = NP_EXP; + ++len; + obstack_1grow (stack, c); + c = get_effective_char (pfile); + continue; + } + else + break; + } + } + num_part = NP_INT_SUFFIX; + continue; + + case NP_FRACT: + if (NT_DEC == num_type) + { + while (ISDIGIT (c)) + { + has_fract = 1; + ++len; + obstack_1grow (stack, c); + c = get_effective_char (pfile); + } + + if ('E' == c || 'e' == c) + { + if (has_whole || has_fract) + { + num_part = NP_EXP; + ++len; + obstack_1grow (stack, c); + c = get_effective_char (pfile); + continue; + } + } + } + else + { + while (ISXDIGIT (c)) + { + has_fract = 1; + ++len; + obstack_1grow (stack, c); + c = get_effective_char (pfile); + } + + if ('P' == c || 'p' == c) + { + if (has_whole || has_fract) + { + num_part = NP_EXP; + ++len; + obstack_1grow (stack, c); + c = get_effective_char (pfile); + continue; + } + } + } + num_part = NP_FLOAT_SUFFIX; + continue; + + case NP_EXP: + if ('+' == c || '-' == c) + { + ++len; + obstack_1grow (stack, c); + c = get_effective_char (pfile); + } + + while (ISDIGIT (c)) + { + ++len; + obstack_1grow (stack, c); + c = get_effective_char (pfile); + } + + num_part = NP_FLOAT_SUFFIX; + continue; + + case NP_INT_SUFFIX: + if ('L' == c || 'l' == c) + { + uchar prevc = c; + + ++len; + obstack_1grow (stack, c); + c = get_effective_char (pfile); + + if (c == prevc) + { + ++len; + obstack_1grow (stack, c); + c = get_effective_char (pfile); + } + } + else if ('U' == c || 'u' == c) + { + ++len; + obstack_1grow (stack, c); + c = get_effective_char (pfile); + } + break; + + case NP_FLOAT_SUFFIX: + if ('F' == c || 'f' == c) + { + ++len; + obstack_1grow (stack, c); + c = get_effective_char (pfile); + } + else if ('L' == c || 'l' == c) + { + ++len; + obstack_1grow (stack, c); + c = get_effective_char (pfile); + } + break; + } + break; + } + + /* Step back over the unwanted char. */ + BACKUP (); + + number->text = obstack_finish (stack); + number->len = len; +} + +/* Lex a number to NUMBER starting at BUFFER->CUR - 1. */ +static void +lex_number (cpp_reader *pfile, cpp_string *number, + struct normalize_state *nst) +{ + const uchar *cur; + const uchar *base; + uchar *dest; + + base = pfile->buffer->cur - 1; + do + { + cur = pfile->buffer->cur; + + /* N.B. ISIDNUM does not include $. */ + while (ISIDNUM (*cur) || *cur == '.' || VALID_SIGN (*cur, cur[-1])) + { + cur++; + NORMALIZE_STATE_UPDATE_IDNUM (nst); + } + + pfile->buffer->cur = cur; + } + while (forms_identifier_p (pfile, false, nst)); + + number->len = cur - base; + dest = _cpp_unaligned_alloc (pfile, number->len + 1); + memcpy (dest, base, number->len); + dest[number->len] = '\0'; + number->text = dest; +} + +/* Create a token of type TYPE with a literal spelling. */ +static void +create_literal (cpp_reader *pfile, cpp_token *token, const uchar *base, + unsigned int len, enum cpp_ttype type) +{ + uchar *dest = _cpp_unaligned_alloc (pfile, len + 1); + + memcpy (dest, base, len); + dest[len] = '\0'; + token->type = type; + token->val.str.len = len; + token->val.str.text = dest; +} + +/* Subroutine of lex_raw_string: Append LEN chars from BASE to the buffer + sequence from *FIRST_BUFF_P to LAST_BUFF_P. */ + +static void +bufring_append (cpp_reader *pfile, const uchar *base, size_t len, + _cpp_buff **first_buff_p, _cpp_buff **last_buff_p) +{ + _cpp_buff *first_buff = *first_buff_p; + _cpp_buff *last_buff = *last_buff_p; + + if (first_buff == NULL) + first_buff = last_buff = _cpp_get_buff (pfile, len); + else if (len > BUFF_ROOM (last_buff)) + { + size_t room = BUFF_ROOM (last_buff); + memcpy (BUFF_FRONT (last_buff), base, room); + BUFF_FRONT (last_buff) += room; + base += room; + len -= room; + last_buff = _cpp_append_extend_buff (pfile, last_buff, len); + } + + memcpy (BUFF_FRONT (last_buff), base, len); + BUFF_FRONT (last_buff) += len; + + *first_buff_p = first_buff; + *last_buff_p = last_buff; +} + +/* Lexes a raw string. The stored string contains the spelling, including + double quotes, delimiter string, '(' and ')', any leading + 'L', 'u', 'U' or 'u8' and 'R' modifier. It returns the type of the + literal, or CPP_OTHER if it was not properly terminated. + + The spelling is NUL-terminated, but it is not guaranteed that this + is the first NUL since embedded NULs are preserved. */ + +static void +lex_raw_string (cpp_reader *pfile, cpp_token *token, const uchar *base, + const uchar *cur) +{ + source_location saw_NUL = 0; + const uchar *raw_prefix; + unsigned int raw_prefix_len = 0; + enum cpp_ttype type; + size_t total_len = 0; + _cpp_buff *first_buff = NULL, *last_buff = NULL; + _cpp_line_note *note = &pfile->buffer->notes[pfile->buffer->cur_note]; + + type = (*base == 'L' ? CPP_WSTRING : + *base == 'U' ? CPP_STRING32 : + *base == 'u' ? (base[1] == '8' ? CPP_UTF8STRING : CPP_STRING16) + : CPP_STRING); + + raw_prefix = cur + 1; + while (raw_prefix_len < 16) + { + switch (raw_prefix[raw_prefix_len]) + { + case ' ': case '(': case ')': case '\\': case '\t': + case '\v': case '\f': case '\n': default: + break; + /* Basic source charset except the above chars. */ + 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': + case '0': case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + case '_': case '{': case '}': case '#': case '[': case ']': + case '<': case '>': case '%': case ':': case ';': case '.': + case '?': case '*': case '+': case '-': case '/': case '^': + case '&': case '|': case '~': case '!': case '=': case ',': + case '"': case '\'': + raw_prefix_len++; + continue; + } + break; + } + + if (raw_prefix[raw_prefix_len] != '(') + { + int col = CPP_BUF_COLUMN (pfile->buffer, raw_prefix + raw_prefix_len) + + 1; + if (raw_prefix_len == 16) + cpp_error_with_line (pfile, CPP_DL_ERROR, token->src_loc, col, + "raw string delimiter longer than 16 characters"); + else + cpp_error_with_line (pfile, CPP_DL_ERROR, token->src_loc, col, + "invalid character '%c' in raw string delimiter", + (int) raw_prefix[raw_prefix_len]); + pfile->buffer->cur = raw_prefix - 1; + create_literal (pfile, token, base, raw_prefix - 1 - base, CPP_OTHER); + return; + } + + cur = raw_prefix + raw_prefix_len + 1; + for (;;) + { +#define BUF_APPEND(STR,LEN) \ + do { \ + bufring_append (pfile, (const uchar *)(STR), (LEN), \ + &first_buff, &last_buff); \ + total_len += (LEN); \ + } while (0); + + cppchar_t c; + + /* If we previously performed any trigraph or line splicing + transformations, undo them within the body of the raw string. */ + while (note->pos < cur) + ++note; + for (; note->pos == cur; ++note) + { + switch (note->type) + { + case '\\': + case ' ': + /* Restore backslash followed by newline. */ + BUF_APPEND (base, cur - base); + base = cur; + BUF_APPEND ("\\", 1); + after_backslash: + if (note->type == ' ') + { + /* GNU backslash whitespace newline extension. FIXME + could be any sequence of non-vertical space. When we + can properly restore any such sequence, we should mark + this note as handled so _cpp_process_line_notes + doesn't warn. */ + BUF_APPEND (" ", 1); + } + + BUF_APPEND ("\n", 1); + break; + + case 0: + /* Already handled. */ + break; + + default: + if (_cpp_trigraph_map[note->type]) + { + /* Don't warn about this trigraph in + _cpp_process_line_notes, since trigraphs show up as + trigraphs in raw strings. */ + uchar type = note->type; + note->type = 0; + + if (!CPP_OPTION (pfile, trigraphs)) + /* If we didn't convert the trigraph in the first + place, don't do anything now either. */ + break; + + BUF_APPEND (base, cur - base); + base = cur; + BUF_APPEND ("??", 2); + + /* ??/ followed by newline gets two line notes, one for + the trigraph and one for the backslash/newline. */ + if (type == '/' && note[1].pos == cur) + { + if (note[1].type != '\\' + && note[1].type != ' ') + abort (); + BUF_APPEND ("/", 1); + ++note; + goto after_backslash; + } + /* The ) from ??) could be part of the suffix. */ + else if (type == ')' + && strncmp ((const char *) cur+1, + (const char *) raw_prefix, + raw_prefix_len) == 0 + && cur[raw_prefix_len+1] == '"') + { + BUF_APPEND (")", 1); + base++; + cur += raw_prefix_len + 2; + goto break_outer_loop; + } + else + { + /* Skip the replacement character. */ + base = ++cur; + BUF_APPEND (&type, 1); + } + } + else + abort (); + break; + } + } + c = *cur++; + + if (c == ')' + && strncmp ((const char *) cur, (const char *) raw_prefix, + raw_prefix_len) == 0 + && cur[raw_prefix_len] == '"') + { + cur += raw_prefix_len + 1; + break; + } + else if (c == '\n') + { + if (pfile->state.in_directive + || pfile->state.parsing_args + || pfile->state.in_deferred_pragma) + { + cur--; + type = CPP_OTHER; + cpp_error_with_line (pfile, CPP_DL_ERROR, token->src_loc, 0, + "unterminated raw string"); + break; + } + + BUF_APPEND (base, cur - base); + + if (pfile->buffer->cur < pfile->buffer->rlimit) + CPP_INCREMENT_LINE (pfile, 0); + pfile->buffer->need_line = true; + + pfile->buffer->cur = cur-1; + _cpp_process_line_notes (pfile, false); + if (!_cpp_get_fresh_line (pfile)) + { + source_location src_loc = token->src_loc; + token->type = CPP_EOF; + /* Tell the compiler the line number of the EOF token. */ + token->src_loc = pfile->line_table->highest_line; + token->flags = BOL; + if (first_buff != NULL) + _cpp_release_buff (pfile, first_buff); + cpp_error_with_line (pfile, CPP_DL_ERROR, src_loc, 0, + "unterminated raw string"); + return; + } + + cur = base = pfile->buffer->cur; + note = &pfile->buffer->notes[pfile->buffer->cur_note]; + } + else if (c == '\0' && !saw_NUL) + LINEMAP_POSITION_FOR_COLUMN (saw_NUL, pfile->line_table, + CPP_BUF_COLUMN (pfile->buffer, cur)); + } + break_outer_loop: + + if (saw_NUL && !pfile->state.skipping) + cpp_error_with_line (pfile, CPP_DL_WARNING, saw_NUL, 0, + "null character(s) preserved in literal"); + + pfile->buffer->cur = cur; + if (first_buff == NULL) + create_literal (pfile, token, base, cur - base, type); + else + { + uchar *dest = _cpp_unaligned_alloc (pfile, total_len + (cur - base) + 1); + + token->type = type; + token->val.str.len = total_len + (cur - base); + token->val.str.text = dest; + last_buff = first_buff; + while (last_buff != NULL) + { + memcpy (dest, last_buff->base, + BUFF_FRONT (last_buff) - last_buff->base); + dest += BUFF_FRONT (last_buff) - last_buff->base; + last_buff = last_buff->next; + } + _cpp_release_buff (pfile, first_buff); + memcpy (dest, base, cur - base); + dest[cur - base] = '\0'; + } +} + +/* Lexes a string, character constant, or angle-bracketed header file + name. The stored string contains the spelling, including opening + quote and any leading 'L', 'u', 'U' or 'u8' and optional + 'R' modifier. It returns the type of the literal, or CPP_OTHER + if it was not properly terminated, or CPP_LESS for an unterminated + header name which must be relexed as normal tokens. + + The spelling is NUL-terminated, but it is not guaranteed that this + is the first NUL since embedded NULs are preserved. */ +static void +lex_string (cpp_reader *pfile, cpp_token *token, const uchar *base) +{ + bool saw_NUL = false; + const uchar *cur; + cppchar_t terminator; + enum cpp_ttype type; + + cur = base; + terminator = *cur++; + if (terminator == 'L' || terminator == 'U') + terminator = *cur++; + else if (terminator == 'u') + { + terminator = *cur++; + if (terminator == '8') + terminator = *cur++; + } + if (terminator == 'R') + { + lex_raw_string (pfile, token, base, cur); + return; + } + if (terminator == '"') + type = (*base == 'L' ? CPP_WSTRING : + *base == 'U' ? CPP_STRING32 : + *base == 'u' ? (base[1] == '8' ? CPP_UTF8STRING : CPP_STRING16) + : CPP_STRING); + else if (terminator == '\'') + type = (*base == 'L' ? CPP_WCHAR : + *base == 'U' ? CPP_CHAR32 : + *base == 'u' ? CPP_CHAR16 : CPP_CHAR); + else + terminator = '>', type = CPP_HEADER_NAME; + + for (;;) + { + cppchar_t c = *cur++; + + /* In #include-style directives, terminators are not escapable. */ + if (c == '\\' && !pfile->state.angled_headers && *cur != '\n') + cur++; + else if (c == terminator) + break; + else if (c == '\n') + { + cur--; + /* Unmatched quotes always yield undefined behavior, but + greedy lexing means that what appears to be an unterminated + header name may actually be a legitimate sequence of tokens. */ + if (terminator == '>') + { + token->type = CPP_LESS; + return; + } + type = CPP_OTHER; + break; + } + else if (c == '\0') + saw_NUL = true; + } + + if (saw_NUL && !pfile->state.skipping) + cpp_error (pfile, CPP_DL_WARNING, + "null character(s) preserved in literal"); + + if (type == CPP_OTHER && CPP_OPTION (pfile, lang) != CLK_ASM) + cpp_error (pfile, CPP_DL_PEDWARN, "missing terminating %c character", + (int) terminator); + + pfile->buffer->cur = cur; + create_literal (pfile, token, base, cur - base, type); +} + +/* sdcpp specific */ +/* Fixed _WIN32 problem with CR-CR-LF sequences when outputting + comment blocks (when executed with -C option) and + _asm (SDCPP specific) blocks */ + +/* Count and copy characters from src to dest, excluding CRs: + CRs are automatically generated, because the output is + opened in TEXT mode. If dest == NULL, only count chars */ +static unsigned int +copy_text_chars (unsigned char *dest, const unsigned char *src, unsigned int len) +{ + unsigned int n = 0; + const unsigned char *p; + + for (p = src; p != src + len; ++p) + { + assert(*p != '\0'); + + if (*p != '\r') + { + if (dest != NULL) + *dest++ = *p; + ++n; + } + } + + return n; +} + +/* SDCC _asm specific */ +/* The stored comment includes the comment start and any terminator. */ +static void +_sdcpp_save_asm (cpp_reader *pfile, cpp_token *token, const unsigned char *from, int is_asm) +{ +#define _ASM_STR "__asm" +#define _ASM_LEN ((sizeof _ASM_STR) - 1) +#define _ASM_STR1 "_asm" +#define _ASM_LEN1 ((sizeof _ASM_STR1) - 1) + + unsigned char *buffer; + unsigned int text_len, len; + unsigned int asm_len = is_asm ? _ASM_LEN : _ASM_LEN1; + const char *asm_str = is_asm ? _ASM_STR : _ASM_STR1; + + len = pfile->buffer->cur - from; + /* + asm_len for the initial '_asm'. */ + text_len = copy_text_chars (NULL, from, len) + asm_len; + buffer = _cpp_unaligned_alloc (pfile, text_len); + + + token->type = CPP_ASM; + token->val.str.len = text_len; + token->val.str.text = buffer; + + memcpy (buffer, asm_str, asm_len); + copy_text_chars (buffer + asm_len, from, len); +} + +/* Return the comment table. The client may not make any assumption + about the ordering of the table. */ +cpp_comment_table * +cpp_get_comments (cpp_reader *pfile) +{ + return &pfile->comments; +} + +/* Append a comment to the end of the comment table. */ +static void +store_comment (cpp_reader *pfile, cpp_token *token) +{ + int len; + + if (pfile->comments.allocated == 0) + { + pfile->comments.allocated = 256; + pfile->comments.entries = (cpp_comment *) xmalloc + (pfile->comments.allocated * sizeof (cpp_comment)); + } + + if (pfile->comments.count == pfile->comments.allocated) + { + pfile->comments.allocated *= 2; + pfile->comments.entries = (cpp_comment *) xrealloc + (pfile->comments.entries, + pfile->comments.allocated * sizeof (cpp_comment)); + } + + len = token->val.str.len; + + /* Copy comment. Note, token may not be NULL terminated. */ + pfile->comments.entries[pfile->comments.count].comment = + (char *) xmalloc (sizeof (char) * (len + 1)); + memcpy (pfile->comments.entries[pfile->comments.count].comment, + token->val.str.text, len); + pfile->comments.entries[pfile->comments.count].comment[len] = '\0'; + + /* Set source location. */ + pfile->comments.entries[pfile->comments.count].sloc = token->src_loc; + + /* Increment the count of entries in the comment table. */ + pfile->comments.count++; +} + +/* The stored comment includes the comment start and any terminator. */ +static void +save_comment (cpp_reader *pfile, cpp_token *token, const unsigned char *from, + cppchar_t type) +{ + unsigned char *buffer; + unsigned int len, clen, i; + + 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 (is_vspace (pfile->buffer->cur[-1])) + len--; + + /* If we are currently in a directive or in argument parsing, then + we need to store all C++ comments as C comments internally, and + so we need to allocate a little extra space in that case. + + Note that the only time we encounter a directive here is + when we are saving comments in a "#define". */ + clen = ((pfile->state.in_directive || pfile->state.parsing_args) + && type == '/') ? len + 2 : len; + + buffer = _cpp_unaligned_alloc (pfile, clen); + + token->type = CPP_COMMENT; + token->val.str.len = clen; + token->val.str.text = buffer; + + buffer[0] = '/'; + /* sdcpp specific */ + copy_text_chars (buffer + 1, from, len); + + /* Finish conversion to a C comment, if necessary. */ + if ((pfile->state.in_directive || pfile->state.parsing_args) && type == '/') + { + buffer[1] = '*'; + buffer[clen - 2] = '*'; + buffer[clen - 1] = '/'; + /* As there can be in a C++ comments illegal sequences for C comments + we need to filter them out. */ + for (i = 2; i < (clen - 2); i++) + if (buffer[i] == '/' && (buffer[i - 1] == '*' || buffer[i + 1] == '*')) + buffer[i] = '|'; + } + + /* Finally store this comment for use by clients of libcpp. */ + store_comment (pfile, token); +} + +/* Allocate COUNT tokens for RUN. */ +void +_cpp_init_tokenrun (tokenrun *run, unsigned int count) +{ + run->base = XNEWVEC (cpp_token, count); + run->limit = run->base + count; + run->next = NULL; +} + +/* Returns the next tokenrun, or creates one if there is none. */ +static tokenrun * +next_tokenrun (tokenrun *run) +{ + if (run->next == NULL) + { + run->next = XNEW (tokenrun); + run->next->prev = run; + _cpp_init_tokenrun (run->next, 250); + } + + return run->next; +} + +/* Look ahead in the input stream. */ +const cpp_token * +cpp_peek_token (cpp_reader *pfile, int index) +{ + cpp_context *context = pfile->context; + const cpp_token *peektok; + int count; + + /* First, scan through any pending cpp_context objects. */ + while (context->prev) + { + ptrdiff_t sz = (context->direct_p + ? LAST (context).token - FIRST (context).token + : LAST (context).ptoken - FIRST (context).ptoken); + + if (index < (int) sz) + return (context->direct_p + ? FIRST (context).token + index + : *(FIRST (context).ptoken + index)); + + index -= (int) sz; + context = context->prev; + } + + /* We will have to read some new tokens after all (and do so + without invalidating preceding tokens). */ + count = index; + pfile->keep_tokens++; + + do + { + peektok = _cpp_lex_token (pfile); + if (peektok->type == CPP_EOF) + return peektok; + } + while (index--); + + _cpp_backup_tokens_direct (pfile, count + 1); + pfile->keep_tokens--; + + return peektok; +} + +/* Allocate a single token that is invalidated at the same time as the + rest of the tokens on the line. Has its line and col set to the + same as the last lexed token, so that diagnostics appear in the + right place. */ +cpp_token * +_cpp_temp_token (cpp_reader *pfile) +{ + cpp_token *old, *result; + ptrdiff_t sz = pfile->cur_run->limit - pfile->cur_token; + ptrdiff_t la = (ptrdiff_t) pfile->lookaheads; + + old = pfile->cur_token - 1; + /* Any pre-existing lookaheads must not be clobbered. */ + if (la) + { + if (sz <= la) + { + tokenrun *next = next_tokenrun (pfile->cur_run); + + if (sz < la) + memmove (next->base + 1, next->base, + (la - sz) * sizeof (cpp_token)); + + next->base[0] = pfile->cur_run->limit[-1]; + } + + if (sz > 1) + memmove (pfile->cur_token + 1, pfile->cur_token, + MIN (la, sz - 1) * sizeof (cpp_token)); + } + + if (!sz && pfile->cur_token == pfile->cur_run->limit) + { + pfile->cur_run = next_tokenrun (pfile->cur_run); + pfile->cur_token = pfile->cur_run->base; + } + + result = pfile->cur_token++; + result->src_loc = old->src_loc; + return result; +} + +/* Lex a token into RESULT (external interface). Takes care of issues + like directive handling, token lookahead, multiple include + optimization and skipping. */ +const cpp_token * +_cpp_lex_token (cpp_reader *pfile) +{ + cpp_token *result; + + for (;;) + { + if (pfile->cur_token == pfile->cur_run->limit) + { + pfile->cur_run = next_tokenrun (pfile->cur_run); + pfile->cur_token = pfile->cur_run->base; + } + /* We assume that the current token is somewhere in the current + run. */ + if (pfile->cur_token < pfile->cur_run->base + || pfile->cur_token >= pfile->cur_run->limit) + abort (); + + if (pfile->lookaheads) + { + pfile->lookaheads--; + result = pfile->cur_token++; + } + else + result = _cpp_lex_direct (pfile); + + if (result->flags & BOL) + { + /* Is this a directive. If _cpp_handle_directive returns + false, it is an assembler #. */ + if (result->type == CPP_HASH + /* 6.10.3 p 11: Directives in a list of macro arguments + gives undefined behavior. This implementation + handles the directive as normal. */ + && pfile->state.parsing_args != 1) + { + if (_cpp_handle_directive (pfile, result->flags & PREV_WHITE)) + { + if (pfile->directive_result.type == CPP_PADDING) + continue; + result = &pfile->directive_result; + } + } + else if (pfile->state.in_deferred_pragma) + result = &pfile->directive_result; + + if (pfile->cb.line_change && !pfile->state.skipping) + pfile->cb.line_change (pfile, result, pfile->state.parsing_args); + } + + /* We don't skip tokens in directives. */ + if (pfile->state.in_directive || pfile->state.in_deferred_pragma) + break; + + /* Outside a directive, invalidate controlling macros. At file + EOF, _cpp_lex_direct takes care of popping the buffer, so we never + get here and MI optimization works. */ + pfile->mi_valid = false; + + if (!pfile->state.skipping || result->type == CPP_EOF) + break; + } + + return result; +} + +/* Returns true if a fresh line has been loaded. */ +bool +_cpp_get_fresh_line (cpp_reader *pfile) +{ + int return_at_eof; + + /* We can't get a new line until we leave the current directive. */ + if (pfile->state.in_directive) + return false; + + for (;;) + { + cpp_buffer *buffer = pfile->buffer; + + if (!buffer->need_line) + return true; + + if (buffer->next_line < buffer->rlimit) + { + _cpp_clean_line (pfile); + return true; + } + + /* First, get out of parsing arguments state. */ + if (pfile->state.parsing_args) + return false; + + /* End of buffer. Non-empty files should end in a newline. */ + if (buffer->buf != buffer->rlimit + && buffer->next_line > buffer->rlimit + && !buffer->from_stage3) + { + /* Clip to buffer size. */ + buffer->next_line = buffer->rlimit; + } + + return_at_eof = buffer->return_at_eof; + _cpp_pop_buffer (pfile); + if (pfile->buffer == NULL || return_at_eof) + return false; + } +} + +#define IF_NEXT_IS(CHAR, THEN_TYPE, ELSE_TYPE) \ + do \ + { \ + result->type = ELSE_TYPE; \ + if (*buffer->cur == CHAR) \ + buffer->cur++, result->type = THEN_TYPE; \ + } \ + while (0) + +/* Lex a token into pfile->cur_token, which is also incremented, to + get diagnostics pointing to the correct location. + + Does not handle issues such as token lookahead, multiple-include + optimization, directives, skipping etc. This function is only + suitable for use by _cpp_lex_token, and in special cases like + lex_expansion_token which doesn't care for any of these issues. + + When meeting a newline, returns CPP_EOF if parsing a directive, + otherwise returns to the start of the token buffer if permissible. + Returns the location of the lexed token. */ +cpp_token * +_cpp_lex_direct (cpp_reader *pfile) +{ + cppchar_t c; + cpp_buffer *buffer; + const unsigned char *comment_start; + cpp_token *result = pfile->cur_token++; + + fresh_line: + result->flags = 0; + buffer = pfile->buffer; + if (buffer->need_line) + { + if (pfile->state.in_deferred_pragma) + { + result->type = CPP_PRAGMA_EOL; + pfile->state.in_deferred_pragma = false; + if (!pfile->state.pragma_allow_expansion) + pfile->state.prevent_expansion--; + return result; + } + if (!_cpp_get_fresh_line (pfile)) + { + result->type = CPP_EOF; + if (!pfile->state.in_directive) + { + /* Tell the compiler the line number of the EOF token. */ + result->src_loc = pfile->line_table->highest_line; + result->flags = BOL; + } + return result; + } + if (!pfile->keep_tokens) + { + pfile->cur_run = &pfile->base_run; + result = pfile->base_run.base; + pfile->cur_token = result + 1; + } + result->flags = BOL; + if (pfile->state.parsing_args == 2) + result->flags |= PREV_WHITE; + } + buffer = pfile->buffer; + update_tokens_line: + result->src_loc = pfile->line_table->highest_line; + + skipped_white: + if (buffer->cur >= buffer->notes[buffer->cur_note].pos + && !pfile->overlaid_buffer) + { + result->flags |= _cpp_process_line_notes (pfile, false); + result->src_loc = pfile->line_table->highest_line; + } + c = *buffer->cur++; + + LINEMAP_POSITION_FOR_COLUMN (result->src_loc, pfile->line_table, + CPP_BUF_COLUMN (buffer, buffer->cur)); + + switch (c) + { + case ' ': case '\t': case '\f': case '\v': case '\0': + result->flags |= PREV_WHITE; + skip_whitespace (pfile, c); + goto skipped_white; + + case '\n': + if (buffer->cur < buffer->rlimit) + CPP_INCREMENT_LINE (pfile, 0); + buffer->need_line = true; + goto fresh_line; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + { + struct normalize_state nst = INITIAL_NORMALIZE_STATE; + result->type = CPP_NUMBER; + /* sdcpp specific */ + if (CPP_OPTION (pfile, pedantic_parse_number)) + pedantic_lex_number (pfile, &result->val.str); + else + lex_number (pfile, &result->val.str, &nst); + warn_about_normalization (pfile, result, &nst); + break; + } + + case 'L': + case 'u': + case 'U': + case 'R': + /* 'L', 'u', 'U', 'u8' or 'R' may introduce wide characters, + wide strings or raw strings. */ + if (c == 'L' || CPP_OPTION (pfile, uliterals)) + { + if ((*buffer->cur == '\'' && c != 'R') + || *buffer->cur == '"' + || (*buffer->cur == 'R' + && c != 'R' + && buffer->cur[1] == '"' + && CPP_OPTION (pfile, uliterals)) + || (*buffer->cur == '8' + && c == 'u' + && (buffer->cur[1] == '"' + || (buffer->cur[1] == 'R' && buffer->cur[2] == '"')))) + { + lex_string (pfile, result, buffer->cur - 1); + break; + } + } + /* 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 '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 'M': case 'N': case 'O': case 'P': case 'Q': + case 'S': case 'T': case 'V': case 'W': case 'X': + case 'Y': case 'Z': + result->type = CPP_NAME; + { + struct normalize_state nst = INITIAL_NORMALIZE_STATE; + result->val.node.node = lex_identifier (pfile, buffer->cur - 1, false, + &nst); + warn_about_normalization (pfile, result, &nst); + } + + /* SDCC __asm specific */ + /* handle __asm ... __endasm ; */ + if (result->val.node.node == pfile->spec_nodes.n__asm) + { + if (CPP_OPTION (pfile, preproc_asm) == 0) + { + comment_start = buffer->cur; + result->type = CPP_ASM; + _sdcpp_skip_asm_block (pfile); + /* Save the __asm block as a token in its own right. */ + _sdcpp_save_asm (pfile, result, comment_start, result->val.node.node == pfile->spec_nodes.n__asm); + } + result->flags |= ENTER_ASM; + } + else if (result->val.node.node == pfile->spec_nodes.n__endasm) + { + result->flags |= EXIT_ASM; + } + /* Convert named operators to their proper types. */ + else if (result->val.node.node->flags & NODE_OPERATOR) + { + result->flags |= NAMED_OP; + result->type = (enum cpp_ttype) result->val.node.node->directive_index; + } + break; + + case '\'': + case '"': + lex_string (pfile, result, buffer->cur - 1); + break; + + case '/': + /* A potential block or line comment. */ + comment_start = buffer->cur; + c = *buffer->cur; + + if (c == '*') + { + if (_cpp_skip_block_comment (pfile)) + cpp_error (pfile, CPP_DL_ERROR, "unterminated comment"); + } + else if (c == '/' && (CPP_OPTION (pfile, cplusplus_comments) + || cpp_in_system_header (pfile))) + { + /* 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_error (pfile, CPP_DL_PEDWARN, + "C++ style comments are not allowed in ISO C90"); + cpp_error (pfile, CPP_DL_PEDWARN, + "(this will be reported only once per input file)"); + buffer->warned_cplusplus_comments = 1; + } + + if (skip_line_comment (pfile) && CPP_OPTION (pfile, warn_comments)) + cpp_warning (pfile, CPP_W_COMMENTS, "multi-line comment"); + } + else if (c == '=') + { + buffer->cur++; + result->type = CPP_DIV_EQ; + break; + } + else + { + result->type = CPP_DIV; + break; + } + + if (!pfile->state.save_comments) + { + result->flags |= PREV_WHITE; + goto update_tokens_line; + } + + /* Save the comment as a token in its own right. */ + save_comment (pfile, result, comment_start, c); + break; + + case '<': + if (pfile->state.angled_headers) + { + lex_string (pfile, result, buffer->cur - 1); + if (result->type != CPP_LESS) + break; + } + + result->type = CPP_LESS; + if (*buffer->cur == '=') + buffer->cur++, result->type = CPP_LESS_EQ; + else if (*buffer->cur == '<') + { + buffer->cur++; + IF_NEXT_IS ('=', CPP_LSHIFT_EQ, CPP_LSHIFT); + } + else if (CPP_OPTION (pfile, digraphs)) + { + if (*buffer->cur == ':') + { + buffer->cur++; + result->flags |= DIGRAPH; + result->type = CPP_OPEN_SQUARE; + } + else if (*buffer->cur == '%') + { + buffer->cur++; + result->flags |= DIGRAPH; + result->type = CPP_OPEN_BRACE; + } + } + break; + + case '>': + result->type = CPP_GREATER; + if (*buffer->cur == '=') + buffer->cur++, result->type = CPP_GREATER_EQ; + else if (*buffer->cur == '>') + { + buffer->cur++; + IF_NEXT_IS ('=', CPP_RSHIFT_EQ, CPP_RSHIFT); + } + break; + + case '%': + result->type = CPP_MOD; + if (*buffer->cur == '=') + buffer->cur++, result->type = CPP_MOD_EQ; + else if (CPP_OPTION (pfile, digraphs)) + { + if (*buffer->cur == ':') + { + buffer->cur++; + result->flags |= DIGRAPH; + result->type = CPP_HASH; + if (*buffer->cur == '%' && buffer->cur[1] == ':') + buffer->cur += 2, result->type = CPP_PASTE, result->val.token_no = 0; + } + else if (*buffer->cur == '>') + { + buffer->cur++; + result->flags |= DIGRAPH; + result->type = CPP_CLOSE_BRACE; + } + } + break; + + case '.': + result->type = CPP_DOT; + if (ISDIGIT (*buffer->cur)) + { + struct normalize_state nst = INITIAL_NORMALIZE_STATE; + result->type = CPP_NUMBER; + /* sdcpp specific */ + if (CPP_OPTION (pfile, pedantic_parse_number)) + pedantic_lex_number (pfile, &result->val.str); + else + lex_number (pfile, &result->val.str, &nst); + warn_about_normalization (pfile, result, &nst); + } + else if (*buffer->cur == '.' && buffer->cur[1] == '.') + buffer->cur += 2, result->type = CPP_ELLIPSIS; + else if (*buffer->cur == '*' && CPP_OPTION (pfile, cplusplus)) + buffer->cur++, result->type = CPP_DOT_STAR; + break; + + case '+': + result->type = CPP_PLUS; + if (*buffer->cur == '+') + buffer->cur++, result->type = CPP_PLUS_PLUS; + else if (*buffer->cur == '=') + buffer->cur++, result->type = CPP_PLUS_EQ; + break; + + case '-': + result->type = CPP_MINUS; + if (*buffer->cur == '>') + { + buffer->cur++; + result->type = CPP_DEREF; + if (*buffer->cur == '*' && CPP_OPTION (pfile, cplusplus)) + buffer->cur++, result->type = CPP_DEREF_STAR; + } + else if (*buffer->cur == '-') + buffer->cur++, result->type = CPP_MINUS_MINUS; + else if (*buffer->cur == '=') + buffer->cur++, result->type = CPP_MINUS_EQ; + break; + + case '&': + result->type = CPP_AND; + if (*buffer->cur == '&') + buffer->cur++, result->type = CPP_AND_AND; + else if (*buffer->cur == '=') + buffer->cur++, result->type = CPP_AND_EQ; + break; + + case '|': + result->type = CPP_OR; + if (*buffer->cur == '|') + buffer->cur++, result->type = CPP_OR_OR; + else if (*buffer->cur == '=') + buffer->cur++, result->type = CPP_OR_EQ; + break; + + case ':': + result->type = CPP_COLON; + if (*buffer->cur == ':' && CPP_OPTION (pfile, cplusplus)) + buffer->cur++, result->type = CPP_SCOPE; + else if (*buffer->cur == '>' && CPP_OPTION (pfile, digraphs)) + { + buffer->cur++; + result->flags |= DIGRAPH; + result->type = CPP_CLOSE_SQUARE; + } + break; + + case '*': IF_NEXT_IS ('=', CPP_MULT_EQ, CPP_MULT); break; + case '=': IF_NEXT_IS ('=', CPP_EQ_EQ, CPP_EQ); break; + case '!': IF_NEXT_IS ('=', CPP_NOT_EQ, CPP_NOT); break; + case '^': IF_NEXT_IS ('=', CPP_XOR_EQ, CPP_XOR); break; + case '#': IF_NEXT_IS ('#', CPP_PASTE, CPP_HASH); result->val.token_no = 0; break; + + case '?': result->type = CPP_QUERY; 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; + + case '$': + case '\\': + { + const uchar *base = --buffer->cur; + struct normalize_state nst = INITIAL_NORMALIZE_STATE; + + if (forms_identifier_p (pfile, true, &nst)) + { + result->type = CPP_NAME; + result->val.node.node = lex_identifier (pfile, base, true, &nst); + warn_about_normalization (pfile, result, &nst); + break; + } + buffer->cur++; + } + + default: + create_literal (pfile, result, buffer->cur - 1, 1, CPP_OTHER); + break; + } + + return result; +} + +/* An upper bound on the number of bytes needed to spell TOKEN. + Does not include preceding whitespace. */ +unsigned int +cpp_token_len (const cpp_token *token) +{ + unsigned int len; + + switch (TOKEN_SPELL (token)) + { + default: len = 6; break; + case SPELL_LITERAL: len = token->val.str.len; break; + case SPELL_IDENT: len = NODE_LEN (token->val.node.node) * 10; break; + } + + return len; +} + +/* Parse UTF-8 out of NAMEP and place a \U escape in BUFFER. + Return the number of bytes read out of NAME. (There are always + 10 bytes written to BUFFER.) */ + +static size_t +utf8_to_ucn (unsigned char *buffer, const unsigned char *name) +{ + int j; + int ucn_len = 0; + int ucn_len_c; + unsigned t; + unsigned long utf32; + + /* Compute the length of the UTF-8 sequence. */ + for (t = *name; t & 0x80; t <<= 1) + ucn_len++; + + utf32 = *name & (0x7F >> ucn_len); + for (ucn_len_c = 1; ucn_len_c < ucn_len; ucn_len_c++) + { + utf32 = (utf32 << 6) | (*++name & 0x3F); + + /* Ill-formed UTF-8. */ + if ((*name & ~0x3F) != 0x80) + abort (); + } + + *buffer++ = '\\'; + *buffer++ = 'U'; + for (j = 7; j >= 0; j--) + *buffer++ = "0123456789abcdef"[(utf32 >> (4 * j)) & 0xF]; + return ucn_len; +} + +/* Given a token TYPE corresponding to a digraph, return a pointer to + the spelling of the digraph. */ +static const unsigned char * +cpp_digraph2name (enum cpp_ttype type) +{ + return digraph_spellings[(int) type - (int) CPP_FIRST_DIGRAPH]; +} + +/* 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. + FORSTRING is true if this is to be the spelling after translation + phase 1 (this is different for UCNs). + FIXME: Would be nice if we didn't need the PFILE argument. */ +unsigned char * +cpp_spell_token (cpp_reader *pfile, const cpp_token *token, + unsigned char *buffer, bool forstring) +{ + switch (TOKEN_SPELL (token)) + { + case SPELL_OPERATOR: + { + const unsigned char *spelling; + unsigned char c; + + if (token->flags & DIGRAPH) + spelling = cpp_digraph2name (token->type); + else if (token->flags & NAMED_OP) + goto spell_ident; + else + spelling = TOKEN_NAME (token); + + while ((c = *spelling++) != '\0') + *buffer++ = c; + } + break; + + spell_ident: + case SPELL_IDENT: + if (forstring) + { + memcpy (buffer, NODE_NAME (token->val.node.node), + NODE_LEN (token->val.node.node)); + buffer += NODE_LEN (token->val.node.node); + } + else + { + size_t i; + const unsigned char * name = NODE_NAME (token->val.node.node); + + for (i = 0; i < NODE_LEN (token->val.node.node); i++) + if (name[i] & ~0x7F) + { + i += utf8_to_ucn (buffer, name + i) - 1; + buffer += 10; + } + else + *buffer++ = NODE_NAME (token->val.node.node)[i]; + } + break; + + case SPELL_LITERAL: + memcpy (buffer, token->val.str.text, token->val.str.len); + buffer += token->val.str.len; + break; + + case SPELL_NONE: + cpp_error (pfile, CPP_DL_ICE, + "unspellable token %s", TOKEN_NAME (token)); + break; + } + + return buffer; +} + +/* Returns TOKEN spelt as a null-terminated string. The string is + freed when the reader is destroyed. Useful for diagnostics. */ +unsigned char * +cpp_token_as_text (cpp_reader *pfile, const cpp_token *token) +{ + unsigned int len = cpp_token_len (token) + 1; + unsigned char *start = _cpp_unaligned_alloc (pfile, len), *end; + + end = cpp_spell_token (pfile, token, start, false); + end[0] = '\0'; + + return start; +} + +/* Returns a pointer to a string which spells the token defined by + TYPE and FLAGS. Used by C front ends, which really should move to + using cpp_token_as_text. */ +const char * +cpp_type2name (enum cpp_ttype type, unsigned char flags) +{ + if (flags & DIGRAPH) + return (const char *) cpp_digraph2name (type); + else if (flags & NAMED_OP) + return cpp_named_operator2name (type); + + return (const char *) token_spellings[type].name; +} + +/* Writes the spelling of token to FP, without any preceding space. + Separated from cpp_spell_token for efficiency - to avoid stdio + double-buffering. */ +void +cpp_output_token (const cpp_token *token, FILE *fp) +{ + if (token->flags & ENTER_ASM) + in_asm++; + if (token->flags & EXIT_ASM) + in_asm--; + + switch (TOKEN_SPELL (token)) + { + case SPELL_OPERATOR: + { + const unsigned char *spelling; + int c; + + if (token->flags & DIGRAPH) + spelling = cpp_digraph2name (token->type); + else if (token->flags & NAMED_OP) + goto spell_ident; + else + spelling = TOKEN_NAME (token); + + c = *spelling; + do + putc (c, fp); + while ((c = *++spelling) != '\0'); + } + break; + + spell_ident: + case SPELL_IDENT: + { + size_t i; + const unsigned char * name = NODE_NAME (token->val.node.node); + + for (i = 0; i < NODE_LEN (token->val.node.node); i++) + if (name[i] & ~0x7F) + { + unsigned char buffer[10]; + i += utf8_to_ucn (buffer, name + i) - 1; + fwrite (buffer, 1, 10, fp); + } + else + fputc (NODE_NAME (token->val.node.node)[i], fp); + } + break; + + case SPELL_LITERAL: + fwrite (token->val.str.text, 1, token->val.str.len, fp); + break; + + case SPELL_NONE: + /* An error, most probably. */ + break; + } +} + +/* Compare two tokens. */ +int +_cpp_equiv_tokens (const cpp_token *a, const cpp_token *b) +{ + if (a->type == b->type && a->flags == b->flags) + switch (TOKEN_SPELL (a)) + { + default: /* Keep compiler happy. */ + case SPELL_OPERATOR: + /* token_no is used to track where multiple consecutive ## + tokens were originally located. */ + return (a->type != CPP_PASTE || a->val.token_no == b->val.token_no); + case SPELL_NONE: + return (a->type != CPP_MACRO_ARG + || a->val.macro_arg.arg_no == b->val.macro_arg.arg_no); + case SPELL_IDENT: + return a->val.node.node == b->val.node.node; + case SPELL_LITERAL: + return (a->val.str.len == b->val.str.len + && !memcmp (a->val.str.text, b->val.str.text, + a->val.str.len)); + } + + return 0; +} + +/* 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 (cpp_reader *pfile, const cpp_token *token1, + const cpp_token *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 == '>'; + case CPP_LESS: return 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 == '-'); + /* UCNs */ + case CPP_OTHER: return ((token1->val.str.text[0] == '\\' + && b == CPP_NAME) + || (CPP_OPTION (pfile, objc) + && token1->val.str.text[0] == '@' + && (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. If there are + macros, special token padding is not performed. */ +void +cpp_output_line (cpp_reader *pfile, FILE *fp) +{ + const cpp_token *token; + + token = cpp_get_token (pfile); + while (token->type != CPP_EOF) + { + cpp_output_token (token, fp); + token = cpp_get_token (pfile); + if (token->flags & PREV_WHITE) + putc (' ', fp); + if (in_asm && token->flags & PREV_NL) + fputs ("\x87 ", fp); + } + + putc ('\n', fp); +} + +/* Return a string representation of all the remaining tokens on the + current line. The result is allocated using xmalloc and must be + freed by the caller. */ +unsigned char * +cpp_output_line_to_string (cpp_reader *pfile, const unsigned char *dir_name) +{ + const cpp_token *token; + unsigned int out = dir_name ? ustrlen (dir_name) : 0; + unsigned int alloced = 120 + out; + unsigned char *result = (unsigned char *) xmalloc (alloced); + + /* If DIR_NAME is empty, there are no initial contents. */ + if (dir_name) + { + sprintf ((char *) result, "#%s ", dir_name); + out += 2; + } + + token = cpp_get_token (pfile); + while (token->type != CPP_EOF) + { + unsigned char *last; + /* Include room for a possible space and the terminating nul. */ + unsigned int len = cpp_token_len (token) + 2; + + if (out + len > alloced) + { + alloced *= 2; + if (out + len > alloced) + alloced = out + len; + result = (unsigned char *) xrealloc (result, alloced); + } + + last = cpp_spell_token (pfile, token, &result[out], 0); + out = last - result; + + token = cpp_get_token (pfile); + if (token->flags & PREV_WHITE) + result[out++] = ' '; + } + + result[out] = '\0'; + return result; +} + +/* Memory buffers. Changing these three constants can have a dramatic + effect on performance. The values here are reasonable defaults, + but might be tuned. If you adjust them, be sure to test across a + range of uses of cpplib, including heavy nested function-like macro + expansion. Also check the change in peak memory usage (NJAMD is a + good tool for this). */ +#define MIN_BUFF_SIZE 8000 +#define BUFF_SIZE_UPPER_BOUND(MIN_SIZE) (MIN_BUFF_SIZE + (MIN_SIZE) * 3 / 2) +#define EXTENDED_BUFF_SIZE(BUFF, MIN_EXTRA) \ + (MIN_EXTRA + ((BUFF)->limit - (BUFF)->cur) * 2) + +#if MIN_BUFF_SIZE > BUFF_SIZE_UPPER_BOUND (0) + #error BUFF_SIZE_UPPER_BOUND must be at least as large as MIN_BUFF_SIZE! +#endif + +/* Create a new allocation buffer. Place the control block at the end + of the buffer, so that buffer overflows will cause immediate chaos. */ +static _cpp_buff * +new_buff (size_t len) +{ + _cpp_buff *result; + unsigned char *base; + + if (len < MIN_BUFF_SIZE) + len = MIN_BUFF_SIZE; + len = CPP_ALIGN (len); + + base = XNEWVEC (unsigned char, len + sizeof (_cpp_buff)); + result = (_cpp_buff *) (base + len); + result->base = base; + result->cur = base; + result->limit = base + len; + result->next = NULL; + return result; +} + +/* Place a chain of unwanted allocation buffers on the free list. */ +void +_cpp_release_buff (cpp_reader *pfile, _cpp_buff *buff) +{ + _cpp_buff *end = buff; + + while (end->next) + end = end->next; + end->next = pfile->free_buffs; + pfile->free_buffs = buff; +} + +/* Return a free buffer of size at least MIN_SIZE. */ +_cpp_buff * +_cpp_get_buff (cpp_reader *pfile, size_t min_size) +{ + _cpp_buff *result, **p; + + for (p = &pfile->free_buffs;; p = &(*p)->next) + { + size_t size; + + if (*p == NULL) + return new_buff (min_size); + result = *p; + size = result->limit - result->base; + /* Return a buffer that's big enough, but don't waste one that's + way too big. */ + if (size >= min_size && size <= BUFF_SIZE_UPPER_BOUND (min_size)) + break; + } + + *p = result->next; + result->next = NULL; + result->cur = result->base; + return result; +} + +/* Creates a new buffer with enough space to hold the uncommitted + remaining bytes of BUFF, and at least MIN_EXTRA more bytes. Copies + the excess bytes to the new buffer. Chains the new buffer after + BUFF, and returns the new buffer. */ +_cpp_buff * +_cpp_append_extend_buff (cpp_reader *pfile, _cpp_buff *buff, size_t min_extra) +{ + size_t size = EXTENDED_BUFF_SIZE (buff, min_extra); + _cpp_buff *new_buff = _cpp_get_buff (pfile, size); + + buff->next = new_buff; + memcpy (new_buff->base, buff->cur, BUFF_ROOM (buff)); + return new_buff; +} + +/* Creates a new buffer with enough space to hold the uncommitted + remaining bytes of the buffer pointed to by BUFF, and at least + MIN_EXTRA more bytes. Copies the excess bytes to the new buffer. + Chains the new buffer before the buffer pointed to by BUFF, and + updates the pointer to point to the new buffer. */ +void +_cpp_extend_buff (cpp_reader *pfile, _cpp_buff **pbuff, size_t min_extra) +{ + _cpp_buff *new_buff, *old_buff = *pbuff; + size_t size = EXTENDED_BUFF_SIZE (old_buff, min_extra); + + new_buff = _cpp_get_buff (pfile, size); + memcpy (new_buff->base, old_buff->cur, BUFF_ROOM (old_buff)); + new_buff->next = old_buff; + *pbuff = new_buff; +} + +/* Free a chain of buffers starting at BUFF. */ +void +_cpp_free_buff (_cpp_buff *buff) +{ + _cpp_buff *next; + + for (; buff; buff = next) + { + next = buff->next; + free (buff->base); + } +} + +/* Allocate permanent, unaligned storage of length LEN. */ +unsigned char * +_cpp_unaligned_alloc (cpp_reader *pfile, size_t len) +{ + _cpp_buff *buff = pfile->u_buff; + unsigned char *result = buff->cur; + + if (len > (size_t) (buff->limit - result)) + { + buff = _cpp_get_buff (pfile, len); + buff->next = pfile->u_buff; + pfile->u_buff = buff; + result = buff->cur; + } + + buff->cur = result + len; + return result; +} + +/* Allocate permanent, unaligned storage of length LEN from a_buff. + That buffer is used for growing allocations when saving macro + replacement lists in a #define, and when parsing an answer to an + assertion in #assert, #unassert or #if (and therefore possibly + whilst expanding macros). It therefore must not be used by any + code that they might call: specifically the lexer and the guts of + the macro expander. + + All existing other uses clearly fit this restriction: storing + registered pragmas during initialization. */ +unsigned char * +_cpp_aligned_alloc (cpp_reader *pfile, size_t len) +{ + _cpp_buff *buff = pfile->a_buff; + unsigned char *result = buff->cur; + + if (len > (size_t) (buff->limit - result)) + { + buff = _cpp_get_buff (pfile, len); + buff->next = pfile->a_buff; + pfile->a_buff = buff; + result = buff->cur; + } + + buff->cur = result + len; + return result; +} + +/* Say which field of TOK is in use. */ + +enum cpp_token_fld_kind +cpp_token_val_index (cpp_token *tok) +{ + switch (TOKEN_SPELL (tok)) + { + case SPELL_IDENT: + return CPP_TOKEN_FLD_NODE; + case SPELL_LITERAL: + return CPP_TOKEN_FLD_STR; + case SPELL_OPERATOR: + if (tok->type == CPP_PASTE) + return CPP_TOKEN_FLD_TOKEN_NO; + else + return CPP_TOKEN_FLD_NONE; + case SPELL_NONE: + if (tok->type == CPP_MACRO_ARG) + return CPP_TOKEN_FLD_ARG_NO; + else if (tok->type == CPP_PADDING) + return CPP_TOKEN_FLD_SOURCE; + else if (tok->type == CPP_PRAGMA) + return CPP_TOKEN_FLD_PRAGMA; + /* else fall through */ + default: + return CPP_TOKEN_FLD_NONE; + } +} diff --git a/support/cpp/libcpp/line-map.c b/support/cpp/libcpp/line-map.c new file mode 100644 index 0000000..a82c428 --- /dev/null +++ b/support/cpp/libcpp/line-map.c @@ -0,0 +1,319 @@ +/* Map logical line numbers to (source file, line number) pairs. + Copyright (C) 2001, 2003, 2004, 2007, 2008, 2009 + Free Software Foundation, Inc. + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. + + 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 "line-map.h" + +static void trace_include (const struct line_maps *, const struct line_map *); + +/* Initialize a line map set. */ + +void +linemap_init (struct line_maps *set) +{ + set->maps = NULL; + set->allocated = 0; + set->used = 0; + set->last_listed = -1; + set->trace_includes = false; + set->depth = 0; + set->cache = 0; + set->highest_location = RESERVED_LOCATION_COUNT - 1; + set->highest_line = RESERVED_LOCATION_COUNT - 1; + set->max_column_hint = 0; + set->reallocator = 0; +} + +/* Check for and warn about line_maps entered but not exited. */ + +void +linemap_check_files_exited (struct line_maps *set) +{ + struct line_map *map; + /* Depending upon whether we are handling preprocessed input or + not, this can be a user error or an ICE. */ + for (map = &set->maps[set->used - 1]; ! MAIN_FILE_P (map); + map = INCLUDED_FROM (set, map)) + fprintf (stderr, "line-map.c: file \"%s\" entered but not left\n", + map->to_file); +} + +/* Free a line map set. */ + +void +linemap_free (struct line_maps *set) +{ + if (set->maps) + { + linemap_check_files_exited (set); + + free (set->maps); + } +} + +/* Add a mapping of logical source line to physical source file and + line number. + + The text pointed to by TO_FILE must have a lifetime + at least as long as the final call to lookup_line (). An empty + TO_FILE means standard input. If reason is LC_LEAVE, and + TO_FILE is NULL, then TO_FILE, TO_LINE and SYSP are given their + natural values considering the file we are returning to. + + FROM_LINE should be monotonic increasing across calls to this + function. A call to this function can relocate the previous set of + maps, so any stored line_map pointers should not be used. */ + +const struct line_map * +linemap_add (struct line_maps *set, enum lc_reason reason, + unsigned int sysp, const char *to_file, linenum_type to_line) +{ + struct line_map *map; + source_location start_location = set->highest_location + 1; + + if (set->used && start_location < set->maps[set->used - 1].start_location) + abort (); + + if (set->used == set->allocated) + { + line_map_realloc reallocator + = set->reallocator ? set->reallocator : xrealloc; + set->allocated = 2 * set->allocated + 256; + set->maps + = (struct line_map *) (*reallocator) (set->maps, + set->allocated + * sizeof (struct line_map)); + memset (&set->maps[set->used], 0, ((set->allocated - set->used) + * sizeof (struct line_map))); + } + + map = &set->maps[set->used]; + + if (to_file && *to_file == '\0' && reason != LC_RENAME_VERBATIM) + to_file = "<stdin>"; + + if (reason == LC_RENAME_VERBATIM) + reason = LC_RENAME; + + /* If we don't keep our line maps consistent, we can easily + segfault. Don't rely on the client to do it for us. */ + if (set->depth == 0) + reason = LC_ENTER; + else if (reason == LC_LEAVE) + { + struct line_map *from; + bool error; + + if (MAIN_FILE_P (map - 1)) + { + if (to_file == NULL) + { + set->depth--; + return NULL; + } + error = true; + reason = LC_RENAME; + from = map - 1; + } + else + { + from = INCLUDED_FROM (set, map - 1); + error = to_file && strcmp (from->to_file, to_file); + } + + /* Depending upon whether we are handling preprocessed input or + not, this can be a user error or an ICE. */ + if (error) + fprintf (stderr, "line-map.c: file \"%s\" left but not entered\n", + to_file); + + /* A TO_FILE of NULL is special - we use the natural values. */ + if (error || to_file == NULL) + { + to_file = from->to_file; + to_line = SOURCE_LINE (from, from[1].start_location); + sysp = from->sysp; + } + } + + map->reason = reason; + map->sysp = sysp; + map->start_location = start_location; + map->to_file = to_file; + map->to_line = to_line; + set->cache = set->used++; + map->column_bits = 0; + set->highest_location = start_location; + set->highest_line = start_location; + set->max_column_hint = 0; + + if (reason == LC_ENTER) + { + map->included_from = set->depth == 0 ? -1 : (int) (set->used - 2); + set->depth++; + if (set->trace_includes) + trace_include (set, map); + } + else if (reason == LC_RENAME) + map->included_from = map[-1].included_from; + else if (reason == LC_LEAVE) + { + set->depth--; + map->included_from = INCLUDED_FROM (set, map - 1)->included_from; + } + + return map; +} + +source_location +linemap_line_start (struct line_maps *set, linenum_type to_line, + unsigned int max_column_hint) +{ + struct line_map *map = &set->maps[set->used - 1]; + source_location highest = set->highest_location; + source_location r; + linenum_type last_line = SOURCE_LINE (map, set->highest_line); + int line_delta = to_line - last_line; + bool add_map = false; + if (line_delta < 0 + || (line_delta > 10 && line_delta * map->column_bits > 1000) + || (max_column_hint >= (1U << map->column_bits)) + || (max_column_hint <= 80 && map->column_bits >= 10)) + { + add_map = true; + } + else + max_column_hint = set->max_column_hint; + if (add_map) + { + int column_bits; + if (max_column_hint > 100000 || highest > 0xC0000000) + { + /* If the column number is ridiculous or we've allocated a huge + number of source_locations, give up on column numbers. */ + max_column_hint = 0; + if (highest >0xF0000000) + return 0; + column_bits = 0; + } + else + { + column_bits = 7; + while (max_column_hint >= (1U << column_bits)) + column_bits++; + max_column_hint = 1U << column_bits; + } + /* Allocate the new line_map. However, if the current map only has a + single line we can sometimes just increase its column_bits instead. */ + if (line_delta < 0 + || last_line != map->to_line + || SOURCE_COLUMN (map, highest) >= (1U << column_bits)) + map = (struct line_map *) linemap_add (set, LC_RENAME, map->sysp, + map->to_file, to_line); + map->column_bits = column_bits; + r = map->start_location + ((to_line - map->to_line) << column_bits); + } + else + r = highest - SOURCE_COLUMN (map, highest) + + (line_delta << map->column_bits); + set->highest_line = r; + if (r > set->highest_location) + set->highest_location = r; + set->max_column_hint = max_column_hint; + return r; +} + +source_location +linemap_position_for_column (struct line_maps *set, unsigned int to_column) +{ + source_location r = set->highest_line; + if (to_column >= set->max_column_hint) + { + if (r >= 0xC000000 || to_column > 100000) + { + /* Running low on source_locations - disable column numbers. */ + return r; + } + else + { + struct line_map *map = &set->maps[set->used - 1]; + r = linemap_line_start (set, SOURCE_LINE (map, r), to_column + 50); + } + } + r = r + to_column; + if (r >= set->highest_location) + set->highest_location = r; + return r; +} + +/* Given a logical line, returns the map from which the corresponding + (source file, line) pair can be deduced. Since the set is built + chronologically, the logical lines are monotonic increasing, and so + the list is sorted and we can use a binary search. */ + +const struct line_map * +linemap_lookup (struct line_maps *set, source_location line) +{ + unsigned int md, mn, mx; + const struct line_map *cached; + + mn = set->cache; + mx = set->used; + + cached = &set->maps[mn]; + /* We should get a segfault if no line_maps have been added yet. */ + if (line >= cached->start_location) + { + if (mn + 1 == mx || line < cached[1].start_location) + return cached; + } + else + { + mx = mn; + mn = 0; + } + + while (mx - mn > 1) + { + md = (mn + mx) / 2; + if (set->maps[md].start_location > line) + mx = md; + else + mn = md; + } + + set->cache = mn; + return &set->maps[mn]; +} + +/* Print an include trace, for e.g. the -H option of the preprocessor. */ + +static void +trace_include (const struct line_maps *set, const struct line_map *map) +{ + unsigned int i = set->depth; + + while (--i) + putc ('.', stderr); + fprintf (stderr, " %s\n", map->to_file); +} diff --git a/support/cpp/libcpp/macro.c b/support/cpp/libcpp/macro.c new file mode 100644 index 0000000..a89ec33 --- /dev/null +++ b/support/cpp/libcpp/macro.c @@ -0,0 +1,2136 @@ +/* Part of CPP library. (Macro and #define handling.) + Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1998, + 1999, 2000, 2001, 2002, 2003, 2004, 2005, + 2006, 2007, 2008, 2009, 2010 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 3, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. + + 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 "internal.h" + +typedef struct macro_arg macro_arg; +struct macro_arg +{ + const cpp_token **first; /* First token in unexpanded argument. */ + const cpp_token **expanded; /* Macro-expanded argument. */ + const cpp_token *stringified; /* Stringified argument. */ + unsigned int count; /* # of tokens in argument. */ + unsigned int expanded_count; /* # of tokens in expanded argument. */ +}; + +/* Macro expansion. */ + +static int enter_macro_context (cpp_reader *, cpp_hashnode *, + const cpp_token *); +static int builtin_macro (cpp_reader *, cpp_hashnode *); +static void push_ptoken_context (cpp_reader *, cpp_hashnode *, _cpp_buff *, + const cpp_token **, unsigned int); +static _cpp_buff *collect_args (cpp_reader *, const cpp_hashnode *, + _cpp_buff **); +static cpp_context *next_context (cpp_reader *); +static const cpp_token *padding_token (cpp_reader *, const cpp_token *); +static void expand_arg (cpp_reader *, macro_arg *); +static const cpp_token *new_string_token (cpp_reader *, uchar *, unsigned int); +static const cpp_token *stringify_arg (cpp_reader *, macro_arg *); +static void paste_all_tokens (cpp_reader *, const cpp_token *); +static bool paste_tokens (cpp_reader *, const cpp_token **, const cpp_token *); +static void replace_args (cpp_reader *, cpp_hashnode *, cpp_macro *, + macro_arg *); +static _cpp_buff *funlike_invocation_p (cpp_reader *, cpp_hashnode *, + _cpp_buff **); +static bool create_iso_definition (cpp_reader *, cpp_macro *); + +/* #define directive parsing and handling. */ + +static cpp_token *alloc_expansion_token (cpp_reader *, cpp_macro *); +static cpp_token *lex_expansion_token (cpp_reader *, cpp_macro *); +static bool warn_of_redefinition (cpp_reader *, cpp_hashnode *, + const cpp_macro *); +static bool parse_params (cpp_reader *, cpp_macro *); +static void check_trad_stringification (cpp_reader *, const cpp_macro *, + const cpp_string *); + +/* Emits a warning if NODE is a macro defined in the main file that + has not been used. */ +int +_cpp_warn_if_unused_macro (cpp_reader *pfile, cpp_hashnode *node, + void *v ATTRIBUTE_UNUSED) +{ + if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN)) + { + cpp_macro *macro = node->value.macro; + + if (!macro->used + && MAIN_FILE_P (linemap_lookup (pfile->line_table, macro->line))) + cpp_warning_with_line (pfile, CPP_W_UNUSED_MACROS, macro->line, 0, + "macro \"%s\" is not used", NODE_NAME (node)); + } + + return 1; +} + +/* Allocates and returns a CPP_STRING token, containing TEXT of length + LEN, after null-terminating it. TEXT must be in permanent storage. */ +static const cpp_token * +new_string_token (cpp_reader *pfile, unsigned char *text, unsigned int len) +{ + cpp_token *token = _cpp_temp_token (pfile); + + text[len] = '\0'; + token->type = CPP_STRING; + token->val.str.len = len; + token->val.str.text = text; + token->flags = 0; + return token; +} + +static const char * const monthnames[] = +{ + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" +}; + +/* Helper function for builtin_macro. Returns the text generated by + a builtin macro. */ +const uchar * +_cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node) +{ + const struct line_map *map; + const uchar *result = NULL; + linenum_type number = 1; + + switch (node->value.builtin) + { + default: + cpp_error (pfile, CPP_DL_ICE, "invalid built-in macro \"%s\"", + NODE_NAME (node)); + break; + + case BT_TIMESTAMP: + { + cpp_buffer *pbuffer = cpp_get_buffer (pfile); + if (pbuffer->timestamp == NULL) + { + /* Initialize timestamp value of the assotiated file. */ + struct _cpp_file *file = cpp_get_file (pbuffer); + if (file) + { + /* Generate __TIMESTAMP__ string, that represents + the date and time of the last modification + of the current source file. The string constant + looks like "Sun Sep 16 01:03:52 1973". */ + struct tm *tb = NULL; + struct stat *st = _cpp_get_file_stat (file); + if (st) + tb = localtime (&st->st_mtime); + if (tb) + { + char *str = asctime (tb); + size_t len = strlen (str); + unsigned char *buf = _cpp_unaligned_alloc (pfile, len + 2); + buf[0] = '"'; + strcpy ((char *) buf + 1, str); + buf[len] = '"'; + pbuffer->timestamp = buf; + } + else + { + cpp_errno (pfile, CPP_DL_WARNING, + "could not determine file timestamp"); + pbuffer->timestamp = UC"\"??? ??? ?? ??:??:?? ????\""; + } + } + } + result = pbuffer->timestamp; + } + break; + case BT_FUNCTION: + { + uchar *buf; + buf = _cpp_unaligned_alloc (pfile, 256); + memset (buf, 255, 256); + buf[0] = buf[254] = '"'; + buf[255] = 0; + result = buf; + } + break; + case BT_FILE: + case BT_BASE_FILE: + { + unsigned int len; + const char *name; + uchar *buf; + map = linemap_lookup (pfile->line_table, pfile->line_table->highest_line); + + if (node->value.builtin == BT_BASE_FILE) + while (! MAIN_FILE_P (map)) + map = INCLUDED_FROM (pfile->line_table, map); + + name = map->to_file; + len = strlen (name); + buf = _cpp_unaligned_alloc (pfile, len * 2 + 3); + result = buf; + *buf = '"'; + buf = cpp_quote_string (buf + 1, (const unsigned char *) name, len); + *buf++ = '"'; + *buf = '\0'; + } + break; + + case BT_INCLUDE_LEVEL: + /* The line map depth counts the primary source as level 1, but + historically __INCLUDE_DEPTH__ has called the primary source + level 0. */ + number = pfile->line_table->depth - 1; + break; + + case BT_SPECLINE: + map = &pfile->line_table->maps[pfile->line_table->used-1]; + /* 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. */ + number = SOURCE_LINE (map, + CPP_OPTION (pfile, traditional) + ? pfile->line_table->highest_line + : pfile->cur_token[-1].src_loc); + break; + + /* __STDC__ has the value 1 under normal circumstances. + However, if (a) we are in a system header, (b) the option + stdc_0_in_system_headers is true (set by target config), and + (c) we are not in strictly conforming mode, then it has the + value 0. (b) and (c) are already checked in cpp_init_builtins. */ + case BT_STDC: + if (cpp_in_system_header (pfile)) + number = 0; + else + number = 1; + break; + + case BT_DATE: + case BT_TIME: + if (pfile->date == NULL) + { + /* Allocate __DATE__ and __TIME__ strings from permanent + storage. We only do this once, and don't generate them + at init time, because time() and localtime() are very + slow on some systems. */ + time_t tt; + struct tm *tb = NULL; + + /* (time_t) -1 is a legitimate value for "number of seconds + since the Epoch", so we have to do a little dance to + distinguish that from a genuine error. */ + errno = 0; + tt = time(NULL); + if (tt != (time_t)-1 || errno == 0) + tb = localtime (&tt); + + if (tb) + { + pfile->date = _cpp_unaligned_alloc (pfile, + sizeof ("\"Oct 11 1347\"")); + sprintf ((char *) pfile->date, "\"%s %2d %4d\"", + monthnames[tb->tm_mon], tb->tm_mday, + tb->tm_year + 1900); + + pfile->time = _cpp_unaligned_alloc (pfile, + sizeof ("\"12:34:56\"")); + sprintf ((char *) pfile->time, "\"%02d:%02d:%02d\"", + tb->tm_hour, tb->tm_min, tb->tm_sec); + } + else + { + cpp_errno (pfile, CPP_DL_WARNING, + "could not determine date and time"); + + pfile->date = UC"\"??? ?? ????\""; + pfile->time = UC"\"??:??:??\""; + } + } + + if (node->value.builtin == BT_DATE) + result = pfile->date; + else + result = pfile->time; + break; + + case BT_COUNTER: + if (CPP_OPTION (pfile, directives_only) && pfile->state.in_directive) + cpp_error (pfile, CPP_DL_ERROR, + "__COUNTER__ expanded inside directive with -fdirectives-only"); + number = pfile->counter++; + break; + } + + if (result == NULL) + { + /* 21 bytes holds all NUL-terminated unsigned 64-bit numbers. */ + result = _cpp_unaligned_alloc (pfile, 21); + sprintf ((char *) result, "%u", number); + } + + return result; +} + +/* Convert builtin macros like __FILE__ to a token and push it on the + context stack. Also handles _Pragma, for which a new token may not + be created. Returns 1 if it generates a new token context, 0 to + return the token to the caller. */ +static int +builtin_macro (cpp_reader *pfile, cpp_hashnode *node) +{ + const uchar *buf; + size_t len; + char *nbuf; + + if (node->value.builtin == BT_PRAGMA) + { + /* Don't interpret _Pragma within directives. The standard is + not clear on this, but to me this makes most sense. */ + if (pfile->state.in_directive) + return 0; + + return _cpp_do__Pragma (pfile); + } + + buf = _cpp_builtin_macro_text (pfile, node); + len = ustrlen (buf); + nbuf = (char *) alloca (len + 1); + memcpy (nbuf, buf, len); + nbuf[len]='\n'; + + cpp_push_buffer (pfile, (uchar *) nbuf, len, /* from_stage3 */ true); + _cpp_clean_line (pfile); + + /* Set pfile->cur_token as required by _cpp_lex_direct. */ + pfile->cur_token = _cpp_temp_token (pfile); + _cpp_push_token_context (pfile, NULL, _cpp_lex_direct (pfile), 1); + if (pfile->buffer->cur != pfile->buffer->rlimit) + cpp_error (pfile, CPP_DL_ICE, "invalid built-in macro \"%s\"", + NODE_NAME (node)); + _cpp_pop_buffer (pfile); + + return 1; +} + +/* Copies SRC, of length LEN, to DEST, adding backslashes before all + backslashes and double quotes. DEST must be of sufficient size. + Returns a pointer to the end of the string. */ +uchar * +cpp_quote_string (uchar *dest, const uchar *src, unsigned int len) +{ + while (len--) + { + uchar c = *src++; + + if (c == '\\' || c == '"') + { + *dest++ = '\\'; + *dest++ = c; + } + else + *dest++ = c; + } + + return dest; +} + +/* Convert a token sequence ARG to a single string token according to + the rules of the ISO C #-operator. */ +static const cpp_token * +stringify_arg (cpp_reader *pfile, macro_arg *arg) +{ + unsigned char *dest; + unsigned int i, escape_it, backslash_count = 0; + const cpp_token *source = NULL; + size_t len; + + if (BUFF_ROOM (pfile->u_buff) < 3) + _cpp_extend_buff (pfile, &pfile->u_buff, 3); + dest = BUFF_FRONT (pfile->u_buff); + *dest++ = '"'; + + /* Loop, reading in the argument's tokens. */ + for (i = 0; i < arg->count; i++) + { + const cpp_token *token = arg->first[i]; + + if (token->type == CPP_PADDING) + { + if (source == NULL + || (!(source->flags & PREV_WHITE) + && token->val.source == NULL)) + source = token->val.source; + continue; + } + + escape_it = (token->type == CPP_STRING || token->type == CPP_CHAR + || token->type == CPP_WSTRING || token->type == CPP_WCHAR + || token->type == CPP_STRING32 || token->type == CPP_CHAR32 + || token->type == CPP_STRING16 || token->type == CPP_CHAR16 + || token->type == CPP_UTF8STRING); + + /* Room for each char being written in octal, initial space and + final quote and NUL. */ + len = cpp_token_len (token); + if (escape_it) + len *= 4; + len += 3; + + if ((size_t) (BUFF_LIMIT (pfile->u_buff) - dest) < len) + { + size_t len_so_far = dest - BUFF_FRONT (pfile->u_buff); + _cpp_extend_buff (pfile, &pfile->u_buff, len); + dest = BUFF_FRONT (pfile->u_buff) + len_so_far; + } + + /* Leading white space? */ + if (dest - 1 != BUFF_FRONT (pfile->u_buff)) + { + if (source == NULL) + source = token; + if (source->flags & PREV_WHITE) + *dest++ = ' '; + } + source = NULL; + + if (escape_it) + { + _cpp_buff *buff = _cpp_get_buff (pfile, len); + unsigned char *buf = BUFF_FRONT (buff); + len = cpp_spell_token (pfile, token, buf, true) - buf; + dest = cpp_quote_string (dest, buf, len); + _cpp_release_buff (pfile, buff); + } + else + dest = cpp_spell_token (pfile, token, dest, true); + + if (token->type == CPP_OTHER && token->val.str.text[0] == '\\') + backslash_count++; + else + backslash_count = 0; + } + + /* Ignore the final \ of invalid string literals. */ + if (backslash_count & 1) + { + cpp_error (pfile, CPP_DL_WARNING, + "invalid string literal, ignoring final '\\'"); + dest--; + } + + /* Commit the memory, including NUL, and return the token. */ + *dest++ = '"'; + len = dest - BUFF_FRONT (pfile->u_buff); + BUFF_FRONT (pfile->u_buff) = dest + 1; + return new_string_token (pfile, dest - len, len); +} + +/* Try to paste two tokens. On success, return nonzero. In any + case, PLHS is updated to point to the pasted token, which is + guaranteed to not have the PASTE_LEFT flag set. */ +static bool +paste_tokens (cpp_reader *pfile, const cpp_token **plhs, const cpp_token *rhs) +{ + unsigned char *buf, *end, *lhsend; + cpp_token *lhs; + unsigned int len; + + len = cpp_token_len (*plhs) + cpp_token_len (rhs) + 1; + buf = (unsigned char *) alloca (len); + end = lhsend = cpp_spell_token (pfile, *plhs, buf, false); + + /* Avoid comment headers, since they are still processed in stage 3. + It is simpler to insert a space here, rather than modifying the + lexer to ignore comments in some circumstances. Simply returning + false doesn't work, since we want to clear the PASTE_LEFT flag. */ + if ((*plhs)->type == CPP_DIV && rhs->type != CPP_EQ) + *end++ = ' '; + /* In one obscure case we might see padding here. */ + if (rhs->type != CPP_PADDING) + end = cpp_spell_token (pfile, rhs, end, false); + *end = '\n'; + + cpp_push_buffer (pfile, buf, end - buf, /* from_stage3 */ true); + _cpp_clean_line (pfile); + + /* Set pfile->cur_token as required by _cpp_lex_direct. */ + pfile->cur_token = _cpp_temp_token (pfile); + lhs = _cpp_lex_direct (pfile); + if (pfile->buffer->cur != pfile->buffer->rlimit) + { + source_location saved_loc = lhs->src_loc; + + _cpp_pop_buffer (pfile); + _cpp_backup_tokens (pfile, 1); + *lhsend = '\0'; + + /* We have to remove the PASTE_LEFT flag from the old lhs, but + we want to keep the new location. */ + *lhs = **plhs; + *plhs = lhs; + lhs->src_loc = saved_loc; + lhs->flags &= ~PASTE_LEFT; + + /* Mandatory error for all apart from assembler. */ + if (CPP_OPTION (pfile, lang) != CLK_ASM) + cpp_error (pfile, CPP_DL_ERROR, + "pasting \"%s\" and \"%s\" does not give a valid preprocessing token", + buf, cpp_token_as_text (pfile, rhs)); + return false; + } + + *plhs = lhs; + _cpp_pop_buffer (pfile); + return true; +} + +/* Handles an arbitrarily long sequence of ## operators, with initial + operand LHS. This implementation is left-associative, + non-recursive, and finishes a paste before handling succeeding + ones. If a paste fails, we back up to the RHS of the failing ## + operator before pushing the context containing the result of prior + successful pastes, with the effect that the RHS appears in the + output stream after the pasted LHS normally. */ +static void +paste_all_tokens (cpp_reader *pfile, const cpp_token *lhs) +{ + const cpp_token *rhs; + cpp_context *context = pfile->context; + + 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. */ + if (context->direct_p) + rhs = FIRST (context).token++; + else + rhs = *FIRST (context).ptoken++; + + if (rhs->type == CPP_PADDING) + { + if (rhs->flags & PASTE_LEFT) + abort (); + } + if (!paste_tokens (pfile, &lhs, rhs)) + break; + } + while (rhs->flags & PASTE_LEFT); + + /* Put the resulting token in its own context. */ + _cpp_push_token_context (pfile, NULL, lhs, 1); +} + +/* Returns TRUE if the number of arguments ARGC supplied in an + invocation of the MACRO referenced by NODE is valid. An empty + invocation to a macro with no parameters should pass ARGC as zero. + + Note that MACRO cannot necessarily be deduced from NODE, in case + NODE was redefined whilst collecting arguments. */ +bool +_cpp_arguments_ok (cpp_reader *pfile, cpp_macro *macro, const cpp_hashnode *node, unsigned int argc) +{ + if (argc == macro->paramc) + return true; + + 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_error (pfile, CPP_DL_PEDWARN, + "ISO C99 requires rest arguments to be used"); + return true; + } + + cpp_error (pfile, CPP_DL_ERROR, + "macro \"%s\" requires %u arguments, but only %u given", + NODE_NAME (node), macro->paramc, argc); + } + else + cpp_error (pfile, CPP_DL_ERROR, + "macro \"%s\" passed %u arguments, but takes just %u", + NODE_NAME (node), argc, macro->paramc); + + return false; +} + +/* Reads and returns the arguments to a function-like macro + invocation. Assumes the opening parenthesis has been processed. + If there is an error, emits an appropriate diagnostic and returns + NULL. Each argument is terminated by a CPP_EOF token, for the + future benefit of expand_arg(). If there are any deferred + #pragma directives among macro arguments, store pointers to the + CPP_PRAGMA ... CPP_PRAGMA_EOL tokens into *PRAGMA_BUFF buffer. */ +static _cpp_buff * +collect_args (cpp_reader *pfile, const cpp_hashnode *node, + _cpp_buff **pragma_buff) +{ + _cpp_buff *buff, *base_buff; + cpp_macro *macro; + macro_arg *args, *arg; + const cpp_token *token; + unsigned int argc; + + macro = node->value.macro; + if (macro->paramc) + argc = macro->paramc; + else + argc = 1; + buff = _cpp_get_buff (pfile, argc * (50 * sizeof (cpp_token *) + + sizeof (macro_arg))); + base_buff = buff; + args = (macro_arg *) buff->base; + memset (args, 0, argc * sizeof (macro_arg)); + buff->cur = (unsigned char *) &args[argc]; + arg = args, argc = 0; + + /* Collect the tokens making up each argument. We don't yet know + how many arguments have been supplied, whether too many or too + few. Hence the slightly bizarre usage of "argc" and "arg". */ + do + { + unsigned int paren_depth = 0; + unsigned int ntokens = 0; + + argc++; + arg->first = (const cpp_token **) buff->cur; + + for (;;) + { + /* Require space for 2 new tokens (including a CPP_EOF). */ + if ((unsigned char *) &arg->first[ntokens + 2] > buff->limit) + { + buff = _cpp_append_extend_buff (pfile, buff, + 1000 * sizeof (cpp_token *)); + arg->first = (const cpp_token **) buff->cur; + } + + token = cpp_get_token (pfile); + + if (token->type == CPP_PADDING) + { + /* Drop leading padding. */ + if (ntokens == 0) + continue; + } + else if (token->type == CPP_OPEN_PAREN) + paren_depth++; + else if (token->type == CPP_CLOSE_PAREN) + { + if (paren_depth-- == 0) + break; + } + else if (token->type == CPP_COMMA) + { + /* A comma does not terminate an argument within + parentheses or as part of a variable argument. */ + if (paren_depth == 0 + && ! (macro->variadic && argc == macro->paramc)) + break; + } + else if (token->type == CPP_EOF + || (token->type == CPP_HASH && token->flags & BOL)) + break; + else if (token->type == CPP_PRAGMA) + { + cpp_token *newtok = _cpp_temp_token (pfile); + + /* CPP_PRAGMA token lives in directive_result, which will + be overwritten on the next directive. */ + *newtok = *token; + token = newtok; + do + { + if (*pragma_buff == NULL + || BUFF_ROOM (*pragma_buff) < sizeof (cpp_token *)) + { + _cpp_buff *next; + if (*pragma_buff == NULL) + *pragma_buff + = _cpp_get_buff (pfile, 32 * sizeof (cpp_token *)); + else + { + next = *pragma_buff; + *pragma_buff + = _cpp_get_buff (pfile, + (BUFF_FRONT (*pragma_buff) + - (*pragma_buff)->base) * 2); + (*pragma_buff)->next = next; + } + } + *(const cpp_token **) BUFF_FRONT (*pragma_buff) = token; + BUFF_FRONT (*pragma_buff) += sizeof (cpp_token *); + if (token->type == CPP_PRAGMA_EOL) + break; + token = cpp_get_token (pfile); + } + while (token->type != CPP_EOF); + + /* In deferred pragmas parsing_args and prevent_expansion + had been changed, reset it. */ + pfile->state.parsing_args = 2; + pfile->state.prevent_expansion = 1; + + if (token->type == CPP_EOF) + break; + else + continue; + } + + arg->first[ntokens++] = token; + } + + /* Drop trailing padding. */ + while (ntokens > 0 && arg->first[ntokens - 1]->type == CPP_PADDING) + ntokens--; + + arg->count = ntokens; + arg->first[ntokens] = &pfile->eof; + + /* Terminate the argument. Excess arguments loop back and + overwrite the final legitimate argument, before failing. */ + if (argc <= macro->paramc) + { + buff->cur = (unsigned char *) &arg->first[ntokens + 1]; + if (argc != macro->paramc) + arg++; + } + } + while (token->type != CPP_CLOSE_PAREN && token->type != CPP_EOF); + + if (token->type == CPP_EOF) + { + /* We still need the CPP_EOF to end directives, and to end + pre-expansion of a macro argument. Step back is not + unconditional, since we don't want to return a CPP_EOF to our + callers at the end of an -include-d file. */ + if (pfile->context->prev || pfile->state.in_directive) + _cpp_backup_tokens (pfile, 1); + cpp_error (pfile, CPP_DL_ERROR, + "unterminated argument list invoking macro \"%s\"", + NODE_NAME (node)); + } + else + { + /* A single empty argument is counted as no argument. */ + if (argc == 1 && macro->paramc == 0 && args[0].count == 0) + argc = 0; + if (_cpp_arguments_ok (pfile, macro, node, argc)) + { + /* GCC has special semantics for , ## b where b is a varargs + parameter: we remove the comma if b was omitted entirely. + If b was merely an empty argument, the comma is retained. + If the macro takes just one (varargs) parameter, then we + retain the comma only if we are standards conforming. + + If FIRST is NULL replace_args () swallows the comma. */ + if (macro->variadic && (argc < macro->paramc + || (argc == 1 && args[0].count == 0 + && !CPP_OPTION (pfile, std)))) + args[macro->paramc - 1].first = NULL; + return base_buff; + } + } + + /* An error occurred. */ + _cpp_release_buff (pfile, base_buff); + return NULL; +} + +/* Search for an opening parenthesis to the macro of NODE, in such a + way that, if none is found, we don't lose the information in any + intervening padding tokens. If we find the parenthesis, collect + the arguments and return the buffer containing them. PRAGMA_BUFF + argument is the same as in collect_args. */ +static _cpp_buff * +funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node, + _cpp_buff **pragma_buff) +{ + const cpp_token *token, *padding = NULL; + + for (;;) + { + token = cpp_get_token (pfile); + if (token->type != CPP_PADDING) + break; + if (padding == NULL + || (!(padding->flags & PREV_WHITE) && token->val.source == NULL)) + padding = token; + } + + if (token->type == CPP_OPEN_PAREN) + { + pfile->state.parsing_args = 2; + return collect_args (pfile, node, pragma_buff); + } + + /* CPP_EOF can be the end of macro arguments, or the end of the + file. We mustn't back up over the latter. Ugh. */ + if (token->type != CPP_EOF || token == &pfile->eof) + { + /* Back up. We may have skipped padding, in which case backing + up more than one token when expanding macros is in general + too difficult. We re-insert it in its own context. */ + _cpp_backup_tokens (pfile, 1); + if (padding) + _cpp_push_token_context (pfile, NULL, padding, 1); + } + + return NULL; +} + +/* Return the real number of tokens in the expansion of MACRO. */ +static inline unsigned int +macro_real_token_count (const cpp_macro *macro) +{ + unsigned int i; + if (__builtin_expect (!macro->extra_tokens, true)) + return macro->count; + for (i = 0; i < macro->count; i++) + if (macro->exp.tokens[i].type == CPP_PASTE) + return i; + abort (); + return 0; //makes compiler happy +} + +/* Push the context of a macro with hash entry NODE onto the context + stack. If we can successfully expand the macro, we push a context + containing its yet-to-be-rescanned replacement list and return one. + If there were additionally any unexpanded deferred #pragma directives + among macro arguments, push another context containing the + pragma tokens before the yet-to-be-rescanned replacement list + and return two. Otherwise, we don't push a context and return zero. */ +static int +enter_macro_context (cpp_reader *pfile, cpp_hashnode *node, + const cpp_token *result) +{ + /* The presence of a macro invalidates a file's controlling macro. */ + pfile->mi_valid = false; + + pfile->state.angled_headers = false; + + if ((node->flags & NODE_BUILTIN) && !(node->flags & NODE_USED)) + { + node->flags |= NODE_USED; + if ((!pfile->cb.user_builtin_macro + || !pfile->cb.user_builtin_macro (pfile, node)) + && pfile->cb.used_define) + pfile->cb.used_define (pfile, pfile->directive_line, node); + } + + /* Handle standard macros. */ + if (! (node->flags & NODE_BUILTIN)) + { + cpp_macro *macro = node->value.macro; + _cpp_buff *pragma_buff = NULL; + + if (macro->fun_like) + { + _cpp_buff *buff; + + pfile->state.prevent_expansion++; + pfile->keep_tokens++; + pfile->state.parsing_args = 1; + buff = funlike_invocation_p (pfile, node, &pragma_buff); + pfile->state.parsing_args = 0; + pfile->keep_tokens--; + pfile->state.prevent_expansion--; + + if (buff == NULL) + { + if (CPP_WTRADITIONAL (pfile) && ! node->value.macro->syshdr) + cpp_warning (pfile, CPP_W_TRADITIONAL, + "function-like macro \"%s\" must be used with arguments in traditional C", + NODE_NAME (node)); + + if (pragma_buff) + _cpp_release_buff (pfile, pragma_buff); + + return 0; + } + + if (macro->paramc > 0) + replace_args (pfile, node, macro, (macro_arg *) buff->base); + _cpp_release_buff (pfile, buff); + } + + /* Disable the macro within its expansion. */ + node->flags |= NODE_DISABLED; + + if (!(node->flags & NODE_USED)) + { + node->flags |= NODE_USED; + if (pfile->cb.used_define) + pfile->cb.used_define (pfile, pfile->directive_line, node); + } + + if (pfile->cb.used) + pfile->cb.used (pfile, result->src_loc, node); + + macro->used = 1; + + if (macro->paramc == 0) + _cpp_push_token_context (pfile, node, macro->exp.tokens, + macro_real_token_count (macro)); + + if (pragma_buff) + { + if (!pfile->state.in_directive) + _cpp_push_token_context (pfile, NULL, + padding_token (pfile, result), 1); + do + { + _cpp_buff *tail = pragma_buff->next; + pragma_buff->next = NULL; + push_ptoken_context (pfile, NULL, pragma_buff, + (const cpp_token **) pragma_buff->base, + ((const cpp_token **) BUFF_FRONT (pragma_buff) + - (const cpp_token **) pragma_buff->base)); + pragma_buff = tail; + } + while (pragma_buff != NULL); + return 2; + } + + return 1; + } + + /* Handle built-in macros and the _Pragma operator. */ + return builtin_macro (pfile, node); +} + +/* Replace the parameters in a function-like macro of NODE with the + actual ARGS, and place the result in a newly pushed token context. + Expand each argument before replacing, unless it is operated upon + by the # or ## operators. */ +static void +replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro, macro_arg *args) +{ + unsigned int i, total; + const cpp_token *src, *limit; + const cpp_token **dest, **first; + macro_arg *arg; + _cpp_buff *buff; + unsigned int count; + + /* First, fully macro-expand arguments, calculating the number of + tokens in the final expansion as we go. The ordering of the if + statements below is subtle; we must handle stringification before + pasting. */ + count = macro_real_token_count (macro); + total = count; + limit = macro->exp.tokens + count; + + for (src = macro->exp.tokens; src < limit; src++) + if (src->type == CPP_MACRO_ARG) + { + /* Leading and trailing padding tokens. */ + total += 2; + + /* We have an argument. If it is not being stringified or + pasted it is macro-replaced before insertion. */ + arg = &args[src->val.macro_arg.arg_no - 1]; + + if (src->flags & STRINGIFY_ARG) + { + if (!arg->stringified) + arg->stringified = stringify_arg (pfile, arg); + } + else if ((src->flags & PASTE_LEFT) + || (src > macro->exp.tokens && (src[-1].flags & PASTE_LEFT))) + total += arg->count - 1; + else + { + if (!arg->expanded) + expand_arg (pfile, arg); + total += arg->expanded_count - 1; + } + } + + /* Now allocate space for the expansion, copy the tokens and replace + the arguments. */ + buff = _cpp_get_buff (pfile, total * sizeof (cpp_token *)); + first = (const cpp_token **) buff->base; + dest = first; + + for (src = macro->exp.tokens; src < limit; src++) + { + unsigned int count; + const cpp_token **from, **paste_flag; + + if (src->type != CPP_MACRO_ARG) + { + *dest++ = src; + continue; + } + + paste_flag = 0; + arg = &args[src->val.macro_arg.arg_no - 1]; + if (src->flags & STRINGIFY_ARG) + count = 1, from = &arg->stringified; + else if (src->flags & PASTE_LEFT) + count = arg->count, from = arg->first; + else if (src != macro->exp.tokens && (src[-1].flags & PASTE_LEFT)) + { + count = arg->count, from = arg->first; + if (dest != first) + { + if (dest[-1]->type == CPP_COMMA + && macro->variadic + && src->val.macro_arg.arg_no == macro->paramc) + { + /* Swallow a pasted comma if from == NULL, otherwise + drop the paste flag. */ + if (from == NULL) + dest--; + else + paste_flag = dest - 1; + } + /* Remove the paste flag if the RHS is a placemarker. */ + else if (count == 0) + paste_flag = dest - 1; + } + } + else + count = arg->expanded_count, from = arg->expanded; + + /* Padding on the left of an argument (unless RHS of ##). */ + if ((!pfile->state.in_directive || pfile->state.directive_wants_padding) + && src != macro->exp.tokens && !(src[-1].flags & PASTE_LEFT)) + *dest++ = padding_token (pfile, src); + + if (count) + { + memcpy (dest, from, count * sizeof (cpp_token *)); + dest += count; + + /* With a non-empty argument on the LHS of ##, the last + token should be flagged PASTE_LEFT. */ + if (src->flags & PASTE_LEFT) + paste_flag = dest - 1; + } + else if (CPP_PEDANTIC (pfile) && ! macro->syshdr + && ! CPP_OPTION (pfile, c99) + && ! cpp_in_system_header (pfile)) + { + cpp_error (pfile, CPP_DL_PEDWARN, + "invoking macro %s argument %d: " + "empty macro arguments are undefined" + " in ISO C90 and ISO C++98", + NODE_NAME (node), + src->val.macro_arg.arg_no); + } + + /* Avoid paste on RHS (even case count == 0). */ + if (!pfile->state.in_directive && !(src->flags & PASTE_LEFT)) + *dest++ = &pfile->avoid_paste; + + /* Add a new paste flag, or remove an unwanted one. */ + if (paste_flag) + { + cpp_token *token = _cpp_temp_token (pfile); + token->type = (*paste_flag)->type; + token->val = (*paste_flag)->val; + if (src->flags & PASTE_LEFT) + token->flags = (*paste_flag)->flags | PASTE_LEFT; + else + token->flags = (*paste_flag)->flags & ~PASTE_LEFT; + *paste_flag = token; + } + } + + /* Free the expanded arguments. */ + for (i = 0; i < macro->paramc; i++) + if (args[i].expanded) + free (args[i].expanded); + + push_ptoken_context (pfile, node, buff, first, dest - first); +} + +/* Return a special padding token, with padding inherited from SOURCE. */ +static const cpp_token * +padding_token (cpp_reader *pfile, const cpp_token *source) +{ + cpp_token *result = _cpp_temp_token (pfile); + + result->type = CPP_PADDING; + + /* Data in GCed data structures cannot be made const so far, so we + need a cast here. */ + result->val.source = (cpp_token *) source; + result->flags = 0; + return result; +} + +/* Get a new uninitialized context. Create a new one if we cannot + re-use an old one. */ +static cpp_context * +next_context (cpp_reader *pfile) +{ + cpp_context *result = pfile->context->next; + + if (result == 0) + { + result = XNEW (cpp_context); + result->prev = pfile->context; + result->next = 0; + pfile->context->next = result; + } + + pfile->context = result; + return result; +} + +/* Push a list of pointers to tokens. */ +static void +push_ptoken_context (cpp_reader *pfile, cpp_hashnode *macro, _cpp_buff *buff, + const cpp_token **first, unsigned int count) +{ + cpp_context *context = next_context (pfile); + + context->direct_p = false; + context->macro = macro; + context->buff = buff; + FIRST (context).ptoken = first; + LAST (context).ptoken = first + count; +} + +/* Push a list of tokens. */ +void +_cpp_push_token_context (cpp_reader *pfile, cpp_hashnode *macro, + const cpp_token *first, unsigned int count) +{ + cpp_context *context = next_context (pfile); + + context->direct_p = true; + context->macro = macro; + context->buff = NULL; + FIRST (context).token = first; + LAST (context).token = first + count; +} + +/* Push a traditional macro's replacement text. */ +void +_cpp_push_text_context (cpp_reader *pfile, cpp_hashnode *macro, + const uchar *start, size_t len) +{ + cpp_context *context = next_context (pfile); + + context->direct_p = true; + context->macro = macro; + context->buff = NULL; + CUR (context) = start; + RLIMIT (context) = start + len; + macro->flags |= NODE_DISABLED; +} + +/* Expand an argument ARG before replacing parameters in a + function-like macro. This works by pushing a context with the + argument's tokens, and then expanding that into a temporary buffer + as if it were a normal part of the token stream. collect_args() + has terminated the argument's tokens with a CPP_EOF so that we know + when we have fully expanded the argument. */ +static void +expand_arg (cpp_reader *pfile, macro_arg *arg) +{ + unsigned int capacity; + bool saved_warn_trad; + + if (arg->count == 0) + return; + + /* Don't warn about funlike macros when pre-expanding. */ + saved_warn_trad = CPP_WTRADITIONAL (pfile); + CPP_WTRADITIONAL (pfile) = 0; + + /* Loop, reading in the arguments. */ + capacity = 256; + arg->expanded = XNEWVEC (const cpp_token *, capacity); + + push_ptoken_context (pfile, NULL, NULL, arg->first, arg->count + 1); + for (;;) + { + const cpp_token *token; + + if (arg->expanded_count + 1 >= capacity) + { + capacity *= 2; + arg->expanded = XRESIZEVEC (const cpp_token *, arg->expanded, + capacity); + } + + token = cpp_get_token (pfile); + + if (token->type == CPP_EOF) + break; + + arg->expanded[arg->expanded_count++] = token; + } + + _cpp_pop_context (pfile); + + CPP_WTRADITIONAL (pfile) = saved_warn_trad; +} + +/* Pop the current context off the stack, re-enabling the macro if the + context represented a macro's replacement list. The context + structure is not freed so that we can re-use it later. */ +void +_cpp_pop_context (cpp_reader *pfile) +{ + cpp_context *context = pfile->context; + + if (context->macro) + context->macro->flags &= ~NODE_DISABLED; + + if (context->buff) + _cpp_release_buff (pfile, context->buff); + + pfile->context = context->prev; +} + +/* External routine to get a token. Also used nearly everywhere + internally, except for places where we know we can safely call + _cpp_lex_token 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. */ +const cpp_token * +cpp_get_token (cpp_reader *pfile) +{ + const cpp_token *result; + bool can_set = pfile->set_invocation_location; + pfile->set_invocation_location = false; + + for (;;) + { + cpp_hashnode *node; + cpp_context *context = pfile->context; + + /* Context->prev == 0 <=> base context. */ + if (!context->prev) + result = _cpp_lex_token (pfile); + else if (FIRST (context).token != LAST (context).token) + { + if (context->direct_p) + result = FIRST (context).token++; + else + result = *FIRST (context).ptoken++; + + if (result->flags & PASTE_LEFT) + { + paste_all_tokens (pfile, result); + if (pfile->state.in_directive) + continue; + return padding_token (pfile, result); + } + } + else + { + _cpp_pop_context (pfile); + if (pfile->state.in_directive) + continue; + return &pfile->avoid_paste; + } + + if (pfile->state.in_directive && result->type == CPP_COMMENT) + continue; + + if (result->type != CPP_NAME) + break; + + node = result->val.node.node; + + if (node->type != NT_MACRO || (result->flags & NO_EXPAND)) + break; + + if (!(node->flags & NODE_DISABLED)) + { + int ret = 0; + /* If not in a macro context, and we're going to start an + expansion, record the location. */ + if (can_set && !context->macro) + pfile->invocation_location = result->src_loc; + if (pfile->state.prevent_expansion) + break; + + /* Conditional macros require that a predicate be evaluated + first. */ + if ((node->flags & NODE_CONDITIONAL) != 0) + { + if (pfile->cb.macro_to_expand) + { + bool whitespace_after; + const cpp_token *peek_tok = cpp_peek_token (pfile, 0); + + whitespace_after = (peek_tok->type == CPP_PADDING + || (peek_tok->flags & PREV_WHITE)); + node = pfile->cb.macro_to_expand (pfile, result); + if (node) + ret = enter_macro_context (pfile, node, result); + else if (whitespace_after) + { + /* If macro_to_expand hook returned NULL and it + ate some tokens, see if we don't need to add + a padding token in between this and the + next token. */ + peek_tok = cpp_peek_token (pfile, 0); + if (peek_tok->type != CPP_PADDING + && (peek_tok->flags & PREV_WHITE) == 0) + _cpp_push_token_context (pfile, NULL, + padding_token (pfile, + peek_tok), 1); + } + } + } + else + ret = enter_macro_context (pfile, node, result); + if (ret) + { + if (pfile->state.in_directive || ret == 2) + continue; + return padding_token (pfile, result); + } + } + else + { + /* Flag this token as always unexpandable. FIXME: move this + to collect_args()?. */ + cpp_token *t = _cpp_temp_token (pfile); + t->type = result->type; + t->flags = result->flags | NO_EXPAND; + t->val = result->val; + result = t; + } + + break; + } + + return result; +} + +/* Like cpp_get_token, but also returns a location separate from the + one provided by the returned token. LOC is an out parameter; *LOC + is set to the location "as expected by the user". This matters + when a token results from macro expansion -- the token's location + will indicate where the macro is defined, but *LOC will be the + location of the start of the expansion. */ +const cpp_token * +cpp_get_token_with_location (cpp_reader *pfile, source_location *loc) +{ + const cpp_token *result; + + pfile->set_invocation_location = true; + result = cpp_get_token (pfile); + if (pfile->context->macro) + *loc = pfile->invocation_location; + else + *loc = result->src_loc; + + return result; +} + +/* 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 (cpp_reader *pfile) +{ + cpp_hashnode *node = pfile->context->macro; + + return node && node->value.macro && node->value.macro->syshdr; +} + +/* Read each token in, until end of the current file. Directives are + transparently processed. */ +void +cpp_scan_nooutput (cpp_reader *pfile) +{ + /* Request a CPP_EOF token at the end of this file, rather than + transparently continuing with the including file. */ + pfile->buffer->return_at_eof = true; + + pfile->state.discarding_output++; + pfile->state.prevent_expansion++; + + if (CPP_OPTION (pfile, traditional)) + while (_cpp_read_logical_line_trad (pfile)) + ; + else + while (cpp_get_token (pfile)->type != CPP_EOF) + ; + + pfile->state.discarding_output--; + pfile->state.prevent_expansion--; +} + +/* Step back one or more tokens obtained from the lexer. */ +void +_cpp_backup_tokens_direct (cpp_reader *pfile, unsigned int count) +{ + pfile->lookaheads += count; + while (count--) + { + pfile->cur_token--; + if (pfile->cur_token == pfile->cur_run->base + /* Possible with -fpreprocessed and no leading #line. */ + && pfile->cur_run->prev != NULL) + { + pfile->cur_run = pfile->cur_run->prev; + pfile->cur_token = pfile->cur_run->limit; + } + } +} + +/* Step back one (or more) tokens. Can only step back more than 1 if + they are from the lexer, and not from macro expansion. */ +void +_cpp_backup_tokens (cpp_reader *pfile, unsigned int count) +{ + if (pfile->context->prev == NULL) + _cpp_backup_tokens_direct (pfile, count); + else + { + if (count != 1) + abort (); + if (pfile->context->direct_p) + FIRST (pfile->context).token--; + else + FIRST (pfile->context).ptoken--; + } +} + +/* #define directive parsing and handling. */ + +/* Returns nonzero if a macro redefinition warning is required. */ +static bool +warn_of_redefinition (cpp_reader *pfile, 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 true; + + /* Suppress warnings for builtins that lack the NODE_WARN flag. */ + if (node->flags & NODE_BUILTIN) + { + if (!pfile->cb.user_builtin_macro + || !pfile->cb.user_builtin_macro (pfile, node)) + return false; + } + + /* Redefinitions of conditional (context-sensitive) macros, on + the other hand, must be allowed silently. */ + if (node->flags & NODE_CONDITIONAL) + return false; + + /* 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; + + /* Don't check count here as it can be different in valid + traditional redefinitions with just whitespace differences. */ + if (macro1->paramc != macro2->paramc + || macro1->fun_like != macro2->fun_like + || macro1->variadic != macro2->variadic) + return true; + + /* Check parameter spellings. */ + for (i = 0; i < macro1->paramc; i++) + if (macro1->params[i] != macro2->params[i]) + return true; + + /* Check the replacement text or tokens. */ + if (CPP_OPTION (pfile, traditional)) + return _cpp_expansions_different_trad (macro1, macro2); + + if (macro1->count != macro2->count) + return true; + + for (i = 0; i < macro1->count; i++) + if (!_cpp_equiv_tokens (¯o1->exp.tokens[i], ¯o2->exp.tokens[i])) + return true; + + return false; +} + +/* Free the definition of hashnode H. */ +void +_cpp_free_definition (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 | NODE_DISABLED | NODE_USED); +} + +/* Save parameter NODE to the parameter list of macro MACRO. Returns + zero on success, nonzero if the parameter is a duplicate. */ +bool +_cpp_save_parameter (cpp_reader *pfile, cpp_macro *macro, cpp_hashnode *node) +{ + unsigned int len; + /* Constraint 6.10.3.6 - duplicate parameter names. */ + if (node->flags & NODE_MACRO_ARG) + { + cpp_error (pfile, CPP_DL_ERROR, "duplicate macro parameter \"%s\"", + NODE_NAME (node)); + return true; + } + + if (BUFF_ROOM (pfile->a_buff) + < (macro->paramc + 1) * sizeof (cpp_hashnode *)) + _cpp_extend_buff (pfile, &pfile->a_buff, sizeof (cpp_hashnode *)); + + ((cpp_hashnode **) BUFF_FRONT (pfile->a_buff))[macro->paramc++] = node; + node->flags |= NODE_MACRO_ARG; + len = macro->paramc * sizeof (union _cpp_hashnode_value); + if (len > pfile->macro_buffer_len) + { + pfile->macro_buffer = XRESIZEVEC (unsigned char, pfile->macro_buffer, + len); + pfile->macro_buffer_len = len; + } + ((union _cpp_hashnode_value *) pfile->macro_buffer)[macro->paramc - 1] + = node->value; + + node->value.arg_index = macro->paramc; + return false; +} + +/* Check the syntax of the parameters in a MACRO definition. Returns + false if an error occurs. */ +static bool +parse_params (cpp_reader *pfile, cpp_macro *macro) +{ + unsigned int prev_ident = 0; + + for (;;) + { + const cpp_token *token = _cpp_lex_token (pfile); + + switch (token->type) + { + default: + /* Allow/ignore comments in parameter lists if we are + preserving comments in macro expansions. */ + if (token->type == CPP_COMMENT + && ! CPP_OPTION (pfile, discard_comments_in_macro_exp)) + continue; + + cpp_error (pfile, CPP_DL_ERROR, + "\"%s\" may not appear in macro parameter list", + cpp_token_as_text (pfile, token)); + return false; + + case CPP_NAME: + if (prev_ident) + { + cpp_error (pfile, CPP_DL_ERROR, + "macro parameters must be comma-separated"); + return false; + } + prev_ident = 1; + + if (_cpp_save_parameter (pfile, macro, token->val.node.node)) + return false; + continue; + + case CPP_CLOSE_PAREN: + if (prev_ident || macro->paramc == 0) + return true; + + /* Fall through to pick up the error. */ + case CPP_COMMA: + if (!prev_ident) + { + cpp_error (pfile, CPP_DL_ERROR, "parameter name missing"); + return false; + } + prev_ident = 0; + continue; + + case CPP_ELLIPSIS: + macro->variadic = 1; + if (!prev_ident) + { + _cpp_save_parameter (pfile, macro, + pfile->spec_nodes.n__VA_ARGS__); + pfile->state.va_args_ok = 1; + if (! CPP_OPTION (pfile, c99) + && CPP_OPTION (pfile, cpp_pedantic) + && CPP_OPTION (pfile, warn_variadic_macros)) + cpp_pedwarning + (pfile, CPP_W_VARIADIC_MACROS, + "anonymous variadic macros were introduced in C99"); + } + else if (CPP_OPTION (pfile, cpp_pedantic) + && CPP_OPTION (pfile, warn_variadic_macros)) + cpp_pedwarning (pfile, CPP_W_VARIADIC_MACROS, + "ISO C does not permit named variadic macros"); + + /* We're at the end, and just expect a closing parenthesis. */ + token = _cpp_lex_token (pfile); + if (token->type == CPP_CLOSE_PAREN) + return true; + /* Fall through. */ + + case CPP_EOF: + cpp_error (pfile, CPP_DL_ERROR, "missing ')' in macro parameter list"); + return false; + } + } +} + +/* Allocate room for a token from a macro's replacement list. */ +static cpp_token * +alloc_expansion_token (cpp_reader *pfile, cpp_macro *macro) +{ + if (BUFF_ROOM (pfile->a_buff) < (macro->count + 1) * sizeof (cpp_token)) + _cpp_extend_buff (pfile, &pfile->a_buff, sizeof (cpp_token)); + + return &((cpp_token *) BUFF_FRONT (pfile->a_buff))[macro->count++]; +} + +/* Lex a token from the expansion of MACRO, but mark parameters as we + find them and warn of traditional stringification. */ +static cpp_token * +lex_expansion_token (cpp_reader *pfile, cpp_macro *macro) +{ + cpp_token *token, *saved_cur_token; + + saved_cur_token = pfile->cur_token; + pfile->cur_token = alloc_expansion_token (pfile, macro); + token = _cpp_lex_direct (pfile); + pfile->cur_token = saved_cur_token; + + /* Is this a parameter? */ + if (token->type == CPP_NAME + && (token->val.node.node->flags & NODE_MACRO_ARG) != 0) + { + token->type = CPP_MACRO_ARG; + token->val.macro_arg.arg_no = token->val.node.node->value.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; +} + +static bool +create_iso_definition (cpp_reader *pfile, cpp_macro *macro) +{ + cpp_token *token; + const cpp_token *ctoken; + bool following_paste_op = false; + #define paste_op_error_msg \ + N_("'##' cannot appear at either end of a macro expansion") + unsigned int num_extra_tokens = 0; + + /* Get the first token of the expansion (or the '(' of a + function-like macro). */ + ctoken = _cpp_lex_token (pfile); + + if (ctoken->type == CPP_OPEN_PAREN && !(ctoken->flags & PREV_WHITE)) + { + bool ok = parse_params (pfile, macro); + macro->params = (cpp_hashnode **) BUFF_FRONT (pfile->a_buff); + if (!ok) + return false; + + /* Success. Commit or allocate the parameter array. */ + if (pfile->hash_table->alloc_subobject) + { + cpp_hashnode **params = + (cpp_hashnode **) pfile->hash_table->alloc_subobject + (sizeof (cpp_hashnode *) * macro->paramc); + memcpy (params, macro->params, + sizeof (cpp_hashnode *) * macro->paramc); + macro->params = params; + } + else + BUFF_FRONT (pfile->a_buff) = (uchar *) ¯o->params[macro->paramc]; + macro->fun_like = 1; + } + else if (ctoken->type != CPP_EOF && !(ctoken->flags & PREV_WHITE)) + { + /* While ISO C99 requires whitespace before replacement text + in a macro definition, ISO C90 with TC1 allows there characters + from the basic source character set. */ + if (CPP_OPTION (pfile, c99)) + cpp_error (pfile, CPP_DL_PEDWARN, + "ISO C99 requires whitespace after the macro name"); + else + { + int warntype = CPP_DL_WARNING; + switch (ctoken->type) + { + case CPP_ATSIGN: + case CPP_AT_NAME: + case CPP_OBJC_STRING: + /* '@' is not in basic character set. */ + warntype = CPP_DL_PEDWARN; + break; + case CPP_OTHER: + /* Basic character set sans letters, digits and _. */ + if (strchr ("!\"#%&'()*+,-./:;<=>?[\\]^{|}~", + ctoken->val.str.text[0]) == NULL) + warntype = CPP_DL_PEDWARN; + break; + default: + /* All other tokens start with a character from basic + character set. */ + break; + } + cpp_error (pfile, warntype, + "missing whitespace after the macro name"); + } + } + + if (macro->fun_like) + token = lex_expansion_token (pfile, macro); + else + { + token = alloc_expansion_token (pfile, macro); + *token = *ctoken; + } + + 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) + { + if (token->flags & PREV_WHITE) + token->flags |= SP_PREV_WHITE; + if (token[-1].flags & DIGRAPH) + token->flags |= SP_DIGRAPH; + 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. */ + /* sdcpp specific: don't complain abuout naked hash */ + else if ((CPP_OPTION (pfile, lang) != CLK_ASM) + && (!CPP_OPTION(pfile, allow_naked_hash))) + { + cpp_error (pfile, CPP_DL_ERROR, + "'#' is not followed by a macro parameter"); + return false; + } + } + + if (token->type == CPP_EOF) + { + /* Paste operator constraint 6.10.3.3.1: + Token-paste ##, can appear in both object-like and + function-like macros, but not at the end. */ + if (following_paste_op) + { + cpp_error (pfile, CPP_DL_ERROR, paste_op_error_msg); + return false; + } + 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 beginning. */ + if (macro->count == 1) + { + cpp_error (pfile, CPP_DL_ERROR, paste_op_error_msg); + return false; + } + + if (token[-1].flags & PASTE_LEFT) + { + macro->extra_tokens = 1; + num_extra_tokens++; + token->val.token_no = macro->count - 1; + } + else + { + --macro->count; + token[-1].flags |= PASTE_LEFT; + if (token->flags & DIGRAPH) + token[-1].flags |= SP_DIGRAPH; + if (token->flags & PREV_WHITE) + token[-1].flags |= SP_PREV_WHITE; + } + } + + following_paste_op = (token->type == CPP_PASTE); + token = lex_expansion_token (pfile, macro); + } + + macro->exp.tokens = (cpp_token *) BUFF_FRONT (pfile->a_buff); + macro->traditional = 0; + + /* Don't count the CPP_EOF. */ + macro->count--; + + /* Clear whitespace on first token for warn_of_redefinition(). */ + if (macro->count) + macro->exp.tokens[0].flags &= ~PREV_WHITE; + + /* Commit or allocate the memory. */ + if (pfile->hash_table->alloc_subobject) + { + cpp_token *tokns = + (cpp_token *) pfile->hash_table->alloc_subobject (sizeof (cpp_token) + * macro->count); + if (num_extra_tokens) + { + /* Place second and subsequent ## or %:%: tokens in + sequences of consecutive such tokens at the end of the + list to preserve information about where they appear, how + they are spelt and whether they are preceded by + whitespace without otherwise interfering with macro + expansion. */ + cpp_token *normal_dest = tokns; + cpp_token *extra_dest = tokns + macro->count - num_extra_tokens; + unsigned int i; + for (i = 0; i < macro->count; i++) + { + if (macro->exp.tokens[i].type == CPP_PASTE) + *extra_dest++ = macro->exp.tokens[i]; + else + *normal_dest++ = macro->exp.tokens[i]; + } + } + else + memcpy (tokns, macro->exp.tokens, sizeof (cpp_token) * macro->count); + macro->exp.tokens = tokns; + } + else + BUFF_FRONT (pfile->a_buff) = (uchar *) ¯o->exp.tokens[macro->count]; + + return true; +} + +/* Parse a macro and save its expansion. Returns nonzero on success. */ +bool +_cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node) +{ + cpp_macro *macro; + unsigned int i; + bool ok; + + if (pfile->hash_table->alloc_subobject) + macro = (cpp_macro *) pfile->hash_table->alloc_subobject + (sizeof (cpp_macro)); + else + macro = (cpp_macro *) _cpp_aligned_alloc (pfile, sizeof (cpp_macro)); + macro->line = pfile->directive_line; + macro->params = 0; + macro->paramc = 0; + macro->variadic = 0; + macro->used = !CPP_OPTION (pfile, warn_unused_macros); + macro->count = 0; + macro->fun_like = 0; + macro->extra_tokens = 0; + /* To suppress some diagnostics. */ + macro->syshdr = pfile->buffer && pfile->buffer->sysp != 0; + + if (CPP_OPTION (pfile, traditional)) + ok = _cpp_create_trad_definition (pfile, macro); + else + { + ok = create_iso_definition (pfile, macro); + + /* We set the type for SEEN_EOL() in directives.c. + + Longer term we should lex the whole line before coming here, + and just copy the expansion. */ + + /* Stop the lexer accepting __VA_ARGS__. */ + pfile->state.va_args_ok = 0; + } + + /* Clear the fast argument lookup indices. */ + for (i = macro->paramc; i-- > 0; ) + { + struct cpp_hashnode *node = macro->params[i]; + node->flags &= ~ NODE_MACRO_ARG; + node->value = ((union _cpp_hashnode_value *) pfile->macro_buffer)[i]; + } + + if (!ok) + return ok; + + if (node->type == NT_MACRO) + { + if (CPP_OPTION (pfile, warn_unused_macros)) + _cpp_warn_if_unused_macro (pfile, node, NULL); + + if (warn_of_redefinition (pfile, node, macro)) + { + const int reason = (node->flags & NODE_BUILTIN) + ? CPP_W_BUILTIN_MACRO_REDEFINED : CPP_W_NONE; + bool warned; + + warned = cpp_pedwarning_with_line (pfile, reason, + pfile->directive_line, 0, + "\"%s\" redefined", + NODE_NAME (node)); + + if (warned && node->type == NT_MACRO && !(node->flags & NODE_BUILTIN)) + cpp_error_with_line (pfile, CPP_DL_NOTE, + node->value.macro->line, 0, + "this is the location of the previous definition"); + } + } + + if (node->type != NT_VOID) + _cpp_free_definition (node); + + /* Enter definition in hash table. */ + node->type = NT_MACRO; + node->value.macro = macro; + if (! ustrncmp (NODE_NAME (node), DSC ("__STDC_")) + && ustrcmp (NODE_NAME (node), (const uchar *) "__STDC_FORMAT_MACROS") + /* __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS are mentioned + in the C standard, as something that one must use in C++. + However DR#593 indicates that these aren't actually mentioned + in the C++ standard. We special-case them anyway. */ + && ustrcmp (NODE_NAME (node), (const uchar *) "__STDC_LIMIT_MACROS") + && ustrcmp (NODE_NAME (node), (const uchar *) "__STDC_CONSTANT_MACROS")) + node->flags |= NODE_WARN; + + /* If user defines one of the conditional macros, remove the + conditional flag */ + node->flags &= ~NODE_CONDITIONAL; + + return ok; +} + +/* Warn if a token in STRING matches one of a function-like MACRO's + parameters. */ +static void +check_trad_stringification (cpp_reader *pfile, const cpp_macro *macro, + const cpp_string *string) +{ + unsigned int i, len; + const uchar *p, *q, *limit; + + /* Loop over the string. */ + limit = string->text + string->len - 1; + for (p = string->text + 1; 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_error (pfile, CPP_DL_WARNING, + "macro argument \"%s\" would be stringified in traditional C", + 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 (cpp_reader *pfile, cpp_hashnode *node) +{ + unsigned int i, len; + const cpp_macro *macro; + unsigned char *buffer; + + if (node->type != NT_MACRO || (node->flags & NODE_BUILTIN)) + { + if (node->type != NT_MACRO + || !pfile->cb.user_builtin_macro + || !pfile->cb.user_builtin_macro (pfile, node)) + { + cpp_error (pfile, CPP_DL_ICE, + "invalid hash type %d in cpp_macro_definition", + node->type); + return 0; + } + } + + macro = node->value.macro; + /* Calculate length. */ + len = NODE_LEN (node) + 2; /* ' ' and NUL. */ + if (macro->fun_like) + { + len += 4; /* "()" plus possible final ".." of named + varargs (we have + 1 below). */ + for (i = 0; i < macro->paramc; i++) + len += NODE_LEN (macro->params[i]) + 1; /* "," */ + } + + /* This should match below where we fill in the buffer. */ + if (CPP_OPTION (pfile, traditional)) + len += _cpp_replacement_text_len (macro); + else + { + unsigned int count = macro_real_token_count (macro); + for (i = 0; i < count; i++) + { + cpp_token *token = ¯o->exp.tokens[i]; + + if (token->type == CPP_MACRO_ARG) + len += NODE_LEN (macro->params[token->val.macro_arg.arg_no - 1]); + else + len += cpp_token_len (token); + + if (token->flags & STRINGIFY_ARG) + len++; /* "#" */ + if (token->flags & PASTE_LEFT) + len += 3; /* " ##" */ + if (token->flags & PREV_WHITE) + len++; /* " " */ + } + } + + if (len > pfile->macro_buffer_len) + { + pfile->macro_buffer = XRESIZEVEC (unsigned char, + 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) + /* Don't emit a space after the comma here; we're trying + to emit a Dwarf-friendly definition, and the Dwarf spec + forbids spaces in the argument list. */ + *buffer++ = ','; + else if (macro->variadic) + *buffer++ = '.', *buffer++ = '.', *buffer++ = '.'; + } + *buffer++ = ')'; + } + + /* The Dwarf spec requires a space after the macro name, even if the + definition is the empty string. */ + *buffer++ = ' '; + + if (CPP_OPTION (pfile, traditional)) + buffer = _cpp_copy_replacement_text (macro, buffer); + else if (macro->count) + /* Expansion tokens. */ + { + unsigned int count = macro_real_token_count (macro); + for (i = 0; i < count; i++) + { + cpp_token *token = ¯o->exp.tokens[i]; + + if (token->flags & PREV_WHITE) + *buffer++ = ' '; + if (token->flags & STRINGIFY_ARG) + *buffer++ = '#'; + + if (token->type == CPP_MACRO_ARG) + { + memcpy (buffer, + NODE_NAME (macro->params[token->val.macro_arg.arg_no - 1]), + NODE_LEN (macro->params[token->val.macro_arg.arg_no - 1])); + buffer += NODE_LEN (macro->params[token->val.macro_arg.arg_no - 1]); + } + else + buffer = cpp_spell_token (pfile, token, buffer, false); + + if (token->flags & PASTE_LEFT) + { + *buffer++ = ' '; + *buffer++ = '#'; + *buffer++ = '#'; + /* Next has PREV_WHITE; see _cpp_create_definition. */ + } + } + } + + *buffer = '\0'; + return pfile->macro_buffer; +} diff --git a/support/cpp/libcpp/mkdeps.c b/support/cpp/libcpp/mkdeps.c new file mode 100644 index 0000000..144f0d1 --- /dev/null +++ b/support/cpp/libcpp/mkdeps.c @@ -0,0 +1,447 @@ +/* Dependency generator for Makefile fragments. + Copyright (C) 2000, 2001, 2003, 2007, 2008, 2009 + 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 3, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. + + 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" +#include "internal.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; + + const char **vpathv; + size_t *vpathlv; + unsigned int nvpaths; + unsigned int vpaths_size; +}; + +static const char *munge (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 (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; + + case '#': + /* '#' is quoted with a backslash. */ + len++; + break; + } + } + + /* Now we know how big to make the buffer. */ + buffer = XNEWVEC (char, 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; + + case '#': + *dst++ = '\\'; + break; + + default: + /* nothing */; + } + *dst = *p; + } + + *dst = '\0'; + return buffer; +} + +/* If T begins with any of the partial pathnames listed in d->vpathv, + then advance T to point beyond that pathname. */ +static const char * +apply_vpath (struct deps *d, const char *t) +{ + if (d->vpathv) + { + unsigned int i; + for (i = 0; i < d->nvpaths; i++) + { + if (!strncmp (d->vpathv[i], t, d->vpathlv[i])) + { + const char *p = t + d->vpathlv[i]; + if (!IS_DIR_SEPARATOR (*p)) + goto not_this_one; + + /* Do not simplify $(vpath)/../whatever. ??? Might not + be necessary. */ + if (p[1] == '.' && p[2] == '.' && IS_DIR_SEPARATOR (p[3])) + goto not_this_one; + + /* found a match */ + t = t + d->vpathlv[i] + 1; + break; + } + not_this_one:; + } + } + + /* Remove leading ./ in any case. */ + while (t[0] == '.' && IS_DIR_SEPARATOR (t[1])) + { + t += 2; + /* If we removed a leading ./, then also remove any /s after the + first. */ + while (IS_DIR_SEPARATOR (t[0])) + ++t; + } + + return t; +} + +/* Public routines. */ + +struct deps * +deps_init (void) +{ + return XCNEW (struct deps); +} + +void +deps_free (struct deps *d) +{ + unsigned int i; + + if (d->targetv) + { + for (i = 0; i < d->ntargets; i++) + free ((void *) d->targetv[i]); + free (d->targetv); + } + + if (d->depv) + { + for (i = 0; i < d->ndeps; i++) + free ((void *) d->depv[i]); + free (d->depv); + } + + if (d->vpathv) + { + for (i = 0; i < d->nvpaths; i++) + free ((void *) d->vpathv[i]); + free (d->vpathv); + free (d->vpathlv); + } + + 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 (struct deps *d, const char *t, int quote) +{ + if (d->ntargets == d->targets_size) + { + d->targets_size = d->targets_size * 2 + 4; + d->targetv = XRESIZEVEC (const char *, d->targetv, d->targets_size); + } + + t = apply_vpath (d, t); + 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 (cpp_reader *pfile, const char *tgt) +{ + struct deps *d = pfile->deps; + + /* 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 + const char *start = lbasename (tgt); + char *o; + + char *suffix; + const char *obj_ext; + + if (NULL == CPP_OPTION (pfile, obj_ext)) + obj_ext = TARGET_OBJECT_SUFFIX; + else if (CPP_OPTION (pfile, obj_ext)[0] != '.') + { + char *t = alloca (strlen (CPP_OPTION (pfile, obj_ext)) + 2); + t[0] = '.'; + strcpy (&t[1], CPP_OPTION (pfile, obj_ext)); + obj_ext = t; + } + else + obj_ext = CPP_OPTION (pfile, obj_ext); + + o = (char *) alloca (strlen (start) + strlen (obj_ext) + 1); + strcpy (o, start); + + suffix = strrchr (o, '.'); + if (!suffix) + suffix = o + strlen (o); + strcpy (suffix, obj_ext); + + deps_add_target (d, o, 1); + } +} + +void +deps_add_dep (struct deps *d, const char *t) +{ + t = munge (apply_vpath (d, t)); /* Also makes permanent copy. */ + + if (d->ndeps == d->deps_size) + { + d->deps_size = d->deps_size * 2 + 8; + d->depv = XRESIZEVEC (const char *, d->depv, d->deps_size); + } + d->depv[d->ndeps++] = t; +} + +void +deps_add_vpath (struct deps *d, const char *vpath) +{ + const char *elem, *p; + char *copy; + size_t len; + + for (elem = vpath; *elem; elem = p) + { + for (p = elem; *p && *p != ':'; p++); + len = p - elem; + copy = XNEWVEC (char, len + 1); + memcpy (copy, elem, len); + copy[len] = '\0'; + if (*p == ':') + p++; + + if (d->nvpaths == d->vpaths_size) + { + d->vpaths_size = d->vpaths_size * 2 + 8; + d->vpathv = XRESIZEVEC (const char *, d->vpathv, d->vpaths_size); + d->vpathlv = XRESIZEVEC (size_t, d->vpathlv, d->vpaths_size); + } + d->vpathv[d->nvpaths] = copy; + d->vpathlv[d->nvpaths] = len; + d->nvpaths++; + } +} + +void +deps_write (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 (i) + { + if (colmax && column > colmax) + { + fputs (" \\\n ", fp); + column = 1 + size; + } + else + { + putc (' ', fp); + column++; + } + } + fputs (d->targetv[i], fp); + } + + putc (':', fp); + column++; + + for (i = 0; i < d->ndeps; i++) + { + size = strlen (d->depv[i]); + column += size; + if (colmax && column > colmax) + { + fputs (" \\\n ", fp); + column = 1 + size; + } + else + { + putc (' ', fp); + column++; + } + fputs (d->depv[i], fp); + } + putc ('\n', fp); +} + +void +deps_phony_targets (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); + } +} + +/* Write out a deps buffer to a file, in a form that can be read back + with deps_restore. Returns nonzero on error, in which case the + error number will be in errno. */ + +int +deps_save (struct deps *deps, FILE *f) +{ + unsigned int i; + + /* The cppreader structure contains makefile dependences. Write out this + structure. */ + + /* The number of dependences. */ + if (fwrite (&deps->ndeps, sizeof (deps->ndeps), 1, f) != 1) + return -1; + /* The length of each dependence followed by the string. */ + for (i = 0; i < deps->ndeps; i++) + { + size_t num_to_write = strlen (deps->depv[i]); + if (fwrite (&num_to_write, sizeof (size_t), 1, f) != 1) + return -1; + if (fwrite (deps->depv[i], num_to_write, 1, f) != 1) + return -1; + } + + return 0; +} + +/* Read back dependency information written with deps_save into + the deps buffer. The third argument may be NULL, in which case + the dependency information is just skipped, or it may be a filename, + in which case that filename is skipped. */ + +int +deps_restore (struct deps *deps, FILE *fd, const char *self) +{ + unsigned int i, count; + size_t num_to_read; + size_t buf_size = 512; + char *buf = XNEWVEC (char, buf_size); + + /* Number of dependences. */ + if (fread (&count, 1, sizeof (count), fd) != sizeof (count)) + return -1; + + /* The length of each dependence string, followed by the string. */ + for (i = 0; i < count; i++) + { + /* Read in # bytes in string. */ + if (fread (&num_to_read, 1, sizeof (size_t), fd) != sizeof (size_t)) + return -1; + if (buf_size < num_to_read + 1) + { + buf_size = num_to_read + 1 + 127; + buf = XRESIZEVEC (char, buf, buf_size); + } + if (fread (buf, 1, num_to_read, fd) != num_to_read) + return -1; + buf[num_to_read] = '\0'; + + /* Generate makefile dependencies from .pch if -nopch-deps. */ + if (self != NULL && strcmp (buf, self) != 0) + deps_add_dep (deps, buf); + } + + free (buf); + return 0; +} diff --git a/support/cpp/libcpp/symtab.c b/support/cpp/libcpp/symtab.c new file mode 100644 index 0000000..18be40d --- /dev/null +++ b/support/cpp/libcpp/symtab.c @@ -0,0 +1,363 @@ +/* Hash tables. + Copyright (C) 2000, 2001, 2003, 2004, 2008, 2009 + Free Software Foundation, Inc. + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. + + 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 "symtab.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. */ + +static unsigned int calc_hash (const unsigned char *, size_t); +static void ht_expand (hash_table *); +static double approx_sqrt (double); + +/* A deleted entry. */ +#define DELETED ((hashnode) -1) + +/* Calculate the hash of the string STR of length LEN. */ + +static unsigned int +calc_hash (const unsigned char *str, size_t len) +{ + size_t n = len; + unsigned int r = 0; + + while (n--) + r = HT_HASHSTEP (r, *str++); + + return HT_HASHFINISH (r, len); +} + +/* Initialize an identifier hashtable. */ + +hash_table * +ht_create (unsigned int order) +{ + unsigned int nslots = 1 << order; + hash_table *table; + + table = XCNEW (hash_table); + + /* Strings need no alignment. */ + _obstack_begin (&table->stack, 0, 0, + (void *(*) (size_t)) xmalloc, + (void (*) (void *)) free); + + obstack_alignment_mask (&table->stack) = 0; + + table->entries = XCNEWVEC (hashnode, nslots); + table->entries_owned = true; + table->nslots = nslots; + return table; +} + +/* Frees all memory associated with a hash table. */ + +void +ht_destroy (hash_table *table) +{ + obstack_free (&table->stack, NULL); + if (table->entries_owned) + free (table->entries); + free (table); +} + +/* Returns the hash entry for the a STR of length LEN. If that string + already exists in the table, returns the existing entry. 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 allocated. */ +hashnode +ht_lookup (hash_table *table, const unsigned char *str, size_t len, + enum ht_lookup_option insert) +{ + return ht_lookup_with_hash (table, str, len, calc_hash (str, len), + insert); +} + +hashnode +ht_lookup_with_hash (hash_table *table, const unsigned char *str, + size_t len, unsigned int hash, + enum ht_lookup_option insert) +{ + unsigned int hash2; + unsigned int index; + unsigned int deleted_index = table->nslots; + size_t sizemask; + hashnode node; + + sizemask = table->nslots - 1; + index = hash & sizemask; + table->searches++; + + node = table->entries[index]; + + if (node != NULL) + { + if (node == DELETED) + deleted_index = index; + else if (node->hash_value == hash + && HT_LEN (node) == (unsigned int) len + && !memcmp (HT_STR (node), str, len)) + return node; + + /* hash2 must be odd, so we're guaranteed to visit every possible + location in the table during rehashing. */ + hash2 = ((hash * 17) & sizemask) | 1; + + for (;;) + { + table->collisions++; + index = (index + hash2) & sizemask; + node = table->entries[index]; + if (node == NULL) + break; + + if (node == DELETED) + { + if (deleted_index != table->nslots) + deleted_index = index; + } + else if (node->hash_value == hash + && HT_LEN (node) == (unsigned int) len + && !memcmp (HT_STR (node), str, len)) + return node; + } + } + + if (insert == HT_NO_INSERT) + return NULL; + + /* We prefer to overwrite the first deleted slot we saw. */ + if (deleted_index != table->nslots) + index = deleted_index; + + node = (*table->alloc_node) (table); + table->entries[index] = node; + + HT_LEN (node) = (unsigned int) len; + node->hash_value = hash; + + if (table->alloc_subobject) + { + char *chars = (char *) table->alloc_subobject (len + 1); + memcpy (chars, str, len); + chars[len] = '\0'; + HT_STR (node) = (const unsigned char *) chars; + } + else + HT_STR (node) = (const unsigned char *) obstack_copy0 (&table->stack, + str, len); + + 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 (hash_table *table) +{ + hashnode *nentries, *p, *limit; + unsigned int size, sizemask; + + size = table->nslots * 2; + nentries = XCNEWVEC (hashnode, size); + sizemask = size - 1; + + p = table->entries; + limit = p + table->nslots; + do + if (*p && *p != DELETED) + { + unsigned int index, hash, hash2; + + hash = (*p)->hash_value; + index = hash & sizemask; + + if (nentries[index]) + { + hash2 = ((hash * 17) & sizemask) | 1; + do + { + index = (index + hash2) & sizemask; + } + while (nentries[index]); + } + nentries[index] = *p; + } + while (++p < limit); + + if (table->entries_owned) + free (table->entries); + table->entries_owned = true; + table->entries = nentries; + table->nslots = size; +} + +/* For all nodes in TABLE, callback CB with parameters TABLE->PFILE, + the node, and V. */ +void +ht_forall (hash_table *table, ht_cb cb, const void *v) +{ + hashnode *p, *limit; + + p = table->entries; + limit = p + table->nslots; + do + if (*p && *p != DELETED) + { + if ((*cb) (table->pfile, *p, v) == 0) + break; + } + while (++p < limit); +} + +/* Like ht_forall, but a nonzero return from the callback means that + the entry should be removed from the table. */ +void +ht_purge (hash_table *table, ht_cb cb, const void *v) +{ + hashnode *p, *limit; + + p = table->entries; + limit = p + table->nslots; + do + if (*p && *p != DELETED) + { + if ((*cb) (table->pfile, *p, v)) + *p = DELETED; + } + while (++p < limit); +} + +/* Restore the hash table. */ +void +ht_load (hash_table *ht, hashnode *entries, + unsigned int nslots, unsigned int nelements, + bool own) +{ + if (ht->entries_owned) + free (ht->entries); + ht->entries = entries; + ht->nslots = nslots; + ht->nelements = nelements; + ht->entries_owned = own; +} + +/* Dump allocation statistics to stderr. */ + +void +ht_dump_statistics (hash_table *table) +{ + size_t nelts, nids, overhead, headers; + size_t total_bytes, longest, deleted = 0; + double sum_of_squares, 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 == DELETED) + ++deleted; + else if (*p) + { + size_t n = HT_LEN (*p); + + total_bytes += n; + sum_of_squares += (double) 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, "deleted\t\t%lu\n", + (unsigned long) deleted); + 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. */ +static double +approx_sqrt (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; +} diff --git a/support/cpp/libcpp/system.h b/support/cpp/libcpp/system.h new file mode 100644 index 0000000..9dc83e6 --- /dev/null +++ b/support/cpp/libcpp/system.h @@ -0,0 +1,448 @@ +/* Get common system includes and various definitions and declarations based + on autoconf macros. + Copyright (C) 1998-2014 Free Software Foundation, Inc. + +This file is part of GCC. + +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 3, 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 COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + + +#ifndef LIBCPP_SYSTEM_H +#define LIBCPP_SYSTEM_H + +/* We must include stdarg.h before stdio.h. */ +#include <stdarg.h> + +#ifdef HAVE_STDDEF_H +# include <stddef.h> +#endif +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#ifdef HAVE_INTTYPES_H +# include <inttypes.h> +#endif + +#include <stdio.h> + +/* Define a generic NULL if one hasn't already been defined. */ +#ifndef NULL +#define NULL 0 +#endif + +/* Use the unlocked open routines from libiberty. */ + +/* Some of these are #define on some systems, e.g. on AIX to redirect + the names to 64bit capable functions for LARGE_FILES support. These + redefs are pointless here so we can override them. */ + +#undef fopen +#undef freopen + +#define fopen(PATH,MODE) fopen_unlocked(PATH,MODE) +#define fdopen(FILDES,MODE) fdopen_unlocked(FILDES,MODE) +#define freopen(PATH,MODE,STREAM) freopen_unlocked(PATH,MODE,STREAM) + +/* The compiler is not a multi-threaded application and therefore we + do not have to use the locking functions. In fact, using the locking + functions can cause the compiler to be significantly slower under + I/O bound conditions (such as -g -O0 on very large source files). + + HAVE_DECL_PUTC_UNLOCKED actually indicates whether or not the stdio + code is multi-thread safe by default. If it is set to 0, then do + not worry about using the _unlocked functions. + + fputs_unlocked, fwrite_unlocked, and fprintf_unlocked are + extensions and need to be prototyped by hand (since we do not + define _GNU_SOURCE). */ + +#if defined HAVE_DECL_PUTC_UNLOCKED && HAVE_DECL_PUTC_UNLOCKED + +# ifdef HAVE_PUTC_UNLOCKED +# undef putc +# define putc(C, Stream) putc_unlocked (C, Stream) +# endif +# ifdef HAVE_PUTCHAR_UNLOCKED +# undef putchar +# define putchar(C) putchar_unlocked (C) +# endif +# ifdef HAVE_GETC_UNLOCKED +# undef getc +# define getc(Stream) getc_unlocked (Stream) +# endif +# ifdef HAVE_GETCHAR_UNLOCKED +# undef getchar +# define getchar() getchar_unlocked () +# endif +# ifdef HAVE_FPUTC_UNLOCKED +# undef fputc +# define fputc(C, Stream) fputc_unlocked (C, Stream) +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef HAVE_CLEARERR_UNLOCKED +# undef clearerr +# define clearerr(Stream) clearerr_unlocked (Stream) +# if defined (HAVE_DECL_CLEARERR_UNLOCKED) && !HAVE_DECL_CLEARERR_UNLOCKED +extern void clearerr_unlocked (FILE *); +# endif +# endif +# ifdef HAVE_FEOF_UNLOCKED +# undef feof +# define feof(Stream) feof_unlocked (Stream) +# if defined (HAVE_DECL_FEOF_UNLOCKED) && !HAVE_DECL_FEOF_UNLOCKED +extern int feof_unlocked (FILE *); +# endif +# endif +# ifdef HAVE_FILENO_UNLOCKED +# undef fileno +# define fileno(Stream) fileno_unlocked (Stream) +# if defined (HAVE_DECL_FILENO_UNLOCKED) && !HAVE_DECL_FILENO_UNLOCKED +extern int fileno_unlocked (FILE *); +# endif +# endif +# ifdef HAVE_FFLUSH_UNLOCKED +# undef fflush +# define fflush(Stream) fflush_unlocked (Stream) +# if defined (HAVE_DECL_FFLUSH_UNLOCKED) && !HAVE_DECL_FFLUSH_UNLOCKED +extern int fflush_unlocked (FILE *); +# endif +# endif +# ifdef HAVE_FGETC_UNLOCKED +# undef fgetc +# define fgetc(Stream) fgetc_unlocked (Stream) +# if defined (HAVE_DECL_FGETC_UNLOCKED) && !HAVE_DECL_FGETC_UNLOCKED +extern int fgetc_unlocked (FILE *); +# endif +# endif +# ifdef HAVE_FGETS_UNLOCKED +# undef fgets +# define fgets(S, n, Stream) fgets_unlocked (S, n, Stream) +# if defined (HAVE_DECL_FGETS_UNLOCKED) && !HAVE_DECL_FGETS_UNLOCKED +extern char *fgets_unlocked (char *, int, FILE *); +# endif +# endif +# ifdef HAVE_FPUTS_UNLOCKED +# undef fputs +# define fputs(String, Stream) fputs_unlocked (String, Stream) +# if defined (HAVE_DECL_FPUTS_UNLOCKED) && !HAVE_DECL_FPUTS_UNLOCKED +extern int fputs_unlocked (const char *, FILE *); +# endif +# endif +# ifdef HAVE_FERROR_UNLOCKED +# undef ferror +# define ferror(Stream) ferror_unlocked (Stream) +# if defined (HAVE_DECL_FERROR_UNLOCKED) && !HAVE_DECL_FERROR_UNLOCKED +extern int ferror_unlocked (FILE *); +# endif +# endif +# ifdef HAVE_FREAD_UNLOCKED +# undef fread +# define fread(Ptr, Size, N, Stream) fread_unlocked (Ptr, Size, N, Stream) +# if defined (HAVE_DECL_FREAD_UNLOCKED) && !HAVE_DECL_FREAD_UNLOCKED +extern size_t fread_unlocked (void *, size_t, size_t, FILE *); +# endif +# endif +# ifdef HAVE_FWRITE_UNLOCKED +# undef fwrite +# define fwrite(Ptr, Size, N, Stream) fwrite_unlocked (Ptr, Size, N, Stream) +# if defined (HAVE_DECL_FWRITE_UNLOCKED) && !HAVE_DECL_FWRITE_UNLOCKED +extern size_t fwrite_unlocked (const void *, size_t, size_t, FILE *); +# endif +# endif +# ifdef HAVE_FPRINTF_UNLOCKED +# undef fprintf +/* We can't use a function-like macro here because we don't know if + we have varargs macros. */ +# define fprintf fprintf_unlocked +# if defined (HAVE_DECL_FPRINTF_UNLOCKED) && !HAVE_DECL_FPRINTF_UNLOCKED +extern int fprintf_unlocked (FILE *, const char *, ...); +# endif +# endif + +#ifdef __cplusplus +} +#endif + +#endif + +/* ??? Glibc's fwrite/fread_unlocked macros cause + "warning: signed and unsigned type in conditional expression". */ +#undef fread_unlocked +#undef fwrite_unlocked + +#include <sys/types.h> +#include <errno.h> + +#if !defined (errno) && defined (HAVE_DECL_ERRNO) && !HAVE_DECL_ERRNO +extern int errno; +#endif + +/* Some of glibc's string inlines cause warnings. Plus we'd rather + rely on (and therefore test) GCC's string builtins. */ +#define __NO_STRING_INLINES + +#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 + +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif + +#if HAVE_LIMITS_H +# include <limits.h> +#endif + +/* 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 + +#ifdef HAVE_LOCALE_H +# include <locale.h> +#endif + +#ifdef HAVE_LANGINFO_CODESET +# include <langinfo.h> +#endif + +#ifndef HAVE_SETLOCALE +# define setlocale(category, locale) (locale) +#endif + +#ifdef ENABLE_NLS +#include <libintl.h> +#else +/* Stubs. */ +# undef dgettext +# define dgettext(package, msgid) (msgid) +#endif + +#ifndef _ +# define _(msgid) dgettext (PACKAGE, msgid) +#endif + +#ifndef N_ +# define N_(msgid) msgid +#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)) + +/* 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_*)". */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined (HAVE_DECL_ABORT) && !HAVE_DECL_ABORT +extern void abort (void); +#endif + +#ifdef __cplusplus +} +#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_NOCTTY and O_BINARY. */ +#ifndef O_NOCTTY +#define O_NOCTTY 0 +#endif +#ifndef O_BINARY +# define O_BINARY 0 +#endif + +/* Filename handling macros. */ +#include "filenames.h" + +/* Get libiberty declarations. */ +#include "libiberty.h" +#include "safe-ctype.h" + +/* 1 if we have C99 designated initializers. + + ??? C99 designated initializers are not supported by most C++ + compilers, including G++. -- gdr, 2005-05-18 */ +#if !defined(HAVE_DESIGNATED_INITIALIZERS) +#define HAVE_DESIGNATED_INITIALIZERS \ + (!defined(__cplusplus) \ + && ((GCC_VERSION >= 2007) || (__STDC_VERSION__ >= 199901L))) +#endif + +#ifndef offsetof +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *) 0)->MEMBER) +#endif + +/* __builtin_expect(A, B) evaluates to A, but notifies the compiler that + the most likely value of A is B. This feature was added at some point + between 2.95 and 3.0. Let's use 3.0 as the lower bound for now. */ +#if (GCC_VERSION < 3000) +#define __builtin_expect(a, b) (a) +#endif + +/* Provide a fake boolean type. We make no attempt to use the + C99 _Bool, as it may not be available in the bootstrap compiler, + and even if it is, it is liable to be buggy. + This must be after all inclusion of system headers, as some of + them will mess us up. */ +#undef bool +#undef true +#undef false +#undef TRUE +#undef FALSE + +#ifndef __cplusplus +#define bool unsigned char +#endif +#define true 1 +#define false 0 + +/* Some compilers do not allow the use of unsigned char in bitfields. */ +#define BOOL_BITFIELD unsigned int + +/* Poison identifiers we do not want to use. */ +#if (GCC_VERSION >= 3000) +#undef calloc +#undef strdup +#undef malloc +#undef realloc + #pragma GCC poison calloc strdup + #pragma GCC poison malloc realloc + +/* Libiberty macros that are no longer used in GCC. */ +#undef ANSI_PROTOTYPES +#undef PTR_CONST +#undef LONG_DOUBLE +#undef VPARAMS +#undef VA_OPEN +#undef VA_FIXEDARG +#undef VA_CLOSE +#undef VA_START + #pragma GCC poison ANSI_PROTOTYPES PTR_CONST LONG_DOUBLE VPARAMS VA_OPEN \ + VA_FIXEDARG VA_CLOSE VA_START + +/* 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 */ + +/* SDCC specific */ +#include "sdcpp.h" + +#endif /* ! LIBCPP_SYSTEM_H */ diff --git a/support/cpp/libcpp/traditional.c b/support/cpp/libcpp/traditional.c new file mode 100644 index 0000000..7ff11bb --- /dev/null +++ b/support/cpp/libcpp/traditional.c @@ -0,0 +1,1170 @@ +/* CPP Library - traditional lexical analysis and macro expansion. + Copyright (C) 2002, 2004, 2005, 2007, 2008, 2009 + Free Software Foundation, Inc. + Contributed by Neil Booth, May 2002 + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "cpplib.h" +#include "internal.h" + +/* The replacement text of a function-like macro is stored as a + contiguous sequence of aligned blocks, each representing the text + between subsequent parameters. + + Each block comprises the text between its surrounding parameters, + the length of that text, and the one-based index of the following + parameter. The final block in the replacement text is easily + recognizable as it has an argument index of zero. */ + +struct block +{ + unsigned int text_len; + unsigned short arg_index; + uchar text[1]; +}; + +#define BLOCK_HEADER_LEN offsetof (struct block, text) +#define BLOCK_LEN(TEXT_LEN) CPP_ALIGN (BLOCK_HEADER_LEN + (TEXT_LEN)) + +/* Structure holding information about a function-like macro + invocation. */ +struct fun_macro +{ + /* Memory buffer holding the trad_arg array. */ + _cpp_buff *buff; + + /* An array of size the number of macro parameters + 1, containing + the offsets of the start of each macro argument in the output + buffer. The argument continues until the character before the + start of the next one. */ + size_t *args; + + /* The hashnode of the macro. */ + cpp_hashnode *node; + + /* The offset of the macro name in the output buffer. */ + size_t offset; + + /* The line the macro name appeared on. */ + source_location line; + + /* Zero-based index of argument being currently lexed. */ + unsigned int argc; +}; + +/* Lexing state. It is mostly used to prevent macro expansion. */ +enum ls {ls_none = 0, /* Normal state. */ + ls_fun_open, /* When looking for '('. */ + ls_fun_close, /* When looking for ')'. */ + ls_defined, /* After defined. */ + ls_defined_close, /* Looking for ')' of defined(). */ + ls_hash, /* After # in preprocessor conditional. */ + ls_predicate, /* After the predicate, maybe paren? */ + ls_answer}; /* In answer to predicate. */ + +/* Lexing TODO: Maybe handle space in escaped newlines. Stop lex.c + from recognizing comments and directives during its lexing pass. */ + +static const uchar *skip_whitespace (cpp_reader *, const uchar *, int); +static cpp_hashnode *lex_identifier (cpp_reader *, const uchar *); +static const uchar *copy_comment (cpp_reader *, const uchar *, int); +static void check_output_buffer (cpp_reader *, size_t); +static void push_replacement_text (cpp_reader *, cpp_hashnode *); +static bool scan_parameters (cpp_reader *, cpp_macro *); +static bool recursive_macro (cpp_reader *, cpp_hashnode *); +static void save_replacement_text (cpp_reader *, cpp_macro *, unsigned int); +static void maybe_start_funlike (cpp_reader *, cpp_hashnode *, const uchar *, + struct fun_macro *); +static void save_argument (struct fun_macro *, size_t); +static void replace_args_and_push (cpp_reader *, struct fun_macro *); +static size_t canonicalize_text (uchar *, const uchar *, size_t, uchar *); + +/* Ensures we have N bytes' space in the output buffer, and + reallocates it if not. */ +static void +check_output_buffer (cpp_reader *pfile, size_t n) +{ + /* We might need two bytes to terminate an unterminated comment, and + one more to terminate the line with a NUL. */ + n += 2 + 1; + + if (n > (size_t) (pfile->out.limit - pfile->out.cur)) + { + size_t size = pfile->out.cur - pfile->out.base; + size_t new_size = (size + n) * 3 / 2; + + pfile->out.base = XRESIZEVEC (unsigned char, pfile->out.base, new_size); + pfile->out.limit = pfile->out.base + new_size; + pfile->out.cur = pfile->out.base + size; + } +} + +/* Skip a C-style block comment in a macro as a result of -CC. + Buffer->cur points to the initial asterisk of the comment. */ +static void +skip_macro_block_comment (cpp_reader *pfile) +{ + const uchar *cur = pfile->buffer->cur; + + cur++; + if (*cur == '/') + cur++; + + /* People like decorating comments with '*', so check for '/' + instead for efficiency. */ + while(! (*cur++ == '/' && cur[-2] == '*') ) + ; + + pfile->buffer->cur = cur; +} + +/* CUR points to the asterisk introducing a comment in the current + context. IN_DEFINE is true if we are in the replacement text of a + macro. + + The asterisk and following comment is copied to the buffer pointed + to by pfile->out.cur, which must be of sufficient size. + Unterminated comments are diagnosed, and correctly terminated in + the output. pfile->out.cur is updated depending upon IN_DEFINE, + -C, -CC and pfile->state.in_directive. + + Returns a pointer to the first character after the comment in the + input buffer. */ +static const uchar * +copy_comment (cpp_reader *pfile, const uchar *cur, int in_define) +{ + bool unterminated, copy = false; + source_location src_loc = pfile->line_table->highest_line; + cpp_buffer *buffer = pfile->buffer; + + buffer->cur = cur; + if (pfile->context->prev) + unterminated = false, skip_macro_block_comment (pfile); + else + unterminated = _cpp_skip_block_comment (pfile); + + if (unterminated) + cpp_error_with_line (pfile, CPP_DL_ERROR, src_loc, 0, + "unterminated comment"); + + /* Comments in directives become spaces so that tokens are properly + separated when the ISO preprocessor re-lexes the line. The + exception is #define. */ + if (pfile->state.in_directive) + { + if (in_define) + { + if (CPP_OPTION (pfile, discard_comments_in_macro_exp)) + pfile->out.cur--; + else + copy = true; + } + else + pfile->out.cur[-1] = ' '; + } + else if (CPP_OPTION (pfile, discard_comments)) + pfile->out.cur--; + else + copy = true; + + if (copy) + { + size_t len = (size_t) (buffer->cur - cur); + memcpy (pfile->out.cur, cur, len); + pfile->out.cur += len; + if (unterminated) + { + *pfile->out.cur++ = '*'; + *pfile->out.cur++ = '/'; + } + } + + return buffer->cur; +} + +/* CUR points to any character in the input buffer. Skips over all + contiguous horizontal white space and NULs, including comments if + SKIP_COMMENTS, until reaching the first non-horizontal-whitespace + character or the end of the current context. Escaped newlines are + removed. + + The whitespace is copied verbatim to the output buffer, except that + comments are handled as described in copy_comment(). + pfile->out.cur is updated. + + Returns a pointer to the first character after the whitespace in + the input buffer. */ +static const uchar * +skip_whitespace (cpp_reader *pfile, const uchar *cur, int skip_comments) +{ + uchar *out = pfile->out.cur; + + for (;;) + { + unsigned int c = *cur++; + *out++ = c; + + if (is_nvspace (c)) + continue; + + if (c == '/' && *cur == '*' && skip_comments) + { + pfile->out.cur = out; + cur = copy_comment (pfile, cur, false /* in_define */); + out = pfile->out.cur; + continue; + } + + out--; + break; + } + + pfile->out.cur = out; + return cur - 1; +} + +/* Lexes and outputs an identifier starting at CUR, which is assumed + to point to a valid first character of an identifier. Returns + the hashnode, and updates out.cur. */ +static cpp_hashnode * +lex_identifier (cpp_reader *pfile, const uchar *cur) +{ + size_t len; + uchar *out = pfile->out.cur; + cpp_hashnode *result; + + do + *out++ = *cur++; + while (is_numchar (*cur)); + + CUR (pfile->context) = cur; + len = out - pfile->out.cur; + result = CPP_HASHNODE (ht_lookup (pfile->hash_table, pfile->out.cur, + len, HT_ALLOC)); + pfile->out.cur = out; + return result; +} + +/* Overlays the true file buffer temporarily with text of length LEN + starting at START. The true buffer is restored upon calling + restore_buff(). */ +void +_cpp_overlay_buffer (cpp_reader *pfile, const uchar *start, size_t len) +{ + cpp_buffer *buffer = pfile->buffer; + + pfile->overlaid_buffer = buffer; + pfile->saved_cur = buffer->cur; + pfile->saved_rlimit = buffer->rlimit; + pfile->saved_line_base = buffer->next_line; + buffer->need_line = false; + + buffer->cur = start; + buffer->line_base = start; + buffer->rlimit = start + len; +} + +/* Restores a buffer overlaid by _cpp_overlay_buffer(). */ +void +_cpp_remove_overlay (cpp_reader *pfile) +{ + cpp_buffer *buffer = pfile->overlaid_buffer; + + buffer->cur = pfile->saved_cur; + buffer->rlimit = pfile->saved_rlimit; + buffer->line_base = pfile->saved_line_base; + buffer->need_line = true; + + pfile->overlaid_buffer = NULL; +} + +/* Reads a logical line into the output buffer. Returns TRUE if there + is more text left in the buffer. */ +bool +_cpp_read_logical_line_trad (cpp_reader *pfile) +{ + do + { + if (pfile->buffer->need_line && !_cpp_get_fresh_line (pfile)) + return false; + } + while (!_cpp_scan_out_logical_line (pfile, NULL) || pfile->state.skipping); + + return pfile->buffer != NULL; +} + +/* Set up state for finding the opening '(' of a function-like + macro. */ +static void +maybe_start_funlike (cpp_reader *pfile, cpp_hashnode *node, const uchar *start, struct fun_macro *macro) +{ + unsigned int n = node->value.macro->paramc + 1; + + if (macro->buff) + _cpp_release_buff (pfile, macro->buff); + macro->buff = _cpp_get_buff (pfile, n * sizeof (size_t)); + macro->args = (size_t *) BUFF_FRONT (macro->buff); + macro->node = node; + macro->offset = start - pfile->out.base; + macro->argc = 0; +} + +/* Save the OFFSET of the start of the next argument to MACRO. */ +static void +save_argument (struct fun_macro *macro, size_t offset) +{ + macro->argc++; + if (macro->argc <= macro->node->value.macro->paramc) + macro->args[macro->argc] = offset; +} + +/* Copies the next logical line in the current buffer (starting at + buffer->cur) to the output buffer. The output is guaranteed to + terminate with a NUL character. buffer->cur is updated. + + If MACRO is non-NULL, then we are scanning the replacement list of + MACRO, and we call save_replacement_text() every time we meet an + argument. */ +bool +_cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro) +{ + bool result = true; + cpp_context *context; + const uchar *cur; + uchar *out; + struct fun_macro fmacro; + unsigned int c, paren_depth = 0, quote; + enum ls lex_state = ls_none; + bool header_ok; + const uchar *start_of_input_line; + + fmacro.buff = NULL; + fmacro.args = NULL; + fmacro.node = NULL; + fmacro.offset = 0; + fmacro.line = 0; + fmacro.argc = 0; + + quote = 0; + header_ok = pfile->state.angled_headers; + CUR (pfile->context) = pfile->buffer->cur; + RLIMIT (pfile->context) = pfile->buffer->rlimit; + pfile->out.cur = pfile->out.base; + pfile->out.first_line = pfile->line_table->highest_line; + /* start_of_input_line is needed to make sure that directives really, + really start at the first character of the line. */ + start_of_input_line = pfile->buffer->cur; + new_context: + context = pfile->context; + cur = CUR (context); + check_output_buffer (pfile, RLIMIT (context) - cur); + out = pfile->out.cur; + + for (;;) + { + if (!context->prev + && cur >= pfile->buffer->notes[pfile->buffer->cur_note].pos) + { + pfile->buffer->cur = cur; + _cpp_process_line_notes (pfile, false); + } + c = *cur++; + *out++ = c; + + /* Whitespace should "continue" out of the switch, + non-whitespace should "break" out of it. */ + switch (c) + { + case ' ': + case '\t': + case '\f': + case '\v': + case '\0': + continue; + + case '\n': + /* If this is a macro's expansion, pop it. */ + if (context->prev) + { + pfile->out.cur = out - 1; + _cpp_pop_context (pfile); + goto new_context; + } + + /* Omit the newline from the output buffer. */ + pfile->out.cur = out - 1; + pfile->buffer->cur = cur; + pfile->buffer->need_line = true; + CPP_INCREMENT_LINE (pfile, 0); + + if ((lex_state == ls_fun_open || lex_state == ls_fun_close) + && !pfile->state.in_directive + && _cpp_get_fresh_line (pfile)) + { + /* Newlines in arguments become a space, but we don't + clear any in-progress quote. */ + if (lex_state == ls_fun_close) + out[-1] = ' '; + cur = pfile->buffer->cur; + continue; + } + goto done; + + case '<': + if (header_ok) + quote = '>'; + break; + case '>': + if (c == quote) + quote = 0; + break; + + case '"': + case '\'': + if (c == quote) + quote = 0; + else if (!quote) + quote = c; + break; + + case '\\': + /* Skip escaped quotes here, it's easier than above. */ + if (*cur == '\\' || *cur == '"' || *cur == '\'') + *out++ = *cur++; + break; + + case '/': + /* Traditional CPP does not recognize comments within + literals. */ + if (!quote && *cur == '*') + { + pfile->out.cur = out; + cur = copy_comment (pfile, cur, macro != 0); + out = pfile->out.cur; + continue; + } + break; + + 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': + if (!pfile->state.skipping && (quote == 0 || macro)) + { + cpp_hashnode *node; + uchar *out_start = out - 1; + + pfile->out.cur = out_start; + node = lex_identifier (pfile, cur - 1); + out = pfile->out.cur; + cur = CUR (context); + + if (node->type == NT_MACRO + /* Should we expand for ls_answer? */ + && (lex_state == ls_none || lex_state == ls_fun_open) + && !pfile->state.prevent_expansion) + { + /* Macros invalidate MI optimization. */ + pfile->mi_valid = false; + if (! (node->flags & NODE_BUILTIN) + && node->value.macro->fun_like) + { + maybe_start_funlike (pfile, node, out_start, &fmacro); + lex_state = ls_fun_open; + fmacro.line = pfile->line_table->highest_line; + continue; + } + else if (!recursive_macro (pfile, node)) + { + /* Remove the object-like macro's name from the + output, and push its replacement text. */ + pfile->out.cur = out_start; + push_replacement_text (pfile, node); + lex_state = ls_none; + goto new_context; + } + } + else if (macro && (node->flags & NODE_MACRO_ARG) != 0) + { + /* Found a parameter in the replacement text of a + #define. Remove its name from the output. */ + pfile->out.cur = out_start; + save_replacement_text (pfile, macro, node->value.arg_index); + out = pfile->out.base; + } + else if (lex_state == ls_hash) + { + lex_state = ls_predicate; + continue; + } + else if (pfile->state.in_expression + && node == pfile->spec_nodes.n_defined) + { + lex_state = ls_defined; + continue; + } + } + break; + + case '(': + if (quote == 0) + { + paren_depth++; + if (lex_state == ls_fun_open) + { + if (recursive_macro (pfile, fmacro.node)) + lex_state = ls_none; + else + { + lex_state = ls_fun_close; + paren_depth = 1; + out = pfile->out.base + fmacro.offset; + fmacro.args[0] = fmacro.offset; + } + } + else if (lex_state == ls_predicate) + lex_state = ls_answer; + else if (lex_state == ls_defined) + lex_state = ls_defined_close; + } + break; + + case ',': + if (quote == 0 && lex_state == ls_fun_close && paren_depth == 1) + save_argument (&fmacro, out - pfile->out.base); + break; + + case ')': + if (quote == 0) + { + paren_depth--; + if (lex_state == ls_fun_close && paren_depth == 0) + { + cpp_macro *m = fmacro.node->value.macro; + + m->used = 1; + lex_state = ls_none; + save_argument (&fmacro, out - pfile->out.base); + + /* A single zero-length argument is no argument. */ + if (fmacro.argc == 1 + && m->paramc == 0 + && out == pfile->out.base + fmacro.offset + 1) + fmacro.argc = 0; + + if (_cpp_arguments_ok (pfile, m, fmacro.node, fmacro.argc)) + { + /* Remove the macro's invocation from the + output, and push its replacement text. */ + pfile->out.cur = (pfile->out.base + + fmacro.offset); + CUR (context) = cur; + replace_args_and_push (pfile, &fmacro); + goto new_context; + } + } + else if (lex_state == ls_answer || lex_state == ls_defined_close) + lex_state = ls_none; + } + break; + + case '#': + if (cur - 1 == start_of_input_line + /* A '#' from a macro doesn't start a directive. */ + && !pfile->context->prev + && !pfile->state.in_directive) + { + /* A directive. With the way _cpp_handle_directive + currently works, we only want to call it if either we + know the directive is OK, or we want it to fail and + be removed from the output. If we want it to be + passed through (the assembler case) then we must not + call _cpp_handle_directive. */ + pfile->out.cur = out; + cur = skip_whitespace (pfile, cur, true /* skip_comments */); + out = pfile->out.cur; + + if (*cur == '\n') + { + /* Null directive. Ignore it and don't invalidate + the MI optimization. */ + pfile->buffer->need_line = true; + CPP_INCREMENT_LINE (pfile, 0); + result = false; + goto done; + } + else + { + bool do_it = false; + + if (is_numstart (*cur) + && CPP_OPTION (pfile, lang) != CLK_ASM) + do_it = true; + else if (is_idstart (*cur)) + /* Check whether we know this directive, but don't + advance. */ + do_it = lex_identifier (pfile, cur)->is_directive; + + if (do_it || CPP_OPTION (pfile, lang) != CLK_ASM) + { + /* This is a kludge. We want to have the ISO + preprocessor lex the next token. */ + pfile->buffer->cur = cur; + _cpp_handle_directive (pfile, false /* indented */); + result = false; + goto done; + } + } + } + + if (pfile->state.in_expression) + { + lex_state = ls_hash; + continue; + } + break; + + default: + break; + } + + /* Non-whitespace disables MI optimization and stops treating + '<' as a quote in #include. */ + header_ok = false; + if (!pfile->state.in_directive) + pfile->mi_valid = false; + + if (lex_state == ls_none) + continue; + + /* Some of these transitions of state are syntax errors. The + ISO preprocessor will issue errors later. */ + if (lex_state == ls_fun_open) + /* Missing '('. */ + lex_state = ls_none; + else if (lex_state == ls_hash + || lex_state == ls_predicate + || lex_state == ls_defined) + lex_state = ls_none; + + /* ls_answer and ls_defined_close keep going until ')'. */ + } + + done: + if (fmacro.buff) + _cpp_release_buff (pfile, fmacro.buff); + + if (lex_state == ls_fun_close) + cpp_error_with_line (pfile, CPP_DL_ERROR, fmacro.line, 0, + "unterminated argument list invoking macro \"%s\"", + NODE_NAME (fmacro.node)); + return result; +} + +/* Push a context holding the replacement text of the macro NODE on + the context stack. NODE is either object-like, or a function-like + macro with no arguments. */ +static void +push_replacement_text (cpp_reader *pfile, cpp_hashnode *node) +{ + size_t len; + const uchar *text; + uchar *buf; + + if (node->flags & NODE_BUILTIN) + { + text = _cpp_builtin_macro_text (pfile, node); + len = ustrlen (text); + buf = _cpp_unaligned_alloc (pfile, len + 1); + memcpy (buf, text, len); + buf[len]='\n'; + text = buf; + } + else + { + cpp_macro *macro = node->value.macro; + macro->used = 1; + text = macro->exp.text; + macro->traditional = 1; + len = macro->count; + } + + _cpp_push_text_context (pfile, node, text, len); +} + +/* Returns TRUE if traditional macro recursion is detected. */ +static bool +recursive_macro (cpp_reader *pfile, cpp_hashnode *node) +{ + bool recursing = !!(node->flags & NODE_DISABLED); + + /* Object-like macros that are already expanding are necessarily + recursive. + + However, it is possible to have traditional function-like macros + that are not infinitely recursive but recurse to any given depth. + Further, it is easy to construct examples that get ever longer + until the point they stop recursing. So there is no easy way to + detect true recursion; instead we assume any expansion more than + 20 deep since the first invocation of this macro must be + recursing. */ + if (recursing && node->value.macro->fun_like) + { + size_t depth = 0; + cpp_context *context = pfile->context; + + do + { + depth++; + if (context->macro == node && depth > 20) + break; + context = context->prev; + } + while (context); + recursing = context != NULL; + } + + if (recursing) + cpp_error (pfile, CPP_DL_ERROR, + "detected recursion whilst expanding macro \"%s\"", + NODE_NAME (node)); + + return recursing; +} + +/* Return the length of the replacement text of a function-like or + object-like non-builtin macro. */ +size_t +_cpp_replacement_text_len (const cpp_macro *macro) +{ + size_t len; + + if (macro->fun_like && (macro->paramc != 0)) + { + const uchar *exp; + + len = 0; + for (exp = macro->exp.text;;) + { + struct block *b = (struct block *) exp; + + len += b->text_len; + if (b->arg_index == 0) + break; + len += NODE_LEN (macro->params[b->arg_index - 1]); + exp += BLOCK_LEN (b->text_len); + } + } + else + len = macro->count; + + return len; +} + +/* Copy the replacement text of MACRO to DEST, which must be of + sufficient size. It is not NUL-terminated. The next character is + returned. */ +uchar * +_cpp_copy_replacement_text (const cpp_macro *macro, uchar *dest) +{ + if (macro->fun_like && (macro->paramc != 0)) + { + const uchar *exp; + + for (exp = macro->exp.text;;) + { + struct block *b = (struct block *) exp; + cpp_hashnode *param; + + memcpy (dest, b->text, b->text_len); + dest += b->text_len; + if (b->arg_index == 0) + break; + param = macro->params[b->arg_index - 1]; + memcpy (dest, NODE_NAME (param), NODE_LEN (param)); + dest += NODE_LEN (param); + exp += BLOCK_LEN (b->text_len); + } + } + else + { + memcpy (dest, macro->exp.text, macro->count); + dest += macro->count; + } + + return dest; +} + +/* Push a context holding the replacement text of the macro NODE on + the context stack. NODE is either object-like, or a function-like + macro with no arguments. */ +static void +replace_args_and_push (cpp_reader *pfile, struct fun_macro *fmacro) +{ + cpp_macro *macro = fmacro->node->value.macro; + + if (macro->paramc == 0) + push_replacement_text (pfile, fmacro->node); + else + { + const uchar *exp; + uchar *p; + _cpp_buff *buff; + size_t len = 0; + int cxtquote = 0; + + /* Get an estimate of the length of the argument-replaced text. + This is a worst case estimate, assuming that every replacement + text character needs quoting. */ + for (exp = macro->exp.text;;) + { + struct block *b = (struct block *) exp; + + len += b->text_len; + if (b->arg_index == 0) + break; + len += 2 * (fmacro->args[b->arg_index] + - fmacro->args[b->arg_index - 1] - 1); + exp += BLOCK_LEN (b->text_len); + } + + /* Allocate room for the expansion plus \n. */ + buff = _cpp_get_buff (pfile, len + 1); + + /* Copy the expansion and replace arguments. */ + /* Accumulate actual length, including quoting as necessary */ + p = BUFF_FRONT (buff); + len = 0; + for (exp = macro->exp.text;;) + { + struct block *b = (struct block *) exp; + size_t arglen; + int argquote; + uchar *base; + uchar *in; + + len += b->text_len; + /* Copy the non-argument text literally, keeping + track of whether matching quotes have been seen. */ + for (arglen = b->text_len, in = b->text; arglen > 0; arglen--) + { + if (*in == '"') + cxtquote = ! cxtquote; + *p++ = *in++; + } + /* Done if no more arguments */ + if (b->arg_index == 0) + break; + arglen = (fmacro->args[b->arg_index] + - fmacro->args[b->arg_index - 1] - 1); + base = pfile->out.base + fmacro->args[b->arg_index - 1]; + in = base; +#if 0 + /* Skip leading whitespace in the text for the argument to + be substituted. To be compatible with gcc 2.95, we would + also need to trim trailing whitespace. Gcc 2.95 trims + leading and trailing whitespace, which may be a bug. The + current gcc testsuite explicitly checks that this leading + and trailing whitespace in actual arguments is + preserved. */ + while (arglen > 0 && is_space (*in)) + { + in++; + arglen--; + } +#endif + for (argquote = 0; arglen > 0; arglen--) + { + if (cxtquote && *in == '"') + { + if (in > base && *(in-1) != '\\') + argquote = ! argquote; + /* Always add backslash before double quote if argument + is expanded in a quoted context */ + *p++ = '\\'; + len++; + } + else if (cxtquote && argquote && *in == '\\') + { + /* Always add backslash before a backslash in an argument + that is expanded in a quoted context and also in the + range of a quoted context in the argument itself. */ + *p++ = '\\'; + len++; + } + *p++ = *in++; + len++; + } + exp += BLOCK_LEN (b->text_len); + } + + /* \n-terminate. */ + *p = '\n'; + _cpp_push_text_context (pfile, fmacro->node, BUFF_FRONT (buff), len); + + /* So we free buffer allocation when macro is left. */ + pfile->context->buff = buff; + } +} + +/* Read and record the parameters, if any, of a function-like macro + definition. Destroys pfile->out.cur. + + Returns true on success, false on failure (syntax error or a + duplicate parameter). On success, CUR (pfile->context) is just + past the closing parenthesis. */ +static bool +scan_parameters (cpp_reader *pfile, cpp_macro *macro) +{ + const uchar *cur = CUR (pfile->context) + 1; + bool ok; + + for (;;) + { + cur = skip_whitespace (pfile, cur, true /* skip_comments */); + + if (is_idstart (*cur)) + { + ok = false; + if (_cpp_save_parameter (pfile, macro, lex_identifier (pfile, cur))) + break; + cur = skip_whitespace (pfile, CUR (pfile->context), + true /* skip_comments */); + if (*cur == ',') + { + cur++; + continue; + } + ok = (*cur == ')'); + break; + } + + ok = (*cur == ')' && macro->paramc == 0); + break; + } + + if (!ok) + cpp_error (pfile, CPP_DL_ERROR, "syntax error in macro parameter list"); + + CUR (pfile->context) = cur + (*cur == ')'); + + return ok; +} + +/* Save the text from pfile->out.base to pfile->out.cur as + the replacement text for the current macro, followed by argument + ARG_INDEX, with zero indicating the end of the replacement + text. */ +static void +save_replacement_text (cpp_reader *pfile, cpp_macro *macro, + unsigned int arg_index) +{ + size_t len = pfile->out.cur - pfile->out.base; + uchar *exp; + + if (macro->paramc == 0) + { + /* Object-like and function-like macros without parameters + simply store their \n-terminated replacement text. */ + exp = _cpp_unaligned_alloc (pfile, len + 1); + memcpy (exp, pfile->out.base, len); + exp[len] = '\n'; + macro->exp.text = exp; + macro->traditional = 1; + macro->count = len; + } + else + { + /* Store the text's length (unsigned int), the argument index + (unsigned short, base 1) and then the text. */ + size_t blen = BLOCK_LEN (len); + struct block *block; + + if (macro->count + blen > BUFF_ROOM (pfile->a_buff)) + _cpp_extend_buff (pfile, &pfile->a_buff, macro->count + blen); + + exp = BUFF_FRONT (pfile->a_buff); + block = (struct block *) (exp + macro->count); + macro->exp.text = exp; + macro->traditional = 1; + + /* Write out the block information. */ + block->text_len = len; + block->arg_index = arg_index; + memcpy (block->text, pfile->out.base, len); + + /* Lex the rest into the start of the output buffer. */ + pfile->out.cur = pfile->out.base; + + macro->count += blen; + + /* If we've finished, commit the memory. */ + if (arg_index == 0) + BUFF_FRONT (pfile->a_buff) += macro->count; + } +} + +/* Analyze and save the replacement text of a macro. Returns true on + success. */ +bool +_cpp_create_trad_definition (cpp_reader *pfile, cpp_macro *macro) +{ + const uchar *cur; + uchar *limit; + cpp_context *context = pfile->context; + + /* The context has not been set up for command line defines, and CUR + has not been updated for the macro name for in-file defines. */ + pfile->out.cur = pfile->out.base; + CUR (context) = pfile->buffer->cur; + RLIMIT (context) = pfile->buffer->rlimit; + check_output_buffer (pfile, RLIMIT (context) - CUR (context)); + + /* Is this a function-like macro? */ + if (* CUR (context) == '(') + { + bool ok = scan_parameters (pfile, macro); + + /* Remember the params so we can clear NODE_MACRO_ARG flags. */ + macro->params = (cpp_hashnode **) BUFF_FRONT (pfile->a_buff); + + /* Setting macro to NULL indicates an error occurred, and + prevents unnecessary work in _cpp_scan_out_logical_line. */ + if (!ok) + macro = NULL; + else + { + BUFF_FRONT (pfile->a_buff) = (uchar *) ¯o->params[macro->paramc]; + macro->fun_like = 1; + } + } + + /* Skip leading whitespace in the replacement text. */ + pfile->buffer->cur + = skip_whitespace (pfile, CUR (context), + CPP_OPTION (pfile, discard_comments_in_macro_exp)); + + pfile->state.prevent_expansion++; + _cpp_scan_out_logical_line (pfile, macro); + pfile->state.prevent_expansion--; + + if (!macro) + return false; + + /* Skip trailing white space. */ + cur = pfile->out.base; + limit = pfile->out.cur; + while (limit > cur && is_space (limit[-1])) + limit--; + pfile->out.cur = limit; + save_replacement_text (pfile, macro, 0); + + return true; +} + +/* Copy SRC of length LEN to DEST, but convert all contiguous + whitespace to a single space, provided it is not in quotes. The + quote currently in effect is pointed to by PQUOTE, and is updated + by the function. Returns the number of bytes copied. */ +static size_t +canonicalize_text (uchar *dest, const uchar *src, size_t len, uchar *pquote) +{ + uchar *orig_dest = dest; + uchar quote = *pquote; + + while (len) + { + if (is_space (*src) && !quote) + { + do + src++, len--; + while (len && is_space (*src)); + *dest++ = ' '; + } + else + { + if (*src == '\'' || *src == '"') + { + if (!quote) + quote = *src; + else if (quote == *src) + quote = 0; + } + *dest++ = *src++, len--; + } + } + + *pquote = quote; + return dest - orig_dest; +} + +/* Returns true if MACRO1 and MACRO2 have expansions different other + than in the form of their whitespace. */ +bool +_cpp_expansions_different_trad (const cpp_macro *macro1, + const cpp_macro *macro2) +{ + uchar *p1 = XNEWVEC (uchar, macro1->count + macro2->count); + uchar *p2 = p1 + macro1->count; + uchar quote1 = 0, quote2 = 0; + bool mismatch; + size_t len1, len2; + + if (macro1->paramc > 0) + { + const uchar *exp1 = macro1->exp.text, *exp2 = macro2->exp.text; + + mismatch = true; + for (;;) + { + struct block *b1 = (struct block *) exp1; + struct block *b2 = (struct block *) exp2; + + if (b1->arg_index != b2->arg_index) + break; + + len1 = canonicalize_text (p1, b1->text, b1->text_len, "e1); + len2 = canonicalize_text (p2, b2->text, b2->text_len, "e2); + if (len1 != len2 || memcmp (p1, p2, len1)) + break; + if (b1->arg_index == 0) + { + mismatch = false; + break; + } + exp1 += BLOCK_LEN (b1->text_len); + exp2 += BLOCK_LEN (b2->text_len); + } + } + else + { + len1 = canonicalize_text (p1, macro1->exp.text, macro1->count, "e1); + len2 = canonicalize_text (p2, macro2->exp.text, macro2->count, "e2); + mismatch = (len1 != len2 || memcmp (p1, p2, len1)); + } + + free (p1); + return mismatch; +} diff --git a/support/cpp/libcpp/ucnid.h b/support/cpp/libcpp/ucnid.h new file mode 100644 index 0000000..e5690b2 --- /dev/null +++ b/support/cpp/libcpp/ucnid.h @@ -0,0 +1,801 @@ +/* Unicode characters and various properties. + Copyright (C) 2003, 2005, 2009 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. + + + Copyright (C) 1991-2005 Unicode, Inc. All rights reserved. + Distributed under the Terms of Use in + http://www.unicode.org/copyright.html. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of the Unicode data files and any associated + documentation (the "Data Files") or Unicode software and any + associated documentation (the "Software") to deal in the Data Files + or Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, and/or + sell copies of the Data Files or Software, and to permit persons to + whom the Data Files or Software are furnished to do so, provided + that (a) the above copyright notice(s) and this permission notice + appear with all copies of the Data Files or Software, (b) both the + above copyright notice(s) and this permission notice appear in + associated documentation, and (c) there is clear notice in each + modified Data File or in the Software as well as in the + documentation associated with the Data File(s) or Software that the + data or software has been modified. + + THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY + OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE + COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR + ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY + DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + OF THE DATA FILES OR SOFTWARE. + + Except as contained in this notice, the name of a copyright holder + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in these Data Files or Software without prior + written authorization of the copyright holder. */ + +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00a9 }, +{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x00aa }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00b4 }, +{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x00b5 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00b6 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x00b7 }, +{ 0| 0| 0|CID|NFC| 0| 0, 0, 0x00b9 }, +{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x00ba }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00bf }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x00d6 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00d7 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x00f6 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00f7 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0131 }, +{ C99| 0|CXX|CID|NFC| 0| 0, 0, 0x0133 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x013e }, +{ C99| 0|CXX|CID|NFC| 0| 0, 0, 0x0140 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0148 }, +{ C99| 0|CXX|CID|NFC| 0| 0, 0, 0x0149 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x017e }, +{ C99| 0|CXX|CID|NFC| 0| 0, 0, 0x017f }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x01c3 }, +{ C99| 0|CXX|CID|NFC| 0| 0, 0, 0x01cc }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x01f0 }, +{ C99| 0|CXX|CID|NFC| 0| 0, 0, 0x01f3 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x01f5 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x01f9 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0217 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x024f }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x02a8 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x02af }, +{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x02b8 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x02ba }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x02bb }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x02bc }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x02c1 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x02cf }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x02d1 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x02df }, +{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x02e4 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0379 }, +{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x037a }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0383 }, +{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0x0384 }, +{ 0| 0| 0|CID|NFC| 0| 0, 0, 0x0385 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0386 }, +{ 0| 0| 0|CID| 0| 0| 0, 0, 0x0387 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x038a }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x038b }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x038c }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x038d }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x03a1 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x03a2 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x03ce }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x03cf }, +{ C99| 0|CXX|CID|NFC| 0| 0, 0, 0x03d6 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x03d9 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x03da }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x03db }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x03dc }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x03dd }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x03de }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x03df }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x03e0 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x03e1 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x03ef }, +{ C99| 0|CXX|CID|NFC| 0| 0, 0, 0x03f2 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x03f3 }, +{ 0| 0| 0|CID|NFC| 0| 0, 0, 0x0400 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x040c }, +{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0x040d }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x040e }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x044f }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0450 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x045c }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x045d }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0481 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x048f }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x04c4 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x04c6 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x04c8 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x04ca }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x04cc }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x04cf }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x04eb }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x04ed }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x04f5 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x04f7 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x04f9 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0530 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0556 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0558 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0559 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0560 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0586 }, +{ C99| 0|CXX|CID|NFC| 0| 0, 0, 0x0587 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x05af }, +{ C99| 0| 0|CID|NFC|NKC| 0, 10, 0x05b0 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 11, 0x05b1 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 12, 0x05b2 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 13, 0x05b3 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 14, 0x05b4 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 15, 0x05b5 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 16, 0x05b6 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 17, 0x05b7 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 18, 0x05b8 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 19, 0x05b9 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x05ba }, +{ C99| 0| 0|CID|NFC|NKC| 0, 20, 0x05bb }, +{ C99| 0| 0|CID|NFC|NKC| 0, 21, 0x05bc }, +{ C99| 0| 0|CID|NFC|NKC| 0, 22, 0x05bd }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x05be }, +{ C99| 0| 0|CID|NFC|NKC| 0, 23, 0x05bf }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x05c0 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 24, 0x05c1 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 25, 0x05c2 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x05cf }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x05ea }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x05ef }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x05f2 }, +{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0x05f4 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0620 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x063a }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x063f }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x064a }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 27, 0x064b }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 28, 0x064c }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 29, 0x064d }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 30, 0x064e }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 31, 0x064f }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 32, 0x0650 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 33, 0x0651 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 34, 0x0652 }, +{ 0| 0| 0|CID|NFC|NKC|CTX, 0, 0x065f }, +{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x0669 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x066f }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0674 }, +{ C99| 0|CXX|CID|NFC| 0| 0, 0, 0x0678 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x06b7 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x06b9 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x06be }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x06bf }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x06ce }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x06cf }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x06d5 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 230, 0x06d6 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 230, 0x06d7 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 230, 0x06d8 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 230, 0x06d9 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 230, 0x06da }, +{ C99| 0| 0|CID|NFC|NKC| 0, 230, 0x06db }, +{ C99| 0| 0|CID|NFC|NKC| 0, 230, 0x06dc }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x06e4 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x06e6 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 230, 0x06e7 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 230, 0x06e8 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x06e9 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 220, 0x06ea }, +{ C99| 0| 0|CID|NFC|NKC| 0, 230, 0x06eb }, +{ C99| 0| 0|CID|NFC|NKC| 0, 230, 0x06ec }, +{ C99| 0| 0|CID|NFC|NKC| 0, 220, 0x06ed }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x06ef }, +{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x06f9 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0900 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0903 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0904 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0939 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x093c }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x094c }, +{ C99| 0| 0|CID|NFC|NKC| 0, 9, 0x094d }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x094f }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0950 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 230, 0x0951 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 220, 0x0952 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0957 }, +{ C99| 0|CXX|CID| 0| 0| 0, 0, 0x095f }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0962 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0963 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0965 }, +{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x096f }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0980 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0983 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0984 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x098c }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x098e }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0990 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0992 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x09a8 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x09a9 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x09b0 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x09b1 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x09b2 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x09b5 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x09b9 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x09bd }, +{ C99| 0| 0|CID|NFC|NKC|CTX, 0, 0x09be }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x09c4 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x09c6 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x09c8 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x09ca }, +{ C99| 0| 0| 0|NFC|NKC| 0, 0, 0x09cb }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x09cc }, +{ C99| 0| 0|CID|NFC|NKC| 0, 9, 0x09cd }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x09db }, +{ C99| 0|CXX|CID| 0| 0| 0, 0, 0x09dd }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x09de }, +{ C99| 0|CXX|CID| 0| 0| 0, 0, 0x09df }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x09e1 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x09e3 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x09e5 }, +{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x09ef }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x09f1 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a01 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0a02 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a04 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0a0a }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a0e }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0a10 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a12 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0a28 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a29 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0a30 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a31 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0a32 }, +{ C99| 0|CXX|CID| 0| 0| 0, 0, 0x0a33 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a34 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0a35 }, +{ C99| 0|CXX|CID| 0| 0| 0, 0, 0x0a36 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a37 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0a39 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a3d }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0a42 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a46 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0a48 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a4a }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0a4c }, +{ C99| 0| 0|CID|NFC|NKC| 0, 9, 0x0a4d }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a58 }, +{ C99| 0|CXX|CID| 0| 0| 0, 0, 0x0a5b }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0a5c }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a5d }, +{ C99| 0|CXX|CID| 0| 0| 0, 0, 0x0a5e }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a65 }, +{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x0a6f }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a73 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0a74 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a80 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0a83 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a84 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0a8b }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a8c }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0a8d }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a8e }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0a91 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a92 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0aa8 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0aa9 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0ab0 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ab1 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0ab3 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ab4 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0ab9 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0abc }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0ac5 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ac6 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0ac9 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0aca }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0acc }, +{ C99| 0| 0|CID|NFC|NKC| 0, 9, 0x0acd }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0acf }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0ad0 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0adf }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0ae0 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ae5 }, +{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x0aef }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b00 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0b03 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b04 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0b0c }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b0e }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0b10 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b12 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0b28 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b29 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0b30 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b31 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0b33 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b35 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0b39 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b3c }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0b3d }, +{ C99| 0| 0|CID|NFC|NKC|CTX, 0, 0x0b3e }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0b43 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b46 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0b48 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b4a }, +{ C99| 0| 0| 0|NFC|NKC| 0, 0, 0x0b4b }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0b4c }, +{ C99| 0| 0|CID|NFC|NKC| 0, 9, 0x0b4d }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b5b }, +{ C99| 0|CXX|CID| 0| 0| 0, 0, 0x0b5d }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b5e }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0b61 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b65 }, +{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x0b6f }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b81 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0b83 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b84 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0b8a }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b8d }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0b90 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b91 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0b95 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b98 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0b9a }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b9b }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0b9c }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b9d }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0b9f }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ba2 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0ba4 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ba7 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0baa }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0bad }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0bb5 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0bb6 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0bb9 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0bbd }, +{ C99| 0| 0|CID|NFC|NKC|CTX, 0, 0x0bbe }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0bc2 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0bc5 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0bc8 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0bc9 }, +{ C99| 0| 0| 0|NFC|NKC| 0, 0, 0x0bcb }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0bcc }, +{ C99| 0| 0|CID|NFC|NKC| 0, 9, 0x0bcd }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0be6 }, +{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x0bef }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c00 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0c03 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c04 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0c0c }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c0d }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0c10 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c11 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0c28 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c29 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0c33 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c34 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0c39 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c3d }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0c44 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c45 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0c48 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c49 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0c4c }, +{ C99| 0| 0|CID|NFC|NKC| 0, 9, 0x0c4d }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c5f }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0c61 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c65 }, +{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x0c6f }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c81 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0c83 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c84 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0c8c }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c8d }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0c90 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c91 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0ca8 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ca9 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0cb3 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0cb4 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0cb9 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0cbd }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0cc1 }, +{ C99| 0| 0|CID|NFC|NKC|CTX, 0, 0x0cc2 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0cc4 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0cc5 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0cc8 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0cc9 }, +{ C99| 0| 0| 0|NFC|NKC| 0, 0, 0x0cca }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0ccc }, +{ C99| 0| 0|CID|NFC|NKC| 0, 9, 0x0ccd }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0cdd }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0cde }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0cdf }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0ce1 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ce5 }, +{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x0cef }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d01 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0d03 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d04 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0d0c }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d0d }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0d10 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d11 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0d28 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d29 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0d39 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d3d }, +{ C99| 0| 0|CID|NFC|NKC|CTX, 0, 0x0d3e }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0d43 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d45 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0d48 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d49 }, +{ C99| 0| 0| 0|NFC|NKC| 0, 0, 0x0d4b }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0d4c }, +{ C99| 0| 0|CID|NFC|NKC| 0, 9, 0x0d4d }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d5f }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0d61 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d65 }, +{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x0d6f }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0e00 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0e30 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0e31 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0e32 }, +{ C99| 0|CXX|CID|NFC| 0| 0, 0, 0x0e33 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0e37 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 103, 0x0e38 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 103, 0x0e39 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 9, 0x0e3a }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0e3f }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0e46 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0e47 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 107, 0x0e48 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 107, 0x0e49 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0e4e }, +{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0x0e4f }, +{ C99|DIG|CXX|CID|NFC|NKC| 0, 0, 0x0e59 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0e5b }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0e80 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0e82 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0e83 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0e84 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0e86 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0e88 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0e89 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0e8a }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0e8c }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0e8d }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0e93 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0e97 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0e98 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0e9f }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ea0 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0ea3 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ea4 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0ea5 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ea6 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0ea7 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ea9 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0eab }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0eac }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0eae }, +{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0x0eaf }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0eb0 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0eb1 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0eb2 }, +{ C99| 0|CXX|CID|NFC| 0| 0, 0, 0x0eb3 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0eb7 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 118, 0x0eb8 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 118, 0x0eb9 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0eba }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0ebc }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0ebd }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ebf }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0ec4 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ec5 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x0ec6 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ec7 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 122, 0x0ec8 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 122, 0x0ec9 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 122, 0x0eca }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0ecd }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ecf }, +{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x0ed9 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0edb }, +{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x0edd }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0eff }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0f00 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f17 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 220, 0x0f18 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 220, 0x0f19 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f1f }, +{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x0f33 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f34 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 220, 0x0f35 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f36 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 220, 0x0f37 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f38 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 216, 0x0f39 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f3d }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0f42 }, +{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0f43 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0f47 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f48 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0f4c }, +{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0f4d }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0f51 }, +{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0f52 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0f56 }, +{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0f57 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0f5b }, +{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0f5c }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0f68 }, +{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0f69 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f70 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 129, 0x0f71 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 130, 0x0f72 }, +{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0f73 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 132, 0x0f74 }, +{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0f76 }, +{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x0f77 }, +{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0f78 }, +{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x0f79 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 130, 0x0f7a }, +{ C99| 0| 0|CID|NFC|NKC| 0, 130, 0x0f7b }, +{ C99| 0| 0|CID|NFC|NKC| 0, 130, 0x0f7c }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0f7f }, +{ C99| 0| 0|CID|NFC|NKC| 0, 130, 0x0f80 }, +{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0f81 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 230, 0x0f82 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 230, 0x0f83 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 9, 0x0f84 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f85 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 230, 0x0f86 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0f8b }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f8f }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0f92 }, +{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0f93 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0f95 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f96 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0f97 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f98 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0f9c }, +{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0f9d }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0fa1 }, +{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0fa2 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0fa6 }, +{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0fa7 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0fab }, +{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0fac }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0fad }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0fb0 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x0fb7 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0fb8 }, +{ C99| 0| 0| 0| 0| 0| 0, 0, 0x0fb9 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x109f }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x10c5 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10cf }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x10f6 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10ff }, +{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0x1159 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1160 }, +{ 0| 0|CXX|CID|NFC|NKC|CTX, 0, 0x1175 }, +{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0x11a2 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11a7 }, +{ 0| 0|CXX|CID|NFC|NKC|CTX, 0, 0x11c2 }, +{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0x11f9 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1dff }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1e99 }, +{ C99| 0|CXX|CID|NFC| 0| 0, 0, 0x1e9a }, +{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x1e9b }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1e9f }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1ef9 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1eff }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1f15 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f17 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1f1d }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f1f }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1f45 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f47 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1f4d }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f4f }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1f57 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f58 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1f59 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f5a }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1f5b }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f5c }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1f5d }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f5e }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1f70 }, +{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1f71 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1f72 }, +{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1f73 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1f74 }, +{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1f75 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1f76 }, +{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1f77 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1f78 }, +{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1f79 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1f7a }, +{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1f7b }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1f7c }, +{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1f7d }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f7f }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1fb4 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1fb5 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1fba }, +{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1fbb }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1fbc }, +{ 0| 0| 0|CID|NFC| 0| 0, 0, 0x1fbd }, +{ C99| 0| 0| 0| 0| 0| 0, 0, 0x1fbe }, +{ 0| 0| 0|CID|NFC| 0| 0, 0, 0x1fc1 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1fc4 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1fc5 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1fc8 }, +{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1fc9 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1fca }, +{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1fcb }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1fcc }, +{ 0| 0| 0|CID|NFC| 0| 0, 0, 0x1fcf }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1fd2 }, +{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1fd3 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1fd5 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1fda }, +{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1fdb }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1fdf }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1fe2 }, +{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1fe3 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1fea }, +{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1feb }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1fec }, +{ 0| 0| 0|CID|NFC| 0| 0, 0, 0x1ff1 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1ff4 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ff5 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1ff8 }, +{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1ff9 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1ffa }, +{ C99| 0|CXX| 0| 0| 0| 0, 0, 0x1ffb }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x1ffc }, +{ 0| 0| 0|CID| 0| 0| 0, 0, 0x203e }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x2040 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x207e }, +{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x207f }, +{ 0| 0| 0|CID|NFC| 0| 0, 0, 0x2101 }, +{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x2102 }, +{ 0| 0| 0|CID|NFC| 0| 0, 0, 0x2106 }, +{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x2107 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2109 }, +{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x2113 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2114 }, +{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x2115 }, +{ 0| 0| 0|CID|NFC| 0| 0, 0, 0x2117 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x2118 }, +{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x211d }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2123 }, +{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x2124 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2125 }, +{ C99| 0| 0| 0| 0| 0| 0, 0, 0x2126 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2127 }, +{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x2128 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2129 }, +{ C99| 0| 0|CID| 0| 0| 0, 0, 0x212a }, +{ C99| 0| 0| 0| 0| 0| 0, 0, 0x212b }, +{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x212d }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x212e }, +{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x2131 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2132 }, +{ C99| 0| 0|CID|NFC| 0| 0, 0, 0x2138 }, +{ 0| 0| 0|CID|NFC| 0| 0, 0, 0x215f }, +{ C99|DIG| 0|CID|NFC| 0| 0, 0, 0x217f }, +{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x2182 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x3004 }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0x3006 }, +{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x3007 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x3020 }, +{ C99|DIG| 0|CID|NFC|NKC| 0, 0, 0x3029 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x3040 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x3093 }, +{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0x3094 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x309a }, +{ C99| 0|CXX|CID|NFC| 0| 0, 0, 0x309c }, +{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0x309e }, +{ 0| 0| 0|CID|NFC| 0| 0, 0, 0x30a0 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x30f6 }, +{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0x30fa }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x30fc }, +{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0x30fe }, +{ 0| 0| 0|CID|NFC| 0| 0, 0, 0x3104 }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x312c }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0x4dff }, +{ C99| 0|CXX|CID|NFC|NKC| 0, 0, 0x9fa5 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xabff }, +{ C99| 0| 0|CID|NFC|NKC| 0, 0, 0xd7a3 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xf8ff }, +{ 0| 0|CXX| 0| 0| 0| 0, 0, 0xfa0d }, +{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0xfa0f }, +{ 0| 0|CXX| 0| 0| 0| 0, 0, 0xfa10 }, +{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0xfa11 }, +{ 0| 0|CXX| 0| 0| 0| 0, 0, 0xfa12 }, +{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0xfa14 }, +{ 0| 0|CXX| 0| 0| 0| 0, 0, 0xfa1e }, +{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0xfa1f }, +{ 0| 0|CXX| 0| 0| 0| 0, 0, 0xfa20 }, +{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0xfa21 }, +{ 0| 0|CXX| 0| 0| 0| 0, 0, 0xfa22 }, +{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0xfa24 }, +{ 0| 0|CXX| 0| 0| 0| 0, 0, 0xfa26 }, +{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0xfa29 }, +{ 0| 0|CXX| 0| 0| 0| 0, 0, 0xfa2d }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfb1e }, +{ 0| 0|CXX|CID| 0| 0| 0, 0, 0xfb1f }, +{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xfb29 }, +{ 0| 0|CXX|CID| 0| 0| 0, 0, 0xfb36 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfb37 }, +{ 0| 0|CXX|CID| 0| 0| 0, 0, 0xfb3c }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfb3d }, +{ 0| 0|CXX|CID| 0| 0| 0, 0, 0xfb3e }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfb3f }, +{ 0| 0|CXX|CID| 0| 0| 0, 0, 0xfb41 }, +{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0xfb42 }, +{ 0| 0|CXX|CID| 0| 0| 0, 0, 0xfb44 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfb45 }, +{ 0| 0|CXX|CID| 0| 0| 0, 0, 0xfb4e }, +{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xfbb1 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfbd2 }, +{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xfd3d }, +{ 0| 0|CXX|CID|NFC|NKC| 0, 0, 0xfd3f }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfd4f }, +{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xfd8f }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfd91 }, +{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xfdc7 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfdef }, +{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xfdfb }, +{ 0| 0| 0|CID|NFC| 0| 0, 0, 0xfe6f }, +{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xfe72 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfe73 }, +{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xfe74 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfe75 }, +{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xfefc }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xff20 }, +{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xff3a }, +{ 0| 0| 0|CID|NFC| 0| 0, 0, 0xff40 }, +{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xff5a }, +{ 0| 0| 0|CID|NFC| 0| 0, 0, 0xff65 }, +{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xffbe }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xffc1 }, +{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xffc7 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xffc9 }, +{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xffcf }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xffd1 }, +{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xffd7 }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xffd9 }, +{ 0| 0|CXX|CID|NFC| 0| 0, 0, 0xffdc }, +{ 0| 0| 0|CID|NFC|NKC| 0, 0, 0xffff }, diff --git a/support/cpp/md5.h b/support/cpp/md5.h new file mode 100644 index 0000000..b823943 --- /dev/null +++ b/support/cpp/md5.h @@ -0,0 +1,154 @@ +/* md5.h - Declaration of functions and data types used for MD5 sum + computing library functions. + Copyright 1995, 1996, 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@prep.ai.mit.edu. + + 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _MD5_H +#define _MD5_H 1 + +#include <stdio.h> + +#if defined HAVE_LIMITS_H || _LIBC +# include <limits.h> +#endif + +#include "ansidecl.h" + +/* The following contortions are an attempt to use the C preprocessor + to determine an unsigned integral type that is 32 bits wide. An + alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but + doing that would require that the configure script compile and *run* + the resulting executable. Locally running cross-compiled executables + is usually not possible. */ + +#ifdef _LIBC +# include <sys/types.h> +typedef u_int32_t md5_uint32; +typedef uintptr_t md5_uintptr; +#else +# define INT_MAX_32_BITS 2147483647 + +/* If UINT_MAX isn't defined, assume it's a 32-bit type. + This should be valid for all systems GNU cares about because + that doesn't include 16-bit systems, and only modern systems + (that certainly have <limits.h>) have 64+-bit integral types. */ + +# ifndef INT_MAX +# define INT_MAX INT_MAX_32_BITS +# endif + +# if INT_MAX == INT_MAX_32_BITS + typedef unsigned int md5_uint32; +# else +# if SHRT_MAX == INT_MAX_32_BITS + typedef unsigned short md5_uint32; +# else +# if LONG_MAX == INT_MAX_32_BITS + typedef unsigned long md5_uint32; +# else + /* The following line is intended to evoke an error. + Using #error is not portable enough. */ + "Cannot determine unsigned 32-bit data type." +# endif +# endif +# endif +# ifdef _WIN32 +# include <stdint.h> + typedef uintptr_t md5_uintptr; +# else + /* We have to make a guess about the integer type equivalent in size + to pointers which should always be correct. */ + typedef unsigned long int md5_uintptr; +# endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Structure to save state of computation between the single steps. */ +struct md5_ctx +{ + md5_uint32 A; + md5_uint32 B; + md5_uint32 C; + md5_uint32 D; + + md5_uint32 total[2]; + md5_uint32 buflen; + char buffer[128] ATTRIBUTE_ALIGNED_ALIGNOF(md5_uint32); +}; + +/* + * The following three functions are build up the low level used in + * the functions `md5_stream' and `md5_buffer'. + */ + +/* Initialize structure containing state of computation. + (RFC 1321, 3.3: Step 3) */ +extern void md5_init_ctx (struct md5_ctx *ctx); + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is necessary that LEN is a multiple of 64!!! */ +extern void md5_process_block (const void *buffer, size_t len, + struct md5_ctx *ctx); + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is NOT required that LEN is a multiple of 64. */ +extern void md5_process_bytes (const void *buffer, size_t len, + struct md5_ctx *ctx); + +/* Process the remaining bytes in the buffer and put result from CTX + in first 16 bytes following RESBUF. The result is always in little + endian byte order, so that a byte-wise output yields to the wanted + ASCII representation of the message digest. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +extern void *md5_finish_ctx (struct md5_ctx *ctx, void *resbuf); + + +/* Put result from CTX in first 16 bytes following RESBUF. The result is + always in little endian byte order, so that a byte-wise output yields + to the wanted ASCII representation of the message digest. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +extern void *md5_read_ctx (const struct md5_ctx *ctx, void *resbuf); + + +/* Compute MD5 message digest for bytes read from STREAM. The + resulting message digest number will be written into the 16 bytes + beginning at RESBLOCK. */ +extern int md5_stream (FILE *stream, void *resblock); + +/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The + result is always in little endian byte order, so that a byte-wise + output yields to the wanted ASCII representation of the message + digest. */ +extern void *md5_buffer (const char *buffer, size_t len, void *resblock); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/support/cpp/move-if-change b/support/cpp/move-if-change new file mode 100644 index 0000000..d267e72 --- /dev/null +++ b/support/cpp/move-if-change @@ -0,0 +1,32 @@ +#!/bin/sh + +# Copyright (C) 1996 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +if +test -r $2 +then +if +cmp $1 $2 > /dev/null +then +echo $2 is unchanged +rm -f $1 +else +mv -f $1 $2 +fi +else +mv -f $1 $2 +fi diff --git a/support/cpp/opt-functions.awk b/support/cpp/opt-functions.awk new file mode 100644 index 0000000..3e4c805 --- /dev/null +++ b/support/cpp/opt-functions.awk @@ -0,0 +1,169 @@ +# Copyright (C) 2003,2004 Free Software Foundation, Inc. +# Contributed by Kelley Cook, June 2004. +# Original code from Neil Booth, May 2003. +# +# 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# Some common subroutines for use by opt[ch]-gen.awk. + +# Return nonzero if FLAGS contains a flag matching REGEX. +function flag_set_p(regex, flags) +{ + return (" " flags " ") ~ (" " regex " ") +} + +# Return STRING if FLAGS contains a flag matching regexp REGEX, +# otherwise return the empty string. +function test_flag(regex, flags, string) +{ + if (flag_set_p(regex, flags)) + return string + return "" +} + +# If FLAGS contains a "NAME(...argument...)" flag, return the value +# of the argument. Return the empty string otherwise. +function opt_args(name, flags) +{ + flags = " " flags + if (flags !~ " " name "\\(") + return "" + sub(".* " name "\\(", "", flags) + sub("\\).*", "", flags) + + return flags +} + +# Return the Nth comma-separated element of S. Return the empty string +# if S does not contain N elements. +function nth_arg(n, s) +{ + while (n-- > 0) { + if (s !~ ",") + return "" + sub("[^,]*, *", "", s) + } + sub(",.*", "", s) + return s +} + +# Return a bitmask of CL_* values for option flags FLAGS. +function switch_flags (flags) +{ + result = "0" + for (j = 0; j < n_langs; j++) { + regex = langs[j] + gsub ( "\\+", "\\+", regex ) + result = result test_flag(regex, flags, " | " macros[j]) + } + result = result \ + test_flag("Common", flags, " | CL_COMMON") \ + test_flag("Target", flags, " | CL_TARGET") \ + test_flag("Joined", flags, " | CL_JOINED") \ + test_flag("JoinedOrMissing", flags, " | CL_JOINED | CL_MISSING_OK") \ + test_flag("Separate", flags, " | CL_SEPARATE") \ + test_flag("RejectNegative", flags, " | CL_REJECT_NEGATIVE") \ + test_flag("UInteger", flags, " | CL_UINTEGER") \ + test_flag("Undocumented", flags, " | CL_UNDOCUMENTED") \ + test_flag("Report", flags, " | CL_REPORT") + sub( "^0 \\| ", "", result ) + return result +} + +# If FLAGS includes a Var flag, return the name of the variable it specifies. +# Return the empty string otherwise. +function var_name(flags) +{ + return nth_arg(0, opt_args("Var", flags)) +} + +# Return true if the option described by FLAGS has a globally-visible state. +function global_state_p(flags) +{ + return (var_name(flags) != "" \ + || opt_args("Mask", flags) != "" \ + || opt_args("InverseMask", flags) != "") +} + +# Return true if the option described by FLAGS must have some state +# associated with it. +function needs_state_p(flags) +{ + return flag_set_p("Target", flags) +} + +# If FLAGS describes an option that needs a static state variable, +# return the name of that variable, otherwise return "". NAME is +# the name of the option. +function static_var(name, flags) +{ + if (global_state_p(flags) || !needs_state_p(flags)) + return "" + gsub ("[^A-Za-z0-9]", "_", name) + return "VAR_" name +} + +# Return the type of variable that should be associated with the given flags. +function var_type(flags) +{ + if (!flag_set_p("Joined.*", flags)) + return "int " + else if (flag_set_p("UInteger", flags)) + return "int " + else + return "const char *" +} + +# Given that an option has flags FLAGS, return an initializer for the +# "var_cond" and "var_value" fields of its cl_options[] entry. +function var_set(flags) +{ + s = nth_arg(1, opt_args("Var", flags)) + if (s != "") + return "CLVC_EQUAL, " s + s = opt_args("Mask", flags); + if (s != "") { + vn = var_name(flags); + if (vn) + return "CLVC_BIT_SET, OPTION_MASK_" s + else + return "CLVC_BIT_SET, MASK_" s + } + s = nth_arg(0, opt_args("InverseMask", flags)); + if (s != "") { + vn = var_name(flags); + if (vn) + return "CLVC_BIT_CLEAR, OPTION_MASK_" s + else + return "CLVC_BIT_CLEAR, MASK_" s + } + if (var_type(flags) == "const char *") + return "CLVC_STRING, 0" + return "CLVC_BOOLEAN, 0" +} + +# Given that an option called NAME has flags FLAGS, return an initializer +# for the "flag_var" field of its cl_options[] entry. +function var_ref(name, flags) +{ + name = var_name(flags) static_var(name, flags) + if (name != "") + return "&" name + if (opt_args("Mask", flags) != "") + return "&target_flags" + if (opt_args("InverseMask", flags) != "") + return "&target_flags" + return "0" +} diff --git a/support/cpp/opt-gather.awk b/support/cpp/opt-gather.awk new file mode 100644 index 0000000..084362e --- /dev/null +++ b/support/cpp/opt-gather.awk @@ -0,0 +1,54 @@ +# Copyright (C) 2003,2004 Free Software Foundation, Inc. +# Contributed by Kelley Cook, June 2004. +# Original code from Neil Booth, May 2003. +# +# 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# This Awk script takes a list of *.opt files and combines them into +# a three-field sorted list suitable for input into opt[ch]-gen.awk. +# +# Usage: awk -f opt-gather.awk file1.opt [...] > outputfile + +function sort(ARRAY, ELEMENTS) +{ + for (i = 2; i <= ELEMENTS; ++i) { + for (j = i; ARRAY[j-1] > ARRAY[j]; --j) { + temp = ARRAY[j] + ARRAY[j] = ARRAY[j-1] + ARRAY[j-1] = temp + } + } + return +} + +BEGIN { numrec = 0 } + +# Ignore comments and blank lines +/^[ \t]*(;|$)/ { flag = 0; next } +/^[^ \t]/ { if (flag == 0) { + record[++numrec] = $0 + flag = 1 } + else { + record[numrec] = record[numrec] SUBSEP $0 + } +} + +# Sort it and output it +END { + sort(record,numrec) + + for (i = 1; i <= numrec; i++) { + print record[i] } +} diff --git a/support/cpp/optc-gen.awk b/support/cpp/optc-gen.awk new file mode 100644 index 0000000..aa6bb11 --- /dev/null +++ b/support/cpp/optc-gen.awk @@ -0,0 +1,209 @@ +# Copyright (C) 2003,2004 Free Software Foundation, Inc. +# Contributed by Kelley Cook, June 2004. +# Original code from Neil Booth, May 2003. +# +# 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# This Awk script reads in the option records generated from +# opt-gather.awk, combines the flags of duplicat options and generates a +# C file. +# +# This program uses functions from opt-functions.awk +# +# Usage: awk -f opt-functions.awk -f optc-gen.awk \ +# [-v header_name=header.h] < inputfile > options.c + +BEGIN { + n_opts = 0 + n_langs = 0 + quote = "\042" + comma = "," + FS=SUBSEP + # Default the name of header created from opth-gen.awk to options.h + if (header_name == "") header_name="options.h" +} + +# Collect the text and flags of each option into an array + { + if ($1 == "Language") { + langs[n_langs] = $2 + n_langs++; + } + else { + name = opt_args("Mask", $1) + if (name == "") { + opts[n_opts] = $1 + flags[n_opts] = $2 + help[n_opts] = $3 + n_opts++; + } + } + } + +# Dump that array of options into a C file. +END { +print "/* This file is auto-generated by opts.sh. */" +print "" +n_headers = split(header_name, headers, " ") +for (i = 1; i <= n_headers; i++) + print "#include " quote headers[i] quote +print "#include " quote "opts.h" quote +print "#include " quote "intl.h" quote +print "" +print "#ifdef GCC_DRIVER" +print "int target_flags;" +print "#endif /* GCC_DRIVER */" +print "" + +for (i = 0; i < n_opts; i++) { + name = var_name(flags[i]); + if (name == "") + continue; + + if (flag_set_p("VarExists", flags[i])) { + # Need it for the gcc driver. + if (name in var_seen) + continue; + init = "" + gcc_driver = 1 + } + else { + init = opt_args("Init", flags[i]) + if (init != "") + init = " = " init; + else if (name in var_seen) + continue; + gcc_driver = 0 + } + + if (gcc_driver == 1) + print "#ifdef GCC_DRIVER" + print "/* Set by -" opts[i] "." + print " " help[i] " */" + print var_type(flags[i]) name init ";" + if (gcc_driver == 1) + print "#endif /* GCC_DRIVER */" + print "" + + var_seen[name] = 1; +} + +print "" +print "/* Local state variables. */" +for (i = 0; i < n_opts; i++) { + name = static_var(opts[i], flags[i]); + if (name != "") + print "static " var_type(flags[i]) name ";" +} +print "" + +print "const char * const lang_names[] =\n{" +for (i = 0; i < n_langs; i++) { + macros[i] = "CL_" langs[i] + gsub( "[^A-Za-z0-9_]", "X", macros[i] ) + s = substr(" ", length (macros[i])) + print " " quote langs[i] quote "," + } + +print " 0\n};\n" +print "const unsigned int cl_options_count = N_OPTS;\n" + +print "const struct cl_option cl_options[] =\n{" + +j = 0 +for (i = 0; i < n_opts; i++) { + back_chain[i] = "N_OPTS"; + indices[opts[i]] = j; + # Combine the flags of identical switches. Switches + # appear many times if they are handled by many front + # ends, for example. + while( i + 1 != n_opts && opts[i] == opts[i + 1] ) { + flags[i + 1] = flags[i] " " flags[i + 1]; + i++; + back_chain[i] = "N_OPTS"; + indices[opts[i]] = j; + } + j++; +} + +for (i = 0; i < n_opts; i++) { + # Combine the flags of identical switches. Switches + # appear many times if they are handled by many front + # ends, for example. + while( i + 1 != n_opts && opts[i] == opts[i + 1] ) { + flags[i + 1] = flags[i] " " flags[i + 1]; + i++; + } + + len = length (opts[i]); + enum = "OPT_" opts[i] + if (opts[i] == "finline-limit=") + enum = enum "eq" + gsub ("[^A-Za-z0-9]", "_", enum) + + # If this switch takes joined arguments, back-chain all + # subsequent switches to it for which it is a prefix. If + # a later switch S is a longer prefix of a switch T, T + # will be back-chained to S in a later iteration of this + # for() loop, which is what we want. + if (flag_set_p("Joined.*", flags[i])) { + for (j = i + 1; j < n_opts; j++) { + if (substr (opts[j], 1, len) != opts[i]) + break; + back_chain[j] = enum; + } + } + + s = substr(" ", length (opts[i])) + if (i + 1 == n_opts) + comma = "" + + if (help[i] == "") + hlp = "0" + else + hlp = quote help[i] quote; + + neg = opt_args("Negative", flags[i]); + if (neg != "") + idx = indices[neg] + else { + if (flag_set_p("RejectNegative", flags[i])) + idx = -1; + else { + if (opts[i] ~ "^[Wfm]") + idx = indices[opts[i]]; + else + idx = -1; + } + } + printf(" { %c-%s%c,\n %s,\n %s, %u, %d,\n", + quote, opts[i], quote, hlp, back_chain[i], len, idx) + condition = opt_args("Condition", flags[i]) + cl_flags = switch_flags(flags[i]) + if (condition != "") + printf("#if %s\n" \ + " %s,\n" \ + "#else\n" \ + " CL_DISABLED,\n" \ + "#endif\n", + condition, cl_flags, cl_flags) + else + printf(" %s,\n", cl_flags) + printf(" %s, %s }%s\n", var_ref(opts[i], flags[i]), + var_set(flags[i]), comma) +} + +print "};" +} diff --git a/support/cpp/opth-gen.awk b/support/cpp/opth-gen.awk new file mode 100644 index 0000000..e7ffc1a --- /dev/null +++ b/support/cpp/opth-gen.awk @@ -0,0 +1,194 @@ +# Copyright (C) 2003,2004,2005,2006 Free Software Foundation, Inc. +# Contributed by Kelley Cook, June 2004. +# Original code from Neil Booth, May 2003. +# +# 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# This Awk script reads in the option records generated from +# opt-gather.awk, combines the flags of duplicate options and generates a +# C header file. +# +# This program uses functions from opt-functions.awk +# Usage: awk -f opt-functions.awk -f opth-gen.awk < inputfile > options.h + +BEGIN { + n_opts = 0 + n_langs = 0 + n_extra_masks = 0 + quote = "\042" + comma = "," + FS=SUBSEP +} + +# Collect the text and flags of each option into an array + { + if ($1 == "Language") { + langs[n_langs] = $2 + n_langs++; + } + else { + name = opt_args("Mask", $1) + if (name == "") { + opts[n_opts] = $1 + flags[n_opts] = $2 + help[n_opts] = $3 + n_opts++; + } + else { + extra_masks[n_extra_masks++] = name + } + } + } + +# Dump out an enumeration into a .h file. +# Combine the flags of duplicate options. +END { +print "/* This file is auto-generated by opts.sh. */" +print "" +print "#ifndef OPTIONS_H" +print "#define OPTIONS_H" +print "" +print "extern int target_flags;" +print "" + +for (i = 0; i < n_opts; i++) { + name = var_name(flags[i]); + if (name == "") + continue; + + print "extern " var_type(flags[i]) name ";" +} +print "" + +for (i = 0; i < n_opts; i++) { + name = opt_args("Mask", flags[i]) + vname = var_name(flags[i]) + mask = "MASK_" + if (vname != "") { + mask = "OPTION_MASK_" + } + if (name != "" && !flag_set_p("MaskExists", flags[i])) + print "#define " mask name " (1 << " masknum[vname]++ ")" +} +for (i = 0; i < n_extra_masks; i++) { + print "#define MASK_" extra_masks[i] " (1 << " masknum[""]++ ")" +} + +for (var in masknum) { + if (masknum[var] > 31) { + if (var == "") + print "#error too many target masks" + else + print "#error too many masks for " var + } +} +print "" + +for (i = 0; i < n_opts; i++) { + name = opt_args("Mask", flags[i]) + vname = var_name(flags[i]) + macro = "OPTION_" + mask = "OPTION_MASK_" + if (vname == "") { + vname = "target_flags" + macro = "TARGET_" + mask = "MASK_" + } + if (name != "" && !flag_set_p("MaskExists", flags[i])) + print "#define " macro name \ + " ((" vname " & " mask name ") != 0)" +} +for (i = 0; i < n_extra_masks; i++) { + print "#define TARGET_" extra_masks[i] \ + " ((target_flags & MASK_" extra_masks[i] ") != 0)" +} +print "" + +for (i = 0; i < n_opts; i++) { + opt = opt_args("InverseMask", flags[i]) + if (opt ~ ",") { + vname = var_name(flags[i]) + macro = "OPTION_" + mask = "OPTION_MASK_" + if (vname == "") { + vname = "target_flags" + macro = "TARGET_" + mask = "MASK_" + } + print "#define " macro nth_arg(1, opt) \ + " ((" vname " & " mask nth_arg(0, opt) ") == 0)" + } +} +print "" + +for (i = 0; i < n_langs; i++) { + macros[i] = "CL_" langs[i] + gsub( "[^A-Za-z0-9_]", "X", macros[i] ) + s = substr(" ", length (macros[i])) + print "#define " macros[i] s " (1 << " i ")" + } + +print "" +print "enum opt_code" +print "{" + +for (i = 0; i < n_opts; i++) + back_chain[i] = "N_OPTS"; + +for (i = 0; i < n_opts; i++) { + # Combine the flags of identical switches. Switches + # appear many times if they are handled by many front + # ends, for example. + while( i + 1 != n_opts && opts[i] == opts[i + 1] ) { + flags[i + 1] = flags[i] " " flags[i + 1]; + i++; + } + + len = length (opts[i]); + enum = "OPT_" opts[i] + if (opts[i] == "finline-limit=") + enum = enum "eq" + gsub ("[^A-Za-z0-9]", "_", enum) + + # If this switch takes joined arguments, back-chain all + # subsequent switches to it for which it is a prefix. If + # a later switch S is a longer prefix of a switch T, T + # will be back-chained to S in a later iteration of this + # for() loop, which is what we want. + if (flag_set_p("Joined.*", flags[i])) { + for (j = i + 1; j < n_opts; j++) { + if (substr (opts[j], 1, len) != opts[i]) + break; + back_chain[j] = enum; + } + } + + s = substr(" ", length (opts[i])) + if (i + 1 == n_opts) + comma = "" + + if (help[i] == "") + hlp = "0" + else + hlp = "N_(\"" help[i] "\")"; + + print " " enum "," s "/* -" opts[i] " */" +} + +print " N_OPTS" +print "};" +print "" +print "#endif /* OPTIONS_H */" +} diff --git a/support/cpp/opts-common.c b/support/cpp/opts-common.c new file mode 100644 index 0000000..f442c56 --- /dev/null +++ b/support/cpp/opts-common.c @@ -0,0 +1,235 @@ +/* Command line option handling. + Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc. + +This file is part of GCC. + +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 3, 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 COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "intl.h" +#include "opts.h" + +/* Perform a binary search to find which option the command-line INPUT + matches. Returns its index in the option array, and N_OPTS + (cl_options_count) on failure. + + This routine is quite subtle. A normal binary search is not good + enough because some options can be suffixed with an argument, and + multiple sub-matches can occur, e.g. input of "-pedantic" matching + the initial substring of "-pedantic-errors". + + A more complicated example is -gstabs. It should match "-g" with + an argument of "stabs". Suppose, however, that the number and list + of switches are such that the binary search tests "-gen-decls" + before having tested "-g". This doesn't match, and as "-gen-decls" + is less than "-gstabs", it will become the lower bound of the + binary search range, and "-g" will never be seen. To resolve this + issue, 'optc-gen.awk' makes "-gen-decls" point, via the back_chain member, + to "-g" so that failed searches that end between "-gen-decls" and + the lexicographically subsequent switch know to go back and see if + "-g" causes a match (which it does in this example). + + This search is done in such a way that the longest match for the + front end in question wins. If there is no match for the current + front end, the longest match for a different front end is returned + (or N_OPTS if none) and the caller emits an error message. */ +size_t +find_opt (const char *input, int lang_mask) +{ + size_t mn, mx, md, opt_len; + size_t match_wrong_lang; + int comp; + + mn = 0; + mx = cl_options_count; + + /* Find mn such this lexicographical inequality holds: + cl_options[mn] <= input < cl_options[mn + 1]. */ + while (mx - mn > 1) + { + md = (mn + mx) / 2; + opt_len = cl_options[md].opt_len; + comp = strncmp (input, cl_options[md].opt_text + 1, opt_len); + + if (comp < 0) + mx = md; + else + mn = md; + } + + /* This is the switch that is the best match but for a different + front end, or cl_options_count if there is no match at all. */ + match_wrong_lang = cl_options_count; + + /* Backtrace the chain of possible matches, returning the longest + one, if any, that fits best. With current GCC switches, this + loop executes at most twice. */ + do + { + const struct cl_option *opt = &cl_options[mn]; + + /* Is the input either an exact match or a prefix that takes a + joined argument? */ + if (!strncmp (input, opt->opt_text + 1, opt->opt_len) + && (input[opt->opt_len] == '\0' || (opt->flags & CL_JOINED))) + { + /* If language is OK, return it. */ + if (opt->flags & lang_mask) + return mn; + + /* If we haven't remembered a prior match, remember this + one. Any prior match is necessarily better. */ + if (match_wrong_lang == cl_options_count) + match_wrong_lang = mn; + } + + /* Try the next possibility. This is cl_options_count if there + are no more. */ + mn = opt->back_chain; + } + while (mn != cl_options_count); + + /* Return the best wrong match, or cl_options_count if none. */ + return match_wrong_lang; +} + +/* Return true if NEXT_OPT_IDX cancels OPT_IDX. Return false if the + next one is the same as ORIG_NEXT_OPT_IDX. */ + +static bool +cancel_option (int opt_idx, int next_opt_idx, int orig_next_opt_idx) +{ + /* An option can be canceled by the same option or an option with + Negative. */ + if (cl_options [next_opt_idx].neg_index == opt_idx) + return true; + + if (cl_options [next_opt_idx].neg_index != orig_next_opt_idx) + return cancel_option (opt_idx, cl_options [next_opt_idx].neg_index, + orig_next_opt_idx); + + return false; +} + +/* Filter out options canceled by the ones after them. */ + +void +prune_options (int *argcp, char ***argvp) +{ + int argc = *argcp; + int *options = XNEWVEC (int, argc); + char **argv = XNEWVEC (char *, argc); + int i, arg_count, need_prune = 0; + const struct cl_option *option; + size_t opt_index; + + /* Scan all arguments. */ + for (i = 1; i < argc; i++) + { + int value = 1; + const char *opt = (*argvp) [i]; + + opt_index = find_opt (opt + 1, -1); + if (opt_index == cl_options_count + && (opt[1] == 'W' || opt[1] == 'f' || opt[1] == 'm') + && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-') + { + char *dup; + + /* Drop the "no-" from negative switches. */ + size_t len = strlen (opt) - 3; + + dup = XNEWVEC (char, len + 1); + dup[0] = '-'; + dup[1] = opt[1]; + memcpy (dup + 2, opt + 5, len - 2 + 1); + opt = dup; + value = 0; + opt_index = find_opt (opt + 1, -1); + free (dup); + } + + if (opt_index == cl_options_count) + { +cont: + options [i] = 0; + continue; + } + + option = &cl_options[opt_index]; + if (option->neg_index < 0) + goto cont; + + /* Skip joined switches. */ + if ((option->flags & CL_JOINED)) + goto cont; + + /* Reject negative form of switches that don't take negatives as + unrecognized. */ + if (!value && (option->flags & CL_REJECT_NEGATIVE)) + goto cont; + + options [i] = (int) opt_index; + need_prune |= options [i]; + } + + if (!need_prune) + goto done; + + /* Remove arguments which are negated by others after them. */ + argv [0] = (*argvp) [0]; + arg_count = 1; + for (i = 1; i < argc; i++) + { + int j, opt_idx; + + opt_idx = options [i]; + if (opt_idx) + { + int next_opt_idx; + for (j = i + 1; j < argc; j++) + { + next_opt_idx = options [j]; + if (next_opt_idx + && cancel_option (opt_idx, next_opt_idx, + next_opt_idx)) + break; + } + } + else + goto keep; + + if (j == argc) + { +keep: + argv [arg_count] = (*argvp) [i]; + arg_count++; + } + } + + if (arg_count != argc) + { + *argcp = arg_count; + *argvp = argv; + } + else + { +done: + free (argv); + } + + free (options); +} diff --git a/support/cpp/opts.c b/support/cpp/opts.c new file mode 100644 index 0000000..4f7e439 --- /dev/null +++ b/support/cpp/opts.c @@ -0,0 +1,629 @@ +/* Command line option handling. + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 + Free Software Foundation, Inc. + Contributed by Neil Booth. + +This file is part of GCC. + +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, 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301, USA. */ + +#include "config.h" +#include "system.h" +#include "intl.h" +#include "opts.h" +#include "options.h" +#include "version.h" + +/* True if we should exit after parsing options. */ +bool exit_after_options; + +/* Treat warnings as errors. -Werror. */ +bool warnings_are_errors; + +/* Don't suppress warnings from system headers. -Wsystem-headers. */ +bool warn_system_headers; + +/* Columns of --help display. */ +static unsigned int columns = 80; + +/* What to print when a switch has no documentation. */ +static const char undocumented_msg[] = N_("This switch lacks documentation"); + +/* Input file names. */ +const char **in_fnames; +unsigned num_in_fnames; + +static int common_handle_option (size_t scode, const char *arg, int value); +static unsigned int handle_option (const char **argv, unsigned int lang_mask); +static char *write_langs (unsigned int lang_mask); +static void complain_wrong_lang (const char *, const struct cl_option *, + unsigned int lang_mask); +static void handle_options (unsigned int, const char **, unsigned int); +static void wrap_help (const char *help, const char *item, unsigned int); +static void print_help (void); +static void print_filtered_help (unsigned int); +static unsigned int print_switch (const char *text, unsigned int indent); + +/* If ARG is a non-negative integer made up solely of digits, return its + value, otherwise return -1. */ +static int +integral_argument (const char *arg) +{ + const char *p = arg; + + while (*p && ISDIGIT (*p)) + p++; + + if (*p == '\0') + return atoi (arg); + + return -1; +} + +/* Return a malloced slash-separated list of languages in MASK. */ +static char * +write_langs (unsigned int mask) +{ + unsigned int n = 0, len = 0; + const char *lang_name; + char *result; + + for (n = 0; (lang_name = lang_names[n]) != 0; n++) + if (mask & (1U << n)) + len += strlen (lang_name) + 1; + + result = XNEWVEC (char, len); + len = 0; + for (n = 0; (lang_name = lang_names[n]) != 0; n++) + if (mask & (1U << n)) + { + if (len) + result[len++] = '/'; + strcpy (result + len, lang_name); + len += strlen (lang_name); + } + + result[len] = 0; + + return result; +} + +/* Complain that switch OPT_INDEX does not apply to this front end. */ +static void +complain_wrong_lang (const char *text, const struct cl_option *option, + unsigned int lang_mask) +{ + char *ok_langs, *bad_lang; + + ok_langs = write_langs (option->flags); + bad_lang = write_langs (lang_mask); + + /* Eventually this should become a hard error IMO. */ + warning (0, "command line option \"%s\" is valid for %s but not for %s", + text, ok_langs, bad_lang); + + free (ok_langs); + free (bad_lang); +} + +/* Handle the switch beginning at ARGV for the language indicated by + LANG_MASK. Returns the number of switches consumed. */ +static unsigned int +handle_option (const char **argv, unsigned int lang_mask) +{ + size_t opt_index; + const char *opt, *arg = 0; + char *dup = 0; + int value = 1; + unsigned int result = 0; + const struct cl_option *option; + + opt = argv[0]; + + opt_index = find_opt (opt + 1, lang_mask | CL_COMMON | CL_TARGET); + if (opt_index == cl_options_count + && (opt[1] == 'W' || opt[1] == 'f' || opt[1] == 'm') + && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-') + { + /* Drop the "no-" from negative switches. */ + size_t len = strlen (opt) - 3; + + dup = XNEWVEC (char, len + 1); + dup[0] = '-'; + dup[1] = opt[1]; + memcpy (dup + 2, opt + 5, len - 2 + 1); + opt = dup; + value = 0; + opt_index = find_opt (opt + 1, lang_mask | CL_COMMON | CL_TARGET); + } + + if (opt_index == cl_options_count) + goto done; + + option = &cl_options[opt_index]; + + /* Reject negative form of switches that don't take negatives as + unrecognized. */ + if (!value && (option->flags & CL_REJECT_NEGATIVE)) + goto done; + + /* We've recognized this switch. */ + result = 1; + + /* Check to see if the option is disabled for this configuration. */ + if (option->flags & CL_DISABLED) + { + error ("command line option \"%s\"" + " is not supported by this configuration", opt); + goto done; + } + + /* Sort out any argument the switch takes. */ + if (option->flags & CL_JOINED) + { + /* Have arg point to the original switch. This is because + some code, such as disable_builtin_function, expects its + argument to be persistent until the program exits. */ + arg = argv[0] + cl_options[opt_index].opt_len + 1; + if (!value) + arg += strlen ("no-"); + + if (*arg == '\0' && !(option->flags & CL_MISSING_OK)) + { + if (option->flags & CL_SEPARATE) + { + arg = argv[1]; + result = 2; + } + else + /* Missing argument. */ + arg = NULL; + } + } + else if (option->flags & CL_SEPARATE) + { + arg = argv[1]; + result = 2; + } + + /* Now we've swallowed any potential argument, complain if this + is a switch for a different front end. */ + if (!(option->flags & (lang_mask | CL_COMMON | CL_TARGET))) + { + complain_wrong_lang (argv[0], option, lang_mask); + goto done; + } + + if (arg == NULL && (option->flags & (CL_JOINED | CL_SEPARATE))) + { + if (!lang_hooks.missing_argument (opt, opt_index)) + error ("missing argument to \"%s\"", opt); + goto done; + } + + /* If the switch takes an integer, convert it. */ + if (arg && (option->flags & CL_UINTEGER)) + { + value = integral_argument (arg); + if (value == -1) + { + error ("argument to \"%s\" should be a non-negative integer", + option->opt_text); + goto done; + } + } + + if (option->flag_var) + switch (option->var_type) + { + case CLVC_BOOLEAN: + *(int *) option->flag_var = value; + break; + + case CLVC_EQUAL: + *(int *) option->flag_var = (value + ? option->var_value + : !option->var_value); + break; + + case CLVC_BIT_CLEAR: + case CLVC_BIT_SET: + if ((value != 0) == (option->var_type == CLVC_BIT_SET)) + *(int *) option->flag_var |= option->var_value; + else + *(int *) option->flag_var &= ~option->var_value; + ////if (option->flag_var == &target_flags) + //// target_flags_explicit |= option->var_value; + break; + + case CLVC_STRING: + *(const char **) option->flag_var = arg; + break; + } + + if (option->flags & lang_mask) + if (lang_hooks.handle_option (opt_index, arg, value) == 0) + result = 0; + + if (result && (option->flags & CL_COMMON)) + if (common_handle_option (opt_index, arg, value) == 0) + result = 0; + + ////if (result && (option->flags & CL_TARGET)) + //// if (!targetm.handle_option (opt_index, arg, value)) + //// result = 0; + + done: + if (dup) + free (dup); + return result; +} + +/* Handle FILENAME from the command line. */ +static void +add_input_filename (const char *filename) +{ + num_in_fnames++; + in_fnames = xrealloc (in_fnames, num_in_fnames * sizeof (in_fnames[0])); + in_fnames[num_in_fnames - 1] = filename; +} + +/* Decode and handle the vector of command line options. LANG_MASK + contains has a single bit set representing the current + language. */ +static void +handle_options (unsigned int argc, const char **argv, unsigned int lang_mask) +{ + unsigned int n, i; + + for (i = 1; i < argc; i += n) + { + const char *opt = argv[i]; + + /* Interpret "-" or a non-switch as a file name. */ + if (opt[0] != '-' || opt[1] == '\0') + { + if (main_input_filename == NULL) + main_input_filename = opt; + add_input_filename (opt); + n = 1; + continue; + } + + n = handle_option (argv + i, lang_mask); + + if (!n) + { + n = 1; + error ("unrecognized command line option \"%s\"", opt); + } + } +} + +/* Parse command line options and set default flag values. Do minimal + options processing. */ +void +decode_options (unsigned int argc, const char **argv) +{ + unsigned int lang_mask; + + /* Perform language-specific options initialization. */ + lang_mask = lang_hooks.init_options (argc, argv); + + /* Scan to see what optimization level has been specified. That will + determine the default value of many flags. */ + + handle_options (argc, argv, lang_mask); +} + +/* Handle target- and language-independent options. Return zero to + generate an "unknown option" message. Only options that need + extra handling need to be listed here; if you simply want + VALUE assigned to a variable, it happens automatically. */ + +static int +common_handle_option (size_t scode, const char *arg, + int value ATTRIBUTE_UNUSED) +{ + enum opt_code code = (enum opt_code) scode; + + switch (code) + { + default: + abort (); + + case OPT__help: + print_help (); + exit_after_options = true; + break; + + case OPT__version: + print_version (stderr, ""); + exit_after_options = true; + break; + + case OPT_Werror: + warnings_are_errors = value; + break; + + case OPT_Wsystem_headers: + warn_system_headers = value; + break; + + case OPT_d: + decode_d_option (arg); + break; + + case OPT_pedantic_errors: + flag_pedantic_errors = 1; + break; + + case OPT_w: + inhibit_warnings = true; + break; + } + + return 1; +} + +/* Output --help text. */ +static void +print_help (void) +{ + size_t i; + const char *p; + + GET_ENVIRONMENT (p, "COLUMNS"); + if (p) + { + int value = atoi (p); + if (value > 0) + columns = value; + } + + puts (_("The following options are language-independent:\n")); + + print_filtered_help (CL_COMMON); + + for (i = 0; lang_names[i]; i++) + { + printf (_("The %s front end recognizes the following options:\n\n"), + lang_names[i]); + print_filtered_help (1U << i); + } + + printf (_("\nFor bug reporting instructions, please see:\n")); + printf ("%s.\n", bug_report_url); +} + +/* Print help for a specific front-end, etc. */ +static void +print_filtered_help (unsigned int flag) +{ + unsigned int i, len, filter, indent = 0; + bool duplicates = false; + const char *help, *opt, *tab; + static char *printed; + + if (flag == CL_COMMON || flag == CL_TARGET) + { + filter = flag; + if (!printed) + printed = xmalloc (cl_options_count); + memset (printed, 0, cl_options_count); + } + else + { + /* Don't print COMMON options twice. */ + filter = flag | CL_COMMON; + + for (i = 0; i < cl_options_count; i++) + { + if ((cl_options[i].flags & filter) != flag) + continue; + + /* Skip help for internal switches. */ + if (cl_options[i].flags & CL_UNDOCUMENTED) + continue; + + /* Skip switches that have already been printed, mark them to be + listed later. */ + if (printed[i]) + { + duplicates = true; + indent = print_switch (cl_options[i].opt_text, indent); + } + } + + if (duplicates) + { + putchar ('\n'); + putchar ('\n'); + } + } + + for (i = 0; i < cl_options_count; i++) + { + if ((cl_options[i].flags & filter) != flag) + continue; + + /* Skip help for internal switches. */ + if (cl_options[i].flags & CL_UNDOCUMENTED) + continue; + + /* Skip switches that have already been printed. */ + if (printed[i]) + continue; + + printed[i] = true; + + help = cl_options[i].help; + if (!help) + help = undocumented_msg; + + /* Get the translation. */ + help = _(help); + + tab = strchr (help, '\t'); + if (tab) + { + len = tab - help; + opt = help; + help = tab + 1; + } + else + { + opt = cl_options[i].opt_text; + len = strlen (opt); + } + + wrap_help (help, opt, len); + } + + putchar ('\n'); +} + +/* Output ITEM, of length ITEM_WIDTH, in the left column, followed by + word-wrapped HELP in a second column. */ +static unsigned int +print_switch (const char *text, unsigned int indent) +{ + unsigned int len = strlen (text) + 1; /* trailing comma */ + + if (indent) + { + putchar (','); + if (indent + len > columns) + { + putchar ('\n'); + putchar (' '); + indent = 1; + } + } + else + putchar (' '); + + putchar (' '); + fputs (text, stdout); + + return indent + len + 1; +} + +/* Output ITEM, of length ITEM_WIDTH, in the left column, followed by + word-wrapped HELP in a second column. */ +static void +wrap_help (const char *help, const char *item, unsigned int item_width) +{ + unsigned int col_width = 27; + unsigned int remaining, room, len; + + remaining = strlen (help); + + do + { + room = columns - 3 - MAX (col_width, item_width); + if (room > columns) + room = 0; + len = remaining; + + if (room < len) + { + unsigned int i; + + for (i = 0; help[i]; i++) + { + if (i >= room && len != remaining) + break; + if (help[i] == ' ') + len = i; + else if ((help[i] == '-' || help[i] == '/') + && help[i + 1] != ' ' + && i > 0 && ISALPHA (help[i - 1])) + len = i + 1; + } + } + + printf( " %-*.*s %.*s\n", col_width, item_width, item, len, help); + item_width = 0; + while (help[len] == ' ') + len++; + help += len; + remaining -= len; + } + while (remaining); +} + +/* Return 1 if OPTION is enabled, 0 if it is disabled, or -1 if it isn't + a simple on-off switch. */ + +int +option_enabled (int opt_idx) +{ + const struct cl_option *option = &(cl_options[opt_idx]); + if (option->flag_var) + switch (option->var_type) + { + case CLVC_BOOLEAN: + return *(int *) option->flag_var != 0; + + case CLVC_EQUAL: + return *(int *) option->flag_var == option->var_value; + + case CLVC_BIT_CLEAR: + return (*(int *) option->flag_var & option->var_value) == 0; + + case CLVC_BIT_SET: + return (*(int *) option->flag_var & option->var_value) != 0; + + case CLVC_STRING: + break; + } + return -1; +} + +/* Fill STATE with the current state of option OPTION. Return true if + there is some state to store. */ + +bool +get_option_state (int option, struct cl_option_state *state) +{ + if (cl_options[option].flag_var == 0) + return false; + + switch (cl_options[option].var_type) + { + case CLVC_BOOLEAN: + case CLVC_EQUAL: + state->data = cl_options[option].flag_var; + state->size = sizeof (int); + break; + + case CLVC_BIT_CLEAR: + case CLVC_BIT_SET: + state->ch = option_enabled (option); + state->data = &state->ch; + state->size = 1; + break; + + case CLVC_STRING: + state->data = *(const char **) cl_options[option].flag_var; + if (state->data == 0) + state->data = ""; + state->size = strlen (state->data) + 1; + break; + } + return true; +} diff --git a/support/cpp/opts.h b/support/cpp/opts.h new file mode 100644 index 0000000..7211437 --- /dev/null +++ b/support/cpp/opts.h @@ -0,0 +1,110 @@ +/* Command line option handling. + Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008 + Free Software Foundation, Inc. + +This file is part of GCC. + +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 3, 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 COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#ifndef GCC_OPTS_H +#define GCC_OPTS_H + +/* Specifies how a switch's VAR_VALUE relates to its FLAG_VAR. */ +enum cl_var_type { + /* The switch is enabled when FLAG_VAR is nonzero. */ + CLVC_BOOLEAN, + + /* The switch is enabled when FLAG_VAR == VAR_VALUE. */ + CLVC_EQUAL, + + /* The switch is enabled when VAR_VALUE is not set in FLAG_VAR. */ + CLVC_BIT_CLEAR, + + /* The switch is enabled when VAR_VALUE is set in FLAG_VAR. */ + CLVC_BIT_SET, + + /* The switch takes a string argument and FLAG_VAR points to that + argument. */ + CLVC_STRING +}; + +struct cl_option +{ + const char *opt_text; + const char *help; + unsigned short back_chain; + unsigned char opt_len; + int neg_index; + unsigned int flags; + void *flag_var; + enum cl_var_type var_type; + int var_value; +}; + +/* Records that the state of an option consists of SIZE bytes starting + at DATA. DATA might point to CH in some cases. */ +struct cl_option_state { + const void *data; + size_t size; + char ch; +}; + +extern const struct cl_option cl_options[]; +extern const unsigned int cl_options_count; +extern const char *const lang_names[]; +extern const unsigned int cl_lang_count; + +#define CL_PARAMS (1 << 17) /* Fake entry. Used to display --param info with --help. */ +#define CL_WARNING (1 << 18) /* Enables an (optional) warning message. */ +#define CL_OPTIMIZATION (1 << 19) /* Enables an (optional) optimization. */ +#define CL_TARGET (1 << 20) /* Target-specific option. */ +#define CL_COMMON (1 << 21) /* Language-independent. */ + +#define CL_MIN_OPTION_CLASS CL_PARAMS +#define CL_MAX_OPTION_CLASS CL_COMMON + +/* From here on the bits describe attributes of the options. + Before this point the bits have described the class of the option. + This distinction is important because --help will not list options + which only have these higher bits set. */ + +#define CL_SAVE (1 << 22) /* Target-specific option for attribute. */ +#define CL_DISABLED (1 << 23) /* Disabled in this configuration. */ +#define CL_REPORT (1 << 24) /* Report argument with -fverbose-asm */ +#define CL_JOINED (1 << 25) /* If takes joined argument. */ +#define CL_SEPARATE (1 << 26) /* If takes a separate argument. */ +#define CL_REJECT_NEGATIVE (1 << 27) /* Reject no- form. */ +#define CL_MISSING_OK (1 << 28) /* Missing argument OK (joined). */ +#define CL_UINTEGER (1 << 29) /* Argument is an integer >=0. */ +#define CL_UNDOCUMENTED (1 << 30) /* Do not output with --help. */ + +/* Input file names. */ + +extern const char **in_fnames; + +/* The count of input filenames. */ + +extern unsigned num_in_fnames; + +size_t find_opt (const char *input, int lang_mask); +extern void prune_options (int *argcp, char ***argvp); +extern void decode_options (unsigned int argc, const char **argv); +extern int option_enabled (int opt_idx); +extern bool get_option_state (int, struct cl_option_state *); + +extern void enable_warning_as_error (const char *arg, int value, + unsigned int lang_mask); +extern void print_ignored_options (void); +#endif diff --git a/support/cpp/output.h b/support/cpp/output.h new file mode 100644 index 0000000..0ac1318 --- /dev/null +++ b/support/cpp/output.h @@ -0,0 +1,649 @@ +/* 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, 2001, 2002, + 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + +This file is part of GCC. + +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 3, 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 COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#ifndef GCC_OUTPUT_H +#define GCC_OUTPUT_H + +/* Initialize data in final at the beginning of a compilation. */ +extern void init_final (const char *); + +/* Enable APP processing of subsequent output. + Used before the output from an `asm' statement. */ +extern void app_enable (void); + +/* Disable APP processing of subsequent output. + Called from varasm.c before most kinds of output. */ +extern void app_disable (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 (void); + +/* Indicate that branch shortening hasn't yet been done. */ +extern void init_insn_lengths (void); + +/* 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 (rtx); + +/* Obtain the current length of an insn. If branch shortening has been done, + get its actual length. Otherwise, get its minimum length. */ +extern int get_attr_min_length (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 (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 (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 (void); + +/* Output assembler code for some insns: all or part of a function. */ +extern void final (rtx, FILE *, 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 (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 (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 (const char *, ...) ATTRIBUTE_PRINTF_1; + +/* Output a string of assembler code, substituting insn operands. + Defined in final.c. */ +extern void output_asm_insn (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 (rtx); + +/* Find the alignment associated with a CODE_LABEL. + Defined in final.c. */ +extern int label_to_alignment (rtx); + +/* Output a LABEL_REF, or a bare CODE_LABEL, as an assembler symbol. */ +extern void output_asm_label (rtx); + +/* Marks SYMBOL_REFs in x as referenced through use of assemble_external. */ +extern void mark_symbol_refs_as_used (rtx); + +/* Print a memory reference operand for address X + using machine-dependent assembler syntax. */ +extern void output_address (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 (FILE *, rtx); + +/* Output a string of assembler code, substituting numbers, strings + and fixed syntactic prefixes. */ +#if GCC_VERSION >= 3004 +#define ATTRIBUTE_ASM_FPRINTF(m, n) __attribute__ ((__format__ (__asm_fprintf__, m, n))) ATTRIBUTE_NONNULL(m) +/* This is a magic identifier which allows GCC to figure out the type + of HOST_WIDE_INT for %wd specifier checks. You must issue this + typedef before using the __asm_fprintf__ format attribute. */ +typedef HOST_WIDE_INT __gcc_host_wide_int__; +#else +#define ATTRIBUTE_ASM_FPRINTF(m, n) ATTRIBUTE_NONNULL(m) +#endif + +extern void asm_fprintf (FILE *file, const char *p, ...) + ATTRIBUTE_ASM_FPRINTF(2, 3); + +/* Split up a CONST_DOUBLE or integer constant rtx into two rtx's for single + words. */ +extern void split_double (rtx, rtx *, rtx *); + +/* Return nonzero if this function has no function calls. */ +extern int leaf_function_p (void); + +/* Return 1 if branch is a forward branch. + Uses insn_shuid array, so it works only in the final pass. May be used by + output templates to add branch prediction hints, for example. */ +extern int final_forward_branch_p (rtx); + +/* Return 1 if this function uses only the registers that can be + safely renumbered. */ +extern int only_leaf_regs_used (void); + +/* Scan IN_RTX and its subexpressions, and renumber all regs into those + available in leaf functions. */ +extern void leaf_renumber_regs_insn (rtx); + +/* Locate the proper template for the given insn-code. */ +extern const char *get_insn_template (int, rtx); + +/* Functions in varasm.c. */ + +/* Declare DECL to be a weak symbol. */ +extern void declare_weak (tree); +/* Merge weak status. */ +extern void merge_weak (tree, tree); + +/* Emit any pending weak declarations. */ +extern void weak_finish (void); + +/* Emit any pending emutls declarations and initializations. */ +extern void emutls_finish (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 (const char *); + +extern void assemble_alias (tree, tree); + +extern void default_assemble_visibility (tree, int); + +/* Output a string of literal assembler code + for an `asm' keyword used between functions. */ +extern void assemble_asm (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 (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 (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 (tree, int, int, int); + +/* Compute the alignment of variable specified by DECL. + DONT_OUTPUT_DATA is from assemble_variable. */ +extern void align_variable (tree decl, bool dont_output_data); + +/* Queue for outputting 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 (tree); + +/* Assemble code to leave SIZE bytes of zeros. */ +extern void assemble_zeros (unsigned HOST_WIDE_INT); + +/* Assemble an alignment pseudo op for an ALIGN-bit boundary. */ +extern void assemble_align (int); + +/* Assemble a string constant with the specified C string as contents. */ +extern void assemble_string (const char *, int); + +/* Similar, for calling a library function FUN. */ +extern void assemble_external_libcall (rtx); + +/* Assemble a label named NAME. */ +extern void assemble_label (const char *); + +/* Output to FILE (an assembly file) a reference to NAME. If NAME + starts with a *, the rest of NAME is output verbatim. Otherwise + NAME is transformed in a target-specific way (usually by the + addition of an underscore). */ +extern void assemble_name_raw (FILE *, const char *); + +/* Like assemble_name_raw, but should be used when NAME might refer to + an entity that is also represented as a tree (like a function or + variable). If NAME does refer to such an entity, that entity will + be marked as referenced. */ +extern void assemble_name (FILE *, const char *); + +/* Return the assembler directive for creating a given kind of integer + object. SIZE is the number of bytes in the object and ALIGNED_P + indicates whether it is known to be aligned. Return NULL if the + assembly dialect has no such directive. + + The returned string should be printed at the start of a new line and + be followed immediately by the object's initial value. */ +extern const char *integer_asm_op (int, int); + +/* Use directive OP to assemble an integer object X. Print OP at the + start of the line, followed immediately by the value of X. */ +extern void assemble_integer_with_op (const char *, rtx); + +/* The default implementation of the asm_out.integer target hook. */ +extern bool default_assemble_integer (rtx, unsigned int, int); + +/* Assemble the integer constant X into an object of SIZE bytes. ALIGN is + the alignment of the integer in bits. Return 1 if we were able to output + the constant, otherwise 0. If FORCE is nonzero the constant must + be outputable. */ +extern bool assemble_integer (rtx, unsigned, unsigned, int); + +/* An interface to assemble_integer for the common case in which a value is + fully aligned and must be printed. VALUE is the value of the integer + object and SIZE is the number of bytes it contains. */ +#define assemble_aligned_integer(SIZE, VALUE) \ + assemble_integer (VALUE, SIZE, (SIZE) * BITS_PER_UNIT, 1) + +#ifdef REAL_VALUE_TYPE_SIZE +/* Assemble the floating-point constant D into an object of size MODE. */ +extern void assemble_real (REAL_VALUE_TYPE, enum machine_mode, unsigned); +#endif + +/* Write the address of the entity given by SYMBOL to SEC. */ +extern void assemble_addr_to_section (rtx, section *); + +/* Return the size of the constant pool. */ +extern int get_pool_size (void); + +#ifdef HAVE_peephole +extern rtx peephole (rtx); +#endif + +extern void output_shared_constant_pool (void); + +extern void output_object_blocks (void); + +/* Whether a constructor CTOR is a valid static constant initializer if all + its elements are. This used to be internal to initializer_constant_valid_p + and has been exposed to let other functions like categorize_ctor_elements + evaluate the property while walking a constructor for other purposes. */ + +extern bool constructor_static_from_elts_p (const_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 (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. + + ALIGN is the alignment in bits that may be assumed for the data. */ +extern void output_constant (tree, unsigned HOST_WIDE_INT, unsigned int); + +/* 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; + +/* The line number of the beginning of the current function. Various + md code 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 modify the stack pointer + (ignoring the prologue and epilogue). This is only valid after + pass_stack_ptr_mod 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 *dump_file; +#endif + +/* Nonnull if the insn currently being emitted was a COND_EXEC pattern. */ +extern rtx current_insn_predicate; + +/* Last insn processed by final_scan_insn. */ +extern rtx current_output_insn; + +/* Nonzero while outputting an `asm' with operands. + This means that inconsistencies are the user's fault, so don't die. + The precise value is the insn being output, to pass to error_for_asm. */ +extern rtx this_is_asm_operands; + +/* Carry information from ASM_DECLARE_OBJECT_NAME + to ASM_FINISH_DECLARE_OBJECT. */ +extern int size_directive_output; +extern tree last_assemble_variable_decl; + +extern bool first_function_block_is_cold; + +/* Decide whether DECL needs to be in a writable section. + RELOC is the same as for SELECT_SECTION. */ +extern bool decl_readonly_section (const_tree, int); + +/* This can be used to compute RELOC for the function above, when + given a constant expression. */ +extern int compute_reloc_for_constant (tree); + +/* User label prefix in effect for this compilation. */ +extern const char *user_label_prefix; + +/* Default target function prologue and epilogue assembler output. */ +extern void default_function_pro_epilogue (FILE *, HOST_WIDE_INT); + +/* Default target hook that outputs nothing to a stream. */ +extern void no_asm_to_stream (FILE *); + +/* Flags controlling properties of a section. */ +#define SECTION_ENTSIZE 0x000ff /* entity size in section */ +#define SECTION_CODE 0x00100 /* contains code */ +#define SECTION_WRITE 0x00200 /* data is writable */ +#define SECTION_DEBUG 0x00400 /* contains debug data */ +#define SECTION_LINKONCE 0x00800 /* is linkonce */ +#define SECTION_SMALL 0x01000 /* contains "small data" */ +#define SECTION_BSS 0x02000 /* contains zeros only */ +#define SECTION_FORGET 0x04000 /* forget that we've entered the section */ +#define SECTION_MERGE 0x08000 /* contains mergeable data */ +#define SECTION_STRINGS 0x10000 /* contains zero terminated strings without + embedded zeros */ +#define SECTION_OVERRIDE 0x20000 /* allow override of default flags */ +#define SECTION_TLS 0x40000 /* contains thread-local storage */ +#define SECTION_NOTYPE 0x80000 /* don't output @progbits */ +#define SECTION_DECLARED 0x100000 /* section has been used */ +#define SECTION_STYLE_MASK 0x600000 /* bits used for SECTION_STYLE */ +#define SECTION_COMMON 0x800000 /* contains common data */ +#define SECTION_MACH_DEP 0x1000000 /* subsequent bits reserved for target */ + +/* This SECTION_STYLE is used for unnamed sections that we can switch + to using a special assembler directive. */ +#define SECTION_UNNAMED 0x000000 + +/* This SECTION_STYLE is used for named sections that we can switch + to using a general section directive. */ +#define SECTION_NAMED 0x200000 + +/* This SECTION_STYLE is used for sections that we cannot switch to at + all. The choice of section is implied by the directive that we use + to declare the object. */ +#define SECTION_NOSWITCH 0x400000 + +/* A helper function for default_elf_select_section and + default_elf_unique_section. Categorizes the DECL. */ + +enum section_category +{ + SECCAT_TEXT, + + SECCAT_RODATA, + SECCAT_RODATA_MERGE_STR, + SECCAT_RODATA_MERGE_STR_INIT, + SECCAT_RODATA_MERGE_CONST, + SECCAT_SRODATA, + + SECCAT_DATA, + + /* To optimize loading of shared programs, define following subsections + of data section: + _REL Contains data that has relocations, so they get grouped + together and dynamic linker will visit fewer pages in memory. + _RO Contains data that is otherwise read-only. This is useful + with prelinking as most relocations won't be dynamically + linked and thus stay read only. + _LOCAL Marks data containing relocations only to local objects. + These relocations will get fully resolved by prelinking. */ + SECCAT_DATA_REL, + SECCAT_DATA_REL_LOCAL, + SECCAT_DATA_REL_RO, + SECCAT_DATA_REL_RO_LOCAL, + + SECCAT_SDATA, + SECCAT_TDATA, + + SECCAT_BSS, + SECCAT_SBSS, + SECCAT_TBSS, + + SECCAT_EMUTLS_VAR, + SECCAT_EMUTLS_TMPL +}; + +/* Information that is provided by all instances of the section type. */ +struct section_common GTY(()) { + /* The set of SECTION_* flags that apply to this section. */ + unsigned int flags; +}; + +/* Information about a SECTION_NAMED section. */ +struct named_section GTY(()) { + struct section_common common; + + /* The name of the section. */ + const char *name; + + /* If nonnull, the VAR_DECL or FUNCTION_DECL with which the + section is associated. */ + tree decl; +}; + +/* A callback that writes the assembly code for switching to an unnamed + section. The argument provides callback-specific data. */ +typedef void (*unnamed_section_callback) (const void *); + +/* Information about a SECTION_UNNAMED section. */ +struct unnamed_section GTY(()) { + struct section_common common; + + /* The callback used to switch to the section, and the data that + should be passed to the callback. */ + unnamed_section_callback GTY ((skip)) callback; + const void *GTY ((skip)) data; + + /* The next entry in the chain of unnamed sections. */ + section *next; +}; + +/* A callback that writes the assembly code for a decl in a + SECTION_NOSWITCH section. DECL is the decl that should be assembled + and NAME is the name of its SYMBOL_REF. SIZE is the size of the decl + in bytes and ROUNDED is that size rounded up to the next + BIGGEST_ALIGNMENT / BITS_PER_UNIT boundary. + + Return true if the callback used DECL_ALIGN to set the object's + alignment. A false return value implies that we are relying + on the rounded size to align the decl. */ +typedef bool (*noswitch_section_callback) (tree decl, const char *name, + unsigned HOST_WIDE_INT size, + unsigned HOST_WIDE_INT rounded); + +/* Information about a SECTION_NOSWITCH section. */ +struct noswitch_section GTY(()) { + struct section_common common; + + /* The callback used to assemble decls in this section. */ + noswitch_section_callback GTY ((skip)) callback; +}; + +/* Information about a section, which may be named or unnamed. */ +union section GTY ((desc ("SECTION_STYLE (&(%h))"))) +{ + struct section_common GTY ((skip)) common; + struct named_section GTY ((tag ("SECTION_NAMED"))) named; + struct unnamed_section GTY ((tag ("SECTION_UNNAMED"))) unnamed; + struct noswitch_section GTY ((tag ("SECTION_NOSWITCH"))) noswitch; +}; + +/* Return the style of section SECT. */ +#define SECTION_STYLE(SECT) ((SECT)->common.flags & SECTION_STYLE_MASK) + +struct object_block; + +/* Special well-known sections. */ +extern GTY(()) section *text_section; +extern GTY(()) section *data_section; +extern GTY(()) section *readonly_data_section; +extern GTY(()) section *sdata_section; +extern GTY(()) section *ctors_section; +extern GTY(()) section *dtors_section; +extern GTY(()) section *bss_section; +extern GTY(()) section *sbss_section; +extern GTY(()) section *exception_section; +extern GTY(()) section *eh_frame_section; +extern GTY(()) section *tls_comm_section; +extern GTY(()) section *comm_section; +extern GTY(()) section *lcomm_section; +extern GTY(()) section *bss_noswitch_section; + +extern GTY(()) section *in_section; +extern GTY(()) bool in_cold_section_p; + +extern section *get_unnamed_section (unsigned int, void (*) (const void *), + const void *); +extern section *get_section (const char *, unsigned int, tree); +extern section *get_named_section (tree, const char *, int); +extern void place_block_symbol (rtx); +extern rtx get_section_anchor (struct object_block *, HOST_WIDE_INT, + enum tls_model); +extern section *mergeable_constant_section (enum machine_mode, + unsigned HOST_WIDE_INT, + unsigned int); +extern section *function_section (tree); +extern section *unlikely_text_section (void); +extern section *current_function_section (void); + +/* Return the numbered .ctors.N (if CONSTRUCTOR_P) or .dtors.N (if + not) section for PRIORITY. */ +extern section *get_cdtor_priority_section (int, bool); + +extern bool unlikely_text_section_p (section *); +extern void switch_to_section (section *); +extern void output_section_asm_op (const void *); + +extern unsigned int default_section_type_flags (tree, const char *, int); + +extern bool have_global_bss_p (void); +extern void default_no_named_section (const char *, unsigned int, tree); +extern void default_elf_asm_named_section (const char *, unsigned int, tree); +extern enum section_category categorize_decl_for_section (const_tree, int); +extern void default_coff_asm_named_section (const char *, unsigned int, tree); +extern void default_pe_asm_named_section (const char *, unsigned int, tree); + +extern void default_stabs_asm_out_destructor (rtx, int); +extern void default_named_section_asm_out_destructor (rtx, int); +extern void default_dtor_section_asm_out_destructor (rtx, int); +extern void default_stabs_asm_out_constructor (rtx, int); +extern void default_named_section_asm_out_constructor (rtx, int); +extern void default_ctor_section_asm_out_constructor (rtx, int); + +extern section *default_select_section (tree, int, unsigned HOST_WIDE_INT); +extern section *default_elf_select_section (tree, int, unsigned HOST_WIDE_INT); +extern void default_unique_section (tree, int); +extern section *default_function_rodata_section (tree); +extern section *default_no_function_rodata_section (tree); +extern section *default_select_rtx_section (enum machine_mode, rtx, + unsigned HOST_WIDE_INT); +extern section *default_elf_select_rtx_section (enum machine_mode, rtx, + unsigned HOST_WIDE_INT); +extern void default_encode_section_info (tree, rtx, int); +extern const char *default_strip_name_encoding (const char *); +extern void default_asm_output_anchor (rtx); +extern bool default_use_anchors_for_symbol_p (const_rtx); +extern bool default_binds_local_p (const_tree); +extern bool default_binds_local_p_1 (const_tree, int); +extern void default_globalize_label (FILE *, const char *); +extern void default_globalize_decl_name (FILE *, tree); +extern void default_emit_unwind_label (FILE *, tree, int, int); +extern void default_emit_except_table_label (FILE *); +extern void default_internal_label (FILE *, const char *, unsigned long); +extern void default_file_start (void); +extern void file_end_indicate_exec_stack (void); +extern bool default_valid_pointer_mode (enum machine_mode); + +extern void default_elf_asm_output_external (FILE *file, tree, + const char *); +extern int maybe_assemble_visibility (tree); + +extern int default_address_cost (rtx, bool); + +/* dbxout helper functions */ +#if defined DBX_DEBUGGING_INFO || defined XCOFF_DEBUGGING_INFO + +extern void dbxout_int (int); +extern void dbxout_stabd (int, int); +extern void dbxout_begin_stabn (int); +extern void dbxout_begin_stabn_sline (int); +extern void dbxout_begin_empty_stabs (int); +extern void dbxout_begin_simple_stabs (const char *, int); +extern void dbxout_begin_simple_stabs_desc (const char *, int, int); + +extern void dbxout_stab_value_zero (void); +extern void dbxout_stab_value_label (const char *); +extern void dbxout_stab_value_label_diff (const char *, const char *); +extern void dbxout_stab_value_internal_label (const char *, int *); +extern void dbxout_stab_value_internal_label_diff (const char *, int *, + const char *); + +#endif + +#endif /* ! GCC_OUTPUT_H */ diff --git a/support/cpp/prefix.c b/support/cpp/prefix.c new file mode 100644 index 0000000..02301c1 --- /dev/null +++ b/support/cpp/prefix.c @@ -0,0 +1,354 @@ +/* Utility to update paths from internal to external forms. + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, + 2007 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC 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 3 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 COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +/* 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 (char *); +static char *translate_name (char *); +static char *save_string (const char *, int); +static void tr (char *, int, int); + +#if defined(_WIN32) && defined(ENABLE_WIN32_REGISTRY) +static char *lookup_key (char *); +static HKEY reg_key = (HKEY) INVALID_HANDLE_VALUE; +#endif + +/* Given KEY, as above, return its value. */ + +static const char * +get_key_value (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; +} + +/* Return a copy of a string that has been placed in the heap. */ + +static char * +save_string (const char *s, int len) +{ + char *result = XNEWVEC (char, len + 1); + + memcpy (result, s, len); + result[len] = 0; + return result; +} + +#if defined(_WIN32) && defined(ENABLE_WIN32_REGISTRY) + +#ifndef WIN32_REGISTRY_KEY +# define WIN32_REGISTRY_KEY BASEVER +#endif + +/* Look up "key" in the registry, as above. */ + +static char * +lookup_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 = xmalloc (size); + + res = RegQueryValueExA (reg_key, key, 0, &type, (LPBYTE) dst, &size); + if (res == ERROR_MORE_DATA && type == REG_SZ) + { + dst = xrealloc (dst, size); + res = RegQueryValueExA (reg_key, key, 0, &type, (LPBYTE) dst, &size); + } + + if (type != REG_SZ || res != ERROR_SUCCESS) + { + free (dst); + dst = 0; + } + + return dst; +} +#endif + +/* If NAME, a malloc-ed string, starts with a '@' or '$', apply the + translation rules above and return a newly malloc-ed name. + Otherwise, return the given name. */ + +static char * +translate_name (char *name) +{ + char code; + char *key, *old_name; + const char *prefix; + int keylen; + + for (;;) + { + code = name[0]; + if (code != '@' && code != '$') + break; + + 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; + + 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. */ + + old_name = name; + name = concat (prefix, &name[keylen + 1], NULL); + free (old_name); + } + + return name; +} + +/* In a NUL-terminated STRING, replace character C1 with C2 in-place. */ +static void +tr (char *string, int c1, int c2) +{ + do + { + if (*string == c1) + *string = c2; + } + while (*string++); +} + +/* Update PATH using KEY if PATH starts with PREFIX as a directory. + The returned string is always malloc-ed, and the caller is + responsible for freeing it. */ + +char * +update_path (const char *path, const char *key) +{ + char *result, *p; + const int len = strlen (std_prefix); + + if (! strncmp (path, std_prefix, len) + && (IS_DIR_SEPARATOR(path[len]) + || path[len] == '\0') + && key != 0) + { + bool free_key = false; + + if (key[0] != '$') + { + key = concat ("@", key, NULL); + free_key = true; + } + + result = concat (key, &path[len], NULL); + if (free_key) + free (CONST_CAST (char *, key)); + result = translate_name (result); + } + else + result = xstrdup (path); + +#ifndef ALWAYS_STRIP_DOTDOT +#define ALWAYS_STRIP_DOTDOT 0 +#endif + + p = result; + while (1) + { + char *src, *dest; + + p = strchr (p, '.'); + if (p == NULL) + break; + /* Look for `/../' */ + if (p[1] == '.' + && IS_DIR_SEPARATOR (p[2]) + && (p != result && IS_DIR_SEPARATOR (p[-1]))) + { + *p = 0; + if (!ALWAYS_STRIP_DOTDOT && access (result, X_OK) == 0) + { + *p = '.'; + break; + } + else + { + /* We can't access the dir, so we won't be able to + access dir/.. either. Strip out `dir/../'. If `dir' + turns out to be `.', strip one more path component. */ + dest = p; + do + { + --dest; + while (dest != result && IS_DIR_SEPARATOR (*dest)) + --dest; + while (dest != result && !IS_DIR_SEPARATOR (dest[-1])) + --dest; + } + while (dest != result && *dest == '.'); + /* If we have something like `./..' or `/..', don't + strip anything more. */ + if (*dest == '.' || IS_DIR_SEPARATOR (*dest)) + { + *p = '.'; + break; + } + src = p + 3; + while (IS_DIR_SEPARATOR (*src)) + ++src; + p = dest; + while ((*dest++ = *src++) != 0) + ; + } + } + else + ++p; + } + +#ifdef UPDATE_PATH_HOST_CANONICALIZE + /* Perform host dependent canonicalization when needed. */ + UPDATE_PATH_HOST_CANONICALIZE (result); +#endif + +#ifdef DIR_SEPARATOR_2 + /* Convert DIR_SEPARATOR_2 to DIR_SEPARATOR. */ + if (DIR_SEPARATOR_2 != DIR_SEPARATOR) + tr (result, DIR_SEPARATOR_2, DIR_SEPARATOR); +#endif + +#if defined (DIR_SEPARATOR) && !defined (DIR_SEPARATOR_2) + if (DIR_SEPARATOR != '/') + tr (result, '/', DIR_SEPARATOR); +#endif + + return result; +} + +/* Reset the standard prefix. */ +void +set_std_prefix (const char *prefix, int len) +{ + std_prefix = save_string (prefix, len); +} diff --git a/support/cpp/prefix.h b/support/cpp/prefix.h new file mode 100644 index 0000000..c6d9ae5 --- /dev/null +++ b/support/cpp/prefix.h @@ -0,0 +1,30 @@ +/* Provide prototypes for functions exported from prefix.c. + Copyright (C) 1999, 2003, 2007 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC 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 3 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 COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + + +#ifndef GCC_PREFIX_H +#define GCC_PREFIX_H + +/* Update PATH using KEY if PATH starts with PREFIX. The returned + string is always malloc-ed, and the caller is responsible for + freeing it. */ +extern char *update_path (const char *path, const char *key); +extern void set_std_prefix (const char *, int); + +#endif /* ! GCC_PREFIX_H */ diff --git a/support/cpp/sdcpp-diagnostic.c b/support/cpp/sdcpp-diagnostic.c new file mode 100644 index 0000000..e131225 --- /dev/null +++ b/support/cpp/sdcpp-diagnostic.c @@ -0,0 +1,178 @@ +/* diagnostic subroutines for the SDCC + Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, + 2009, 2010 Free Software Foundation, Inc. + Copyright (C) 2010 Borut Razem + Contributed by Gabriel Dos Reis <gdr@codesourcery.com> + +This file is part of GCC. + +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 3, 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 COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "internal.h" +#include "sdcpp.h" + +#ifndef _ +# define _(msgid) (msgid) +#endif + +/* from libcpp/line-map.c */ + +/* Print the file names and line numbers of the #include commands + which led to the map MAP, if any, to stderr. Nothing is output if + the most recently listed stack is the same as the current one. */ + +void +linemap_print_containing_files (struct line_maps *set, + const struct line_map *map) +{ + if (MAIN_FILE_P (map) || set->last_listed == map->included_from) + return; + + set->last_listed = map->included_from; + map = INCLUDED_FROM (set, map); + + fprintf (stderr, _("In file included from %s:%u"), + map->to_file, LAST_SOURCE_LINE (map)); + + while (! MAIN_FILE_P (map)) + { + map = INCLUDED_FROM (set, map); + /* 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"), + map->to_file, LAST_SOURCE_LINE (map)); + } + + fputs (":\n", stderr); +} + +/* from libcpp/errors.c */ + +/* Print the logical file location (LINE, COL) in preparation for a + diagnostic. Outputs the #include chain if it has changed. A line + of zero suppresses the include stack, and outputs the program name + instead. */ +static void +print_location (cpp_reader *pfile, source_location line, unsigned int col) +{ + if (line == 0) + fprintf (stderr, "%s: ", progname); + else + { + const struct line_map *map; + unsigned int lin; + + map = linemap_lookup (pfile->line_table, line); + linemap_print_containing_files (pfile->line_table, map); + + lin = SOURCE_LINE (map, line); + if (col == 0) + { + col = SOURCE_COLUMN (map, line); + if (col == 0) + col = 1; + } + + if (lin == 0) + fprintf (stderr, "%s:", map->to_file); + else + fprintf (stderr, "%s:%u:%u:", map->to_file, lin, col); + + fputc (' ', stderr); + } +} + +/* from c-common.c */ + +/* Callback from cpp_error for PFILE to print diagnostics from the + preprocessor. The diagnostic is of type LEVEL, at location + LOCATION unless this is after lexing and the compiler's location + should be used instead, with column number possibly overridden by + COLUMN_OVERRIDE if not zero; MSG is the translated message and AP + the arguments. Returns true if a diagnostic was emitted, false + otherwise. */ + +bool +c_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level, int reason ATTRIBUTE_UNUSED, + location_t location, unsigned int column_override, + const char *msg, va_list *ap) +{ +/* Moved here from cpplib.h */ +/* Extracts a diagnostic level from an int. */ +#define CPP_DL_EXTRACT(l) (l & 0xf) +/* Nonzero if a diagnostic level is one of the warnings. */ +#define CPP_DL_WARNING_P(l) (CPP_DL_EXTRACT (l) >= CPP_DL_WARNING \ + && CPP_DL_EXTRACT (l) <= CPP_DL_PEDWARN) + + switch (level) + { + case CPP_DL_WARNING: + case CPP_DL_PEDWARN: + if (cpp_in_system_header (pfile) + && ! warn_system_headers) + return false; + /* Fall through. */ + + case CPP_DL_WARNING_SYSHDR: + if (warnings_are_errors + || (level == CPP_DL_PEDWARN && flag_pedantic_errors)) + { + level = CPP_DL_ERROR; + ++errorcount; + } + else if (inhibit_warnings) + return false; + break; + + case CPP_DL_ERROR: + /* ICEs cannot be inhibited. */ + case CPP_DL_ICE: + ++errorcount; + break; + } + + print_location (pfile, location, column_override); + + if (CPP_DL_WARNING_P (level)) + fputs (_("warning: "), stderr); + else if (level == CPP_DL_ICE) + fputs (_("internal error: "), stderr); + else if (level == CPP_DL_FATAL) + fputs (_("fatal error: "), stderr); + else + fputs (_("error: "), stderr); + + vfprintf (stderr, _(msg), *ap); + putc ('\n', stderr); + + if (level == CPP_DL_FATAL) { + fputs(_("compilation terminated.\n"), stderr); + exit (FATAL_EXIT_CODE); + } + + return true; +} diff --git a/support/cpp/sdcpp-opts.c b/support/cpp/sdcpp-opts.c new file mode 100644 index 0000000..9df64f2 --- /dev/null +++ b/support/cpp/sdcpp-opts.c @@ -0,0 +1,936 @@ +/* C/ObjC/C++ command line option handling. + Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + Contributed by Neil Booth. + +This file is part of GCC. + +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, 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301, USA. */ + +#include "config.h" +#include "system.h" +#include "intl.h" +#include "cppdefault.h" +#include "c-incpath.h" +#include "opts.h" +#include "options.h" +#include "mkdeps.h" + +#ifndef DOLLARS_IN_IDENTIFIERS +# define DOLLARS_IN_IDENTIFIERS true +#endif + +#ifndef TARGET_SYSTEM_ROOT +# define TARGET_SYSTEM_ROOT NULL +#endif + +/* CPP's options. */ +static cpp_options *cpp_opts; + +/* Input filename. */ +static const char *this_input_filename; + +/* Filename and stream for preprocessed output. */ +static const char *out_fname; +static FILE *out_stream; + +/* Append dependencies to deps_file. */ +static bool deps_append; + +/* If dependency switches (-MF etc.) have been given. */ +static bool deps_seen; + +/* If -v seen. */ +static bool verbose; + +/* Dependency output file. */ +static const char *deps_file; + +/* The prefix given by -iprefix, if any. */ +static const char *iprefix; + +/* The multilib directory given by -imultilib, if any. */ +static const char *imultilib; + +/* The system root, if any. Overridden by -isysroot. */ +static const char *sysroot = TARGET_SYSTEM_ROOT; + +/* Zero disables all standard directories for headers. */ +static bool std_inc = true; + +/* If the quote chain has been split by -I-. */ +static bool quote_chain_split; + +/* If -Wunused-macros. */ +static bool warn_unused_macros; + +/* If -Wvariadic-macros. */ +static bool warn_variadic_macros = true; + +/* Number of deferred options. */ +static size_t deferred_count; + +/* Number of deferred options scanned for -include. */ +static size_t include_cursor; + +static void handle_OPT_d (const char *); +static void set_std_c89 (int, int); +static void set_std_c99 (int); +static void set_std_c11 (void); +static void check_deps_environment_vars (void); +static void handle_deferred_opts (void); +static void sanitize_cpp_opts (void); +static void add_prefixed_path (const char *, size_t); +static void push_command_line_include (void); +static void cb_file_change (cpp_reader *, const struct line_map *); +static void cb_dir_change (cpp_reader *, const char *); +static void finish_options (void); + +#ifndef STDC_0_IN_SYSTEM_HEADERS +#define STDC_0_IN_SYSTEM_HEADERS 0 +#endif + +/* Holds switches parsed by sdcpp_common_handle_option (), but whose + handling is deferred to sdcpp_common_post_options (). */ +static void defer_opt (enum opt_code, const char *); +static struct deferred_opt +{ + enum opt_code code; + const char *arg; +} *deferred_opts; + +/* Complain that switch CODE expects an argument but none was + provided. OPT was the command-line option. Return FALSE to get + the default message in opts.c, TRUE if we provide a specialized + one. */ +bool +sdcpp_common_missing_argument (const char *opt, size_t code) +{ + switch (code) + { + default: + /* Pick up the default message. */ + return false; + + case OPT_A: + error ("assertion missing after \"%s\"", opt); + break; + + case OPT_D: + case OPT_U: + error ("macro name missing after \"%s\"", opt); + break; + + case OPT_I: + case OPT_idirafter: + case OPT_isysroot: + case OPT_isystem: + case OPT_iquote: + error ("missing path after \"%s\"", opt); + break; + + case OPT_MF: + case OPT_MD: + case OPT_MMD: + case OPT_include: + case OPT_imacros: + case OPT_o: + error ("missing filename after \"%s\"", opt); + break; + + case OPT_MQ: + case OPT_MT: + error ("missing makefile target after \"%s\"", opt); + break; + } + + return true; +} + +/* Defer option CODE with argument ARG. */ +static void +defer_opt (enum opt_code code, const char *arg) +{ + deferred_opts[deferred_count].code = code; + deferred_opts[deferred_count].arg = arg; + deferred_count++; +} + +/* Common initialization before parsing options. */ +unsigned int +sdcpp_common_init_options (unsigned int argc, const char **argv ATTRIBUTE_UNUSED) +{ + struct cpp_callbacks *cb; + + parse_in = cpp_create_reader (CLK_GNUC89, NULL, line_table); + cb = cpp_get_callbacks (parse_in); + cb->error = c_cpp_error; + + cpp_opts = cpp_get_options (parse_in); + cpp_opts->dollars_in_ident = DOLLARS_IN_IDENTIFIERS; + cpp_opts->objc = 0; + + /* Reset to avoid warnings on internal definitions. We set it just + before passing on command-line options to cpplib. */ + cpp_opts->warn_dollars = 0; + + deferred_opts = XNEWVEC (struct deferred_opt, argc); + + return CL_SDCPP; +} + +/* Handle switch SCODE with argument ARG. VALUE is true, unless no- + form of an -f or -W option was given. Returns 0 if the switch was + invalid, a negative number to prevent language-independent + processing in toplev.c (a hack necessary for the short-term). */ +int +sdcpp_common_handle_option (size_t scode, const char *arg, int value) +{ + enum opt_code code = (enum opt_code) scode; + int result = 1; + + switch (code) + { + default: + result = 0; + break; + +#if 0 /* pch not supported by sdcpp */ + case OPT__output_pch_: + pch_file = arg; + break; +#endif + + case OPT_A: + defer_opt (code, arg); + break; + + case OPT_C: + cpp_opts->discard_comments = 0; + break; + + case OPT_CC: + cpp_opts->discard_comments = 0; + cpp_opts->discard_comments_in_macro_exp = 0; + break; + + case OPT_D: + defer_opt (code, arg); + break; + + case OPT_H: + cpp_opts->print_include_names = 1; + break; + + case OPT_I: + if (strcmp (arg, "-")) + add_path (xstrdup (arg), BRACKET, 0, true); + else + { + if (quote_chain_split) + error ("-I- specified twice"); + quote_chain_split = true; + split_quote_chain (); + inform ("obsolete option -I- used, please use -iquote instead"); + } + break; + + case OPT_M: + case OPT_MM: + /* When doing dependencies with -M or -MM, suppress normal + preprocessed output, but still do -dM etc. as software + depends on this. Preprocessed output does occur if -MD, -MMD + or environment var dependency generation is used. */ + cpp_opts->deps.style = (code == OPT_M ? DEPS_SYSTEM: DEPS_USER); + flag_no_output = 1; + inhibit_warnings = 1; + break; + + case OPT_MD: + case OPT_MMD: + cpp_opts->deps.style = (code == OPT_MD ? DEPS_SYSTEM: DEPS_USER); + cpp_opts->deps.need_preprocessor_output = true; + deps_file = arg; + break; + + case OPT_MF: + deps_seen = true; + deps_file = arg; + break; + + case OPT_MG: + deps_seen = true; + cpp_opts->deps.missing_files = true; + break; + + case OPT_MP: + deps_seen = true; + cpp_opts->deps.phony_targets = true; + break; + + case OPT_MQ: + case OPT_MT: + deps_seen = true; + defer_opt (code, arg); + break; + + case OPT_P: + flag_no_line_commands = 1; + break; + + case OPT_fworking_directory: + flag_working_directory = value; + break; + + case OPT_U: + defer_opt (code, arg); + break; + + case OPT_Wall: + cpp_opts->warn_trigraphs = value; + cpp_opts->warn_comments = value; + cpp_opts->warn_num_sign_change = value; + cpp_opts->warn_multichar = value; /* Was C++ only. */ + break; + + case OPT_Wcomment: + case OPT_Wcomments: + cpp_opts->warn_comments = value; + break; + + case OPT_Wdeprecated: + cpp_opts->cpp_warn_deprecated = value; + break; + + case OPT_Wendif_labels: + cpp_opts->warn_endif_labels = value; + break; + + case OPT_Wimport: + /* Silently ignore for now. */ + break; + +#if 0 // pch not supported by sdcpp + case OPT_Winvalid_pch: + cpp_opts->warn_invalid_pch = value; + break; +#endif + + case OPT_Wtraditional: + cpp_opts->cpp_warn_traditional = value; + break; + + case OPT_Wtrigraphs: + cpp_opts->warn_trigraphs = value; + break; + + case OPT_Wundef: + cpp_opts->warn_undef = value; + break; + + case OPT_Wunused_macros: + warn_unused_macros = value; + break; + + case OPT_Wvariadic_macros: + warn_variadic_macros = value; + break; + + case OPT_ansi: + set_std_c89 (false, true); + break; + + case OPT_d: + handle_OPT_d (arg); + break; + + case OPT_fdollars_in_identifiers: + cpp_opts->dollars_in_ident = value; + break; + + case OPT_fsigned_char: + flag_signed_char = value; + break; + + case OPT_funsigned_char: + flag_signed_char = !value; + break; + +#if 0 // pch not supported by sdcpp + case OPT_fpch_deps: + cpp_opts->restore_pch_deps = value; + break; + + case OPT_fpch_preprocess: + flag_pch_preprocess = value; + break; +#endif + + case OPT_fpreprocessed: + cpp_opts->preprocessed = value; + break; + + case OPT_ftabstop_: + /* It is documented that we silently ignore silly values. */ + if (value >= 1 && value <= 100) + cpp_opts->tabstop = value; + break; + + case OPT_fexec_charset_: + cpp_opts->narrow_charset = arg; + break; + + case OPT_fwide_exec_charset_: + cpp_opts->wide_charset = arg; + break; + + case OPT_finput_charset_: + cpp_opts->input_charset = arg; + break; + + case OPT_idirafter: + add_path (xstrdup (arg), AFTER, 0, true); + break; + + case OPT_imacros: + case OPT_include: + defer_opt (code, arg); + break; + + case OPT_iprefix: + iprefix = arg; + break; + + case OPT_imultilib: + imultilib = arg; + break; + + case OPT_iquote: + add_path (xstrdup (arg), QUOTE, 0, true); + break; + + case OPT_isysroot: + sysroot = arg; + break; + + case OPT_isystem: + add_path (xstrdup (arg), SYSTEM, 0, true); + break; + + case OPT_iwithprefix: + add_prefixed_path (arg, SYSTEM); + break; + + case OPT_iwithprefixbefore: + add_prefixed_path (arg, BRACKET); + break; + + case OPT_lang_asm: + cpp_set_lang (parse_in, CLK_ASM); + cpp_opts->dollars_in_ident = false; + break; + + case OPT_lang_objc: + cpp_opts->objc = 1; + break; + + case OPT_nostdinc: + std_inc = false; + break; + + case OPT_o: + if (!out_fname) + out_fname = arg; + else + error ("output filename specified several times"); + break; + + /* SDCPP specfic */ + case OPT_obj_ext_: + cpp_opts->obj_ext = arg; + break; + + /* We need to handle the -pedantic switches here, rather than in + sdcpp_common_post_options, so that a subsequent -Wno-endif-labels + is not overridden. */ + case OPT_pedantic_errors: + case OPT_pedantic: + cpp_opts->cpp_pedantic = 1; + cpp_opts->warn_endif_labels = 1; + break; + + /* SDCPP specfic */ + case OPT_pedantic_parse_number: + cpp_opts->pedantic_parse_number = 1; + break; + +#if 0 // pch not supported by sdcpp + case OPT_print_pch_checksum: + c_common_print_pch_checksum (stdout); + exit_after_options = true; + break; +#endif + + case OPT_remap: + cpp_opts->remap = 1; + break; + + case OPT_std_c89: + case OPT_std_iso9899_1990: + case OPT_std_iso9899_199409: + set_std_c89 (code == OPT_std_iso9899_199409 /* c94 */, true /* ISO */); + break; + + case OPT_std_c99: + case OPT_std_iso9899_1999: + set_std_c99 (true /* ISO */); + break; + + case OPT_std_c11: + set_std_c11 (); + break; + + case OPT_no_trigraphs: + /* trigraphs enabled by default on sdcpp, -no-trgraphs disables them */ + cpp_opts->trigraphs = 0; + break; + + case OPT_traditional_cpp: + cpp_opts->traditional = 1; + break; + + case OPT_v: + verbose = true; + break; + } + + return result; +} + +/* Post-switch processing. */ +bool +sdcpp_common_post_options (const char **pfilename) +{ + struct cpp_callbacks *cb; + + /* Canonicalize the input and output filenames. */ + if (in_fnames == NULL) + { + in_fnames = XNEWVEC (const char *, 1); + in_fnames[0] = ""; + } + else if (strcmp (in_fnames[0], "-") == 0) + in_fnames[0] = ""; + + if (num_in_fnames > 1) + { + if (!out_fname) + out_fname = in_fnames[1]; + else + error ("output filename specified several times"); + } + + if (out_fname == NULL || !strcmp (out_fname, "-")) + out_fname = ""; + + if (cpp_opts->deps.style == DEPS_NONE) + check_deps_environment_vars (); + + handle_deferred_opts (); + + sanitize_cpp_opts (); + + register_include_chains (parse_in, sysroot, iprefix, imultilib, + std_inc, 0, verbose); + + /* Open the output now. We must do so even if flag_no_output is + on, because there may be other output than from the actual + preprocessing (e.g. from -dM). */ + if (out_fname[0] == '\0') + out_stream = stdout; + else + out_stream = fopen (out_fname, "w"); + + if (out_stream == NULL) + { + fatal_error ("opening output file %s: %s", out_fname, strerror(errno)); + return false; + } + + if (num_in_fnames > 2) + error ("too many filenames given. Type %s --help for usage", + progname); + + init_pp_output (out_stream); + + cb = cpp_get_callbacks (parse_in); + cb->file_change = cb_file_change; + cb->dir_change = cb_dir_change; + cpp_post_options (parse_in); + + *pfilename = this_input_filename + = cpp_read_main_file (parse_in, in_fnames[0]); + /* Don't do any compilation or preprocessing if there is no input file. */ + if (this_input_filename == NULL) + { + errorcount++; + return false; + } + + if (flag_working_directory && !flag_no_line_commands) + pp_dir_change (parse_in, get_src_pwd ()); + + return 1; +} + +/* Front end initialization. */ +bool +sdcpp_common_init (void) +{ + /* Default CPP arithmetic to something sensible for the host for the + benefit of dumb users like fix-header. */ + cpp_opts->precision = CHAR_BIT * sizeof (long); + cpp_opts->char_precision = CHAR_BIT; + cpp_opts->int_precision = CHAR_BIT * sizeof (int); + cpp_opts->wchar_precision = CHAR_BIT * sizeof (int); + cpp_opts->unsigned_wchar = 1; + cpp_opts->bytes_big_endian = BYTES_BIG_ENDIAN; + + /* This can't happen until after wchar_precision and bytes_big_endian + are known. */ + cpp_init_iconv (parse_in); + +#if 0 + if (version_flag) + c_common_print_pch_checksum (stderr); +#endif + + finish_options (); + preprocess_file (parse_in); + return true; +} + +/* Common finish hook for the C, ObjC and C++ front ends. */ +void +sdcpp_common_finish (void) +{ + FILE *deps_stream = NULL; + + if (cpp_opts->deps.style != DEPS_NONE) + { + /* If -M or -MM was seen without -MF, default output to the + output stream. */ + if (!deps_file) + deps_stream = out_stream; + else + { + deps_stream = fopen (deps_file, deps_append ? "a": "w"); + if (!deps_stream) + fatal_error ("opening dependency file %s: %s", deps_file, strerror(errno)); + } + } + + /* For performance, avoid tearing down cpplib's internal structures + with cpp_destroy (). */ + cpp_finish (parse_in, deps_stream); + + if (deps_stream && deps_stream != out_stream + && (ferror (deps_stream) || fclose (deps_stream))) + fatal_error ("closing dependency file %s: %s", deps_file, strerror(errno)); + + if (out_stream && (ferror (out_stream) || fclose (out_stream))) + fatal_error ("when writing output to %s: %s", out_fname, strerror(errno)); +} + +/* Either of two environment variables can specify output of + dependencies. Their 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. They also + result in dependency information being appended to the output file + rather than overwriting it, and like Sun's compiler + SUNPRO_DEPENDENCIES suppresses the dependency on the main file. */ +static void +check_deps_environment_vars (void) +{ + char *spec; + + GET_ENVIRONMENT (spec, "DEPENDENCIES_OUTPUT"); + if (spec) + cpp_opts->deps.style = DEPS_USER; + else + { + GET_ENVIRONMENT (spec, "SUNPRO_DEPENDENCIES"); + if (spec) + { + cpp_opts->deps.style = DEPS_SYSTEM; + cpp_opts->deps.ignore_main_file = true; + } + } + + if (spec) + { + /* Find the space before the DEPS_TARGET, if there is one. */ + char *s = strchr (spec, ' '); + if (s) + { + /* Let the caller perform MAKE quoting. */ + defer_opt (OPT_MT, s + 1); + *s = '\0'; + } + + /* Command line -MF overrides environment variables and default. */ + if (!deps_file) + deps_file = spec; + + deps_append = 1; + deps_seen = true; + } +} + +/* Handle deferred command line switches. */ +static void +handle_deferred_opts (void) +{ + size_t i; + struct deps *deps; + + /* Avoid allocating the deps buffer if we don't need it. + (This flag may be true without there having been -MT or -MQ + options, but we'll still need the deps buffer.) */ + if (!deps_seen) + return; + + deps = cpp_get_deps (parse_in); + + for (i = 0; i < deferred_count; i++) + { + struct deferred_opt *opt = &deferred_opts[i]; + + if (opt->code == OPT_MT || opt->code == OPT_MQ) + deps_add_target (deps, opt->arg, opt->code == OPT_MQ); + } +} + +/* These settings are appropriate for GCC, but not necessarily so for + cpplib as a library. */ +static void +sanitize_cpp_opts (void) +{ + /* If we don't know what style of dependencies to output, complain + if any other dependency switches have been given. */ + if (deps_seen && cpp_opts->deps.style == DEPS_NONE) + error ("to generate dependencies you must specify either -M or -MM"); + + /* -dM and dependencies suppress normal output; do it here so that + the last -d[MDN] switch overrides earlier ones. */ + if (flag_dump_macros == 'M') + flag_no_output = 1; + + /* Disable -dD, -dN and -dI if normal output is suppressed. Allow + -dM since at least glibc relies on -M -dM to work. */ + /* Also, flag_no_output implies flag_no_line_commands, always. */ + if (flag_no_output) + { + if (flag_dump_macros != 'M') + flag_dump_macros = 0; + flag_dump_includes = 0; + flag_no_line_commands = 1; + } + + cpp_opts->unsigned_char = !flag_signed_char; + cpp_opts->stdc_0_in_system_headers = STDC_0_IN_SYSTEM_HEADERS; + + /* Similarly with -Wno-variadic-macros. No check for c99 here, since + this also turns off warnings about GCCs extension. */ + cpp_opts->warn_variadic_macros + = warn_variadic_macros && (pedantic || warn_traditional); + + /* If we're generating preprocessor output, emit current directory + if explicitly requested */ + if (flag_working_directory == -1) + flag_working_directory = 0; +} + +/* Add include path with a prefix at the front of its name. */ +static void +add_prefixed_path (const char *suffix, size_t chain) +{ + char *path; + const char *prefix; + size_t prefix_len, suffix_len; + + suffix_len = strlen (suffix); + prefix = iprefix ? iprefix : cpp_GCC_INCLUDE_DIR; + prefix_len = iprefix ? strlen (iprefix) : cpp_GCC_INCLUDE_DIR_len; + + path = (char *) xmalloc (prefix_len + suffix_len + 1); + memcpy (path, prefix, prefix_len); + memcpy (path + prefix_len, suffix, suffix_len); + path[prefix_len + suffix_len] = '\0'; + + add_path (path, chain, 0, false); +} + +/* Handle -D, -U, -A, -imacros, and the first -include. */ +static void +finish_options (void) +{ + if (!cpp_opts->preprocessed) + { + size_t i; + + cb_file_change (parse_in, + linemap_add (line_table, LC_RENAME, 0, + _("<built-in>"), 0)); + + cpp_init_builtins (parse_in, 0 /*flag_hosted*/); + + /* We're about to send user input to cpplib, so make it warn for + things that we previously (when we sent it internal definitions) + told it to not warn. + + C99 permits implementation-defined characters in identifiers. + The documented meaning of -std= is to turn off extensions that + conflict with the specified standard, and since a strictly + conforming program cannot contain a '$', we do not condition + their acceptance on the -std= setting. */ + cpp_opts->warn_dollars = (cpp_opts->cpp_pedantic && !cpp_opts->c99); + + cpp_change_file (parse_in, LC_RENAME, _("<command line>")); + for (i = 0; i < deferred_count; i++) + { + struct deferred_opt *opt = &deferred_opts[i]; + + if (opt->code == OPT_D) + cpp_define (parse_in, opt->arg); + else if (opt->code == OPT_U) + cpp_undef (parse_in, opt->arg); + else if (opt->code == OPT_A) + { + if (opt->arg[0] == '-') + cpp_unassert (parse_in, opt->arg + 1); + else + cpp_assert (parse_in, opt->arg); + } + } + + /* Handle -imacros after -D and -U. */ + for (i = 0; i < deferred_count; i++) + { + struct deferred_opt *opt = &deferred_opts[i]; + + if (opt->code == OPT_imacros + && cpp_push_include (parse_in, opt->arg)) + { + /* Disable push_command_line_include callback for now. */ + include_cursor = deferred_count + 1; + cpp_scan_nooutput (parse_in); + } + } + } + + include_cursor = 0; + push_command_line_include (); +} + +/* Give CPP the next file given by -include, if any. */ +static void +push_command_line_include (void) +{ + while (include_cursor < deferred_count) + { + struct deferred_opt *opt = &deferred_opts[include_cursor++]; + + if (!cpp_opts->preprocessed && opt->code == OPT_include + && cpp_push_include (parse_in, opt->arg)) + return; + } + + if (include_cursor == deferred_count) + { + include_cursor++; + /* -Wunused-macros should only warn about macros defined hereafter. */ + cpp_opts->warn_unused_macros = warn_unused_macros; + /* Restore the line map from <command line>. */ + if (!cpp_opts->preprocessed) + cpp_change_file (parse_in, LC_RENAME, this_input_filename); + + /* Set this here so the client can change the option if it wishes, + and after stacking the main file so we don't trace the main file. */ + line_table->trace_includes = cpp_opts->print_include_names; + } +} + +/* File change callback. Has to handle -include files. */ +static void +cb_file_change (cpp_reader * ARG_UNUSED (pfile), + const struct line_map *new_map) +{ + pp_file_change (new_map); + + if (new_map == 0 || (new_map->reason == LC_LEAVE && MAIN_FILE_P (new_map))) + push_command_line_include (); +} + +void +cb_dir_change (cpp_reader * ARG_UNUSED (pfile), const char *dir) +{ + if (!set_src_pwd (dir)) + warning (0, "too late for # directive to set debug directory"); +} + +/* Set the C 89 standard (with 1994 amendments if C94, without GNU + extensions if ISO). There is no concept of gnu94. */ +static void +set_std_c89 (int c94, int iso) +{ + cpp_set_lang (parse_in, c94 ? CLK_STDC94: iso ? CLK_STDC89: CLK_GNUC89); +} + +/* Set the C 99 standard (without GNU extensions if ISO). */ +static void +set_std_c99 (int iso) +{ + cpp_set_lang (parse_in, iso ? CLK_STDC99: CLK_GNUC99); +} + +/* Set the C 11 standard (without GNU extensions). */ +static void +set_std_c11 (void) +{ + cpp_set_lang (parse_in, CLK_STDC1X); +} + +/* Args to -d specify what to dump. Silently ignore + unrecognized options; they may be aimed at toplev.c. */ +static void +handle_OPT_d (const char *arg) +{ + char c; + + while ((c = *arg++) != '\0') + switch (c) + { + case 'M': /* Dump macros only. */ + case 'N': /* Dump names. */ + case 'D': /* Dump definitions. */ + flag_dump_macros = c; + break; + + case 'I': + flag_dump_includes = 1; + break; + } +} diff --git a/support/cpp/sdcpp.c b/support/cpp/sdcpp.c new file mode 100644 index 0000000..7de1a23 --- /dev/null +++ b/support/cpp/sdcpp.c @@ -0,0 +1,464 @@ +/*------------------------------------------------------------------------- + sdcppmain.c - sdcpp: SDCC preprocessor main file, using cpplib. + + Written by Borut Razem, 2006. + + 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 "internal.h" +#include "version.h" +#include "mkdeps.h" +#include "opts.h" +#include "intl.h" + +const char *progname; /* Needs to be global. */ + +/* From laghooks-def.h */ +/* The whole thing. The structure is defined in langhooks.h. */ +#define LANG_HOOKS_INITIALIZER { \ + LANG_HOOKS_INIT_OPTIONS, \ + LANG_HOOKS_HANDLE_OPTION, \ + LANG_HOOKS_MISSING_ARGUMENT, \ + LANG_HOOKS_POST_OPTIONS, \ + LANG_HOOKS_INIT, \ + LANG_HOOKS_FINISH, \ +} + +/* From c-lang.c */ +#define LANG_HOOKS_INIT_OPTIONS sdcpp_init_options +#define LANG_HOOKS_HANDLE_OPTION sdcpp_common_handle_option +#define LANG_HOOKS_MISSING_ARGUMENT sdcpp_common_missing_argument +#define LANG_HOOKS_POST_OPTIONS sdcpp_common_post_options +#define LANG_HOOKS_INIT sdcpp_common_init +#define LANG_HOOKS_FINISH sdcpp_common_finish + +static unsigned int sdcpp_init_options (unsigned int argc, const char **argv); + +/* Each front end provides its own lang hook initializer. */ +const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; + +/* Name of top-level original source file (what was input to cpp). + This comes from the #-command at the beginning of the actual input. + If there isn't any there, then this is the cc1 input file name. */ + +const char *main_input_filename; + +struct line_maps *line_table; + +/* Temporarily suppress certain warnings. + This is set while reading code from a system header file. */ + +int in_system_header = 0; + +/* Nonzero means change certain warnings into errors. + Usually these are warnings about failure to conform to some standard. */ + +int flag_pedantic_errors = 0; + +cpp_reader *parse_in; /* Declared in c-pragma.h. */ + +/* Nonzero means `char' should be signed. */ + +int flag_signed_char; + +/* Nonzero means don't output line number information. */ + +char flag_no_line_commands; + +/* Nonzero causes -E output not to be done, but directives such as + #define that have side effects are still obeyed. */ + +char flag_no_output; + +/* Nonzero means dump macros in some fashion. */ + +char flag_dump_macros; + +/* Nonzero means pass #include lines through to the output. */ + +char flag_dump_includes; + +/* 0 means we want the preprocessor to not emit line directives for + the current working directory. 1 means we want it to do it. -1 + means we should decide depending on whether debugging information + is being emitted or not. */ + +int flag_working_directory = -1; + +/* The current working directory of a translation. It's generally the + directory from which compilation was initiated, but a preprocessed + file may specify the original directory in which it was + created. */ + +static const char *src_pwd; + +/* Initialize src_pwd with the given string, and return true. If it + was already initialized, return false. As a special case, it may + be called with a NULL argument to test whether src_pwd has NOT been + initialized yet. */ + +/* From intl.c */ +/* Opening quotation mark for diagnostics. */ +const char *open_quote = "'"; + +/* Closing quotation mark for diagnostics. */ +const char *close_quote = "'"; +/* ----------- */ + +bool +set_src_pwd (const char *pwd) +{ + if (src_pwd) + return false; + + src_pwd = xstrdup (pwd); + return true; +} + +/* Return the directory from which the translation unit was initiated, + in case set_src_pwd() was not called before to assign it a + different value. */ + +const char * +get_src_pwd (void) +{ + if (! src_pwd) + src_pwd = getpwd (); + + return src_pwd; +} + +/* SDCPP specific pragmas */ +/* SDCC specific + sdcc_hash pragma */ +static void +do_pragma_sdcc_hash (cpp_reader *pfile) +{ + const cpp_token *tok = _cpp_lex_token (pfile); + + if (tok->type == CPP_PLUS) + { + CPP_OPTION(pfile, allow_naked_hash)++; + } + else if (tok->type == CPP_MINUS) + { + CPP_OPTION(pfile, allow_naked_hash)--; + } + else + { + cpp_error (pfile, CPP_DL_ERROR, + "invalid #pragma sdcc_hash directive, need '+' or '-'"); + } +} + +/* SDCC specific + pedantic_parse_number pragma */ +static void +do_pragma_pedantic_parse_number (cpp_reader *pfile) +{ + const cpp_token *tok = _cpp_lex_token (pfile); + + if (tok->type == CPP_PLUS) + { + CPP_OPTION(pfile, pedantic_parse_number)++; + } + else if (tok->type == CPP_MINUS) + { + CPP_OPTION(pfile, pedantic_parse_number)--; + } + else + { + cpp_error (pfile, CPP_DL_ERROR, + "invalid #pragma pedantic_parse_number directive, need '+' or '-'"); + } +} + +/* SDCC _asm specific + switch _asm block preprocessing on / off */ +static void +do_pragma_preproc_asm (cpp_reader *pfile) +{ + const cpp_token *tok = _cpp_lex_token (pfile); + + if (tok->type == CPP_PLUS) + { + CPP_OPTION(pfile, preproc_asm)++; + } + else if (tok->type == CPP_MINUS) + { + CPP_OPTION(pfile, preproc_asm)--; + } + else + { + cpp_error (pfile, CPP_DL_ERROR, + "invalid #pragma preproc_asm directive, need '+' or '-'"); + } +} + +/* SDCPP specific option initialization */ +static unsigned int +sdcpp_init_options (unsigned int argc, const char **argv) +{ + unsigned int ret = sdcpp_common_init_options(argc, argv); + + CPP_OPTION (parse_in, allow_naked_hash) = 0; + CPP_OPTION (parse_in, preproc_asm) = 1; + CPP_OPTION (parse_in, pedantic_parse_number) = 0; + CPP_OPTION (parse_in, obj_ext) = NULL; + + /* Kevin abuse for SDCC. */ + cpp_register_pragma(parse_in, 0, "sdcc_hash", do_pragma_sdcc_hash, false); + /* SDCC _asm specific */ + cpp_register_pragma(parse_in, 0, "preproc_asm", do_pragma_preproc_asm, false); + /* SDCC specific */ + cpp_register_pragma(parse_in, 0, "pedantic_parse_number", do_pragma_pedantic_parse_number, false); + + /* SDCC _asm specific */ + parse_in->spec_nodes.n__asm = cpp_lookup (parse_in, DSC("__asm")); + parse_in->spec_nodes.n__endasm = cpp_lookup (parse_in, DSC("__endasm")); + + return ret; +} + +void +print_version (FILE *file, const char *indent) +{ + printf (_("%s %s%s\n"), progname, pkgversion_string, version_string); + printf ("Copyright %s 2011 Free Software Foundation, Inc.\n", + _("(C)")); + fputs (_("This is free software; see the source for copying conditions. There is NO\n" + "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"), + stdout); +} + +/* Initialization of the front end environment, before command line + options are parsed. Signal handlers, internationalization etc. + ARGV0 is main's argv[0]. */ +static void +general_init (const char *argv0) +{ + const char *p; + + p = argv0 + strlen (argv0); + while (p != argv0 && !IS_DIR_SEPARATOR (p[-1])) + --p; + progname = p; + + xmalloc_set_program_name (progname); + + hex_init (); + + gcc_init_libintl (); + + line_table = XNEW (struct line_maps); + linemap_init (line_table); + line_table->reallocator = xrealloc; +} + +/* Process the options that have been parsed. */ +static void +process_options (void) +{ + /* Allow the front end to perform consistency checks and do further + initialization based on the command line options. This hook also + sets the original filename if appropriate (e.g. foo.i -> foo.c) + so we can correctly initialize debug output. */ + /*no_backend =*/ (*lang_hooks.post_options) (&main_input_filename); +} + +/* Parse a -d... command line switch. */ + +void +decode_d_option (const char *arg) +{ + int c; + + while (*arg) + switch (c = *arg++) + { + case 'D': /* These are handled by the preprocessor. */ + case 'I': + case 'M': + case 'N': + break; + + default: + warning (0, "unrecognized gcc debugging option: %c", c); + break; + } +} + +/* Diagnostic */ + +int errorcount = 0; + +/* An informative note. Use this for additional details on an error + message. */ +void +inform (const char *gmsgid, ...) +{ + va_list ap; + + va_start (ap, gmsgid); + fprintf (stderr, "%s: note: ", progname); + vfprintf (stderr, gmsgid, ap); + putc('\n', stderr); + va_end (ap); +} + +/* A warning. Use this for code which is correct according to the + relevant language specification but is likely to be buggy anyway. */ +void +warning (int opt, const char *gmsgid, ...) +{ + va_list ap; + + va_start (ap, gmsgid); + fprintf (stderr, "%s: warning: ", progname); + vfprintf (stderr, gmsgid, ap); + putc('\n', stderr); + va_end (ap); +} + +/* A hard error: the code is definitely ill-formed, and an object file + will not be produced. */ +void +error (const char *gmsgid, ...) +{ + va_list ap; + + ++errorcount; + + va_start (ap, gmsgid); + fprintf (stderr, "%s: error: ", progname); + vfprintf (stderr, gmsgid, ap); + putc('\n', stderr); + va_end (ap); +} + +/* An error which is severe enough that we make no attempt to + continue. Do not use this for internal consistency checks; that's + internal_error. Use of this function should be rare. */ +void +fatal_error (const char *gmsgid, ...) +{ + va_list ap; + + va_start (ap, gmsgid); + fprintf (stderr, "%s: fatal error: ", progname); + vfprintf (stderr, gmsgid, ap); + putc('\n', stderr); + va_end (ap); + + exit (FATAL_EXIT_CODE); +} + +/* An internal consistency check has failed. We make no attempt to + continue. Note that unless there is debugging value to be had from + a more specific message, or some other good reason, you should use + abort () instead of calling this function directly. */ +void +internal_error (const char *gmsgid, ...) +{ + va_list ap; + + va_start (ap, gmsgid); + fprintf (stderr, "%s: internal compiler error: ", progname); + vfprintf (stderr, gmsgid, ap); + putc('\n', stderr); + va_end (ap); + + exit (FATAL_EXIT_CODE); +} + +/* Report an internal compiler error in a friendly manner. This is + the function that gets called upon use of abort() in the source + code generally, thanks to a special macro. */ + +void +fancy_abort (const char *file, int line, const char *function) +{ + internal_error ("in %s, at %s:%d", function, file, line); +} + +/* Language-dependent initialization. Returns nonzero on success. */ +static int +lang_dependent_init (const char *name) +{ + /* Other front-end initialization. */ + if ((*lang_hooks.init) () == 0) + return 0; + + return 1; +} + +/* Clean up: close opened files, etc. */ + +static void +finalize (void) +{ + /* Language-specific end of compilation actions. */ + (*lang_hooks.finish) (); +} + +/* Initialize the compiler, and compile the input file. */ +static void +do_compile (void) +{ + process_options (); + + /* Don't do any more if an error has already occurred. */ + if (!errorcount) + { + /* Language-dependent initialization. Returns true on success. */ + lang_dependent_init (main_input_filename); + + finalize (); + } +} + +/* Entry point of sdcpp. + Exit code is FATAL_EXIT_CODE if can't open files or if there were + any errors, or SUCCESS_EXIT_CODE if compilation succeeded. + + It is not safe to call this function more than once. */ + +int +main (int argc, const char **argv) +{ + /* Initialization of SDCPP's environment. */ + general_init (argv[0]); + + /* Parse the options and do minimal processing; basically just + enough to default flags appropriately. */ + decode_options (argc, argv); + + /* Exit early if we can (e.g. -help). */ + if (!exit_after_options) + do_compile (); + + if (errorcount) + return (FATAL_EXIT_CODE); + + return (SUCCESS_EXIT_CODE); +} diff --git a/support/cpp/sdcpp.h b/support/cpp/sdcpp.h new file mode 100644 index 0000000..7435ef8 --- /dev/null +++ b/support/cpp/sdcpp.h @@ -0,0 +1,258 @@ +#ifndef __SDCPP_H +#define __SDCPP_H + +#ifdef _WIN32 +/* declaration of alloca */ +#include <malloc.h> +#include <string.h> +#ifdef __BORLANDC__ +#define strcasecmp stricmp +#else +#define strcasecmp _stricmp +#endif +#endif +#define BYTES_BIG_ENDIAN 0 + +/* + * From defaults.h + */ +#ifndef GET_ENVIRONMENT +#define GET_ENVIRONMENT(VALUE, NAME) do { (VALUE) = getenv (NAME); } while (0) +#endif + +/* 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 TARGET_ESC 033 + +#define CHAR_TYPE_SIZE 8 +#define WCHAR_TYPE_SIZE 32 /* ? maybe ? */ + +#define SUPPORTS_ONE_ONLY 0 + +#define TARGET_OBJECT_SUFFIX ".rel" + +#ifndef WCHAR_UNSIGNED +#define WCHAR_UNSIGNED 0 +#endif + +/* + * From langhooks.h + */ +struct diagnostic_context; + +struct lang_hooks +{ + /* The first callback made to the front end, for simple + initialization needed before any calls to handle_option. Return + the language mask to filter the switch array with. */ + unsigned int (*init_options) (unsigned int argc, const char **argv); + + /* Handle the switch CODE, which has real type enum opt_code from + options.h. If the switch takes an argument, it is passed in ARG + which points to permanent storage. The handler is responsible for + checking whether ARG is NULL, which indicates that no argument + was in fact supplied. For -f and -W switches, VALUE is 1 or 0 + for the positive and negative forms respectively. + + Return 1 if the switch is valid, 0 if invalid, and -1 if it's + valid and should not be treated as language-independent too. */ + int (*handle_option) (size_t code, const char *arg, int value); + + /* Return false to use the default complaint about a missing + argument, otherwise output a complaint and return true. */ + bool (*missing_argument) (const char *opt, size_t code); + + /* Called when all command line options have been parsed to allow + further processing and initialization + + Should return true to indicate that a compiler back-end is + not required, such as with the -E option. + + If errorcount is nonzero after this call the compiler exits + immediately and the finish hook is not called. */ + bool (*post_options) (const char **); + + /* Called after post_options to initialize the front end. Return + false to indicate that no further compilation be performed, in + which case the finish hook is called immediately. */ + bool (*init) (void); + + /* Called at the end of compilation, as a finalizer. */ + void (*finish) (void); +}; + +/* Each front end provides its own. */ +extern const struct lang_hooks lang_hooks; + +/* + * From toplev.h + */ +/* If we haven't already defined a frontend specific diagnostics + style, use the generic one. */ +#ifndef GCC_DIAG_STYLE +#define GCC_DIAG_STYLE __gcc_tdiag__ +#endif + +extern void internal_error (const char *, ...) ATTRIBUTE_PRINTF_1 + ATTRIBUTE_NORETURN; +/* Pass one of the OPT_W* from options.h as the first parameter. */ +extern void warning (int, const char *, ...) ATTRIBUTE_PRINTF_2; +extern void error (const char *, ...) ATTRIBUTE_PRINTF_1; +extern void fatal_error (const char *, ...) ATTRIBUTE_PRINTF_1 + ATTRIBUTE_NORETURN; +extern void inform (const char *, ...) ATTRIBUTE_PRINTF_1; + +extern const char *progname; +extern bool exit_after_options; + +extern void print_version (FILE *, const char *); + +/* Handle -d switch. */ +extern void decode_d_option (const char *); + +/* Functions used to get and set GCC's notion of in what directory + compilation was started. */ + +extern const char *get_src_pwd (void); +extern bool set_src_pwd (const char *); + +/* + * From flags.h + */ +/* Don't suppress warnings from system headers. -Wsystem-headers. */ + +extern bool warn_system_headers; + +/* If -Werror. */ + +extern bool warnings_are_errors; + +/* Nonzero for -pedantic switch: warn about anything + that standard C forbids. */ + +/* Temporarily suppress certain warnings. + This is set while reading code from a system header file. */ + +extern int in_system_header; + +/* Nonzero means `char' should be signed. */ + +extern int flag_signed_char; + +/* Nonzero means change certain warnings into errors. + Usually these are warnings about failure to conform to some standard. */ + +extern int flag_pedantic_errors; + +/* + * From options.h + */ +extern int inhibit_warnings; + +/* + * From c-common.h + */ +#include "hwint.h" +#include "cpplib.h" + +/* Nonzero means don't output line number information. */ + +extern char flag_no_line_commands; + +/* Nonzero causes -E output not to be done, but directives such as + #define that have side effects are still obeyed. */ + +extern char flag_no_output; + +/* Nonzero means dump macros in some fashion; contains the 'D', 'M' or + 'N' of the command line switch. */ + +extern char flag_dump_macros; + +/* 0 means we want the preprocessor to not emit line directives for + the current working directory. 1 means we want it to do it. -1 + means we should decide depending on whether debugging information + is being emitted or not. */ + +extern int flag_working_directory; + +/* Nonzero means warn about usage of long long when `-pedantic'. */ + +extern int warn_long_long; + +extern int sdcpp_common_handle_option (size_t code, const char *arg, int value); +extern bool sdcpp_common_missing_argument (const char *opt, size_t code); +extern unsigned int sdcpp_common_init_options (unsigned int, const char **); +extern bool sdcpp_common_post_options (const char **); +extern bool sdcpp_common_init (void); +extern void sdcpp_common_finish (void); + +/* Nonzero means pass #include lines through to the output. */ + +extern char flag_dump_includes; + +/* In c-ppoutput.c */ +extern void init_pp_output (FILE *); +extern void preprocess_file (cpp_reader *); +extern void pp_file_change (const struct line_map *); +extern void pp_dir_change (cpp_reader *, const char *); + +/* + * From c-pragma.h + */ +extern struct cpp_reader* parse_in; + +/* + * From input.h + */ +extern struct line_maps *line_table; + +typedef source_location location_t; /* deprecated typedef */ + +/* Top-level source file. */ +extern const char *main_input_filename; + +/* + * From tree.h + */ +/* Define the overall contents of a tree node. + just to make diagnostic.c happy */ + +union tree_node +{ + struct tree_decl + { + location_t locus; + } decl; +}; + +#define DECL_SOURCE_LOCATION(NODE) ((NODE)->decl.locus) + +/* + * From diagnostic.h + */ +extern int errorcount; + +/* + * From c-tree.h + */ +/* In order for the format checking to accept the C frontend + diagnostic framework extensions, you must include this file before + toplev.h, not after. */ +#if GCC_VERSION >= 4001 +#define ATTRIBUTE_GCC_CDIAG(m, n) __attribute__ ((__format__ (GCC_DIAG_STYLE, m ,n))) ATTRIBUTE_NONNULL(m) +#else +#define ATTRIBUTE_GCC_CDIAG(m, n) ATTRIBUTE_NONNULL(m) +#endif + +extern bool c_cpp_error (cpp_reader *, int, int, location_t, unsigned int, + const char *, va_list *) + ATTRIBUTE_GCC_CDIAG(6,0); + +#endif /* __SDCPP_H */ diff --git a/support/cpp/sdcpp.opt b/support/cpp/sdcpp.opt new file mode 100644 index 0000000..6d811b5 --- /dev/null +++ b/support/cpp/sdcpp.opt @@ -0,0 +1,336 @@ +; Options for the SDCPP front end. +; Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +; +; This file is part of GCC. +; +; 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, 51 Franklin Street, Fifth Floor, Boston, MA +; 02110-1301, USA. + +; See the GCC internals manual for a description of this file's format. + +; Please try to keep this file in ASCII collating order. + +Language +SDCPP + +-help +Common +Display this information + +-version +Common +Display the compiler's version + +;***-output-pch= +;***SDCPP Joined Separate + +A +SDCPP Joined Separate +-A<question>=<answer> Assert the <answer> to <question>. Putting '-' before <question> disables the <answer> to <question> + +C +SDCPP +Do not discard comments + +CC +SDCPP +Do not discard comments in macro expansions + +D +SDCPP Joined Separate +-D<macro>[=<val>] Define a <macro> with <val> as its value. If just <macro> is given, <val> is taken to be 1 + +H +SDCPP +Print the name of header files as they are used + +I +SDCPP Joined Separate +-I <dir> Add <dir> to the end of the main include path. -I- gives more include path control; see info documentation + +M +SDCPP +Generate make dependencies + +MD +SDCPP Separate +Generate make dependencies and compile + +MF +SDCPP Joined Separate +-MF <file> Write dependency output to the given file + +MG +SDCPP +Treat missing header files as generated files + +MM +SDCPP +Like -M but ignore system header files + +MMD +SDCPP Separate +Like -MD but ignore system header files + +MP +SDCPP +Generate phony targets for all headers + +MQ +SDCPP Joined Separate +-MQ <target> Add a MAKE-quoted target + +MT +SDCPP Joined Separate +-MT <target> Add an unquoted target + +P +SDCPP +Do not generate #line directives + +U +SDCPP Joined Separate +-U<macro> Undefine <macro> + +Wall +SDCPP +Enable most warning messages + +Wcomment +SDCPP +Warn about possibly nested block comments, and C++ comments spanning more than one physical line + +Wcomments +SDCPP +Synonym for -Wcomment + +Wdeprecated +SDCPP +Warn about deprecated compiler features + +Wendif-labels +SDCPP +Warn about stray tokens after #elif and #endif + +Werror +Common +Treat all warnings as errors + +Wfatal-errors +SDCPP Var(flag_fatal_errors) +Exit on the first error occurred + +Wimport +SDCPP +Deprecated. This switch has no effect. + +;***Winvalid-pch +;***SDCPP +;***Warn about PCH files that are found but not used + +Wsystem-headers +Common +Do not suppress warnings from system headers + +Wtraditional +SDCPP Var(warn_traditional) +Warn about features not present in traditional C + +Wtrigraphs +SDCPP +Warn if trigraphs are encountered that might affect the meaning of the program + +Wundef +SDCPP +Warn if an undefined macro is used in an #if directive + +Wunused-macros +SDCPP +Warn about macros defined in the main file that are not used + +Wvariadic-macros +SDCPP +Do not warn about using variadic macros when -pedantic + +ansi +SDCPP +A synonym for -std=c89. + +d +Common SDCPP Joined +-d<letters> Enable dumps from specific passes of the compiler + +fdollars-in-identifiers +SDCPP +Permit '$' as an identifier character + +fexec-charset= +SDCPP Joined RejectNegative +-fexec-charset=<cset> Convert all strings and character constants to character set <cset> + +finput-charset= +SDCPP Joined RejectNegative +-finput-charset=<cset> Specify the default character set for source files. + +;***fpch-deps +;***SDCPP + +fpreprocessed +SDCPP +Treat the input file as already preprocessed + +fshow-column +SDCPP + +fsigned-char +SDCPP +Make \"char\" signed by default + +ftabstop= +SDCPP Joined RejectNegative UInteger +-ftabstop=<number> Distance between tab stops for column reporting + +funsigned-char +SDCPP +Make \"char\" unsigned by default + +fwide-exec-charset= +SDCPP Joined RejectNegative +-fwide-exec-charset=<cset> Convert all wide strings and character constants to character set <cset> + +fworking-directory +SDCPP +Generate a #line directive pointing at the current working directory + +idirafter +SDCPP Joined Separate +-idirafter <dir> Add <dir> to the end of the system include path + +imacros +SDCPP Joined Separate +-imacros <file> Accept definition of macros in <file> + +imultilib +C ObjC C++ ObjC++ Joined Separate +-imultilib <dir> Set <dir> to be the multilib include subdirectory + +include +SDCPP Joined Separate +-include <file> Include the contents of <file> before other files + +iprefix +SDCPP Joined Separate +-iprefix <path> Specify <path> as a prefix for next two options + +isysroot +SDCPP Joined Separate +-isysroot <dir> Set <dir> to be the system root directory + +isystem +SDCPP Joined Separate +-isystem <dir> Add <dir> to the start of the system include path + +iquote +SDCPP Joined Separate +-iquote <dir> Add <dir> to the end of the quote include path + +iwithprefix +SDCPP Joined Separate +-iwithprefix <dir> Add <dir> to the end of the system include path + +iwithprefixbefore +SDCPP Joined Separate +-iwithprefixbefore <dir> Add <dir> to the end of the main include path + +lang-asm +C Undocumented + +lang-objc +SDCPP Undocumented + +nostdinc +SDCPP +Do not search standard system include directories (those specified with -isystem will still be used) + +o +SDCPP Joined Separate +-o <file> Place output into <file> + +obj-ext= +SDCPP Joined +-obj-ext=<extension> Define object file extension, used for generation of make dependencies + +pedantic +SDCPP Var(pedantic) +Issue warnings needed for strict compliance to the standard + +pedantic-errors +Common SDCPP +Like -pedantic but issue them as errors + +pedantic-parse-number +SDCPP +Pedantic parse number + +remap +SDCPP +Remap file names when including files + +std=c89 +SDCPP +Conform to the ISO 1990 C standard + +std=c99 +SDCPP +Conform to the ISO 1999 C standard + +std=c11 +SDCPP +Conform to the ISO 2011 C standard + +std=iso9899:1990 +C ObjC +Conform to the ISO 1990 C standard + +std=iso9899:199409 +SDCPP +Conform to the ISO 1990 C standard as amended in 1994 (and ratified in 1995) + +std=iso9899:1999 +C ObjC +Conform to the ISO 1999 C standard + +traditional-cpp +SDCPP +Enable traditional preprocessing + +;*** ISO C trigraphs are enabled by default on sdcpp +no-trigraphs +SDCPP +-no-trigraphs Disble ISO C trigraphs support + +v +SDCPP +Enable verbose output + +;***version +;***SDCPP Var(version_flag) +;***Display the compiler's version + +w +Common Var(inhibit_warnings) +Suppress warnings + +; This comment is to ensure we retain the blank line above. diff --git a/support/cpp/sdcpp.vcxproj b/support/cpp/sdcpp.vcxproj new file mode 100644 index 0000000..19f4516 --- /dev/null +++ b/support/cpp/sdcpp.vcxproj @@ -0,0 +1,253 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{57BCB0F8-EF4A-4688-9B36-55A8F6DC93BF}</ProjectGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\..\SDCC.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\..\SDCC.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\bin_vc\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\bin_vc\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectName)</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectName)</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>.\Release/sdcpp.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>.;..\sdbinutils\include;.\win32;.\libcpp;.\libcpp\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WIN32;_CONSOLE;HAVE_CONFIG_H;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>.\Release/sdcpp.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>.\Release/</AssemblerListingLocation>
+ <ObjectFileName>.\Release/</ObjectFileName>
+ <ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>..\..\bin_vc\$(TargetFileName)</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <ProgramDatabaseFile>.\Release/sdcpp.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <OutputFile>.\Release/sdcpp.bsc</OutputFile>
+ </Bscmake>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>.\Debug/sdcpp.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>.;..\sdbinutils\include;.\win32;.\libcpp;.\libcpp\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WIN32;_CONSOLE;HAVE_CONFIG_H;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <PrecompiledHeaderOutputFile>.\Debug/sdcpp.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
+ <ObjectFileName>.\Debug/</ObjectFileName>
+ <ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
+ <BrowseInformation>true</BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>..\..\bin_vc\$(TargetFileName)</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>.\Debug/sdcpp.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <OutputFile>.\Debug/sdcpp.bsc</OutputFile>
+ </Bscmake>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\sdbinutils\libiberty\alloca.c" />
+ <ClCompile Include="..\sdbinutils\libiberty\concat.c" />
+ <ClCompile Include="..\sdbinutils\libiberty\fopen_unlocked.c" />
+ <ClCompile Include="..\sdbinutils\libiberty\getpwd.c" />
+ <ClCompile Include="..\sdbinutils\libiberty\hashtab.c" />
+ <ClCompile Include="..\sdbinutils\libiberty\hex.c" />
+ <ClCompile Include="..\sdbinutils\libiberty\lbasename.c" />
+ <ClCompile Include="..\sdbinutils\libiberty\md5.c" />
+ <ClCompile Include="..\sdbinutils\libiberty\obstack.c" />
+ <ClCompile Include="..\sdbinutils\libiberty\safe-ctype.c" />
+ <ClCompile Include="..\sdbinutils\libiberty\vasprintf.c" />
+ <ClCompile Include="..\sdbinutils\libiberty\xexit.c" />
+ <ClCompile Include="..\sdbinutils\libiberty\xmalloc.c" />
+ <ClCompile Include="..\sdbinutils\libiberty\xmemdup.c" />
+ <ClCompile Include="..\sdbinutils\libiberty\xstrdup.c" />
+ <ClCompile Include="..\sdbinutils\libiberty\xstrerror.c" />
+ <ClCompile Include="c-incpath.c" />
+ <ClCompile Include="c-ppoutput.c" />
+ <ClCompile Include="cppdefault.c" />
+ <ClCompile Include="options.c" />
+ <ClCompile Include="opts-common.c" />
+ <ClCompile Include="opts.c" />
+ <ClCompile Include="prefix.c" />
+ <ClCompile Include="sdcpp-diagnostic.c" />
+ <ClCompile Include="sdcpp-opts.c" />
+ <ClCompile Include="sdcpp.c" />
+ <ClCompile Include="version.c" />
+ <ClCompile Include="libcpp\charset.c" />
+ <ClCompile Include="libcpp\directives.c" />
+ <ClCompile Include="libcpp\errors.c" />
+ <ClCompile Include="libcpp\expr.c" />
+ <ClCompile Include="libcpp\files.c" />
+ <ClCompile Include="libcpp\identifiers.c" />
+ <ClCompile Include="libcpp\init.c" />
+ <ClCompile Include="libcpp\lex.c" />
+ <ClCompile Include="libcpp\line-map.c" />
+ <ClCompile Include="libcpp\macro.c" />
+ <ClCompile Include="libcpp\mkdeps.c" />
+ <ClCompile Include="libcpp\symtab.c" />
+ <ClCompile Include="libcpp\traditional.c" />
+ <ClCompile Include="win32\dirent.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="ansidecl.h" />
+ <ClInclude Include="auto-host.h" />
+ <CustomBuild Include="auto-host_vc_in.h">
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy %(Identity) auto-host.h > nul</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy %(Identity) auto-host.h > nul</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">auto-host.h;%(Outputs)</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">auto-host.h;%(Outputs)</Outputs>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Generating: auto-host.h</Message>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Generating: auto-host.h</Message>
+ </CustomBuild>
+ <ClInclude Include="c-incpath.h" />
+ <ClInclude Include="config.h" />
+ <ClInclude Include="cppdefault.h" />
+ <ClInclude Include="hwint.h" />
+ <ClInclude Include="intl.h" />
+ <ClInclude Include="md5.h" />
+ <ClInclude Include="options.h" />
+ <ClInclude Include="opts.h" />
+ <ClInclude Include="output.h" />
+ <ClInclude Include="prefix.h" />
+ <ClInclude Include="sdcpp.h" />
+ <ClInclude Include="symcat.h" />
+ <ClInclude Include="system.h" />
+ <ClInclude Include="version.h" />
+ <ClInclude Include="libcpp\internal.h" />
+ <ClInclude Include="libcpp\system.h" />
+ <ClInclude Include="libcpp\ucnid.h" />
+ <ClInclude Include="libcpp\include\cpp-id-data.h" />
+ <ClInclude Include="libcpp\include\cpplib.h" />
+ <ClInclude Include="libcpp\include\line-map.h" />
+ <ClInclude Include="libcpp\include\mkdeps.h" />
+ <ClInclude Include="libcpp\include\symtab.h" />
+ <ClInclude Include="win32\dirent.h" />
+ <ClInclude Include="..\sdbinutils\include\libiberty.h" />
+ <ClInclude Include="..\sdbinutils\include\safe-ctype.h" />
+ <ClInclude Include="..\sdbinutils\include\splay-tree.h" />
+ <ClInclude Include="..\sdbinutils\include\filenames.h" />
+ <ClInclude Include="..\sdbinutils\include\hashtab.h" />
+ <ClInclude Include="..\sdbinutils\include\obstack.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="sdcpp.opt">
+ <FileType>Document</FileType>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">gawk -f opt-gather.awk %(Identity) > $(TMP)\genopts.tmp
+gawk -f opt-functions.awk -f optc-gen.awk -v header_name="config.h system.h options.h" $(TMP)\genopts.tmp > options.c
+gawk -f opt-functions.awk -f opth-gen.awk $(TMP)\genopts.tmp > options.h
+del $(TMP)\genopts.tmp</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">gawk -f opt-gather.awk %(Identity) > $(TMP)\genopts.tmp
+gawk -f opt-functions.awk -f optc-gen.awk -v header_name="config.h system.h options.h" $(TMP)\genopts.tmp > options.c
+gawk -f opt-functions.awk -f opth-gen.awk $(TMP)\genopts.tmp > options.h
+del $(TMP)\genopts.tmp</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">options.c;options.h;%(Outputs)</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">options.c;options.h;%(Outputs)</Outputs>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Generating: options.c and options.h</Message>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Generating: options.c and options.h</Message>
+ <LinkObjects Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkObjects>
+ </CustomBuild>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="opt-functions.awk" />
+ <None Include="opt-gather.awk" />
+ <None Include="optc-gen.awk" />
+ <None Include="opth-gen.awk" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file diff --git a/support/cpp/sdcpp.vcxproj.filters b/support/cpp/sdcpp.vcxproj.filters new file mode 100644 index 0000000..e25f59c --- /dev/null +++ b/support/cpp/sdcpp.vcxproj.filters @@ -0,0 +1,281 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{9ea8618e-5b35-434a-8483-cbb54ce77efe}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+ </Filter>
+ <Filter Include="Source Files\libcpp">
+ <UniqueIdentifier>{fbe76a09-a173-490d-b6b2-c513882e3379}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+ </Filter>
+ <Filter Include="Source Files\libiberty">
+ <UniqueIdentifier>{c359aa07-8032-4d56-bcd1-10116c18ccaa}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\win32">
+ <UniqueIdentifier>{91bececb-ff6f-4e1a-ac50-e893b4f567a9}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{27267bd9-1c5d-4e30-b898-aac7cffa3138}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl</Extensions>
+ </Filter>
+ <Filter Include="Header Files\libcpp_h">
+ <UniqueIdentifier>{77609fd9-1b04-4cc1-9bc6-9d65fb8799f1}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl</Extensions>
+ </Filter>
+ <Filter Include="Header Files\libcpp_h\include">
+ <UniqueIdentifier>{4ec4ee85-9d9f-4749-a495-0f3a96079d5f}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl</Extensions>
+ </Filter>
+ <Filter Include="Header Files\win32_h">
+ <UniqueIdentifier>{9e3e99c3-3f00-41e5-9964-8e386b8ba272}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl</Extensions>
+ </Filter>
+ <Filter Include="Custom Build">
+ <UniqueIdentifier>{8f30d6d7-0e72-4612-b478-b9c5a74ec6cb}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="c-incpath.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="c-ppoutput.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="cppdefault.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="options.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="opts-common.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="opts.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="prefix.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="sdcpp-diagnostic.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="sdcpp-opts.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="sdcpp.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="version.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="libcpp\charset.c">
+ <Filter>Source Files\libcpp</Filter>
+ </ClCompile>
+ <ClCompile Include="libcpp\directives.c">
+ <Filter>Source Files\libcpp</Filter>
+ </ClCompile>
+ <ClCompile Include="libcpp\errors.c">
+ <Filter>Source Files\libcpp</Filter>
+ </ClCompile>
+ <ClCompile Include="libcpp\expr.c">
+ <Filter>Source Files\libcpp</Filter>
+ </ClCompile>
+ <ClCompile Include="libcpp\files.c">
+ <Filter>Source Files\libcpp</Filter>
+ </ClCompile>
+ <ClCompile Include="libcpp\identifiers.c">
+ <Filter>Source Files\libcpp</Filter>
+ </ClCompile>
+ <ClCompile Include="libcpp\init.c">
+ <Filter>Source Files\libcpp</Filter>
+ </ClCompile>
+ <ClCompile Include="libcpp\lex.c">
+ <Filter>Source Files\libcpp</Filter>
+ </ClCompile>
+ <ClCompile Include="libcpp\line-map.c">
+ <Filter>Source Files\libcpp</Filter>
+ </ClCompile>
+ <ClCompile Include="libcpp\macro.c">
+ <Filter>Source Files\libcpp</Filter>
+ </ClCompile>
+ <ClCompile Include="libcpp\mkdeps.c">
+ <Filter>Source Files\libcpp</Filter>
+ </ClCompile>
+ <ClCompile Include="libcpp\symtab.c">
+ <Filter>Source Files\libcpp</Filter>
+ </ClCompile>
+ <ClCompile Include="libcpp\traditional.c">
+ <Filter>Source Files\libcpp</Filter>
+ </ClCompile>
+ <ClCompile Include="..\sdbinutils\libiberty\concat.c">
+ <Filter>Source Files\libiberty</Filter>
+ </ClCompile>
+ <ClCompile Include="..\sdbinutils\libiberty\fopen_unlocked.c">
+ <Filter>Source Files\libiberty</Filter>
+ </ClCompile>
+ <ClCompile Include="..\sdbinutils\libiberty\getpwd.c">
+ <Filter>Source Files\libiberty</Filter>
+ </ClCompile>
+ <ClCompile Include="..\sdbinutils\libiberty\hashtab.c">
+ <Filter>Source Files\libiberty</Filter>
+ </ClCompile>
+ <ClCompile Include="..\sdbinutils\libiberty\hex.c">
+ <Filter>Source Files\libiberty</Filter>
+ </ClCompile>
+ <ClCompile Include="..\sdbinutils\libiberty\lbasename.c">
+ <Filter>Source Files\libiberty</Filter>
+ </ClCompile>
+ <ClCompile Include="..\sdbinutils\libiberty\md5.c">
+ <Filter>Source Files\libiberty</Filter>
+ </ClCompile>
+ <ClCompile Include="..\sdbinutils\libiberty\obstack.c">
+ <Filter>Source Files\libiberty</Filter>
+ </ClCompile>
+ <ClCompile Include="..\sdbinutils\libiberty\safe-ctype.c">
+ <Filter>Source Files\libiberty</Filter>
+ </ClCompile>
+ <ClCompile Include="..\sdbinutils\libiberty\alloca.c">
+ <Filter>Source Files\libiberty</Filter>
+ </ClCompile>
+ <ClCompile Include="..\sdbinutils\libiberty\vasprintf.c">
+ <Filter>Source Files\libiberty</Filter>
+ </ClCompile>
+ <ClCompile Include="..\sdbinutils\libiberty\xexit.c">
+ <Filter>Source Files\libiberty</Filter>
+ </ClCompile>
+ <ClCompile Include="..\sdbinutils\libiberty\xmalloc.c">
+ <Filter>Source Files\libiberty</Filter>
+ </ClCompile>
+ <ClCompile Include="..\sdbinutils\libiberty\xmemdup.c">
+ <Filter>Source Files\libiberty</Filter>
+ </ClCompile>
+ <ClCompile Include="..\sdbinutils\libiberty\xstrdup.c">
+ <Filter>Source Files\libiberty</Filter>
+ </ClCompile>
+ <ClCompile Include="..\sdbinutils\libiberty\xstrerror.c">
+ <Filter>Source Files\libiberty</Filter>
+ </ClCompile>
+ <ClCompile Include="win32\dirent.c">
+ <Filter>Source Files\win32</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="ansidecl.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="c-incpath.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="config.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="cppdefault.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="hwint.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="intl.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\sdbinutils\include\libiberty.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="md5.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="options.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="opts.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="output.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="prefix.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\sdbinutils\include\safe-ctype.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="sdcpp.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\sdbinutils\include\splay-tree.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="symcat.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="system.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="version.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="libcpp\internal.h">
+ <Filter>Header Files\libcpp_h</Filter>
+ </ClInclude>
+ <ClInclude Include="libcpp\system.h">
+ <Filter>Header Files\libcpp_h</Filter>
+ </ClInclude>
+ <ClInclude Include="libcpp\ucnid.h">
+ <Filter>Header Files\libcpp_h</Filter>
+ </ClInclude>
+ <ClInclude Include="libcpp\include\cpp-id-data.h">
+ <Filter>Header Files\libcpp_h\include</Filter>
+ </ClInclude>
+ <ClInclude Include="libcpp\include\cpplib.h">
+ <Filter>Header Files\libcpp_h\include</Filter>
+ </ClInclude>
+ <ClInclude Include="libcpp\include\line-map.h">
+ <Filter>Header Files\libcpp_h\include</Filter>
+ </ClInclude>
+ <ClInclude Include="libcpp\include\mkdeps.h">
+ <Filter>Header Files\libcpp_h\include</Filter>
+ </ClInclude>
+ <ClInclude Include="libcpp\include\symtab.h">
+ <Filter>Header Files\libcpp_h\include</Filter>
+ </ClInclude>
+ <ClInclude Include="win32\dirent.h">
+ <Filter>Header Files\win32_h</Filter>
+ </ClInclude>
+ <ClInclude Include="..\sdbinutils\include\filenames.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\sdbinutils\include\hashtab.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\sdbinutils\include\obstack.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="auto-host.h">
+ <Filter>Header Files\libcpp_h\include</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="auto-host_vc_in.h">
+ <Filter>Custom Build</Filter>
+ </CustomBuild>
+ <CustomBuild Include="sdcpp.opt">
+ <Filter>Custom Build</Filter>
+ </CustomBuild>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="optc-gen.awk">
+ <Filter>Custom Build</Filter>
+ </None>
+ <None Include="opt-functions.awk">
+ <Filter>Custom Build</Filter>
+ </None>
+ <None Include="opt-gather.awk">
+ <Filter>Custom Build</Filter>
+ </None>
+ <None Include="opth-gen.awk">
+ <Filter>Custom Build</Filter>
+ </None>
+ </ItemGroup>
+</Project>
\ No newline at end of file diff --git a/support/cpp/symcat.h b/support/cpp/symcat.h new file mode 100644 index 0000000..03a1292 --- /dev/null +++ b/support/cpp/symcat.h @@ -0,0 +1,49 @@ +/* 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., + 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, 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 */ diff --git a/support/cpp/system.h b/support/cpp/system.h new file mode 100644 index 0000000..81e23ec --- /dev/null +++ b/support/cpp/system.h @@ -0,0 +1,1075 @@ +/* Get common system includes and various definitions and declarations based + on autoconf macros. + Copyright (C) 1998-2014 Free Software Foundation, Inc. + +This file is part of GCC. + +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 3, 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 COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + + +#ifndef GCC_SYSTEM_H +#define GCC_SYSTEM_H + +/* We must include stdarg.h before stdio.h. */ +#include <stdarg.h> + +#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 a generic NULL if one hasn't already been defined. */ +#ifndef NULL +#define NULL 0 +#endif + +/* Use the unlocked open routines from libiberty. */ + +/* Some of these are #define on some systems, e.g. on AIX to redirect + the names to 64bit capable functions for LARGE_FILES support. These + redefs are pointless here so we can override them. */ + +#undef fopen +#undef freopen + +#define fopen(PATH, MODE) fopen_unlocked (PATH, MODE) +#define fdopen(FILDES, MODE) fdopen_unlocked (FILDES, MODE) +#define freopen(PATH, MODE, STREAM) freopen_unlocked (PATH, MODE, STREAM) + +/* The compiler is not a multi-threaded application and therefore we + do not have to use the locking functions. In fact, using the locking + functions can cause the compiler to be significantly slower under + I/O bound conditions (such as -g -O0 on very large source files). + + HAVE_DECL_PUTC_UNLOCKED actually indicates whether or not the stdio + code is multi-thread safe by default. If it is set to 0, then do + not worry about using the _unlocked functions. + + fputs_unlocked, fwrite_unlocked, and fprintf_unlocked are + extensions and need to be prototyped by hand (since we do not + define _GNU_SOURCE). */ + +#if defined HAVE_DECL_PUTC_UNLOCKED && HAVE_DECL_PUTC_UNLOCKED + +# ifdef HAVE_PUTC_UNLOCKED +# undef putc +# define putc(C, Stream) putc_unlocked (C, Stream) +# endif +# ifdef HAVE_PUTCHAR_UNLOCKED +# undef putchar +# define putchar(C) putchar_unlocked (C) +# endif +# ifdef HAVE_GETC_UNLOCKED +# undef getc +# define getc(Stream) getc_unlocked (Stream) +# endif +# ifdef HAVE_GETCHAR_UNLOCKED +# undef getchar +# define getchar() getchar_unlocked () +# endif +# ifdef HAVE_FPUTC_UNLOCKED +# undef fputc +# define fputc(C, Stream) fputc_unlocked (C, Stream) +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef HAVE_CLEARERR_UNLOCKED +# undef clearerr +# define clearerr(Stream) clearerr_unlocked (Stream) +# if defined (HAVE_DECL_CLEARERR_UNLOCKED) && !HAVE_DECL_CLEARERR_UNLOCKED +extern void clearerr_unlocked (FILE *); +# endif +# endif +# ifdef HAVE_FEOF_UNLOCKED +# undef feof +# define feof(Stream) feof_unlocked (Stream) +# if defined (HAVE_DECL_FEOF_UNLOCKED) && !HAVE_DECL_FEOF_UNLOCKED +extern int feof_unlocked (FILE *); +# endif +# endif +# ifdef HAVE_FILENO_UNLOCKED +# undef fileno +# define fileno(Stream) fileno_unlocked (Stream) +# if defined (HAVE_DECL_FILENO_UNLOCKED) && !HAVE_DECL_FILENO_UNLOCKED +extern int fileno_unlocked (FILE *); +# endif +# endif +# ifdef HAVE_FFLUSH_UNLOCKED +# undef fflush +# define fflush(Stream) fflush_unlocked (Stream) +# if defined (HAVE_DECL_FFLUSH_UNLOCKED) && !HAVE_DECL_FFLUSH_UNLOCKED +extern int fflush_unlocked (FILE *); +# endif +# endif +# ifdef HAVE_FGETC_UNLOCKED +# undef fgetc +# define fgetc(Stream) fgetc_unlocked (Stream) +# if defined (HAVE_DECL_FGETC_UNLOCKED) && !HAVE_DECL_FGETC_UNLOCKED +extern int fgetc_unlocked (FILE *); +# endif +# endif +# ifdef HAVE_FGETS_UNLOCKED +# undef fgets +# define fgets(S, n, Stream) fgets_unlocked (S, n, Stream) +# if defined (HAVE_DECL_FGETS_UNLOCKED) && !HAVE_DECL_FGETS_UNLOCKED +extern char *fgets_unlocked (char *, int, FILE *); +# endif +# endif +# ifdef HAVE_FPUTS_UNLOCKED +# undef fputs +# define fputs(String, Stream) fputs_unlocked (String, Stream) +# if defined (HAVE_DECL_FPUTS_UNLOCKED) && !HAVE_DECL_FPUTS_UNLOCKED +extern int fputs_unlocked (const char *, FILE *); +# endif +# endif +# ifdef HAVE_FERROR_UNLOCKED +# undef ferror +# define ferror(Stream) ferror_unlocked (Stream) +# if defined (HAVE_DECL_FERROR_UNLOCKED) && !HAVE_DECL_FERROR_UNLOCKED +extern int ferror_unlocked (FILE *); +# endif +# endif +# ifdef HAVE_FREAD_UNLOCKED +# undef fread +# define fread(Ptr, Size, N, Stream) fread_unlocked (Ptr, Size, N, Stream) +# if defined (HAVE_DECL_FREAD_UNLOCKED) && !HAVE_DECL_FREAD_UNLOCKED +extern size_t fread_unlocked (void *, size_t, size_t, FILE *); +# endif +# endif +# ifdef HAVE_FWRITE_UNLOCKED +# undef fwrite +# define fwrite(Ptr, Size, N, Stream) fwrite_unlocked (Ptr, Size, N, Stream) +# if defined (HAVE_DECL_FWRITE_UNLOCKED) && !HAVE_DECL_FWRITE_UNLOCKED +extern size_t fwrite_unlocked (const void *, size_t, size_t, FILE *); +# endif +# endif +# ifdef HAVE_FPRINTF_UNLOCKED +# undef fprintf +/* We can't use a function-like macro here because we don't know if + we have varargs macros. */ +# define fprintf fprintf_unlocked +# if defined (HAVE_DECL_FPRINTF_UNLOCKED) && !HAVE_DECL_FPRINTF_UNLOCKED +extern int fprintf_unlocked (FILE *, const char *, ...); +# endif +# endif + +#ifdef __cplusplus +} +#endif + +#endif + +/* ??? Glibc's fwrite/fread_unlocked macros cause + "warning: signed and unsigned type in conditional expression". */ +#undef fread_unlocked +#undef fwrite_unlocked + +/* 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" + +#include <sys/types.h> + +#include <errno.h> + +#if !defined (errno) && defined (HAVE_DECL_ERRNO) && !HAVE_DECL_ERRNO +extern int errno; +#endif + +#ifdef __cplusplus +# include <cstring> +#endif + +/* Some of glibc's string inlines cause warnings. Plus we'd rather + rely on (and therefore test) GCC's string builtins. */ +#define __NO_STRING_INLINES + +#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 + +/* When compiling C++ we need to include <cstdlib> as well as <stdlib.h> so + that it is processed before we poison "malloc"; otherwise, if a source + file uses a standard library header that includes <cstdlib>, we will get + an error about 'using std::malloc'. */ +#ifdef __cplusplus +#include <cstdlib> +#endif + +/* Undef vec_free from AIX stdlib.h header which conflicts with vec.h. */ +#undef vec_free + +/* 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 + +#define ICE_EXIT_CODE 4 + +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif + +#ifdef HAVE_SYS_PARAM_H +# include <sys/param.h> +/* We use these identifiers later and they appear in some vendor param.h's. */ +# undef PREFETCH +# undef m_slot +#endif + +#if HAVE_LIMITS_H +# include <limits.h> +#endif + +/* A macro to determine whether a VALUE lies inclusively within a + certain range without evaluating the VALUE more than once. This + macro won't warn if the VALUE is unsigned and the LOWER bound is + zero, as it would e.g. with "VALUE >= 0 && ...". Note the LOWER + bound *is* evaluated twice, and LOWER must not be greater than + UPPER. However the bounds themselves can be either positive or + negative. */ +#define IN_RANGE(VALUE, LOWER, UPPER) \ + ((unsigned HOST_WIDE_INT) (VALUE) - (unsigned HOST_WIDE_INT) (LOWER) \ + <= (unsigned HOST_WIDE_INT) (UPPER) - (unsigned HOST_WIDE_INT) (LOWER)) + +/* 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 +#ifndef O_BINARY +# define O_BINARY 0 +#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 +#ifndef WCOREDUMP +#define WCOREDUMP(S) ((S) & WCOREFLG) +#endif +#ifndef WCOREFLG +#define WCOREFLG 0200 +#endif + +#include <signal.h> +#if !defined (SIGCHLD) && defined (SIGCLD) +# define SIGCHLD SIGCLD +#endif + +#ifdef HAVE_SYS_MMAN_H +# include <sys/mman.h> +#endif + +#ifndef MAP_FAILED +# define MAP_FAILED ((void *)-1) +#endif + +#if !defined (MAP_ANONYMOUS) && defined (MAP_ANON) +# define MAP_ANONYMOUS MAP_ANON +#endif + +#ifdef HAVE_SYS_RESOURCE_H +# include <sys/resource.h> +#endif + +#ifdef HAVE_SYS_TIMES_H +# include <sys/times.h> +#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_*)". */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined (HAVE_DECL_ATOF) && !HAVE_DECL_ATOF +extern double atof (const char *); +#endif + +#if defined (HAVE_DECL_ATOL) && !HAVE_DECL_ATOL +extern long atol (const char *); +#endif + +#if defined (HAVE_DECL_FREE) && !HAVE_DECL_FREE +extern void free (void *); +#endif + +#if defined (HAVE_DECL_GETCWD) && !HAVE_DECL_GETCWD +extern char *getcwd (char *, size_t); +#endif + +#if defined (HAVE_DECL_GETENV) && !HAVE_DECL_GETENV +extern char *getenv (const char *); +#endif + +#if defined (HAVE_DECL_GETOPT) && !HAVE_DECL_GETOPT +extern int getopt (int, char * const *, const char *); +#endif + +#if defined (HAVE_DECL_GETPAGESIZE) && !HAVE_DECL_GETPAGESIZE +extern int getpagesize (void); +#endif + +#if defined (HAVE_DECL_GETWD) && !HAVE_DECL_GETWD +extern char *getwd (char *); +#endif + +#if defined (HAVE_DECL_SBRK) && !HAVE_DECL_SBRK +extern void *sbrk (int); +#endif + +#if defined (HAVE_DECL_STRSTR) && !HAVE_DECL_STRSTR +extern char *strstr (const char *, const char *); +#endif + +#if defined (HAVE_DECL_STPCPY) && !HAVE_DECL_STPCPY +extern char *stpcpy (char *, const char *); +#endif + +#ifdef __cplusplus +} +#endif + +#ifdef HAVE_MALLOC_H +#include <malloc.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined (HAVE_DECL_MALLOC) && !HAVE_DECL_MALLOC +extern void *malloc (size_t); +#endif + +#if defined (HAVE_DECL_CALLOC) && !HAVE_DECL_CALLOC +extern void *calloc (size_t, size_t); +#endif + +#if defined (HAVE_DECL_REALLOC) && !HAVE_DECL_REALLOC +extern void *realloc (void *, size_t); +#endif + +#ifdef __cplusplus +} +#endif + +#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif + +#ifdef HAVE_INTTYPES_H +#include <inttypes.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* If the system doesn't provide strsignal, we get it defined in + libiberty but no declaration is supplied. */ +#if !defined (HAVE_STRSIGNAL) \ + || (defined (HAVE_DECL_STRSIGNAL) && !HAVE_DECL_STRSIGNAL) +# ifndef strsignal +extern +#if 0 +const +#endif +char *strsignal (int); +# endif +#endif + +#ifdef HAVE_GETRLIMIT +# if defined (HAVE_DECL_GETRLIMIT) && !HAVE_DECL_GETRLIMIT +# ifndef getrlimit +struct rlimit; +extern int getrlimit (int, struct rlimit *); +# endif +# endif +#endif + +#ifdef HAVE_SETRLIMIT +# if defined (HAVE_DECL_SETRLIMIT) && !HAVE_DECL_SETRLIMIT +# ifndef setrlimit +struct rlimit; +extern int setrlimit (int, const struct rlimit *); +# endif +# endif +#endif + +#if defined (HAVE_DECL_ABORT) && !HAVE_DECL_ABORT +extern void abort (void); +#endif + +#if defined (HAVE_DECL_SNPRINTF) && !HAVE_DECL_SNPRINTF +extern int snprintf (char *, size_t, const char *, ...); +#endif + +#if defined (HAVE_DECL_VSNPRINTF) && !HAVE_DECL_VSNPRINTF +extern int vsnprintf (char *, size_t, const char *, va_list); +#endif + +#ifdef __cplusplus +} +#endif + +/* 1 if we have C99 designated initializers. */ +#if !defined(HAVE_DESIGNATED_INITIALIZERS) +#define HAVE_DESIGNATED_INITIALIZERS \ + (((GCC_VERSION >= 2007) || (__STDC_VERSION__ >= 199901L)) \ + && !defined(__cplusplus)) +#endif + +#if !defined(HAVE_DESIGNATED_UNION_INITIALIZERS) +#define HAVE_DESIGNATED_UNION_INITIALIZERS \ + (((GCC_VERSION >= 2007) || (__STDC_VERSION__ >= 199901L)) \ + && (!defined(__cplusplus) || (GCC_VERSION >= 4007))) +#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 + +/* 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 + +#ifndef HAVE_KILL +# define kill(p,s) raise (s) +#endif + +/* Provide a way to print an address via printf. */ +#ifndef HOST_PTR_PRINTF +#define HOST_PTR_PRINTF "%p" +#endif /* ! HOST_PTR_PRINTF */ + +/* By default, colon separates directories in a path. */ +#ifndef PATH_SEPARATOR +#define PATH_SEPARATOR ':' +#endif + +/* Filename handling macros. */ +#include "filenames.h" + +/* These should be phased out in favor of IS_DIR_SEPARATOR, where possible. */ +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# ifdef HAVE_DOS_BASED_FILE_SYSTEM +# define DIR_SEPARATOR_2 '\\' +# endif +#endif + +#if defined (ENABLE_PLUGIN) && defined (HAVE_DLFCN_H) +/* If plugin support is enabled, we could use libdl. */ +#include <dlfcn.h> +#endif + +#if 0 +/* Do not introduce a gmp.h dependency on the build system. */ +#ifndef GENERATOR_FILE +#include <gmp.h> +#endif +#endif + +/* Get libiberty declarations. */ +#include "libiberty.h" + +#undef FFS /* Some systems predefine this symbol; don't let it interfere. */ +#undef FLOAT /* Likewise. */ +#undef ABS /* Likewise. */ +#undef PC /* Likewise. */ + +/* 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 + +#ifndef offsetof +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *) 0)->MEMBER) +#endif + +/* Various error reporting routines want to use __FUNCTION__. */ +#if (GCC_VERSION < 2007) +#ifndef __FUNCTION__ +#define __FUNCTION__ "?" +#endif /* ! __FUNCTION__ */ +#endif + +/* __builtin_expect(A, B) evaluates to A, but notifies the compiler that + the most likely value of A is B. This feature was added at some point + between 2.95 and 3.0. Let's use 3.0 as the lower bound for now. */ +#if (GCC_VERSION < 3000) +#define __builtin_expect(a, b) (a) +#endif + +/* Redefine abort to report an internal error w/o coredump, and + reporting the location of the error in the source file. */ +extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN; +#define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__) + +/* Use gcc_assert(EXPR) to test invariants. */ +#if ENABLE_ASSERT_CHECKING +#define gcc_assert(EXPR) \ + ((void)(!(EXPR) ? fancy_abort (__FILE__, __LINE__, __FUNCTION__), 0 : 0)) +#elif (GCC_VERSION >= 4005) +#define gcc_assert(EXPR) \ + ((void)(__builtin_expect (!(EXPR), 0) ? __builtin_unreachable (), 0 : 0)) +#else +/* Include EXPR, so that unused variable warnings do not occur. */ +#define gcc_assert(EXPR) ((void)(0 && (EXPR))) +#endif + +#ifdef ENABLE_CHECKING +#define gcc_checking_assert(EXPR) gcc_assert (EXPR) +#else +#define gcc_checking_assert(EXPR) ((void)(0 && (EXPR))) +#endif + +/* Use gcc_unreachable() to mark unreachable locations (like an + unreachable default case of a switch. Do not use gcc_assert(0). */ +#if (GCC_VERSION >= 4005) && !ENABLE_ASSERT_CHECKING +#define gcc_unreachable() __builtin_unreachable () +#else +#define gcc_unreachable() (fancy_abort (__FILE__, __LINE__, __FUNCTION__)) +#endif + +/* Provide a fake boolean type. We make no attempt to use the + C99 _Bool, as it may not be available in the bootstrap compiler, + and even if it is, it is liable to be buggy. + This must be after all inclusion of system headers, as some of + them will mess us up. */ + +#undef TRUE +#undef FALSE + +#ifdef __cplusplus + /* Obsolete. */ +# define TRUE true +# define FALSE false +#else /* !__cplusplus */ +# undef bool +# undef true +# undef false + +# define bool unsigned char +# define true 1 +# define false 0 + + /* Obsolete. */ +# define TRUE true +# define FALSE false +#endif /* !__cplusplus */ + +/* Some compilers do not allow the use of unsigned char in bitfields. */ +#define BOOL_BITFIELD unsigned int + +/* 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 defined(FLEX_SCANNER) || defined(YYBISON) || defined(YYBYACC) +/* Flex and bison use malloc and realloc. Yuk. Note that this means + really_call_* cannot be used in a .l or .y file. */ +#define malloc xmalloc +#define realloc xrealloc +#endif + +#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 calloc +#undef strdup + #pragma GCC poison calloc strdup + +#if !defined(FLEX_SCANNER) && !defined(YYBISON) +#undef malloc +#undef realloc + #pragma GCC poison malloc realloc +#endif + +/* The %m format should be used when GCC's main diagnostic functions + supporting %m are available, and xstrerror from libiberty + otherwise. */ +#undef strerror + #pragma GCC poison strerror + +/* loc_t is defined on some systems and too inviting for some + programmers to avoid. */ +#undef loc_t + #pragma GCC poison loc_t + +/* Old target macros that have moved to the target hooks structure. */ + #pragma GCC poison ASM_OPEN_PAREN ASM_CLOSE_PAREN \ + FUNCTION_PROLOGUE FUNCTION_EPILOGUE \ + FUNCTION_END_PROLOGUE FUNCTION_BEGIN_EPILOGUE \ + DECL_MACHINE_ATTRIBUTES COMP_TYPE_ATTRIBUTES INSERT_ATTRIBUTES \ + VALID_MACHINE_DECL_ATTRIBUTE VALID_MACHINE_TYPE_ATTRIBUTE \ + SET_DEFAULT_TYPE_ATTRIBUTES SET_DEFAULT_DECL_ATTRIBUTES \ + MERGE_MACHINE_TYPE_ATTRIBUTES MERGE_MACHINE_DECL_ATTRIBUTES \ + MD_INIT_BUILTINS MD_EXPAND_BUILTIN ASM_OUTPUT_CONSTRUCTOR \ + ASM_OUTPUT_DESTRUCTOR SIGNED_CHAR_SPEC MAX_CHAR_TYPE_SIZE \ + WCHAR_UNSIGNED UNIQUE_SECTION SELECT_SECTION SELECT_RTX_SECTION \ + ENCODE_SECTION_INFO STRIP_NAME_ENCODING ASM_GLOBALIZE_LABEL \ + ASM_OUTPUT_MI_THUNK CONST_COSTS RTX_COSTS DEFAULT_RTX_COSTS \ + ADDRESS_COST MACHINE_DEPENDENT_REORG ASM_FILE_START ASM_FILE_END \ + ASM_SIMPLIFY_DWARF_ADDR INIT_TARGET_OPTABS INIT_SUBTARGET_OPTABS \ + INIT_GOFAST_OPTABS MULSI3_LIBCALL MULDI3_LIBCALL DIVSI3_LIBCALL \ + DIVDI3_LIBCALL UDIVSI3_LIBCALL UDIVDI3_LIBCALL MODSI3_LIBCALL \ + MODDI3_LIBCALL UMODSI3_LIBCALL UMODDI3_LIBCALL BUILD_VA_LIST_TYPE \ + PRETEND_OUTGOING_VARARGS_NAMED STRUCT_VALUE_INCOMING_REGNUM \ + ASM_OUTPUT_SECTION_NAME PROMOTE_FUNCTION_ARGS PROMOTE_FUNCTION_MODE \ + STRUCT_VALUE_INCOMING STRICT_ARGUMENT_NAMING \ + PROMOTE_FUNCTION_RETURN PROMOTE_PROTOTYPES STRUCT_VALUE_REGNUM \ + SETUP_INCOMING_VARARGS EXPAND_BUILTIN_SAVEREGS \ + DEFAULT_SHORT_ENUMS SPLIT_COMPLEX_ARGS MD_ASM_CLOBBERS \ + HANDLE_PRAGMA_REDEFINE_EXTNAME HANDLE_PRAGMA_EXTERN_PREFIX \ + MUST_PASS_IN_STACK FUNCTION_ARG_PASS_BY_REFERENCE \ + VECTOR_MODE_SUPPORTED_P TARGET_SUPPORTS_HIDDEN \ + FUNCTION_ARG_PARTIAL_NREGS ASM_OUTPUT_DWARF_DTPREL \ + ALLOCATE_INITIAL_VALUE LEGITIMIZE_ADDRESS FRAME_POINTER_REQUIRED \ + CAN_ELIMINATE TRAMPOLINE_TEMPLATE INITIALIZE_TRAMPOLINE \ + TRAMPOLINE_ADJUST_ADDRESS STATIC_CHAIN STATIC_CHAIN_INCOMING \ + RETURN_POPS_ARGS UNITS_PER_SIMD_WORD OVERRIDE_OPTIONS \ + OPTIMIZATION_OPTIONS CLASS_LIKELY_SPILLED_P \ + USING_SJLJ_EXCEPTIONS TARGET_UNWIND_INFO \ + LABEL_ALIGN_MAX_SKIP LOOP_ALIGN_MAX_SKIP \ + LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP JUMP_ALIGN_MAX_SKIP \ + CAN_DEBUG_WITHOUT_FP UNLIKELY_EXECUTED_TEXT_SECTION_NAME \ + HOT_TEXT_SECTION_NAME LEGITIMATE_CONSTANT_P ALWAYS_STRIP_DOTDOT \ + OUTPUT_ADDR_CONST_EXTRA SMALL_REGISTER_CLASSES ASM_OUTPUT_IDENT \ + ASM_BYTE_OP MEMBER_TYPE_FORCES_BLK + +/* Target macros only used for code built for the target, that have + moved to libgcc-tm.h or have never been present elsewhere. */ + #pragma GCC poison DECLARE_LIBRARY_RENAMES LIBGCC2_GNU_PREFIX \ + MD_UNWIND_SUPPORT MD_FROB_UPDATE_CONTEXT ENABLE_EXECUTE_STACK \ + REG_VALUE_IN_UNWIND_CONTEXT ASSUME_EXTENDED_UNWIND_CONTEXT + +/* Other obsolete target macros, or macros that used to be in target + headers and were not used, and may be obsolete or may never have + been used. */ + #pragma GCC poison INT_ASM_OP ASM_OUTPUT_EH_REGION_BEG CPP_PREDEFINES \ + ASM_OUTPUT_EH_REGION_END ASM_OUTPUT_LABELREF_AS_INT SMALL_STACK \ + DOESNT_NEED_UNWINDER EH_TABLE_LOOKUP OBJC_SELECTORS_WITHOUT_LABELS \ + OMIT_EH_TABLE EASY_DIV_EXPR IMPLICIT_FIX_EXPR \ + LONGJMP_RESTORE_FROM_STACK MAX_INT_TYPE_SIZE ASM_IDENTIFY_GCC \ + STDC_VALUE TRAMPOLINE_ALIGN ASM_IDENTIFY_GCC_AFTER_SOURCE \ + SLOW_ZERO_EXTEND SUBREG_REGNO_OFFSET DWARF_LINE_MIN_INSTR_LENGTH \ + TRADITIONAL_RETURN_FLOAT NO_BUILTIN_SIZE_TYPE \ + NO_BUILTIN_PTRDIFF_TYPE NO_BUILTIN_WCHAR_TYPE NO_BUILTIN_WINT_TYPE \ + BLOCK_PROFILER BLOCK_PROFILER_CODE FUNCTION_BLOCK_PROFILER \ + FUNCTION_BLOCK_PROFILER_EXIT MACHINE_STATE_SAVE \ + MACHINE_STATE_RESTORE SCCS_DIRECTIVE SECTION_ASM_OP BYTEORDER \ + ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL HOST_WORDS_BIG_ENDIAN \ + OBJC_PROLOGUE ALLOCATE_TRAMPOLINE HANDLE_PRAGMA ROUND_TYPE_SIZE \ + ROUND_TYPE_SIZE_UNIT CONST_SECTION_ASM_OP CRT_GET_RFIB_TEXT \ + DBX_LBRAC_FIRST DBX_OUTPUT_ENUM DBX_OUTPUT_SOURCE_FILENAME \ + DBX_WORKING_DIRECTORY INSN_CACHE_DEPTH INSN_CACHE_SIZE \ + INSN_CACHE_LINE_WIDTH INIT_SECTION_PREAMBLE NEED_ATEXIT ON_EXIT \ + EXIT_BODY OBJECT_FORMAT_ROSE MULTIBYTE_CHARS MAP_CHARACTER \ + LIBGCC_NEEDS_DOUBLE FINAL_PRESCAN_LABEL DEFAULT_CALLER_SAVES \ + LOAD_ARGS_REVERSED MAX_INTEGER_COMPUTATION_MODE \ + CONVERT_HARD_REGISTER_TO_SSA_P ASM_OUTPUT_MAIN_SOURCE_FILENAME \ + FIRST_INSN_ADDRESS TEXT_SECTION SHARED_BSS_SECTION_ASM_OP \ + PROMOTED_MODE EXPAND_BUILTIN_VA_END \ + LINKER_DOES_NOT_WORK_WITH_DWARF2 FUNCTION_ARG_KEEP_AS_REFERENCE \ + GIV_SORT_CRITERION MAX_LONG_TYPE_SIZE MAX_LONG_DOUBLE_TYPE_SIZE \ + MAX_WCHAR_TYPE_SIZE SHARED_SECTION_ASM_OP INTEGRATE_THRESHOLD \ + FINAL_REG_PARM_STACK_SPACE MAYBE_REG_PARM_STACK_SPACE \ + TRADITIONAL_PIPELINE_INTERFACE DFA_PIPELINE_INTERFACE \ + DBX_OUTPUT_STANDARD_TYPES BUILTIN_SETJMP_FRAME_VALUE \ + SUNOS4_SHARED_LIBRARIES PROMOTE_FOR_CALL_ONLY \ + SPACE_AFTER_L_OPTION NO_RECURSIVE_FUNCTION_CSE \ + DEFAULT_MAIN_RETURN TARGET_MEM_FUNCTIONS EXPAND_BUILTIN_VA_ARG \ + COLLECT_PARSE_FLAG DWARF2_GENERATE_TEXT_SECTION_LABEL WINNING_GDB \ + ASM_OUTPUT_FILENAME ASM_OUTPUT_SOURCE_LINE FILE_NAME_JOINER \ + GDB_INV_REF_REGPARM_STABS_LETTER DBX_MEMPARM_STABS_LETTER \ + PUT_SDB_SRC_FILE STABS_GCC_MARKER DBX_OUTPUT_FUNCTION_END \ + DBX_OUTPUT_GCC_MARKER DBX_FINISH_SYMBOL SDB_GENERATE_FAKE \ + NON_SAVING_SETJMP TARGET_LATE_RTL_PROLOGUE_EPILOGUE \ + CASE_DROPS_THROUGH TARGET_BELL TARGET_BS TARGET_CR TARGET_DIGIT0 \ + TARGET_ESC TARGET_FF TARGET_NEWLINE TARGET_TAB TARGET_VT \ + LINK_LIBGCC_SPECIAL DONT_ACCESS_GBLS_AFTER_EPILOGUE \ + TARGET_OPTIONS TARGET_SWITCHES EXTRA_CC_MODES FINALIZE_PIC \ + PREDICATE_CODES SPECIAL_MODE_PREDICATES UNALIGNED_WORD_ASM_OP \ + EXTRA_SECTIONS EXTRA_SECTION_FUNCTIONS READONLY_DATA_SECTION \ + TARGET_ASM_EXCEPTION_SECTION TARGET_ASM_EH_FRAME_SECTION \ + SMALL_ARG_MAX ASM_OUTPUT_SHARED_BSS ASM_OUTPUT_SHARED_COMMON \ + ASM_OUTPUT_SHARED_LOCAL ASM_MAKE_LABEL_LINKONCE \ + STACK_CHECK_PROBE_INTERVAL STACK_CHECK_PROBE_LOAD \ + ORDER_REGS_FOR_LOCAL_ALLOC FUNCTION_OUTGOING_VALUE \ + ASM_DECLARE_CONSTANT_NAME MODIFY_TARGET_NAME SWITCHES_NEED_SPACES \ + SWITCH_CURTAILS_COMPILATION SWITCH_TAKES_ARG WORD_SWITCH_TAKES_ARG \ + TARGET_OPTION_TRANSLATE_TABLE HANDLE_PRAGMA_PACK_PUSH_POP \ + HANDLE_SYSV_PRAGMA HANDLE_PRAGMA_WEAK CONDITIONAL_REGISTER_USAGE \ + FUNCTION_ARG_BOUNDARY MUST_USE_SJLJ_EXCEPTIONS US_SOFTWARE_GOFAST \ + USING_SVR4_H SVR4_ASM_SPEC FUNCTION_ARG FUNCTION_ARG_ADVANCE \ + FUNCTION_INCOMING_ARG IRA_COVER_CLASSES TARGET_VERSION \ + MACHINE_TYPE TARGET_HAS_TARGETCM ASM_OUTPUT_BSS \ + SETJMP_VIA_SAVE_AREA FORBIDDEN_INC_DEC_CLASSES \ + PREFERRED_OUTPUT_RELOAD_CLASS SYSTEM_INCLUDE_DIR \ + STANDARD_INCLUDE_DIR STANDARD_INCLUDE_COMPONENT \ + LINK_ELIMINATE_DUPLICATE_LDIRECTORIES MIPS_DEBUGGING_INFO \ + IDENT_ASM_OP ALL_COP_ADDITIONAL_REGISTER_NAMES DBX_OUTPUT_LBRAC \ + DBX_OUTPUT_NFUN DBX_OUTPUT_RBRAC RANGE_TEST_NON_SHORT_CIRCUIT \ + REAL_VALUE_TRUNCATE REVERSE_CONDEXEC_PREDICATES_P \ + TARGET_ALIGN_ANON_BITFIELDS TARGET_NARROW_VOLATILE_BITFIELDS \ + IDENT_ASM_OP UNALIGNED_SHORT_ASM_OP UNALIGNED_INT_ASM_OP \ + UNALIGNED_LONG_ASM_OP UNALIGNED_DOUBLE_INT_ASM_OP \ + USE_COMMON_FOR_ONE_ONLY IFCVT_EXTRA_FIELDS IFCVT_INIT_EXTRA_FIELDS \ + CASE_USE_BIT_TESTS FIXUNS_TRUNC_LIKE_FIX_TRUNC \ + GO_IF_MODE_DEPENDENT_ADDRESS DELAY_SLOTS_FOR_EPILOGUE \ + ELIGIBLE_FOR_EPILOGUE_DELAY TARGET_C99_FUNCTIONS TARGET_HAS_SINCOS + +/* Hooks that are no longer used. */ + #pragma GCC poison LANG_HOOKS_FUNCTION_MARK LANG_HOOKS_FUNCTION_FREE \ + LANG_HOOKS_MARK_TREE LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES \ + LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS \ + LANG_HOOKS_PUSHLEVEL LANG_HOOKS_SET_BLOCK \ + LANG_HOOKS_MAYBE_BUILD_CLEANUP LANG_HOOKS_UPDATE_DECL_AFTER_SAVING \ + LANG_HOOKS_POPLEVEL LANG_HOOKS_TRUTHVALUE_CONVERSION \ + TARGET_PROMOTE_FUNCTION_ARGS TARGET_PROMOTE_FUNCTION_RETURN \ + LANG_HOOKS_MISSING_ARGUMENT LANG_HOOKS_HASH_TYPES \ + TARGET_HANDLE_OFAST TARGET_OPTION_OPTIMIZATION \ + TARGET_IRA_COVER_CLASSES TARGET_HELP \ + TARGET_HANDLE_PRAGMA_EXTERN_PREFIX \ + TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN \ + TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD \ + +/* Arrays that were deleted in favor of a functional interface. */ + #pragma GCC poison built_in_decls implicit_built_in_decls + +/* Hooks into libgcc2. */ + #pragma GCC poison LIBGCC2_DOUBLE_TYPE_SIZE LIBGCC2_WORDS_BIG_ENDIAN \ + LIBGCC2_FLOAT_WORDS_BIG_ENDIAN + +/* Miscellaneous macros that are no longer used. */ + #pragma GCC poison USE_MAPPED_LOCATION GET_ENVIRONMENT + +/* Libiberty macros that are no longer used in GCC. */ +#undef ANSI_PROTOTYPES +#undef PTR_CONST +#undef LONG_DOUBLE +#undef VPARAMS +#undef VA_OPEN +#undef VA_FIXEDARG +#undef VA_CLOSE +#undef VA_START + #pragma GCC poison ANSI_PROTOTYPES PTR_CONST LONG_DOUBLE VPARAMS VA_OPEN \ + VA_FIXEDARG VA_CLOSE VA_START +#endif /* IN_GCC */ + +/* Front ends should never have to include middle-end headers. Enforce + this by poisoning the header double-include protection defines. */ +#ifdef IN_GCC_FRONTEND +#pragma GCC poison GCC_RTL_H GCC_EXCEPT_H GCC_EXPR_H +#endif + +/* 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 */ + +/* This macro allows casting away const-ness to pass -Wcast-qual + warnings. DO NOT USE THIS UNLESS YOU REALLY HAVE TO! It should + only be used in certain specific cases. One valid case is where + the C standard definitions or prototypes force you to. E.g. if you + need to free a const object, or if you pass a const string to + execv, et al. Another valid use would be in an allocation function + that creates const objects that need to be initialized. In some + cases we have non-const functions that return the argument + (e.g. next_nonnote_insn). Rather than create const shadow + functions, we can cast away const-ness in calling these interfaces + if we're careful to verify that the called function does indeed not + modify its argument and the return value is only used in a const + context. (This can be somewhat dangerous as these assumptions can + change after the fact). Beyond these uses, most other cases of + using this macro should be viewed with extreme caution. */ + +#ifdef __cplusplus +#define CONST_CAST2(TOTYPE,FROMTYPE,X) (const_cast<TOTYPE> (X)) +#else +#if defined(__GNUC__) && GCC_VERSION > 4000 +/* GCC 4.0.x has a bug where it may ICE on this expression, + so does GCC 3.4.x (PR17436). */ +#define CONST_CAST2(TOTYPE,FROMTYPE,X) ((__extension__(union {FROMTYPE _q; TOTYPE _nq;})(X))._nq) +#elif defined(__GNUC__) +static inline char * +helper_const_non_const_cast (const char *p) +{ + union { + const char *const_c; + char *c; + } val; + val.const_c = p; + return val.c; +} + +#define CONST_CAST2(TOTYPE,FROMTYPE,X) \ + ((TOTYPE) helper_const_non_const_cast ((const char *) (FROMTYPE) (X))) +#else +#define CONST_CAST2(TOTYPE,FROMTYPE,X) ((TOTYPE)(FROMTYPE)(X)) +#endif +#endif +#define CONST_CAST(TYPE,X) CONST_CAST2 (TYPE, const TYPE, (X)) +#define CONST_CAST_TREE(X) CONST_CAST (union tree_node *, (X)) +#define CONST_CAST_RTX(X) CONST_CAST (struct rtx_def *, (X)) +#define CONST_CAST_BB(X) CONST_CAST (struct basic_block_def *, (X)) +#define CONST_CAST_GIMPLE(X) CONST_CAST (struct gimple_statement_base *, (X)) + +/* Activate certain diagnostics as warnings (not errors via the + -Werror flag). */ +#if GCC_VERSION >= 4003 +/* If asserts are disabled, activate -Wuninitialized as a warning (not + an error/-Werror). */ +#ifndef ENABLE_ASSERT_CHECKING +#pragma GCC diagnostic warning "-Wuninitialized" +#endif +#endif + +#ifdef ENABLE_VALGRIND_CHECKING +# ifdef HAVE_VALGRIND_MEMCHECK_H +# include <valgrind/memcheck.h> +# elif defined HAVE_MEMCHECK_H +# include <memcheck.h> +# else +# include <valgrind.h> +# endif +/* Compatibility macros to let valgrind 3.1 work. */ +# ifndef VALGRIND_MAKE_MEM_NOACCESS +# define VALGRIND_MAKE_MEM_NOACCESS VALGRIND_MAKE_NOACCESS +# endif +# ifndef VALGRIND_MAKE_MEM_DEFINED +# define VALGRIND_MAKE_MEM_DEFINED VALGRIND_MAKE_READABLE +# endif +# ifndef VALGRIND_MAKE_MEM_UNDEFINED +# define VALGRIND_MAKE_MEM_UNDEFINED VALGRIND_MAKE_WRITABLE +# endif +#else +/* Avoid #ifdef:s when we can help it. */ +#define VALGRIND_DISCARD(x) +#define VALGRIND_MALLOCLIKE_BLOCK(w,x,y,z) +#define VALGRIND_FREELIKE_BLOCK(x,y) +#endif + +/* In LTO -fwhole-program build we still want to keep the debug functions available + for debugger. Mark them as used to prevent removal. */ +#if (GCC_VERSION > 4000) +#define DEBUG_FUNCTION __attribute__ ((__used__)) +#define DEBUG_VARIABLE __attribute__ ((__used__)) +#else +#define DEBUG_FUNCTION +#define DEBUG_VARIABLE +#endif + +/* Get definitions of HOST_WIDE_INT and HOST_WIDEST_INT. */ +#include "hwint.h" + +/* SDCC specific */ +#include "sdcpp.h" + +#endif /* ! GCC_SYSTEM_H */ diff --git a/support/cpp/version.c b/support/cpp/version.c new file mode 100644 index 0000000..ba7334e --- /dev/null +++ b/support/cpp/version.c @@ -0,0 +1,50 @@ +/* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, + 2007 Free Software Foundation, Inc. + +This file is part of GCC. + +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 3, 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 COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "version.h" + +/* This is the trailing component of the string reported as the + version number by all components of the compiler. For an official + FSF release, it is empty. If you distribute a modified version of + GCC, please change this string to indicate that. The suggested + format is a leading space, followed by your organization's name + in parentheses. You may also wish to include a number indicating + the revision of your modified compiler. */ + +#define BASEVER "4.6.3" +#define DATESTAMP +#define DEVPHASE +#define VERSUFFIX " (GNU cpp adapted for SDCC)" +#define PKGVERSION "(SDCC) " + +/* This is the location of the online document giving instructions for + reporting bugs. If you distribute a modified version of GCC, + please configure with --with-bugurl pointing to a document giving + instructions for reporting bugs to you, not us. (You are of course + welcome to forward us bugs reported to you, if you determine that + they are not bugs in your modifications.) */ + +const char bug_report_url[] = "<URL:http://sourceforge.net/tracker/?atid=100599&group_id=599&func=browse>"; + +/* The complete version string, assembled from several pieces. + BASEVER, DATESTAMP, DEVPHASE, and REVISION are defined by the + Makefile. */ + +const char version_string[] = BASEVER DATESTAMP DEVPHASE VERSUFFIX; +const char pkgversion_string[] = PKGVERSION;
\ No newline at end of file diff --git a/support/cpp/version.h b/support/cpp/version.h new file mode 100644 index 0000000..8891903 --- /dev/null +++ b/support/cpp/version.h @@ -0,0 +1,6 @@ +#ifndef GCC_VERSION_H +#define GCC_VERSION_H +extern const char version_string[]; +extern const char pkgversion_string[]; +extern const char bug_report_url[]; +#endif /* ! GCC_VERSION_H */ diff --git a/support/cpp/win32/dirent.c b/support/cpp/win32/dirent.c new file mode 100644 index 0000000..dd9d654 --- /dev/null +++ b/support/cpp/win32/dirent.c @@ -0,0 +1,340 @@ +/* + * dirent.c + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + * Derived from DIRLIB.C by Matt J. Weinstein + * This note appears in the DIRLIB.H + * DIRLIB.H by M. J. Weinstein Released to public domain 1-Jan-89 + * + * Updated by Jeremy Bettis <jeremy@hksys.com> + * Significantly revised and rewinddir, seekdir and telldir added by Colin + * Peters <colin@fu.is.saga-u.ac.jp> + * + */ + +#include <stdlib.h> +#include <errno.h> +#include <string.h> +#include <io.h> +#include <direct.h> +#include <dirent.h> + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> /* for GetFileAttributes */ + +#include <tchar.h> + +#ifdef _UNICODE +#define _tdirent _wdirent +#define _TDIR _WDIR +#define _topendir _wopendir +#define _tclosedir _wclosedir +#define _treaddir _wreaddir +#define _trewinddir _wrewinddir +#define _ttelldir _wtelldir +#define _tseekdir _wseekdir +#else +#define _tdirent dirent +#define _TDIR DIR +#define _topendir opendir +#define _tclosedir closedir +#define _treaddir readdir +#define _trewinddir rewinddir +#define _ttelldir telldir +#define _tseekdir seekdir +#endif + +#define SUFFIX _T("*") +#define SLASH _T("\\") + + +/* + * opendir + * + * Returns a pointer to a DIR structure appropriately filled in to begin + * searching a directory. + */ +_TDIR * +_topendir (const _TCHAR *szPath) +{ + _TDIR *nd; + unsigned int rc; + _TCHAR szFullPath[MAX_PATH]; + + errno = 0; + + if (!szPath) + { + errno = EFAULT; + return (_TDIR *) 0; + } + + if (szPath[0] == _T('\0')) + { + errno = ENOTDIR; + return (_TDIR *) 0; + } + + /* Attempt to determine if the given path really is a directory. */ + rc = GetFileAttributes (szPath); + if (rc == (unsigned int)-1) + { + /* call GetLastError for more error info */ + errno = ENOENT; + return (_TDIR *) 0; + } + if (!(rc & FILE_ATTRIBUTE_DIRECTORY)) + { + /* Error, entry exists but not a directory. */ + errno = ENOTDIR; + return (_TDIR *) 0; + } + + /* Make an absolute pathname. */ + _tfullpath (szFullPath, szPath, MAX_PATH); + + /* Allocate enough space to store DIR structure and the complete + * directory path given. */ + nd = (_TDIR *) malloc (sizeof (_TDIR) + (_tcslen(szFullPath) + _tcslen (SLASH) + + _tcslen(SUFFIX) + 1) * sizeof(_TCHAR)); + + if (!nd) + { + /* Error, out of memory. */ + errno = ENOMEM; + return (_TDIR *) 0; + } + + /* Create the search expression. */ + _tcscpy (nd->dd_name, szFullPath); + + /* Add on a slash if the path does not end with one. */ + if (nd->dd_name[0] != _T('\0') && + nd->dd_name[_tcslen (nd->dd_name) - 1] != _T('/') && + nd->dd_name[_tcslen (nd->dd_name) - 1] != _T('\\')) + { + _tcscat (nd->dd_name, SLASH); + } + + /* Add on the search pattern */ + _tcscat (nd->dd_name, SUFFIX); + + /* Initialize handle to -1 so that a premature closedir doesn't try + * to call _findclose on it. */ + nd->dd_handle = -1; + + /* Initialize the status. */ + nd->dd_stat = 0; + + /* Initialize the dirent structure. ino and reclen are invalid under + * Win32, and name simply points at the appropriate part of the + * findfirst_t structure. */ + nd->dd_dir.d_ino = 0; + nd->dd_dir.d_reclen = 0; + nd->dd_dir.d_namlen = 0; + memset (nd->dd_dir.d_name, 0, FILENAME_MAX); + + return nd; +} + + +/* + * readdir + * + * Return a pointer to a dirent structure filled with the information on the + * next entry in the directory. + */ +struct _tdirent * +_treaddir (_TDIR * dirp) +{ + errno = 0; + + /* Check for valid DIR struct. */ + if (!dirp) + { + errno = EFAULT; + return (struct _tdirent *) 0; + } + + if (dirp->dd_stat < 0) + { + /* We have already returned all files in the directory + * (or the structure has an invalid dd_stat). */ + return (struct _tdirent *) 0; + } + else if (dirp->dd_stat == 0) + { + /* We haven't started the search yet. */ + /* Start the search */ + dirp->dd_handle = _tfindfirst (dirp->dd_name, &(dirp->dd_dta)); + + if (dirp->dd_handle == -1) + { + /* Whoops! Seems there are no files in that + * directory. */ + dirp->dd_stat = -1; + } + else + { + dirp->dd_stat = 1; + } + } + else + { + /* Get the next search entry. */ + if (_tfindnext (dirp->dd_handle, &(dirp->dd_dta))) + { + /* We are off the end or otherwise error. + _findnext sets errno to ENOENT if no more file + Undo this. */ + DWORD winerr = GetLastError(); + if (winerr == ERROR_NO_MORE_FILES) + errno = 0; + _findclose (dirp->dd_handle); + dirp->dd_handle = -1; + dirp->dd_stat = -1; + } + else + { + /* Update the status to indicate the correct + * number. */ + dirp->dd_stat++; + } + } + + if (dirp->dd_stat > 0) + { + /* Successfully got an entry. Everything about the file is + * already appropriately filled in except the length of the + * file name. */ + dirp->dd_dir.d_namlen = _tcslen (dirp->dd_dta.name); + _tcscpy (dirp->dd_dir.d_name, dirp->dd_dta.name); + return &dirp->dd_dir; + } + + return (struct _tdirent *) 0; +} + + +/* + * closedir + * + * Frees up resources allocated by opendir. + */ +int +_tclosedir (_TDIR * dirp) +{ + int rc; + + errno = 0; + rc = 0; + + if (!dirp) + { + errno = EFAULT; + return -1; + } + + if (dirp->dd_handle != -1) + { + rc = _findclose (dirp->dd_handle); + } + + /* Delete the dir structure. */ + free (dirp); + + return rc; +} + +/* + * rewinddir + * + * Return to the beginning of the directory "stream". We simply call findclose + * and then reset things like an opendir. + */ +void +_trewinddir (_TDIR * dirp) +{ + errno = 0; + + if (!dirp) + { + errno = EFAULT; + return; + } + + if (dirp->dd_handle != -1) + { + _findclose (dirp->dd_handle); + } + + dirp->dd_handle = -1; + dirp->dd_stat = 0; +} + +/* + * telldir + * + * Returns the "position" in the "directory stream" which can be used with + * seekdir to go back to an old entry. We simply return the value in stat. + */ +long +_ttelldir (_TDIR * dirp) +{ + errno = 0; + + if (!dirp) + { + errno = EFAULT; + return -1; + } + return dirp->dd_stat; +} + +/* + * seekdir + * + * Seek to an entry previously returned by telldir. We rewind the directory + * and call readdir repeatedly until either dd_stat is the position number + * or -1 (off the end). This is not perfect, in that the directory may + * have changed while we weren't looking. But that is probably the case with + * any such system. + */ +void +_tseekdir (_TDIR * dirp, long lPos) +{ + errno = 0; + + if (!dirp) + { + errno = EFAULT; + return; + } + + if (lPos < -1) + { + /* Seeking to an invalid position. */ + errno = EINVAL; + return; + } + else if (lPos == -1) + { + /* Seek past end. */ + if (dirp->dd_handle != -1) + { + _findclose (dirp->dd_handle); + } + dirp->dd_handle = -1; + dirp->dd_stat = -1; + } + else + { + /* Rewind and read forward to the appropriate index. */ + _trewinddir (dirp); + + while ((dirp->dd_stat < lPos) && _treaddir (dirp)) + ; + } +} diff --git a/support/cpp/win32/dirent.h b/support/cpp/win32/dirent.h new file mode 100644 index 0000000..53c4dc8 --- /dev/null +++ b/support/cpp/win32/dirent.h @@ -0,0 +1,121 @@ +/* + * DIRENT.H (formerly DIRLIB.H) + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within the package. + * + */ +#ifndef _DIRENT_H_ +#define _DIRENT_H_ + +#include <stdio.h> +#include <io.h> + +#ifndef RC_INVOKED + +#ifdef __cplusplus +extern "C" { +#endif + +struct dirent +{ + long d_ino; /* Always zero. */ + unsigned short d_reclen; /* Always zero. */ + unsigned short d_namlen; /* Length of name in d_name. */ + char d_name[FILENAME_MAX]; /* File name. */ +}; + +/* + * This is an internal data structure. Good programmers will not use it + * except as an argument to one of the functions below. + * dd_stat field is now int (was short in older versions). + */ +typedef struct +{ + /* disk transfer area for this dir */ + struct _finddata_t dd_dta; + + /* dirent struct to return from dir (NOTE: this makes this thread + * safe as long as only one thread uses a particular DIR struct at + * a time) */ + struct dirent dd_dir; + + /* _findnext handle */ + long dd_handle; + + /* + * Status of search: + * 0 = not started yet (next entry to read is first entry) + * -1 = off the end + * positive = 0 based index of next entry + */ + int dd_stat; + + /* given path for dir with search pattern (struct is extended) */ + char dd_name[1]; +} DIR; + +DIR* __cdecl opendir (const char*); +struct dirent* __cdecl readdir (DIR*); +int __cdecl closedir (DIR*); +void __cdecl rewinddir (DIR*); +long __cdecl telldir (DIR*); +void __cdecl seekdir (DIR*, long); + + +/* wide char versions */ + +struct _wdirent +{ + long d_ino; /* Always zero. */ + unsigned short d_reclen; /* Always zero. */ + unsigned short d_namlen; /* Length of name in d_name. */ + wchar_t d_name[FILENAME_MAX]; /* File name. */ +}; + +/* + * This is an internal data structure. Good programmers will not use it + * except as an argument to one of the functions below. + */ +typedef struct +{ + /* disk transfer area for this dir */ + struct _wfinddata_t dd_dta; + + /* dirent struct to return from dir (NOTE: this makes this thread + * safe as long as only one thread uses a particular DIR struct at + * a time) */ + struct _wdirent dd_dir; + + /* _findnext handle */ + long dd_handle; + + /* + * Status of search: + * 0 = not started yet (next entry to read is first entry) + * -1 = off the end + * positive = 0 based index of next entry + */ + int dd_stat; + + /* given path for dir with search pattern (struct is extended) */ + wchar_t dd_name[1]; +} _WDIR; + + + +_WDIR* __cdecl _wopendir (const wchar_t*); +struct _wdirent* __cdecl _wreaddir (_WDIR*); +int __cdecl _wclosedir (_WDIR*); +void __cdecl _wrewinddir (_WDIR*); +long __cdecl _wtelldir (_WDIR*); +void __cdecl _wseekdir (_WDIR*, long); + + +#ifdef __cplusplus +} +#endif + +#endif /* Not RC_INVOKED */ + +#endif /* Not _DIRENT_H_ */ |
