From 42f9b5740a20b531ffefdd4a6271f15c10b8f990 Mon Sep 17 00:00:00 2001 From: borutr Date: Sun, 31 Dec 2006 16:29:37 +0000 Subject: [PATCH] * SDCPP synchronized with GCC CPP release version 4.1.1, currently the latest release: * support/cpp2/libcpp, support/cpp2/libcpp/include, support/cpp2/libcpp/include/cpp-id-data.h support/cpp2/libiberty/fopen_unlocked.c support/cpp2/libiberty/md5.c support/cpp2/md5.h support/cpp2/opt-functions.awk support/cpp2/opt-gather.awk support/cpp2/optc-gen.awk support/cpp2/opth-gen.awk: added * support/cpp2/Makefile.in, support/cpp2/auto-host_vc_in.h, support/cpp2/c-incpath.c, support/cpp2/c-incpath.h, support/cpp2/c-ppoutput.c, support/cpp2/c-pretty-print.c, support/cpp2/c-pretty-print.h, support/cpp2/cppdefault.c, support/cpp2/cppdefault.h, support/cpp2/diagnostic.c, support/cpp2/diagnostic.h, support/cpp2/except.h, support/cpp2/hwint.h, support/cpp2/input.h, support/cpp2/intl.h, support/cpp2/move-if-change, support/cpp2/opts.c, support/cpp2/opts.h, support/cpp2/output.h, support/cpp2/prefix.c, support/cpp2/prefix.h, support/cpp2/pretty-print.c, support/cpp2/pretty-print.h, support/cpp2/sdcpp-opts.c, support/cpp2/sdcpp.c, support/cpp2/sdcpp.dsp, support/cpp2/sdcpp.h, support/cpp2/sdcpp.opt, support/cpp2/sdcppa.dsp, support/cpp2/symcat.h, support/cpp2/version.c: modified * support/cpp2/libcpp/charset.c, support/cpp2/libcpp/directives.c, support/cpp2/libcpp/errors.c, support/cpp2/libcpp/expr.c, support/cpp2/libcpp/files.c, support/cpp2/libcpp/identifiers.c, support/cpp2/libcpp/include/cpplib.h, support/cpp2/libcpp/include/line-map.h, support/cpp2/libcpp/include/mkdeps.h, support/cpp2/libcpp/include/symtab.h, support/cpp2/libcpp/init.c, support/cpp2/libcpp/internal.h, support/cpp2/libcpp/lex.c, support/cpp2/libcpp/line-map.c, support/cpp2/libcpp/macro.c, support/cpp2/libcpp/mkdeps.c, support/cpp2/libcpp/symtab.c, support/cpp2/libcpp/system.h, support/cpp2/libcpp/traditional.c, support/cpp2/libcpp/ucnid.h, support/cpp2/libiberty/hashtab.c, support/cpp2/libiberty/hashtab.h: moved * support/cpp2/cppcharset.c, support/cpp2/cpperror.c, support/cpp2/cppexp.c, support/cpp2/cppfiles.c, support/cpp2/cpphash.c, support/cpp2/cpphash.h, support/cpp2/cppinit.c, support/cpp2/cpplex.c, support/cpp2/cpplib.c, support/cpp2/cpplib.h, support/cpp2/cppmacro.c, support/cpp2/cpptrad.c, support/cpp2/cppucnid.h, support/cpp2/hashtab.c, support/cpp2/hashtab.h, support/cpp2/hashtable.c, support/cpp2/hashtable.h, support/cpp2/line-map.c, support/cpp2/line-map.h, support/cpp2/mkdeps.c, support/cpp2/mkdeps.h, support/cpp2/options_vc_in.c, support/cpp2/options_vc_in.h, support/cpp2/opts.sh, support/cpp2/system.h: deleted / moved git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4543 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 58 ++ support/cpp2/Makefile.in | 156 +++- support/cpp2/auto-host_vc_in.h | 3 +- support/cpp2/c-incpath.c | 88 +- support/cpp2/c-incpath.h | 15 +- support/cpp2/c-ppoutput.c | 178 ++-- support/cpp2/c-pretty-print.c | 771 ++++++++--------- support/cpp2/c-pretty-print.h | 21 +- support/cpp2/cppdefault.c | 10 +- support/cpp2/cppdefault.h | 6 +- support/cpp2/cppucnid.h | 336 -------- support/cpp2/diagnostic.c | 289 ++++--- support/cpp2/diagnostic.h | 44 +- support/cpp2/except.h | 109 ++- support/cpp2/hwint.h | 47 +- support/cpp2/input.h | 66 +- support/cpp2/intl.h | 13 +- .../cpp2/{cppcharset.c => libcpp/charset.c} | 363 ++++++-- .../cpp2/{cpplib.c => libcpp/directives.c} | 489 ++++++++--- support/cpp2/{cpperror.c => libcpp/errors.c} | 78 +- support/cpp2/{cppexp.c => libcpp/expr.c} | 52 +- support/cpp2/{cppfiles.c => libcpp/files.c} | 439 ++++++++-- .../cpp2/{cpphash.c => libcpp/identifiers.c} | 7 +- support/cpp2/libcpp/include/cpp-id-data.h | 78 ++ support/cpp2/{ => libcpp/include}/cpplib.h | 396 +++++---- support/cpp2/{ => libcpp/include}/line-map.h | 108 ++- support/cpp2/{ => libcpp/include}/mkdeps.h | 15 +- .../{hashtable.h => libcpp/include/symtab.h} | 27 +- support/cpp2/{cppinit.c => libcpp/init.c} | 105 +-- support/cpp2/{cpphash.h => libcpp/internal.h} | 284 ++++--- support/cpp2/{cpplex.c => libcpp/lex.c} | 320 +++++-- support/cpp2/{ => libcpp}/line-map.c | 161 +++- support/cpp2/{cppmacro.c => libcpp/macro.c} | 199 +++-- support/cpp2/{ => libcpp}/mkdeps.c | 3 +- support/cpp2/{hashtable.c => libcpp/symtab.c} | 59 +- support/cpp2/libcpp/system.h | 437 ++++++++++ .../cpp2/{cpptrad.c => libcpp/traditional.c} | 41 +- support/cpp2/libcpp/ucnid.h | 801 ++++++++++++++++++ support/cpp2/libiberty/fopen_unlocked.c | 126 +++ support/cpp2/{ => libiberty}/hashtab.c | 559 ++++++------ support/cpp2/{ => libiberty}/hashtab.h | 115 +-- support/cpp2/libiberty/md5.c | 430 ++++++++++ support/cpp2/md5.h | 139 +++ support/cpp2/move-if-change | 21 +- support/cpp2/opt-functions.awk | 169 ++++ support/cpp2/opt-gather.awk | 54 ++ support/cpp2/optc-gen.awk | 168 ++++ support/cpp2/opth-gen.awk | 185 ++++ support/cpp2/options_vc_in.c | 221 ----- support/cpp2/options_vc_in.h | 76 -- support/cpp2/opts.c | 160 +++- support/cpp2/opts.h | 44 +- support/cpp2/opts.sh | 175 ---- support/cpp2/output.h | 166 +++- support/cpp2/prefix.c | 28 +- support/cpp2/prefix.h | 4 +- support/cpp2/pretty-print.c | 496 ++++++++--- support/cpp2/pretty-print.h | 124 ++- support/cpp2/sdcpp-opts.c | 103 ++- support/cpp2/sdcpp.c | 18 +- support/cpp2/sdcpp.dsp | 102 ++- support/cpp2/sdcpp.h | 26 +- support/cpp2/sdcpp.opt | 71 +- support/cpp2/sdcppa.dsp | 53 +- support/cpp2/symcat.h | 2 +- support/cpp2/system.h | 676 --------------- support/cpp2/version.c | 2 +- 67 files changed, 7333 insertions(+), 3852 deletions(-) delete mode 100644 support/cpp2/cppucnid.h rename support/cpp2/{cppcharset.c => libcpp/charset.c} (77%) rename support/cpp2/{cpplib.c => libcpp/directives.c} (81%) rename support/cpp2/{cpperror.c => libcpp/errors.c} (68%) rename support/cpp2/{cppexp.c => libcpp/expr.c} (97%) rename support/cpp2/{cppfiles.c => libcpp/files.c} (75%) rename support/cpp2/{cpphash.c => libcpp/identifiers.c} (95%) create mode 100644 support/cpp2/libcpp/include/cpp-id-data.h rename support/cpp2/{ => libcpp/include}/cpplib.h (71%) rename support/cpp2/{ => libcpp/include}/line-map.h (50%) rename support/cpp2/{ => libcpp/include}/mkdeps.h (85%) rename support/cpp2/{hashtable.h => libcpp/include/symtab.h} (71%) rename support/cpp2/{cppinit.c => libcpp/init.c} (88%) rename support/cpp2/{cpphash.h => libcpp/internal.h} (72%) rename support/cpp2/{cpplex.c => libcpp/lex.c} (86%) rename support/cpp2/{ => libcpp}/line-map.c (57%) rename support/cpp2/{cppmacro.c => libcpp/macro.c} (90%) rename support/cpp2/{ => libcpp}/mkdeps.c (99%) rename support/cpp2/{hashtable.c => libcpp/symtab.c} (84%) create mode 100644 support/cpp2/libcpp/system.h rename support/cpp2/{cpptrad.c => libcpp/traditional.c} (96%) create mode 100644 support/cpp2/libcpp/ucnid.h create mode 100644 support/cpp2/libiberty/fopen_unlocked.c rename support/cpp2/{ => libiberty}/hashtab.c (60%) rename support/cpp2/{ => libiberty}/hashtab.h (61%) create mode 100644 support/cpp2/libiberty/md5.c create mode 100644 support/cpp2/md5.h create mode 100644 support/cpp2/opt-functions.awk create mode 100644 support/cpp2/opt-gather.awk create mode 100644 support/cpp2/optc-gen.awk create mode 100644 support/cpp2/opth-gen.awk delete mode 100644 support/cpp2/options_vc_in.c delete mode 100644 support/cpp2/options_vc_in.h delete mode 100755 support/cpp2/opts.sh delete mode 100644 support/cpp2/system.h diff --git a/ChangeLog b/ChangeLog index acb6b0da..73bb2c40 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,61 @@ +2006-12-31 Borut Razem + + * SDCPP synchronized with GCC CPP release version 4.1.1, + currently the latest release: + * support/cpp2/libcpp, support/cpp2/libcpp/include, + support/cpp2/libcpp/include/cpp-id-data.h + support/cpp2/libiberty/fopen_unlocked.c + support/cpp2/libiberty/md5.c + support/cpp2/md5.h + support/cpp2/opt-functions.awk + support/cpp2/opt-gather.awk + support/cpp2/optc-gen.awk + support/cpp2/opth-gen.awk: + added + * support/cpp2/Makefile.in, support/cpp2/auto-host_vc_in.h, + support/cpp2/c-incpath.c, support/cpp2/c-incpath.h, + support/cpp2/c-ppoutput.c, support/cpp2/c-pretty-print.c, + support/cpp2/c-pretty-print.h, support/cpp2/cppdefault.c, + support/cpp2/cppdefault.h, support/cpp2/diagnostic.c, + support/cpp2/diagnostic.h, support/cpp2/except.h, + support/cpp2/hwint.h, support/cpp2/input.h, + support/cpp2/intl.h, support/cpp2/move-if-change, + support/cpp2/opts.c, support/cpp2/opts.h, + support/cpp2/output.h, support/cpp2/prefix.c, + support/cpp2/prefix.h, support/cpp2/pretty-print.c, + support/cpp2/pretty-print.h, support/cpp2/sdcpp-opts.c, + support/cpp2/sdcpp.c, support/cpp2/sdcpp.dsp, + support/cpp2/sdcpp.h, support/cpp2/sdcpp.opt, + support/cpp2/sdcppa.dsp, support/cpp2/symcat.h, + support/cpp2/version.c: + modified + * support/cpp2/libcpp/charset.c, support/cpp2/libcpp/directives.c, + support/cpp2/libcpp/errors.c, support/cpp2/libcpp/expr.c, + support/cpp2/libcpp/files.c, support/cpp2/libcpp/identifiers.c, + support/cpp2/libcpp/include/cpplib.h, support/cpp2/libcpp/include/line-map.h, + support/cpp2/libcpp/include/mkdeps.h, support/cpp2/libcpp/include/symtab.h, + support/cpp2/libcpp/init.c, support/cpp2/libcpp/internal.h, + support/cpp2/libcpp/lex.c, support/cpp2/libcpp/line-map.c, + support/cpp2/libcpp/macro.c, support/cpp2/libcpp/mkdeps.c, + support/cpp2/libcpp/symtab.c, support/cpp2/libcpp/system.h, + support/cpp2/libcpp/traditional.c, support/cpp2/libcpp/ucnid.h, + support/cpp2/libiberty/hashtab.c, support/cpp2/libiberty/hashtab.h: + moved + * support/cpp2/cppcharset.c, support/cpp2/cpperror.c, + support/cpp2/cppexp.c, support/cpp2/cppfiles.c, + support/cpp2/cpphash.c, support/cpp2/cpphash.h, + support/cpp2/cppinit.c, support/cpp2/cpplex.c, + support/cpp2/cpplib.c, support/cpp2/cpplib.h, + support/cpp2/cppmacro.c, support/cpp2/cpptrad.c, + support/cpp2/cppucnid.h, support/cpp2/hashtab.c, + support/cpp2/hashtab.h, support/cpp2/hashtable.c, + support/cpp2/hashtable.h, support/cpp2/line-map.c, + support/cpp2/line-map.h, support/cpp2/mkdeps.c, + support/cpp2/mkdeps.h, support/cpp2/options_vc_in.c, + support/cpp2/options_vc_in.h, support/cpp2/opts.sh, + support/cpp2/system.h: + deleted / moved + 2006-12-31 Borut Razem * configure.in, configure: fixed bug #1538756: configure dies if bison diff --git a/support/cpp2/Makefile.in b/support/cpp2/Makefile.in index 12d10400..46980540 100644 --- a/support/cpp2/Makefile.in +++ b/support/cpp2/Makefile.in @@ -70,6 +70,7 @@ STAMP = echo timestamp > # Where to find some libiberty headers. LIBIBERTY_DIR = $(srcdir)/libiberty +LIBCPP_DIR = $(srcdir)/libcpp OBSTACK_H = $(LIBIBERTY_DIR)/obstack.h SPLAY_TREE_H= $(LIBIBERTY_DIR)/splay-tree.h @@ -95,6 +96,9 @@ 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@ @@ -148,7 +152,7 @@ SYSTEM_H = system.h hwint.h #@build_overrides@ # -INCLUDES = -I$(srcdir) -I$(LIBIBERTY_DIR) -I. +INCLUDES = -I$(srcdir) -I$(LIBCPP_DIR) -I$(LIBCPP_DIR)/include -I$(LIBIBERTY_DIR) -I. # Always use -I$(srcdir)/config when compiling. .c.o: @@ -183,19 +187,28 @@ config.status: $(srcdir)/configure version.c LANGUAGES="$(CONFIG_LANGUAGES)" $(SHELL) config.status --recheck; \ fi -options.c: $(lang_opt_files) $(srcdir)/opts.sh options.h intl.h -options.h: $(lang_opt_files) $(srcdir)/opts.sh Makefile - AWK=$(AWK) $(SHELL) $(srcdir)/opts.sh \ - '$(SHELL) $(srcdir)/move-if-change' \ - options.c options.h $(lang_opt_files) +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) $@ version.o: version.c version.h hashtable.o: hashtable.c hashtable.h $(CONFIG_H) $(SYSTEM_H) $(OBSTACK_H) -hashtab.o: hashtab.c hashtab.h $(CONFIG_H) - cppcharset.o: cppcharset.c $(CONFIG_H) $(SYSTEM_H) prefix.o: prefix.c $(CONFIG_H) $(SYSTEM_H) Makefile prefix.h @@ -215,13 +228,14 @@ PREPROCESSOR_DEFINES = \ -DCROSS_INCLUDE_DIR=\"$(gcc_tooldir)/sys-include\" \ -DTOOL_INCLUDE_DIR=\"$(gcc_tooldir)/include\" -LIBCPP_OBJS = c-ppoutput.o cppinit.o cpplib.o cpplex.o cppmacro.o cppexp.o cppfiles.o \ - cpphash.o cpperror.o cppdefault.o \ - hashtable.o mkdeps.o prefix.o version.o \ - line-map.o cpptrad.o cppcharset.o hashtab.o \ - opts.o options.o diagnostic.o pretty-print.o c-incpath.o +########################## +# 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) + +##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. @@ -230,53 +244,72 @@ libcpp.a: $(LIBCPP_OBJS) $(AR) $(AR_FLAGS) libcpp.a $(LIBCPP_OBJS) -$(RANLIB) libcpp.a -MY_LIBIBERTY_BITS = concat.o getpwd.o hex.o lbasename.o obstack.o \ - safe-ctype.o splay-tree.o vasprintf.o xexit.o xmalloc.o \ - xmemdup.o xstrdup.o xstrerror.o +charset.o: $(LIBCPP_DIR)/charset.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) -$(TARGET): sdcpp.o sdcpp-opts.o $(MY_LIBIBERTY_BITS) libcpp.a $(LIBDEPS) - mkdir -p $(dir $@) - $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ sdcpp.o sdcpp-opts.o \ - $(MY_LIBIBERTY_BITS) libcpp.a $(LIBS) +directives.o: $(LIBCPP_DIR)/directives.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) -sdcpp.o: sdcpp.c $(CONFIG_H) cpplib.h $(SYSTEM_H) options.h -sdcpp-opts.o: sdcpp-opts.c $(CONFIG_H) $(LIBCPP_DEPS) options.h +errors.o: $(LIBCPP_DIR)/errors.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) -c-ppoutput.o: c-ppoutput.c $(CONFIG_H) cpplib.h intl.h $(SYSTEM_H) -cppinit.o: cppinit.c $(CONFIG_H) $(LIBCPP_DEPS) cppdefault.h \ - mkdeps.h prefix.h output.h version.h -cpperror.o: cpperror.c $(CONFIG_H) $(LIBCPP_DEPS) -cppexp.o: cppexp.c $(CONFIG_H) $(LIBCPP_DEPS) -cpplex.o: cpplex.c $(CONFIG_H) $(LIBCPP_DEPS) -cppmacro.o: cppmacro.c $(CONFIG_H) $(LIBCPP_DEPS) -cpplib.o: cpplib.c $(CONFIG_H) $(LIBCPP_DEPS) -cpphash.o: cpphash.c $(CONFIG_H) $(LIBCPP_DEPS) -cppfiles.o: cppfiles.c $(CONFIG_H) $(LIBCPP_DEPS) $(SPLAY_TREE_H) mkdeps.h -cpptrad.o: cpptrad.c $(CONFIG_H) $(LIBCPP_DEPS) -opts.o: opts.c $(CONFIG_H) $(LIBCPP_DEPS) options.h -diagnostic.o: diagnostic.c $(CONFIG_H) $(LIBCPP_DEPS) diagnostic.h -pretty-print.o: pretty-print.c $(CONFIG_H) $(LIBCPP_DEPS) pretty-print.h -c-incpath.o: $(CONFIG_H) $(LIBCPP_DEPS) c-incpath.h +expr.o: $(LIBCPP_DIR)/expr.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) -cppdefault.o: cppdefault.c $(CONFIG_H) $(SYSTEM_H) cppdefault.h Makefile - $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ - $(PREPROCESSOR_DEFINES) \ - -c $(srcdir)/cppdefault.c +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) -mkdeps.o: mkdeps.c $(CONFIG_H) $(SYSTEM_H) mkdeps.h +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 -concat.o: $(LIBIBERTY_DIR)/concat.c $(CONFIG_H) $(LIBCPP_DEPS) +MY_LIBIBERTY_BITS = concat.o fopen_unlocked.o getpwd.o hashtab.o hex.o \ + lbasename.o md5.o obstack.o safe-ctype.o splay-tree.o \ + vasprintf.o xexit.o xmalloc.o xmemdup.o xstrdup.o \ + xstrerror.o + +concat.o: $(LIBIBERTY_DIR)/concat.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +fopen_unlocked.o: $(LIBIBERTY_DIR)/fopen_unlocked.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +getpwd.o: $(LIBIBERTY_DIR)/getpwd.c $(CONFIG_H) $(LIBCPP_DEPS) $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) -getpwd.o: $(LIBIBERTY_DIR)/getpwd.c $(CONFIG_H) $(LIBCPP_DEPS) +hashtab.o: $(LIBIBERTY_DIR)/hashtab.c $(CONFIG_H) $(LIBCPP_DEPS) $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) -hex.o: $(LIBIBERTY_DIR)/hex.c $(CONFIG_H) $(LIBCPP_DEPS) +hex.o: $(LIBIBERTY_DIR)/hex.c $(CONFIG_H) $(LIBCPP_DEPS) $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) -lbasename.o: $(LIBIBERTY_DIR)/lbasename.c $(CONFIG_H) $(LIBCPP_DEPS) +lbasename.o: $(LIBIBERTY_DIR)/lbasename.c $(CONFIG_H) $(LIBCPP_DEPS) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +md5.o: $(LIBIBERTY_DIR)/md5.c $(LIBIBERTY_DIR)/obstack.h $(CONFIG_H) $(LIBCPP_DEPS) $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) obstack.o: $(LIBIBERTY_DIR)/obstack.c $(LIBIBERTY_DIR)/obstack.h $(CONFIG_H) $(LIBCPP_DEPS) @@ -305,3 +338,32 @@ xstrdup.o: $(LIBIBERTY_DIR)/xstrdup.c $(CONFIG_H) $(LIBCPP_DEPS) xstrerror.o: $(LIBIBERTY_DIR)/xstrerror.c $(CONFIG_H) $(LIBCPP_DEPS) $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION) + +########################## +# Sdcpp + +SDCC_OBJS = sdcpp.o sdcpp-opts.o c-ppoutput.o cppdefault.o prefix.o version.o opts.o options.o diagnostic.o pretty-print.o c-incpath.o + +$(TARGET): $(SDCC_OBJS) $(MY_LIBIBERTY_BITS) libcpp.a $(LIBDEPS) + mkdir -p $(dir $@) + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(SDCC_OBJS) \ + $(MY_LIBIBERTY_BITS) libcpp.a $(LIBS) + +sdcpp.o: sdcpp.c $(CONFIG_H) $(SYSTEM_H) options.h + +sdcpp-opts.o: sdcpp-opts.c $(CONFIG_H) $(LIBCPP_DEPS) options.h + +c-ppoutput.o: c-ppoutput.c $(CONFIG_H) $(SYSTEM_H) + +opts.o: opts.c $(CONFIG_H) $(LIBCPP_DEPS) options.h + +diagnostic.o: diagnostic.c $(CONFIG_H) $(LIBCPP_DEPS) diagnostic.h + +pretty-print.o: pretty-print.c $(CONFIG_H) $(LIBCPP_DEPS) pretty-print.h + +c-incpath.o: $(CONFIG_H) $(LIBCPP_DEPS) c-incpath.h + +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/cpp2/auto-host_vc_in.h b/support/cpp2/auto-host_vc_in.h index a2b61ca7..4e3ddad9 100644 --- a/support/cpp2/auto-host_vc_in.h +++ b/support/cpp2/auto-host_vc_in.h @@ -23,9 +23,10 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*/ #include #include #include +#include #define HAVE_STRINGIZE -#define STDC_HEADERS +#define STDC_HEADERS 1 #define PACKAGE "sdcc" #define LOCALEDIR "" #define PREFIX "" diff --git a/support/cpp2/c-incpath.c b/support/cpp2/c-incpath.c index 4b0bf545..8ae9e554 100644 --- a/support/cpp2/c-incpath.c +++ b/support/cpp2/c-incpath.c @@ -1,6 +1,6 @@ /* 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 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Broken out of cppinit.c and cppfiles.c and rewritten Mar 2003. @@ -16,7 +16,7 @@ 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. */ +Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #include "system.h" @@ -33,7 +33,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ # 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__ +# if (defined _WIN32 && !defined (_UWIN)) || defined __MSDOS__ # define INO_T_EQ(A, B) 0 # else # define INO_T_EQ(A, B) ((A) == (B)) @@ -110,7 +110,7 @@ add_env_var_paths (const char *env_var, int chain) path[q - p] = '\0'; } - add_path (path, chain, chain == SYSTEM); + add_path (path, chain, chain == SYSTEM, false); } } @@ -124,7 +124,7 @@ add_standard_paths (const char *sysroot, const char *iprefix, int cxx_stdinc) if (iprefix && (len = cpp_GCC_INCLUDE_DIR_len) != 0) { /* Look for directories that start with the standard prefix. - "Translate" them, ie. replace /usr/local/lib/gcc... with + "Translate" them, i.e. replace /usr/local/lib/gcc... with IPREFIX and search them first. */ for (p = cpp_include_defaults; p->fname; p++) { @@ -138,7 +138,7 @@ add_standard_paths (const char *sysroot, const char *iprefix, int cxx_stdinc) if (!strncmp (p->fname, cpp_GCC_INCLUDE_DIR, len)) { char *str = concat (iprefix, p->fname + len, NULL); - add_path (str, SYSTEM, p->cxx_aware); + add_path (str, SYSTEM, p->cxx_aware, false); } } } @@ -156,7 +156,7 @@ add_standard_paths (const char *sysroot, const char *iprefix, int cxx_stdinc) else str = update_path (p->fname, p->component); - add_path (str, SYSTEM, p->cxx_aware); + add_path (str, SYSTEM, p->cxx_aware, false); } } } @@ -167,6 +167,7 @@ add_standard_paths (const char *sysroot, const char *iprefix, int cxx_stdinc) 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, @@ -187,7 +188,13 @@ remove_duplicates (cpp_reader *pfile, struct cpp_dir *head, if (errno != ENOENT) cpp_errno (pfile, CPP_DL_ERROR, cur->name); else - reason = REASON_NOENT; + { + /* 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, @@ -200,7 +207,8 @@ remove_duplicates (cpp_reader *pfile, struct cpp_dir *head, /* 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) + if (INO_T_EQ (tmp->ino, cur->ino) && tmp->dev == cur->dev + && cur->construct == tmp->construct) break; if (!tmp) @@ -208,14 +216,16 @@ remove_duplicates (cpp_reader *pfile, struct cpp_dir *head, /* 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) + 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->dev == join->dev + && cur->construct == join->construct)) { /* Unique, so keep this directory. */ pcur = &cur->next; @@ -239,9 +249,10 @@ remove_duplicates (cpp_reader *pfile, struct cpp_dir *head, We can't just merge the lists and then uniquify them because then we may lose directories from the <> search path that should be - there; consider -Ifoo -Ibar -I- -Ifoo -Iquux. It is however safe - to treat -Ibar -Ifoo -I- -Ifoo -Iquux as if written -Ibar -I- -Ifoo - -Iquux. */ + 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) { @@ -296,16 +307,28 @@ split_quote_chain (void) 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) +add_path (char *path, int chain, int cxx_aware, bool user_supplied_p) { - struct cpp_dir *p; + cpp_dir *p; #if defined (HAVE_DOS_BASED_FILE_SYSTEM) /* Convert all backslashes to slashes. The native CRT stat() - function does not recognise a directory that ends in a backslash + 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; @@ -313,19 +336,17 @@ add_path (char *path, int chain, int cxx_aware) if (*c == '\\') *c = '/'; #endif - p = xmalloc (sizeof (struct cpp_dir)); + p = xmalloc (sizeof (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; - if (tails[chain]) - tails[chain]->next = p; - else - heads[chain] = p; - tails[chain] = p; + add_cpp_dir_path (p, chain); } /* Exported function to handle include chain merging, duplicate @@ -351,12 +372,33 @@ register_include_chains (cpp_reader *pfile, const char *sysroot, 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, 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/cpp2/c-incpath.h b/support/cpp2/c-incpath.h index 31ed657d..c309844c 100644 --- a/support/cpp2/c-incpath.h +++ b/support/cpp2/c-incpath.h @@ -1,5 +1,5 @@ /* Set up combined include path for the preprocessor. - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005 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 @@ -13,11 +13,20 @@ 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. */ +Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ extern void split_quote_chain (void); -extern void add_path (char *, int, int); +extern void add_path (char *, int, int, bool); extern void register_include_chains (cpp_reader *, 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/cpp2/c-ppoutput.c b/support/cpp2/c-ppoutput.c index f564dfe1..9a543431 100644 --- a/support/cpp2/c-ppoutput.c +++ b/support/cpp2/c-ppoutput.c @@ -15,23 +15,23 @@ 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. */ +Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #include "system.h" #include "cpplib.h" -#include "cpphash.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 struct line_map *map; /* Logical to physical line mappings. */ const cpp_token *prev; /* Previous token. */ const cpp_token *source; /* Source token for spacing. */ - fileline line; /* Line currently being written. */ + 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. */ @@ -40,18 +40,22 @@ 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 (const struct line_map *, fileline, const char *); -static void maybe_print_line (const struct line_map *, fileline); +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 *, fileline, cpp_hashnode *); -static void cb_undef (cpp_reader *, fileline, cpp_hashnode *); -static void cb_include (cpp_reader *, fileline, const unsigned char *, - const char *, int); -static void cb_ident (cpp_reader *, fileline, const cpp_string *); -static void cb_def_pragma (cpp_reader *, fileline); +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 @@ -101,20 +105,28 @@ init_pp_output (FILE *out_stream) 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.line to -1 here is + /* 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.line = (fileline) -1; + print.src_line = -1; print.printed = 0; print.prev = 0; - print.map = 0; print.outf = out_stream; + print.first_time = 1; } /* Writes out the preprocessed file, handling spacing and paste @@ -166,13 +178,13 @@ scan_translation_unit (cpp_reader *pfile) } } -/* Adjust print.line for newlines embedded in output. */ +/* 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.line++; + print.src_line++; } /* Writes out a traditionally preprocessed file. */ @@ -182,7 +194,7 @@ 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 (print.map, pfile->out.first_line); + maybe_print_line (pfile->out.first_line); fwrite (pfile->out.base, 1, len, print.outf); print.printed = 1; if (!CPP_OPTION (pfile, discard_comments)) @@ -194,52 +206,57 @@ scan_translation_unit_trad (cpp_reader *pfile) 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 (const struct line_map *map, fileline line) +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.line++; + print.src_line++; print.printed = 0; } - if (line >= print.line && line < print.line + 8) + if (src_line >= print.src_line && src_line < print.src_line + 8) { - while (line > print.line) + while (src_line > print.src_line) { putc ('\n', print.outf); - print.line++; + print.src_line++; } } else - print_line (map, line, ""); + 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 (const struct line_map *map, fileline line, const char *special_flags) +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; - print.line = line; 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 = 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); + (unsigned char *) map->to_file, to_file_len); *p = '\0'; fprintf (print.outf, "# %u \"%s\"%s", - SOURCE_LINE (map, print.line), + print.src_line == 0 ? 1 : print.src_line, to_file_quoted, special_flags); if (map->sysp == 2) @@ -257,10 +274,12 @@ 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 (print.map, token->line); + maybe_print_line (src_loc); print.prev = 0; print.source = 0; @@ -271,30 +290,28 @@ cb_line_change (cpp_reader *pfile, const cpp_token *token, 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; - if (token->col > 2) - { - unsigned int spaces = token->col - 2; - while (spaces--) - putc (' ', print.outf); - } + while (-- spaces >= 0) + putc (' ', print.outf); } } static void -cb_ident (cpp_reader *pfile ATTRIBUTE_UNUSED, fileline line, +cb_ident (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line, const cpp_string *str) { - maybe_print_line (print.map, line); + maybe_print_line (line); fprintf (print.outf, "#ident %s\n", str->text); - print.line++; + print.src_line++; } static void -cb_define (cpp_reader *pfile, fileline line, cpp_hashnode *node) +cb_define (cpp_reader *pfile, source_location line, cpp_hashnode *node) { - maybe_print_line (print.map, line); + maybe_print_line (line); fputs ("#define ", print.outf); /* 'D' is whole definition; 'N' is name only. */ @@ -305,32 +322,46 @@ cb_define (cpp_reader *pfile, fileline line, cpp_hashnode *node) fputs ((const char *) NODE_NAME (node), print.outf); putc ('\n', print.outf); - print.line++; + print.src_line++; } static void -cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, fileline line, +cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line, cpp_hashnode *node) { - maybe_print_line (print.map, line); + maybe_print_line (line); fprintf (print.outf, "#undef %s\n", NODE_NAME (node)); - print.line++; + print.src_line++; } static void -cb_include (cpp_reader *pfile ATTRIBUTE_UNUSED, fileline line, - const unsigned char *dir, const char *header, int angle_brackets) +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 (print.map, line); + maybe_print_line (line); if (angle_brackets) - fprintf (print.outf, "#%s <%s>\n", dir, header); + fprintf (print.outf, "#%s <%s>", dir, header); else - fprintf (print.outf, "#%s \"%s\"\n", dir, header); - print.line++; + 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 - diretory in cpp output file. */ + directory in cpp output file. */ void pp_dir_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const char *dir) @@ -339,15 +370,14 @@ pp_dir_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const char *dir) unsigned char *to_file_quoted = alloca (to_file_len * 4 + 1); unsigned char *p; - /* cpp_quote_string does not nul-terminate, so we have to do it ourselves. */ + /* 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. From this point on, the old print.map might be - pointing to freed memory, and so must not be dereferenced. */ + described in MAP. */ void pp_file_change (const struct line_map *map) @@ -359,38 +389,38 @@ pp_file_change (const struct line_map *map) if (map != NULL) { - /* First time? */ - if (print.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, map->from_line, flags); + 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) - maybe_print_line (map - 1, map->from_line - 1); - + { + 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, map->from_line, flags); + print_line (map->start_location, flags); } } - - print.map = map; } /* Copy a #pragma directive to the preprocessed output. */ static void -cb_def_pragma (cpp_reader *pfile, fileline line) +cb_def_pragma (cpp_reader *pfile, source_location line) { - maybe_print_line (print.map, line); + maybe_print_line (line); fputs ("#pragma ", print.outf); cpp_output_line (pfile, print.outf); - print.line++; + print.src_line++; } /* Dump out the hash table. */ @@ -403,8 +433,24 @@ dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED) fputs ((const char *) cpp_macro_definition (pfile, node), print.outf); putc ('\n', print.outf); - print.line++; + 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 \ No newline at end of file diff --git a/support/cpp2/c-pretty-print.c b/support/cpp2/c-pretty-print.c index f4b744e0..45f62ad4 100644 --- a/support/cpp2/c-pretty-print.c +++ b/support/cpp2/c-pretty-print.c @@ -1,5 +1,5 @@ /* Subroutines common to both C and C++ pretty-printers. - Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Contributed by Gabriel Dos Reis This file is part of GCC. @@ -16,11 +16,12 @@ 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. */ +Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301, USA. */ #include "config.h" #include "system.h" +#include "real.h" #include "c-pretty-print.h" /* The pretty-printer code is primarily designed to closely follow @@ -37,24 +38,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA pp_c_whitespace (PP); \ } while (0) -#define pp_c_left_bracket(PP) \ - do { \ - pp_left_bracket (PP); \ - pp_base (PP)->padding = pp_none; \ - } while (0) - -#define pp_c_right_bracket(PP) \ - do { \ - pp_right_bracket (PP); \ - pp_base (PP)->padding = pp_none; \ - } while (0) - -#define pp_c_star(PP) \ - do { \ - pp_star (PP); \ - pp_base (PP)->padding = pp_none; \ - } while (0) - /* literal */ static void pp_c_char (c_pretty_printer *, int); @@ -114,6 +97,20 @@ pp_c_right_brace (c_pretty_printer *pp) pp_base (pp)->padding = pp_none; } +void +pp_c_left_bracket (c_pretty_printer *pp) +{ + pp_left_bracket (pp); + pp_base (pp)->padding = pp_none; +} + +void +pp_c_right_bracket (c_pretty_printer *pp) +{ + pp_right_bracket (pp); + pp_base (pp)->padding = pp_none; +} + void pp_c_dot (c_pretty_printer *pp) { @@ -128,6 +125,13 @@ pp_c_ampersand (c_pretty_printer *pp) pp_base (pp)->padding = pp_none; } +void +pp_c_star (c_pretty_printer *pp) +{ + pp_star (pp); + pp_base (pp)->padding = pp_none; +} + void pp_c_arrow (c_pretty_printer *pp) { @@ -136,17 +140,36 @@ pp_c_arrow (c_pretty_printer *pp) } void -pp_c_semicolon(c_pretty_printer *pp) +pp_c_semicolon (c_pretty_printer *pp) { pp_semicolon (pp); pp_base (pp)->padding = pp_none; } +void +pp_c_complement (c_pretty_printer *pp) +{ + pp_complement (pp); + pp_base (pp)->padding = pp_none; +} + +void +pp_c_exclamation (c_pretty_printer *pp) +{ + pp_exclamation (pp); + pp_base (pp)->padding = pp_none; +} + +/* Print out the external representation of CV-QUALIFIER. */ + static void pp_c_cv_qualifier (c_pretty_printer *pp, const char *cv) { const char *p = pp_last_position_in_text (pp); - if (p != NULL && *p == '*') + /* The C programming language does not have references, but it is much + simpler to handle those here rather than going through the same + logic in the C++ pretty-printer. */ + if (p != NULL && (*p == '*' || *p == '&')) pp_c_whitespace (pp); pp_c_identifier (pp, cv); } @@ -161,6 +184,9 @@ pp_c_type_cast (c_pretty_printer *pp, tree t) pp_c_right_paren (pp); } +/* We're about to pretty-print a pointer type as indicated by T. + Output a whitespace, if needed, preparing for subsequent output. */ + void pp_c_space_for_pointer_operator (c_pretty_printer *pp, tree t) { @@ -194,7 +220,7 @@ void pp_c_type_qualifier_list (c_pretty_printer *pp, tree t) { int qualifiers; - + if (!TYPE_P (t)) t = TREE_TYPE (t); @@ -230,6 +256,13 @@ pp_c_pointer (c_pretty_printer *pp, tree t) pp_c_type_qualifier_list (pp, t); break; + /* ??? This node is now in GENERIC and so shouldn't be here. But + we'll fix that later. */ + case DECL_EXPR: + pp_declaration (pp, DECL_EXPR_DECL (t)); + pp_needs_newline (pp) = true; + break; + default: pp_unsupported_tree (pp, t); } @@ -268,7 +301,7 @@ pp_c_type_specifier (c_pretty_printer *pp, tree t) break; case IDENTIFIER_NODE: - pp_c_tree_identifier (pp, t); + pp_c_tree_decl_identifier (pp, t); break; case VOID_TYPE: @@ -277,10 +310,42 @@ pp_c_type_specifier (c_pretty_printer *pp, tree t) case INTEGER_TYPE: case REAL_TYPE: if (TYPE_NAME (t)) - t = TYPE_NAME (t); + { + t = TYPE_NAME (t); + pp_c_type_specifier (pp, t); + } else - t = c_common_type_for_mode (TYPE_MODE (t), TREE_UNSIGNED (t)); - pp_c_type_specifier (pp, t); + { + int prec = TYPE_PRECISION (t); + t = c_common_type_for_mode (TYPE_MODE (t), TYPE_UNSIGNED (t)); + if (TYPE_NAME (t)) + { + pp_c_type_specifier (pp, t); + if (TYPE_PRECISION (t) != prec) + { + pp_string (pp, ":"); + pp_decimal_int (pp, prec); + } + } + else + { + switch (code) + { + case INTEGER_TYPE: + pp_string (pp, (TYPE_UNSIGNED (t) + ? ""); + } + } break; case TYPE_DECL: @@ -346,6 +411,8 @@ pp_c_specifier_qualifier_list (c_pretty_printer *pp, tree t) pp_c_whitespace (pp); pp_c_left_paren (pp); } + else if (!c_dialect_cxx ()) + pp_c_whitespace (pp); pp_ptr_operator (pp, t); } break; @@ -441,7 +508,7 @@ pp_c_direct_abstract_declarator (c_pretty_printer *pp, tree t) case POINTER_TYPE: pp_abstract_declarator (pp, t); break; - + case FUNCTION_TYPE: pp_c_parameter_type_list (pp, t); pp_direct_abstract_declarator (pp, TREE_TYPE (t)); @@ -449,7 +516,7 @@ pp_c_direct_abstract_declarator (c_pretty_printer *pp, tree t) case ARRAY_TYPE: pp_c_left_bracket (pp); - if (TYPE_DOMAIN (t)) + if (TYPE_DOMAIN (t) && TYPE_MAX_VALUE (TYPE_DOMAIN (t))) pp_expression (pp, TYPE_MAX_VALUE (TYPE_DOMAIN (t))); pp_c_right_bracket (pp); pp_direct_abstract_declarator (pp, TREE_TYPE (t)); @@ -467,7 +534,7 @@ pp_c_direct_abstract_declarator (c_pretty_printer *pp, tree t) case COMPLEX_TYPE: case TYPE_DECL: break; - + default: pp_unsupported_tree (pp, t); break; @@ -536,7 +603,7 @@ pp_c_declaration_specifiers (c_pretty_printer *pp, tree t) direct-declarator [ static type-qualifier-list(opt) assignment-expression(opt)] direct-declarator [ type-qualifier-list static assignment-expression ] direct-declarator [ type-qualifier-list * ] - direct-declaratpr ( parameter-type-list ) + direct-declarator ( parameter-type-list ) direct-declarator ( identifier-list(opt) ) */ void @@ -549,11 +616,10 @@ pp_c_direct_declarator (c_pretty_printer *pp, tree t) case TYPE_DECL: case FIELD_DECL: case LABEL_DECL: - if (DECL_NAME (t)) - { - pp_c_space_for_pointer_operator (pp, TREE_TYPE (t)); - pp_c_tree_identifier (pp, DECL_NAME (t)); - } + pp_c_space_for_pointer_operator (pp, TREE_TYPE (t)); + pp_c_tree_decl_identifier (pp, t); + break; + case ARRAY_TYPE: case POINTER_TYPE: pp_abstract_declarator (pp, TREE_TYPE (t)); @@ -566,7 +632,7 @@ pp_c_direct_declarator (c_pretty_printer *pp, tree t) case FUNCTION_DECL: pp_c_space_for_pointer_operator (pp, TREE_TYPE (TREE_TYPE (t))); - pp_c_tree_identifier (pp, DECL_NAME (t)); + pp_c_tree_decl_identifier (pp, t); if (pp_c_base (pp)->flags & pp_c_flag_abstract) pp_abstract_declarator (pp, TREE_TYPE (t)); else @@ -615,7 +681,7 @@ pp_c_declarator (c_pretty_printer *pp, tree t) pp_direct_declarator (pp, t); break; - + default: pp_unsupported_tree (pp, t); break; @@ -673,50 +739,37 @@ pp_c_function_definition (c_pretty_printer *pp, tree t) /* Expressions. */ -/* Print out a c-char. */ +/* Print out a c-char. This is called solely for characters which are + in the *target* execution character set. We ought to convert them + back to the *host* execution character set before printing, but we + have no way to do this at present. A decent compromise is to print + all characters as if they were in the host execution character set, + and not attempt to recover any named escape characters, but render + all unprintables as octal escapes. If the host and target character + sets are the same, this produces relatively readable output. If they + are not the same, strings may appear as gibberish, but that's okay + (in fact, it may well be what the reader wants, e.g. if they are looking + to see if conversion to the target character set happened correctly). + + A special case: we need to prefix \, ", and ' with backslashes. It is + correct to do so for the *host*'s \, ", and ', because the rest of the + file appears in the host character set. */ static void pp_c_char (c_pretty_printer *pp, int c) { - switch (c) + if (ISPRINT (c)) { - case TARGET_NEWLINE: - pp_string (pp, "\\n"); - break; - case TARGET_TAB: - pp_string (pp, "\\t"); - break; - case TARGET_VT: - pp_string (pp, "\\v"); - break; - case TARGET_BS: - pp_string (pp, "\\b"); - break; - case TARGET_CR: - pp_string (pp, "\\r"); - break; - case TARGET_FF: - pp_string (pp, "\\f"); - break; - case TARGET_BELL: - pp_string (pp, "\\a"); - break; - case '\\': - pp_string (pp, "\\\\"); - break; - case '\'': - pp_string (pp, "\\'"); - break; - case '\"': - pp_string (pp, "\\\""); - break; - default: - if (ISPRINT (c)) - pp_character (pp, c); - else - pp_scalar (pp, "\\%03o", (unsigned) c); - break; + switch (c) + { + case '\\': pp_string (pp, "\\\\"); break; + case '\'': pp_string (pp, "\\\'"); break; + case '\"': pp_string (pp, "\\\""); break; + default: pp_character (pp, c); + } } + else + pp_scalar (pp, "\\%03o", (unsigned) c); } /* Print out a STRING literal. */ @@ -733,6 +786,8 @@ pp_c_string_literal (c_pretty_printer *pp, tree s) pp_doublequote (pp); } +/* Pretty-print an INTEGER literal. */ + static void pp_c_integer_constant (c_pretty_printer *pp, tree i) { @@ -744,16 +799,18 @@ pp_c_integer_constant (c_pretty_printer *pp, tree i) { if (tree_int_cst_sgn (i) < 0) { - pp_c_char (pp, '-'); - i = build_int_2 (-TREE_INT_CST_LOW (i), - ~TREE_INT_CST_HIGH (i) + !TREE_INT_CST_LOW (i)); + pp_character (pp, '-'); + i = build_int_cst_wide (NULL_TREE, + -TREE_INT_CST_LOW (i), + ~TREE_INT_CST_HIGH (i) + + !TREE_INT_CST_LOW (i)); } sprintf (pp_buffer (pp)->digit_buffer, HOST_WIDE_INT_PRINT_DOUBLE_HEX, TREE_INT_CST_HIGH (i), TREE_INT_CST_LOW (i)); pp_string (pp, pp_buffer (pp)->digit_buffer); } - if (TREE_UNSIGNED (type)) + if (TYPE_UNSIGNED (type)) pp_character (pp, 'u'); if (type == long_integer_type_node || type == long_unsigned_type_node) pp_character (pp, 'l'); @@ -769,10 +826,10 @@ pp_c_character_constant (c_pretty_printer *pp, tree c) { tree type = TREE_TYPE (c); if (type == wchar_type_node) - pp_character (pp, 'L'); + pp_character (pp, 'L'); pp_quote (pp); - if (host_integerp (c, TREE_UNSIGNED (type))) - pp_c_char (pp, tree_low_cst (c, TREE_UNSIGNED (type))); + if (host_integerp (c, TYPE_UNSIGNED (type))) + pp_c_char (pp, tree_low_cst (c, TYPE_UNSIGNED (type))); else pp_scalar (pp, "\\x%x", (unsigned) TREE_INT_CST_LOW (c)); pp_quote (pp); @@ -852,12 +909,12 @@ pp_c_floating_constant (c_pretty_printer *pp, tree r) } /* Pretty-print a compound literal expression. GNU extensions include - vector constants. */ + vector constants. */ static void pp_c_compound_literal (c_pretty_printer *pp, tree e) { - tree type = TREE_TYPE (e); + tree type = TREE_TYPE (e); pp_c_type_cast (pp, type); switch (TREE_CODE (type)) @@ -898,8 +955,8 @@ pp_c_constant (c_pretty_printer *pp, tree e) pp_c_character_constant (pp, e); else if (TREE_CODE (type) == ENUMERAL_TYPE && pp_c_enumeration_constant (pp, e)) - ; - else + ; + else pp_c_integer_constant (pp, e); } break; @@ -918,11 +975,13 @@ pp_c_constant (c_pretty_printer *pp, tree e) } } +/* Pretty-print an IDENTIFIER_NODE, preceded by whitespace is necessary. */ + void pp_c_identifier (c_pretty_printer *pp, const char *id) { - pp_c_maybe_whitespace (pp); - pp_identifier (pp, id); + pp_c_maybe_whitespace (pp); + pp_identifier (pp, id); pp_base (pp)->padding = pp_before; } @@ -944,8 +1003,9 @@ pp_c_primary_expression (c_pretty_printer *pp, tree e) case CONST_DECL: case FUNCTION_DECL: case LABEL_DECL: - e = DECL_NAME (e); - /* Fall through. */ + pp_c_tree_decl_identifier (pp, e); + break; + case IDENTIFIER_NODE: pp_c_tree_identifier (pp, e); break; @@ -964,9 +1024,19 @@ pp_c_primary_expression (c_pretty_printer *pp, tree e) pp_c_constant (pp, e); break; - case STMT_EXPR: + case TARGET_EXPR: + pp_c_identifier (pp, "__builtin_memcpy"); pp_c_left_paren (pp); - pp_statement (pp, STMT_EXPR_STMT (e)); + pp_ampersand (pp); + pp_primary_expression (pp, TREE_OPERAND (e, 0)); + pp_separate_with (pp, ','); + pp_ampersand (pp); + pp_initializer (pp, TREE_OPERAND (e, 1)); + if (TREE_OPERAND (e, 2)) + { + pp_separate_with (pp, ','); + pp_c_expression (pp, TREE_OPERAND (e, 2)); + } pp_c_right_paren (pp); break; @@ -989,13 +1059,7 @@ static void pp_c_initializer (c_pretty_printer *pp, tree e) { if (TREE_CODE (e) == CONSTRUCTOR) - { - enum tree_code code = TREE_CODE (TREE_TYPE (e)); - if (code == RECORD_TYPE || code == UNION_TYPE || code == ARRAY_TYPE) - pp_c_brace_enclosed_initializer_list (pp, e); - else - pp_unsupported_tree (pp, TREE_OPERAND (e, 1)); - } + pp_c_brace_enclosed_initializer_list (pp, e); else pp_expression (pp, e); } @@ -1008,7 +1072,9 @@ void pp_c_init_declarator (c_pretty_printer *pp, tree t) { pp_declarator (pp, t); - if (DECL_INITIAL (t)) + /* We don't want to output function definitions here. There are handled + elsewhere (and the syntactic form is bogus anyway). */ + if (TREE_CODE (t) != FUNCTION_DECL && DECL_INITIAL (t)) { tree init = DECL_INITIAL (t); /* This C++ bit is handled here because it is easier to do so. @@ -1081,25 +1147,36 @@ pp_c_initializer_list (c_pretty_printer *pp, tree e) pp_separate_with (pp, ','); } } - break; + return; case VECTOR_TYPE: - pp_c_expression_list (pp, TREE_VECTOR_CST_ELTS (e)); - break; + if (TREE_CODE (e) == VECTOR_CST) + pp_c_expression_list (pp, TREE_VECTOR_CST_ELTS (e)); + else if (TREE_CODE (e) == CONSTRUCTOR) + pp_c_constructor_elts (pp, CONSTRUCTOR_ELTS (e)); + else + break; + return; case COMPLEX_TYPE: - { - const bool cst = TREE_CODE (e) == COMPLEX_CST; - pp_expression (pp, cst ? TREE_REALPART (e) : TREE_OPERAND (e, 0)); - pp_separate_with (pp, ','); - pp_expression (pp, cst ? TREE_IMAGPART (e) : TREE_OPERAND (e, 1)); - } - break; + if (TREE_CODE (e) == CONSTRUCTOR) + pp_c_constructor_elts (pp, CONSTRUCTOR_ELTS (e)); + else if (TREE_CODE (e) == COMPLEX_CST || TREE_CODE (e) == COMPLEX_EXPR) + { + const bool cst = TREE_CODE (e) == COMPLEX_CST; + pp_expression (pp, cst ? TREE_REALPART (e) : TREE_OPERAND (e, 0)); + pp_separate_with (pp, ','); + pp_expression (pp, cst ? TREE_IMAGPART (e) : TREE_OPERAND (e, 1)); + } + else + break; + return; default: - pp_unsupported_tree (pp, type); break; } + + pp_unsupported_tree (pp, type); } /* Pretty-print a brace-enclosed initializer-list. */ @@ -1131,7 +1208,9 @@ pp_c_id_expression (c_pretty_printer *pp, tree t) case FUNCTION_DECL: case FIELD_DECL: case LABEL_DECL: - t = DECL_NAME (t); + pp_c_tree_decl_identifier (pp, t); + break; + case IDENTIFIER_NODE: pp_c_tree_identifier (pp, t); break; @@ -1165,11 +1244,6 @@ pp_c_postfix_expression (c_pretty_printer *pp, tree e) pp_identifier (pp, code == POSTINCREMENT_EXPR ? "++" : "--"); break; - case ARROW_EXPR: - pp_postfix_expression (pp, TREE_OPERAND (e, 0)); - pp_c_arrow (pp); - break; - case ARRAY_REF: pp_postfix_expression (pp, TREE_OPERAND (e, 0)); pp_c_left_bracket (pp); @@ -1182,6 +1256,62 @@ pp_c_postfix_expression (c_pretty_printer *pp, tree e) pp_c_call_argument_list (pp, TREE_OPERAND (e, 1)); break; + case UNORDERED_EXPR: + pp_c_identifier (pp, flag_isoc99 + ? "isunordered" + : "__builtin_isunordered"); + goto two_args_fun; + + case ORDERED_EXPR: + pp_c_identifier (pp, flag_isoc99 + ? "!isunordered" + : "!__builtin_isunordered"); + goto two_args_fun; + + case UNLT_EXPR: + pp_c_identifier (pp, flag_isoc99 + ? "!isgreaterequal" + : "!__builtin_isgreaterequal"); + goto two_args_fun; + + case UNLE_EXPR: + pp_c_identifier (pp, flag_isoc99 + ? "!isgreater" + : "!__builtin_isgreater"); + goto two_args_fun; + + case UNGT_EXPR: + pp_c_identifier (pp, flag_isoc99 + ? "!islessequal" + : "!__builtin_islessequal"); + goto two_args_fun; + + case UNGE_EXPR: + pp_c_identifier (pp, flag_isoc99 + ? "!isless" + : "!__builtin_isless"); + goto two_args_fun; + + case UNEQ_EXPR: + pp_c_identifier (pp, flag_isoc99 + ? "!islessgreater" + : "!__builtin_islessgreater"); + goto two_args_fun; + + case LTGT_EXPR: + pp_c_identifier (pp, flag_isoc99 + ? "islessgreater" + : "__builtin_islessgreater"); + goto two_args_fun; + + two_args_fun: + pp_c_left_paren (pp); + pp_expression (pp, TREE_OPERAND (e, 0)); + pp_separate_with (pp, ','); + pp_expression (pp, TREE_OPERAND (e, 1)); + pp_c_right_paren (pp); + break; + case ABS_EXPR: pp_c_identifier (pp, "__builtin_abs"); pp_c_left_paren (pp); @@ -1255,6 +1385,22 @@ pp_c_expression_list (c_pretty_printer *pp, tree e) } } +/* Print out V, which contains the elements of a constructor. */ + +void +pp_c_constructor_elts (c_pretty_printer *pp, VEC(constructor_elt,gc) *v) +{ + unsigned HOST_WIDE_INT ix; + tree value; + + FOR_EACH_CONSTRUCTOR_VALUE (v, ix, value) + { + pp_expression (pp, value); + if (ix != VEC_length (constructor_elt, v) - 1) + pp_separate_with (pp, ','); + } +} + /* Print out an expression-list in parens, as in a function call. */ void @@ -1276,7 +1422,7 @@ pp_c_call_argument_list (c_pretty_printer *pp, tree t) unary-operator: one of * & + - ! ~ - + GNU extensions. unary-expression: __alignof__ unary-expression @@ -1316,16 +1462,6 @@ pp_c_unary_expression (c_pretty_printer *pp, tree e) pp_c_cast_expression (pp, TREE_OPERAND (e, 0)); break; - case SIZEOF_EXPR: - case ALIGNOF_EXPR: - pp_c_identifier (pp, code == SIZEOF_EXPR ? "sizeof" : "__alignof__"); - pp_c_whitespace (pp); - if (TYPE_P (TREE_OPERAND (e, 0))) - pp_c_type_cast (pp, TREE_OPERAND (e, 0)); - else - pp_unary_expression (pp, TREE_OPERAND (e, 0)); - break; - case REALPART_EXPR: case IMAGPART_EXPR: pp_c_identifier (pp, code == REALPART_EXPR ? "__real__" : "__imag__"); @@ -1413,7 +1549,7 @@ pp_c_additive_expression (c_pretty_printer *pp, tree e) else pp_minus (pp); pp_c_whitespace (pp); - pp_multiplicative_expression (pp, TREE_OPERAND (e, 1)); + pp_multiplicative_expression (pp, TREE_OPERAND (e, 1)); break; default: @@ -1631,7 +1767,7 @@ pp_c_conditional_expression (c_pretty_printer *pp, tree e) /* assignment-expression: conditional-expression - unary-expression assignment-operator assignment-expression + unary-expression assignment-operator assignment-expression assignment-expression: one of = *= /= %= += -= >>= <<= &= ^= |= */ @@ -1687,19 +1823,25 @@ pp_c_expression (c_pretty_printer *pp, tree e) case FIELD_DECL: case LABEL_DECL: case ERROR_MARK: - case STMT_EXPR: pp_primary_expression (pp, e); break; case POSTINCREMENT_EXPR: case POSTDECREMENT_EXPR: - case ARROW_EXPR: case ARRAY_REF: case CALL_EXPR: case COMPONENT_REF: case COMPLEX_CST: case COMPLEX_EXPR: case VECTOR_CST: + case ORDERED_EXPR: + case UNORDERED_EXPR: + case LTGT_EXPR: + case UNEQ_EXPR: + case UNLE_EXPR: + case UNLT_EXPR: + case UNGE_EXPR: + case UNGT_EXPR: case ABS_EXPR: case CONSTRUCTOR: case COMPOUND_LITERAL_EXPR: @@ -1715,8 +1857,6 @@ pp_c_expression (c_pretty_printer *pp, tree e) case TRUTH_NOT_EXPR: case PREINCREMENT_EXPR: case PREDECREMENT_EXPR: - case SIZEOF_EXPR: - case ALIGNOF_EXPR: case REALPART_EXPR: case IMAGPART_EXPR: pp_c_unary_expression (pp, e); @@ -1770,7 +1910,7 @@ pp_c_expression (c_pretty_printer *pp, tree e) case NE_EXPR: pp_c_equality_expression (pp, e); break; - + case COND_EXPR: pp_conditional_expression (pp, e); break; @@ -1796,14 +1936,13 @@ pp_c_expression (c_pretty_printer *pp, tree e) case NOP_EXPR: case NON_LVALUE_EXPR: case SAVE_EXPR: - case UNSAVE_EXPR: pp_expression (pp, TREE_OPERAND (e, 0)); break; case TARGET_EXPR: pp_postfix_expression (pp, TREE_OPERAND (e, 1)); break; - + default: pp_unsupported_tree (pp, e); break; @@ -1814,308 +1953,16 @@ pp_c_expression (c_pretty_printer *pp, tree e) /* Statements. */ -/* statement: - labeled-statement - compound-statement - expression-statement - selection-statement - iteration-statement - jump-statement */ - void pp_c_statement (c_pretty_printer *pp, tree stmt) { - enum tree_code code; - if (stmt == NULL) return; - - code = TREE_CODE (stmt); - switch (code) - { - /* labeled-statement: - identifier : statement - case constant-expression : statement - default : statement */ - case LABEL_STMT: - case CASE_LABEL: - if (pp_needs_newline (pp)) - pp_newline_and_indent (pp, -3); - else - pp_indentation (pp) -= 3; - if (code == LABEL_STMT) - pp_tree_identifier (pp, DECL_NAME (LABEL_STMT_LABEL (stmt))); - else if (code == CASE_LABEL) - { - if (CASE_LOW (stmt) == NULL_TREE) - pp_identifier (pp, "default"); - else - { - pp_c_identifier (pp, "case"); - pp_c_whitespace (pp); - pp_conditional_expression (pp, CASE_LOW (stmt)); - if (CASE_HIGH (stmt)) - { - pp_identifier (pp, "..."); - pp_conditional_expression (pp, CASE_HIGH (stmt)); - } - } - } - pp_colon (pp); - pp_indentation (pp) += 3; - pp_needs_newline (pp) = true; - break; - /* compound-statement: - { block-item-list(opt) } - - block-item-list: - block-item - block-item-list block-item - - block-item: - declaration - statement */ - case COMPOUND_STMT: - if (pp_needs_newline (pp)) - pp_newline_and_indent (pp, 0); - pp_c_left_brace (pp); - pp_newline_and_indent (pp, 3); - for (stmt = COMPOUND_BODY (stmt); stmt; stmt = TREE_CHAIN (stmt)) - pp_statement (pp, stmt); - pp_newline_and_indent (pp, -3); - pp_c_right_brace (pp); - pp_needs_newline (pp) = true; - break; + if (pp_needs_newline (pp)) + pp_newline_and_indent (pp, 0); - /* expression-statement: - expression(opt) ; */ - case EXPR_STMT: - case CLEANUP_STMT: - if (pp_needs_newline (pp)) - pp_newline_and_indent (pp, 0); - { - tree e = code == EXPR_STMT - ? EXPR_STMT_EXPR (stmt) - : CLEANUP_EXPR (stmt); - if (e) - pp_expression (pp, e); - } - pp_c_semicolon (pp); - pp_needs_newline (pp) = true; - break; - - /* selection-statement: - if ( expression ) statement - if ( expression ) statement else statement - switch ( expression ) statement */ - case IF_STMT: - if (pp_needs_newline (pp)) - pp_newline_and_indent (pp, 0); - pp_c_identifier (pp, "if"); - pp_c_whitespace (pp); - pp_c_left_paren (pp); - pp_expression (pp, IF_COND (stmt)); - pp_c_right_paren (pp); - pp_newline_and_indent (pp, 3); - pp_statement (pp, THEN_CLAUSE (stmt)); - pp_newline_and_indent (pp, -3); - if (ELSE_CLAUSE (stmt)) - { - tree else_clause = ELSE_CLAUSE (stmt); - pp_c_identifier (pp, "else"); - if (TREE_CODE (else_clause) == IF_STMT) - pp_c_whitespace (pp); - else - pp_newline_and_indent (pp, 3); - pp_statement (pp, else_clause); - if (TREE_CODE (else_clause) != IF_STMT) - pp_newline_and_indent (pp, -3); - } - break; - - case SWITCH_STMT: - if (pp_needs_newline (pp)) - pp_newline_and_indent (pp, 0); - pp_c_identifier (pp, "switch"); - pp_space (pp); - pp_c_left_paren (pp); - pp_expression (pp, SWITCH_COND (stmt)); - pp_c_right_paren (pp); - pp_indentation (pp) += 3; - pp_needs_newline (pp) = true; - pp_statement (pp, SWITCH_BODY (stmt)); - pp_newline_and_indent (pp, -3); - break; - - /* iteration-statement: - while ( expression ) statement - do statement while ( expression ) ; - for ( expression(opt) ; expression(opt) ; expression(opt) ) statement - for ( declaration expression(opt) ; expression(opt) ) statement */ - case WHILE_STMT: - if (pp_needs_newline (pp)) - pp_newline_and_indent (pp, 0); - pp_c_identifier (pp, "while"); - pp_space (pp); - pp_c_left_paren (pp); - pp_expression (pp, WHILE_COND (stmt)); - pp_c_right_paren (pp); - pp_newline_and_indent (pp, 3); - pp_statement (pp, WHILE_BODY (stmt)); - pp_indentation (pp) -= 3; - pp_needs_newline (pp) = true; - break; - - case DO_STMT: - if (pp_needs_newline (pp)) - pp_newline_and_indent (pp, 0); - pp_c_identifier (pp, "do"); - pp_newline_and_indent (pp, 3); - pp_statement (pp, DO_BODY (stmt)); - pp_newline_and_indent (pp, -3); - pp_c_identifier (pp, "while"); - pp_space (pp); - pp_c_left_paren (pp); - pp_expression (pp, DO_COND (stmt)); - pp_c_right_paren (pp); - pp_c_semicolon (pp); - pp_needs_newline (pp) = true; - break; - - case FOR_STMT: - if (pp_needs_newline (pp)) - pp_newline_and_indent (pp, 0); - pp_c_identifier (pp, "for"); - pp_space (pp); - pp_c_left_paren (pp); - if (FOR_INIT_STMT (stmt)) - pp_statement (pp, FOR_INIT_STMT (stmt)); - else - pp_c_semicolon (pp); - pp_needs_newline (pp) = false; - pp_c_whitespace (pp); - if (FOR_COND (stmt)) - pp_expression (pp, FOR_COND (stmt)); - pp_c_semicolon (pp); - pp_needs_newline (pp) = false; - pp_c_whitespace (pp); - if (FOR_EXPR (stmt)) - pp_expression (pp, FOR_EXPR (stmt)); - pp_c_right_paren (pp); - pp_newline_and_indent (pp, 3); - pp_statement (pp, FOR_BODY (stmt)); - pp_indentation (pp) -= 3; - pp_needs_newline (pp) = true; - break; - - /* jump-statement: - goto identifier; - continue ; - return expression(opt) ; */ - case BREAK_STMT: - case CONTINUE_STMT: - if (pp_needs_newline (pp)) - pp_newline_and_indent (pp, 0); - pp_identifier (pp, code == BREAK_STMT ? "break" : "continue"); - pp_c_semicolon (pp); - pp_needs_newline (pp) = true; - break; - - case RETURN_STMT: - case GOTO_STMT: - { - tree e = code == RETURN_STMT - ? RETURN_STMT_EXPR (stmt) - : GOTO_DESTINATION (stmt); - if (pp_needs_newline (pp)) - pp_newline_and_indent (pp, 0); - pp_c_identifier (pp, code == RETURN_STMT ? "return" : "goto"); - pp_c_whitespace (pp); - if (e) - { - if (TREE_CODE (e) == INIT_EXPR - && TREE_CODE (TREE_OPERAND (e, 0)) == RESULT_DECL) - e = TREE_OPERAND (e, 1); - pp_expression (pp, e); - } - pp_c_semicolon (pp); - pp_needs_newline (pp) = true; - } - break; - - case SCOPE_STMT: - if (!SCOPE_NULLIFIED_P (stmt) && SCOPE_NO_CLEANUPS_P (stmt)) - { - int i = 0; - if (pp_needs_newline (pp)) - pp_newline_and_indent (pp, 0); - if (SCOPE_BEGIN_P (stmt)) - { - pp_left_brace (pp); - i = 3; - } - else if (SCOPE_END_P (stmt)) - { - pp_right_brace (pp); - i = -3; - } - pp_indentation (pp) += i; - pp_needs_newline (pp) = true; - } - break; - - case DECL_STMT: - if (pp_needs_newline (pp)) - pp_newline_and_indent (pp, 0); - pp_declaration (pp, DECL_STMT_DECL (stmt)); - pp_needs_newline (pp) = true; - break; - - case ASM_STMT: - { - bool has_volatile_p = ASM_VOLATILE_P (stmt); - bool is_extended = has_volatile_p || ASM_INPUTS (stmt) - || ASM_OUTPUTS (stmt) || ASM_CLOBBERS (stmt); - pp_c_identifier (pp, is_extended ? "__asm__" : "asm"); - if (has_volatile_p) - pp_c_identifier (pp, "__volatile__"); - pp_space (pp); - pp_c_left_paren (pp); - pp_c_string_literal (pp, ASM_STRING (stmt)); - if (is_extended) - { - pp_space (pp); - pp_separate_with (pp, ':'); - if (ASM_OUTPUTS (stmt)) - pp_expression (pp, ASM_OUTPUTS (stmt)); - pp_space (pp); - pp_separate_with (pp, ':'); - if (ASM_INPUTS (stmt)) - pp_expression (pp, ASM_INPUTS (stmt)); - pp_space (pp); - pp_separate_with (pp, ':'); - if (ASM_CLOBBERS (stmt)) - pp_expression (pp, ASM_CLOBBERS (stmt)); - } - pp_c_right_paren (pp); - pp_newline (pp); - } - break; - - case FILE_STMT: - pp_c_identifier (pp, "__FILE__"); - pp_space (pp); - pp_equal (pp); - pp_c_whitespace (pp); - pp_c_identifier (pp, FILE_STMT_FILENAME (stmt)); - pp_c_semicolon (pp); - pp_needs_newline (pp) = true; - break; - - default: - pp_unsupported_tree (pp, stmt); - } + dump_generic_node (pp_base (pp), stmt, pp_indentation (pp), 0, true); } @@ -2152,3 +1999,59 @@ pp_c_pretty_printer_init (c_pretty_printer *pp) pp->assignment_expression = pp_c_assignment_expression; pp->expression = pp_c_expression; } + + +/* Print the tree T in full, on file FILE. */ + +void +print_c_tree (FILE *file, tree t) +{ + static c_pretty_printer pp_rec; + static bool initialized = 0; + c_pretty_printer *pp = &pp_rec; + + if (!initialized) + { + initialized = 1; + pp_construct (pp_base (pp), NULL, 0); + pp_c_pretty_printer_init (pp); + pp_needs_newline (pp) = true; + } + pp_base (pp)->buffer->stream = file; + + pp_statement (pp, t); + + pp_newline (pp); + pp_flush (pp); +} + +/* Print the tree T in full, on stderr. */ + +void +debug_c_tree (tree t) +{ + print_c_tree (stderr, t); + fputc ('\n', stderr); +} + +/* Output the DECL_NAME of T. If T has no DECL_NAME, output a string made + up of T's memory address. */ + +void +pp_c_tree_decl_identifier (c_pretty_printer *pp, tree t) +{ + const char *name; + + gcc_assert (DECL_P (t)); + + if (DECL_NAME (t)) + name = IDENTIFIER_POINTER (DECL_NAME (t)); + else + { + static char xname[8]; + sprintf (xname, "", ((unsigned)((unsigned long)(t) & 0xffff))); + name = xname; + } + + pp_c_identifier (pp, name); +} diff --git a/support/cpp2/c-pretty-print.h b/support/cpp2/c-pretty-print.h index e9084b3e..2b9add61 100644 --- a/support/cpp2/c-pretty-print.h +++ b/support/cpp2/c-pretty-print.h @@ -1,5 +1,5 @@ /* Various declarations for the C and C++ pretty-printers. - Copyright (C) 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. Contributed by Gabriel Dos Reis This file is part of GCC. @@ -16,8 +16,8 @@ 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. */ +Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301, USA. */ #ifndef GCC_C_PRETTY_PRINTER #define GCC_C_PRETTY_PRINTER @@ -28,7 +28,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA typedef enum { pp_c_flag_abstract = 1 << 1, - pp_c_flag_last_bit = 2 + pp_c_flag_last_bit = 2 } pp_c_pretty_print_flags; @@ -58,7 +58,7 @@ struct c_pretty_print_info int *offset_list; pp_flags flags; - + /* These must be overridden by each of the C and C++ front-end to reflect their understanding of syntactic productions when they differ. */ c_pretty_print_fn declaration; @@ -93,7 +93,7 @@ struct c_pretty_print_info #undef pp_base #define pp_base(PP) (&pp_c_base (PP)->base) - + #define pp_c_tree_identifier(PPI, ID) \ pp_c_identifier (PPI, IDENTIFIER_POINTER (ID)) @@ -157,13 +157,19 @@ void pp_c_left_paren (c_pretty_printer *); void pp_c_right_paren (c_pretty_printer *); void pp_c_left_brace (c_pretty_printer *); void pp_c_right_brace (c_pretty_printer *); +void pp_c_left_bracket (c_pretty_printer *); +void pp_c_right_bracket (c_pretty_printer *); void pp_c_dot (c_pretty_printer *); void pp_c_ampersand (c_pretty_printer *); +void pp_c_star (c_pretty_printer *); void pp_c_arrow (c_pretty_printer *); void pp_c_semicolon (c_pretty_printer *); +void pp_c_complement (c_pretty_printer *); +void pp_c_exclamation (c_pretty_printer *); void pp_c_space_for_pointer_operator (c_pretty_printer *, tree); /* Declarations. */ +void pp_c_tree_decl_identifier (c_pretty_printer *, tree); void pp_c_function_definition (c_pretty_printer *, tree); void pp_c_attributes (c_pretty_printer *, tree); void pp_c_type_qualifier_list (c_pretty_printer *, tree); @@ -184,6 +190,7 @@ void pp_c_statement (c_pretty_printer *, tree); void pp_c_expression (c_pretty_printer *, tree); void pp_c_logical_or_expression (c_pretty_printer *, tree); void pp_c_expression_list (c_pretty_printer *, tree); +////void pp_c_constructor_elts (c_pretty_printer *, VEC(constructor_elt,gc) *); void pp_c_call_argument_list (c_pretty_printer *, tree); void pp_c_unary_expression (c_pretty_printer *, tree); void pp_c_cast_expression (c_pretty_printer *, tree); @@ -195,4 +202,6 @@ void pp_c_id_expression (c_pretty_printer *, tree); void pp_c_identifier (c_pretty_printer *, const char *); void pp_c_string_literal (c_pretty_printer *, tree); +void print_c_tree (FILE *file, tree t); + #endif /* GCC_C_PRETTY_PRINTER */ diff --git a/support/cpp2/cppdefault.c b/support/cpp2/cppdefault.c index 60b21537..862ea12e 100644 --- a/support/cpp2/cppdefault.c +++ b/support/cpp2/cppdefault.c @@ -1,6 +1,6 @@ /* CPP Library. Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2003 Free Software Foundation, Inc. + 1999, 2000, 2003, 2004 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 @@ -17,7 +17,7 @@ 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. */ +Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #include "system.h" @@ -94,9 +94,3 @@ const size_t cpp_GCC_INCLUDE_DIR_len = sizeof GCC_INCLUDE_DIR - 8; const char cpp_GCC_INCLUDE_DIR[] = ""; const size_t cpp_GCC_INCLUDE_DIR_len = 0; #endif - -#ifdef TARGET_SYSTEM_ROOT -const char *cpp_SYSROOT = TARGET_SYSTEM_ROOT; -#else -const char *cpp_SYSROOT = ""; -#endif diff --git a/support/cpp2/cppdefault.h b/support/cpp2/cppdefault.h index 368e082c..f5b38884 100644 --- a/support/cpp2/cppdefault.h +++ b/support/cpp2/cppdefault.h @@ -1,6 +1,6 @@ /* CPP Library. Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2003 Free Software Foundation, Inc. + 1999, 2000, 2003, 2004 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 @@ -17,7 +17,7 @@ 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. */ +Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef GCC_CPPDEFAULT_H #define GCC_CPPDEFAULT_H @@ -49,6 +49,4 @@ extern const struct default_include cpp_include_defaults[]; extern const char cpp_GCC_INCLUDE_DIR[]; extern const size_t cpp_GCC_INCLUDE_DIR_len; -extern const char *cpp_SYSROOT; - #endif /* ! GCC_CPPDEFAULT_H */ diff --git a/support/cpp2/cppucnid.h b/support/cpp2/cppucnid.h deleted file mode 100644 index 1cac7df0..00000000 --- a/support/cpp2/cppucnid.h +++ /dev/null @@ -1,336 +0,0 @@ -/* Table of UCNs which are valid in identifiers. - Copyright (C) 2003 Free Software Foundation, Inc. - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Automatically generated from cppucnid.tab, do not edit */ - -/* This file reproduces the table in ISO/IEC 9899:1999 (C99) Annex - D, which is itself a reproduction from ISO/IEC TR 10176:1998, and - the similar table from ISO/IEC 14882:1988 (C++98) Annex E, which is - a reproduction of ISO/IEC PDTR 10176. Unfortunately these tables - are not identical. */ - -#ifndef CPPUCNID_H -#define CPPUCNID_H - -#define C99 1 -#define CXX 2 -#define DIG 4 - -struct ucnrange -{ - unsigned short lo, hi; - unsigned short flags; -}; - -static const struct ucnrange ucnranges[] = { - { 0x00aa, 0x00aa, C99 }, /* Latin */ - { 0x00b5, 0x00b5, C99 }, /* Special characters */ - { 0x00b7, 0x00b7, C99 }, - { 0x00ba, 0x00ba, C99 }, /* Latin */ - { 0x00c0, 0x00d6, CXX|C99 }, - { 0x00d8, 0x00f6, CXX|C99 }, - { 0x00f8, 0x01f5, CXX|C99 }, - { 0x01fa, 0x0217, CXX|C99 }, - { 0x0250, 0x02a8, CXX|C99 }, - { 0x02b0, 0x02b8, C99 }, /* Special characters */ - { 0x02bb, 0x02bb, C99 }, - { 0x02bd, 0x02c1, C99 }, - { 0x02d0, 0x02d1, C99 }, - { 0x02e0, 0x02e4, C99 }, - { 0x037a, 0x037a, C99 }, - { 0x0384, 0x0384, CXX }, /* Greek */ - { 0x0386, 0x0386, C99 }, - { 0x0388, 0x038a, CXX|C99 }, - { 0x038c, 0x038c, CXX|C99 }, - { 0x038e, 0x03a1, CXX|C99 }, - { 0x03a3, 0x03ce, CXX|C99 }, - { 0x03d0, 0x03d6, CXX|C99 }, - { 0x03da, 0x03da, CXX|C99 }, - { 0x03dc, 0x03dc, CXX|C99 }, - { 0x03de, 0x03de, CXX|C99 }, - { 0x03e0, 0x03e0, CXX|C99 }, - { 0x03e2, 0x03f3, CXX|C99 }, - { 0x0401, 0x040c, CXX|C99 }, /* Cyrillic */ - { 0x040d, 0x040d, CXX }, - { 0x040e, 0x040e, C99 }, - { 0x040f, 0x044f, CXX|C99 }, - { 0x0451, 0x045c, CXX|C99 }, - { 0x045e, 0x0481, CXX|C99 }, - { 0x0490, 0x04c4, CXX|C99 }, - { 0x04c7, 0x04c8, CXX|C99 }, - { 0x04cb, 0x04cc, CXX|C99 }, - { 0x04d0, 0x04eb, CXX|C99 }, - { 0x04ee, 0x04f5, CXX|C99 }, - { 0x04f8, 0x04f9, CXX|C99 }, - { 0x0531, 0x0556, CXX|C99 }, /* Armenian */ - { 0x0559, 0x0559, C99 }, /* Special characters */ - { 0x0561, 0x0587, CXX|C99 }, /* Armenian */ - { 0x05b0, 0x05b9, C99 }, /* Hebrew */ - { 0x05bb, 0x05bd, C99 }, - { 0x05bf, 0x05bf, C99 }, - { 0x05c1, 0x05c2, C99 }, - { 0x05d0, 0x05ea, CXX|C99 }, - { 0x05f0, 0x05f2, CXX|C99 }, - { 0x05f3, 0x05f4, CXX }, - { 0x0621, 0x063a, CXX|C99 }, /* Arabic */ - { 0x0640, 0x0652, CXX|C99 }, - { 0x0660, 0x0669, C99|DIG }, /* Digits */ - { 0x0670, 0x06b7, CXX|C99 }, /* Arabic */ - { 0x06ba, 0x06be, CXX|C99 }, - { 0x06c0, 0x06ce, CXX|C99 }, - { 0x06d0, 0x06dc, C99 }, - { 0x06e5, 0x06e7, CXX|C99 }, - { 0x06e8, 0x06e8, C99 }, - { 0x06ea, 0x06ed, C99 }, - { 0x06f0, 0x06f9, C99|DIG }, /* Digits */ - { 0x0901, 0x0903, C99 }, /* Devanagari */ - { 0x0905, 0x0939, CXX|C99 }, - { 0x093d, 0x093d, C99 }, /* Special characters */ - { 0x093e, 0x094d, C99 }, /* Devanagari */ - { 0x0950, 0x0952, C99 }, - { 0x0958, 0x0962, CXX|C99 }, - { 0x0963, 0x0963, C99 }, - { 0x0966, 0x096f, C99|DIG }, /* Digits */ - { 0x0981, 0x0983, C99 }, /* Bengali */ - { 0x0985, 0x098c, CXX|C99 }, - { 0x098f, 0x0990, CXX|C99 }, - { 0x0993, 0x09a8, CXX|C99 }, - { 0x09aa, 0x09b0, CXX|C99 }, - { 0x09b2, 0x09b2, CXX|C99 }, - { 0x09b6, 0x09b9, CXX|C99 }, - { 0x09be, 0x09c4, C99 }, - { 0x09c7, 0x09c8, C99 }, - { 0x09cb, 0x09cd, C99 }, - { 0x09dc, 0x09dd, CXX|C99 }, - { 0x09df, 0x09e1, CXX|C99 }, - { 0x09e2, 0x09e3, C99 }, - { 0x09e6, 0x09ef, C99|DIG }, /* Digits */ - { 0x09f0, 0x09f1, CXX|C99 }, /* Bengali */ - { 0x0a02, 0x0a02, C99 }, /* Gurmukhi */ - { 0x0a05, 0x0a0a, CXX|C99 }, - { 0x0a0f, 0x0a10, CXX|C99 }, - { 0x0a13, 0x0a28, CXX|C99 }, - { 0x0a2a, 0x0a30, CXX|C99 }, - { 0x0a32, 0x0a33, CXX|C99 }, - { 0x0a35, 0x0a36, CXX|C99 }, - { 0x0a38, 0x0a39, CXX|C99 }, - { 0x0a3e, 0x0a42, C99 }, - { 0x0a47, 0x0a48, C99 }, - { 0x0a4b, 0x0a4d, C99 }, - { 0x0a59, 0x0a5c, CXX|C99 }, - { 0x0a5e, 0x0a5e, CXX|C99 }, - { 0x0a66, 0x0a6f, C99|DIG }, /* Digits */ - { 0x0a74, 0x0a74, C99 }, /* Gurmukhi */ - { 0x0a81, 0x0a83, C99 }, /* Gujarati */ - { 0x0a85, 0x0a8b, CXX|C99 }, - { 0x0a8d, 0x0a8d, CXX|C99 }, - { 0x0a8f, 0x0a91, CXX|C99 }, - { 0x0a93, 0x0aa8, CXX|C99 }, - { 0x0aaa, 0x0ab0, CXX|C99 }, - { 0x0ab2, 0x0ab3, CXX|C99 }, - { 0x0ab5, 0x0ab9, CXX|C99 }, - { 0x0abd, 0x0ac5, C99 }, - { 0x0ac7, 0x0ac9, C99 }, - { 0x0acb, 0x0acd, C99 }, - { 0x0ad0, 0x0ad0, C99 }, - { 0x0ae0, 0x0ae0, CXX|C99 }, - { 0x0ae6, 0x0aef, C99|DIG }, /* Digits */ - { 0x0b01, 0x0b03, C99 }, /* Oriya */ - { 0x0b05, 0x0b0c, CXX|C99 }, - { 0x0b0f, 0x0b10, CXX|C99 }, - { 0x0b13, 0x0b28, CXX|C99 }, - { 0x0b2a, 0x0b30, CXX|C99 }, - { 0x0b32, 0x0b33, CXX|C99 }, - { 0x0b36, 0x0b39, CXX|C99 }, - { 0x0b3d, 0x0b3d, C99 }, /* Special characters */ - { 0x0b3e, 0x0b43, C99 }, /* Oriya */ - { 0x0b47, 0x0b48, C99 }, - { 0x0b4b, 0x0b4d, C99 }, - { 0x0b5c, 0x0b5d, CXX|C99 }, - { 0x0b5f, 0x0b61, CXX|C99 }, - { 0x0b66, 0x0b6f, C99|DIG }, /* Digits */ - { 0x0b82, 0x0b83, C99 }, /* Tamil */ - { 0x0b85, 0x0b8a, CXX|C99 }, - { 0x0b8e, 0x0b90, CXX|C99 }, - { 0x0b92, 0x0b95, CXX|C99 }, - { 0x0b99, 0x0b9a, CXX|C99 }, - { 0x0b9c, 0x0b9c, CXX|C99 }, - { 0x0b9e, 0x0b9f, CXX|C99 }, - { 0x0ba3, 0x0ba4, CXX|C99 }, - { 0x0ba8, 0x0baa, CXX|C99 }, - { 0x0bae, 0x0bb5, CXX|C99 }, - { 0x0bb7, 0x0bb9, CXX|C99 }, - { 0x0bbe, 0x0bc2, C99 }, - { 0x0bc6, 0x0bc8, C99 }, - { 0x0bca, 0x0bcd, C99 }, - { 0x0be7, 0x0bef, C99|DIG }, /* Digits */ - { 0x0c01, 0x0c03, C99 }, /* Telugu */ - { 0x0c05, 0x0c0c, CXX|C99 }, - { 0x0c0e, 0x0c10, CXX|C99 }, - { 0x0c12, 0x0c28, CXX|C99 }, - { 0x0c2a, 0x0c33, CXX|C99 }, - { 0x0c35, 0x0c39, CXX|C99 }, - { 0x0c3e, 0x0c44, C99 }, - { 0x0c46, 0x0c48, C99 }, - { 0x0c4a, 0x0c4d, C99 }, - { 0x0c60, 0x0c61, CXX|C99 }, - { 0x0c66, 0x0c6f, C99|DIG }, /* Digits */ - { 0x0c82, 0x0c83, C99 }, /* Kannada */ - { 0x0c85, 0x0c8c, CXX|C99 }, - { 0x0c8e, 0x0c90, CXX|C99 }, - { 0x0c92, 0x0ca8, CXX|C99 }, - { 0x0caa, 0x0cb3, CXX|C99 }, - { 0x0cb5, 0x0cb9, CXX|C99 }, - { 0x0cbe, 0x0cc4, C99 }, - { 0x0cc6, 0x0cc8, C99 }, - { 0x0cca, 0x0ccd, C99 }, - { 0x0cde, 0x0cde, C99 }, - { 0x0ce0, 0x0ce1, CXX|C99 }, - { 0x0ce6, 0x0cef, C99|DIG }, /* Digits */ - { 0x0d02, 0x0d03, C99 }, /* Malayalam */ - { 0x0d05, 0x0d0c, CXX|C99 }, - { 0x0d0e, 0x0d10, CXX|C99 }, - { 0x0d12, 0x0d28, CXX|C99 }, - { 0x0d2a, 0x0d39, CXX|C99 }, - { 0x0d3e, 0x0d43, C99 }, - { 0x0d46, 0x0d48, C99 }, - { 0x0d4a, 0x0d4d, C99 }, - { 0x0d60, 0x0d61, CXX|C99 }, - { 0x0d66, 0x0d6f, C99|DIG }, /* Digits */ - { 0x0e01, 0x0e30, CXX|C99 }, /* Thai */ - { 0x0e31, 0x0e31, C99 }, - { 0x0e32, 0x0e33, CXX|C99 }, - { 0x0e34, 0x0e3a, C99 }, - { 0x0e40, 0x0e46, CXX|C99 }, - { 0x0e47, 0x0e49, C99 }, - { 0x0e50, 0x0e59, CXX|C99|DIG }, /* Digits */ - { 0x0e5a, 0x0e5b, CXX|C99 }, /* Thai */ - { 0x0e81, 0x0e82, CXX|C99 }, /* Lao */ - { 0x0e84, 0x0e84, CXX|C99 }, - { 0x0e87, 0x0e88, CXX|C99 }, - { 0x0e8a, 0x0e8a, CXX|C99 }, - { 0x0e8d, 0x0e8d, CXX|C99 }, - { 0x0e94, 0x0e97, CXX|C99 }, - { 0x0e99, 0x0e9f, CXX|C99 }, - { 0x0ea1, 0x0ea3, CXX|C99 }, - { 0x0ea5, 0x0ea5, CXX|C99 }, - { 0x0ea7, 0x0ea7, CXX|C99 }, - { 0x0eaa, 0x0eab, CXX|C99 }, - { 0x0ead, 0x0eae, CXX|C99 }, - { 0x0eaf, 0x0eaf, CXX }, - { 0x0eb0, 0x0eb0, CXX|C99 }, - { 0x0eb1, 0x0eb1, C99 }, - { 0x0eb2, 0x0eb3, CXX|C99 }, - { 0x0eb4, 0x0eb9, C99 }, - { 0x0ebb, 0x0ebc, C99 }, - { 0x0ebd, 0x0ebd, CXX|C99 }, - { 0x0ec0, 0x0ec4, CXX|C99 }, - { 0x0ec6, 0x0ec6, CXX|C99 }, - { 0x0ec8, 0x0ecd, C99 }, - { 0x0ed0, 0x0ed9, C99|DIG }, /* Digits */ - { 0x0edc, 0x0edd, C99 }, /* Lao */ - { 0x0f00, 0x0f00, C99 }, /* Tibetan */ - { 0x0f18, 0x0f19, C99 }, - { 0x0f20, 0x0f33, C99|DIG }, /* Digits */ - { 0x0f35, 0x0f35, C99 }, /* Tibetan */ - { 0x0f37, 0x0f37, C99 }, - { 0x0f39, 0x0f39, C99 }, - { 0x0f3e, 0x0f47, C99 }, - { 0x0f49, 0x0f69, C99 }, - { 0x0f71, 0x0f84, C99 }, - { 0x0f86, 0x0f8b, C99 }, - { 0x0f90, 0x0f95, C99 }, - { 0x0f97, 0x0f97, C99 }, - { 0x0f99, 0x0fad, C99 }, - { 0x0fb1, 0x0fb7, C99 }, - { 0x0fb9, 0x0fb9, C99 }, - { 0x10a0, 0x10c5, CXX|C99 }, /* Georgian */ - { 0x10d0, 0x10f6, CXX|C99 }, - { 0x1100, 0x1159, CXX }, /* Hangul */ - { 0x1161, 0x11a2, CXX }, - { 0x11a8, 0x11f9, CXX }, - { 0x1e00, 0x1e9a, CXX|C99 }, /* Latin */ - { 0x1e9b, 0x1e9b, C99 }, - { 0x1ea0, 0x1ef9, CXX|C99 }, - { 0x1f00, 0x1f15, CXX|C99 }, /* Greek */ - { 0x1f18, 0x1f1d, CXX|C99 }, - { 0x1f20, 0x1f45, CXX|C99 }, - { 0x1f48, 0x1f4d, CXX|C99 }, - { 0x1f50, 0x1f57, CXX|C99 }, - { 0x1f59, 0x1f59, CXX|C99 }, - { 0x1f5b, 0x1f5b, CXX|C99 }, - { 0x1f5d, 0x1f5d, CXX|C99 }, - { 0x1f5f, 0x1f7d, CXX|C99 }, - { 0x1f80, 0x1fb4, CXX|C99 }, - { 0x1fb6, 0x1fbc, CXX|C99 }, - { 0x1fbe, 0x1fbe, C99 }, /* Special characters */ - { 0x1fc2, 0x1fc4, CXX|C99 }, /* Greek */ - { 0x1fc6, 0x1fcc, CXX|C99 }, - { 0x1fd0, 0x1fd3, CXX|C99 }, - { 0x1fd6, 0x1fdb, CXX|C99 }, - { 0x1fe0, 0x1fec, CXX|C99 }, - { 0x1ff2, 0x1ff4, CXX|C99 }, - { 0x1ff6, 0x1ffc, CXX|C99 }, - { 0x203f, 0x2040, C99 }, /* Special characters */ - { 0x207f, 0x207f, C99 }, /* Latin */ - { 0x2102, 0x2102, C99 }, /* Special characters */ - { 0x2107, 0x2107, C99 }, - { 0x210a, 0x2113, C99 }, - { 0x2115, 0x2115, C99 }, - { 0x2118, 0x211d, C99 }, - { 0x2124, 0x2124, C99 }, - { 0x2126, 0x2126, C99 }, - { 0x2128, 0x2128, C99 }, - { 0x212a, 0x2131, C99 }, - { 0x2133, 0x2138, C99 }, - { 0x2160, 0x2182, C99 }, - { 0x3005, 0x3007, C99 }, - { 0x3021, 0x3029, C99 }, - { 0x3041, 0x3093, CXX|C99 }, /* Hiragana */ - { 0x3094, 0x3094, CXX }, - { 0x309b, 0x309c, CXX|C99 }, - { 0x309d, 0x309e, CXX }, - { 0x30a1, 0x30f6, CXX|C99 }, /* Katakana */ - { 0x30f7, 0x30fa, CXX }, - { 0x30fb, 0x30fc, CXX|C99 }, - { 0x30fd, 0x30fe, CXX }, - { 0x3105, 0x312c, CXX|C99 }, /* Bopomofo */ - { 0x4e00, 0x9fa5, CXX|C99 }, /* CJK Unified Ideographs */ - { 0xac00, 0xd7a3, C99 }, /* Hangul */ - { 0xf900, 0xfa2d, CXX }, /* CJK Unified Ideographs */ - { 0xfb1f, 0xfb36, CXX }, - { 0xfb38, 0xfb3c, CXX }, - { 0xfb3e, 0xfb3e, CXX }, - { 0xfb40, 0xfb44, CXX }, - { 0xfb46, 0xfbb1, CXX }, - { 0xfbd3, 0xfd3f, CXX }, - { 0xfd50, 0xfd8f, CXX }, - { 0xfd92, 0xfdc7, CXX }, - { 0xfdf0, 0xfdfb, CXX }, - { 0xfe70, 0xfe72, CXX }, - { 0xfe74, 0xfe74, CXX }, - { 0xfe76, 0xfefc, CXX }, - { 0xff21, 0xff3a, CXX }, - { 0xff41, 0xff5a, CXX }, - { 0xff66, 0xffbe, CXX }, - { 0xffc2, 0xffc7, CXX }, - { 0xffca, 0xffcf, CXX }, - { 0xffd2, 0xffd7, CXX }, - { 0xffda, 0xffdc, CXX }, -}; - -#endif /* cppucnid.h */ diff --git a/support/cpp2/diagnostic.c b/support/cpp2/diagnostic.c index 7b1155b9..8dc988fd 100644 --- a/support/cpp2/diagnostic.c +++ b/support/cpp2/diagnostic.c @@ -1,5 +1,6 @@ /* Language-independent diagnostic subroutines for the GNU Compiler Collection - Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 + Free Software Foundation, Inc. Contributed by Gabriel Dos Reis This file is part of GCC. @@ -16,8 +17,8 @@ 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. */ +Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301, USA. */ /* This file implements the language independent aspect of diagnostic @@ -27,11 +28,12 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #undef FLOAT /* This is for hpux. They should change hpux. */ #undef FFS /* Some systems define this in param.h. */ #include "system.h" -#include "input.h" +#include "options.h" #include "version.h" #include "input.h" #include "intl.h" #include "diagnostic.h" +#include "opts.h" /* Prototypes. */ @@ -43,25 +45,15 @@ static void default_diagnostic_finalizer (diagnostic_context *, diagnostic_info *); static void error_recursion (diagnostic_context *) ATTRIBUTE_NORETURN; -static bool text_specifies_location (text_info *, location_t *); static bool diagnostic_count_diagnostic (diagnostic_context *, diagnostic_info *); static void diagnostic_action_after_output (diagnostic_context *, diagnostic_info *); static void real_abort (void) ATTRIBUTE_NORETURN; -extern int rtl_dump_and_exit; - /* A diagnostic_context surrogate for stderr. */ static diagnostic_context global_diagnostic_context; diagnostic_context *global_dc = &global_diagnostic_context; - -/* Boilerplate text used in two locations. */ -#define bug_report_request \ -"Please submit a full bug report,\n\ -with preprocessed source if appropriate.\n\ -See %s for instructions.\n" - /* Return a malloc'd string containing MSG formatted a la printf. The caller is responsible for freeing the memory. */ @@ -98,10 +90,12 @@ diagnostic_initialize (diagnostic_context *context) /* By default, diagnostics are sent to stderr. */ context->printer->buffer->stream = stderr; /* By default, we emit prefixes once per message. */ - context->printer->prefixing_rule = DIAGNOSTICS_SHOW_PREFIX_ONCE; + context->printer->wrapping.rule = DIAGNOSTICS_SHOW_PREFIX_ONCE; memset (context->diagnostic_count, 0, sizeof context->diagnostic_count); - context->warnings_are_errors_message = warnings_are_errors; + context->issue_warnings_are_errors_message = true; + context->warning_as_error_requested = false; + context->show_option_requested = false; context->abort_on_error = false; context->internal_error = NULL; diagnostic_starter (context) = default_diagnostic_starter; @@ -109,51 +103,31 @@ diagnostic_initialize (diagnostic_context *context) context->last_module = 0; context->last_function = NULL; context->lock = 0; - context->x_data = NULL; } -/* Returns true if the next format specifier in TEXT is a format specifier - for a location_t. If so, update the object pointed by LOCUS to reflect - the specified location in *TEXT->args_ptr. */ -static bool -text_specifies_location (text_info *text, location_t *locus) +/* Initialize DIAGNOSTIC, where the message MSG has already been + translated. */ +void +diagnostic_set_info_translated (diagnostic_info *diagnostic, const char *msg, + va_list *args, location_t location, + diagnostic_t kind) { - const char *p; - /* Skip any leading text. */ - for (p = text->format_spec; *p && *p != '%'; ++p) - ; - - /* Extract the location information if any. */ - if (p[0] == '%' && p[1] == 'H') - { - *locus = *va_arg (*text->args_ptr, location_t *); - text->format_spec = p + 2; - return true; - } - else if (p[0] == '%' && p[1] == 'J') - { - tree t = va_arg (*text->args_ptr, tree); - *locus = DECL_SOURCE_LOCATION (t); - text->format_spec = p + 2; - return true; - } - - return false; + diagnostic->message.err_no = errno; + diagnostic->message.args_ptr = args; + diagnostic->message.format_spec = msg; + diagnostic->location = location; + diagnostic->kind = kind; + diagnostic->option_index = 0; } +/* Initialize DIAGNOSTIC, where the message GMSGID has not yet been + translated. */ void -diagnostic_set_info (diagnostic_info *diagnostic, const char *msgid, +diagnostic_set_info (diagnostic_info *diagnostic, const char *gmsgid, va_list *args, location_t location, diagnostic_t kind) { - diagnostic->message.err_no = errno; - diagnostic->message.args_ptr = args; - diagnostic->message.format_spec = _(msgid); - /* If the diagnostic message doesn't specify a location, - use LOCATION. */ - if (!text_specifies_location (&diagnostic->message, &diagnostic->location)) - diagnostic->location = location; - diagnostic->kind = kind; + diagnostic_set_info_translated (diagnostic, _(gmsgid), args, location, kind); } /* Return a malloc'd string describing a location. The caller is @@ -167,16 +141,18 @@ diagnostic_build_prefix (diagnostic_info *diagnostic) #undef DEFINE_DIAGNOSTIC_KIND "must-not-happen" }; - if (diagnostic->kind >= DK_LAST_DIAGNOSTIC_KIND) - abort(); - - return diagnostic->location.file - ? build_message_string ("%s:%d: %s", - diagnostic->location.file, - diagnostic->location.line, - _(diagnostic_kind_text[diagnostic->kind])) - : build_message_string ("%s: %s", progname, - _(diagnostic_kind_text[diagnostic->kind])); + const char *text = _(diagnostic_kind_text[diagnostic->kind]); + expanded_location s = expand_location (diagnostic->location); + gcc_assert (diagnostic->kind < DK_LAST_DIAGNOSTIC_KIND); + + return + (s.file == NULL + ? build_message_string ("%s: %s", progname, text) +#ifdef USE_MAPPED_LOCATION + : flag_show_column && s.column != 0 + ? build_message_string ("%s:%d:%d: %s", s.file, s.line, s.column, text) +#endif + : build_message_string ("%s:%d: %s", s.file, s.line, text)); } /* Count a diagnostic. Return true if the message should be printed. */ @@ -188,8 +164,7 @@ diagnostic_count_diagnostic (diagnostic_context *context, switch (kind) { default: - abort(); - break; + gcc_unreachable (); case DK_ICE: #ifndef ENABLE_CHECKING @@ -200,8 +175,9 @@ diagnostic_count_diagnostic (diagnostic_context *context, || diagnostic_kind_count (context, DK_SORRY) > 0) && !context->abort_on_error) { + expanded_location s = expand_location (diagnostic->location); fnotice (stderr, "%s:%d: confused by earlier errors, bailing out\n", - diagnostic->location.file, diagnostic->location.line); + s.file, s.line); exit (FATAL_EXIT_CODE); } #endif @@ -219,17 +195,16 @@ diagnostic_count_diagnostic (diagnostic_context *context, if (!diagnostic_report_warnings_p ()) return false; - if (!warnings_are_errors) + if (!context->warning_as_error_requested) { ++diagnostic_kind_count (context, DK_WARNING); break; } - - if (context->warnings_are_errors_message) + else if (context->issue_warnings_are_errors_message) { pp_verbatim (context->printer, "%s: warnings being treated as errors\n", progname); - context->warnings_are_errors_message = false; + context->issue_warnings_are_errors_message = false; } /* And fall through. */ @@ -259,13 +234,20 @@ diagnostic_action_after_output (diagnostic_context *context, case DK_SORRY: if (context->abort_on_error) real_abort (); + if (flag_fatal_errors) + { + fnotice (stderr, "compilation terminated due to -Wfatal-errors.\n"); + exit (FATAL_EXIT_CODE); + } break; case DK_ICE: if (context->abort_on_error) real_abort (); - fnotice (stderr, bug_report_request, bug_report_url); + fnotice (stderr, "Please submit a full bug report,\n" + "with preprocessed source if appropriate.\n" + "See %s for instructions.\n", bug_report_url); exit (FATAL_EXIT_CODE); case DK_FATAL: @@ -276,19 +258,17 @@ diagnostic_action_after_output (diagnostic_context *context, exit (FATAL_EXIT_CODE); default: - real_abort (); + gcc_unreachable (); } } /* Prints out, if necessary, the name of the current function - that caused an error. Called from all error and warning functions. - We ignore the FILE parameter, as it cannot be relied upon. */ - + that caused an error. Called from all error and warning functions. */ void diagnostic_report_current_function (diagnostic_context *context) { diagnostic_report_current_module (context); - (*lang_hooks.print_error_function) (context, input_filename); + lang_hooks.print_error_function (context, input_filename); } void @@ -302,18 +282,23 @@ diagnostic_report_current_module (diagnostic_context *context) pp_needs_newline (context->printer) = false; } - if (input_file_stack && diagnostic_last_module_changed (context)) + p = input_file_stack; + if (p && diagnostic_last_module_changed (context)) { - p = input_file_stack; + expanded_location xloc = expand_location (p->location); pp_verbatim (context->printer, "In file included from %s:%d", - p->location.file, p->location.line); + xloc.file, xloc.line); while ((p = p->next) != NULL) - pp_verbatim (context->printer, - ",\n from %s:%d", - p->location.file, p->location.line); - pp_verbatim (context->printer, ":\n"); + { + xloc = expand_location (p->location); + pp_verbatim (context->printer, + ",\n from %s:%d", + xloc.file, xloc.line); + } + pp_verbatim (context->printer, ":"); diagnostic_set_last_module (context); + pp_newline (context->printer); } } @@ -327,7 +312,7 @@ default_diagnostic_starter (diagnostic_context *context, static void default_diagnostic_finalizer (diagnostic_context *context, - diagnostic_info *diagnostic __attribute__((unused))) + diagnostic_info *diagnostic ATTRIBUTE_UNUSED) { pp_destroy_prefix (context->printer); } @@ -342,16 +327,40 @@ void diagnostic_report_diagnostic (diagnostic_context *context, diagnostic_info *diagnostic) { - if (context->lock++ && diagnostic->kind < DK_SORRY) - error_recursion (context); + if (context->lock > 0) + { + /* If we're reporting an ICE in the middle of some other error, + try to flush out the previous error, then let this one + through. Don't do this more than once. */ + if (diagnostic->kind == DK_ICE && context->lock == 1) + pp_flush (context->printer); + else + error_recursion (context); + } + + if (diagnostic->option_index + && ! option_enabled (diagnostic->option_index)) + return; + + context->lock++; if (diagnostic_count_diagnostic (context, diagnostic)) { + const char *saved_format_spec = diagnostic->message.format_spec; + + if (context->show_option_requested && diagnostic->option_index) + diagnostic->message.format_spec + = ACONCAT ((diagnostic->message.format_spec, + " [", cl_options[diagnostic->option_index].opt_text, "]", NULL)); + + diagnostic->message.locus = &diagnostic->location; + pp_format (context->printer, &diagnostic->message); (*diagnostic_starter (context)) (context, diagnostic); - pp_format_text (context->printer, &diagnostic->message); + pp_output_formatted_text (context->printer); (*diagnostic_finalizer (context)) (context, diagnostic); pp_flush (context->printer); diagnostic_action_after_output (context, diagnostic); + diagnostic->message.format_spec = saved_format_spec; } context->lock--; @@ -370,20 +379,10 @@ trim_filename (const char *name) /* First skip any "../" in each filename. This allows us to give a proper reference to a file in a subdirectory. */ - while (p[0] == '.' && p[1] == '.' - && (p[2] == DIR_SEPARATOR -#ifdef DIR_SEPARATOR_2 - || p[2] == DIR_SEPARATOR_2 -#endif - )) + while (p[0] == '.' && p[1] == '.' && IS_DIR_SEPARATOR (p[2])) p += 3; - while (q[0] == '.' && q[1] == '.' - && (q[2] == DIR_SEPARATOR -#ifdef DIR_SEPARATOR_2 - || p[2] == DIR_SEPARATOR_2 -#endif - )) + while (q[0] == '.' && q[1] == '.' && IS_DIR_SEPARATOR (q[2])) q += 3; /* Now skip any parts the two filenames have in common. */ @@ -391,11 +390,7 @@ trim_filename (const char *name) p++, q++; /* Now go backwards until the previous directory separator. */ - while (p > name && p[-1] != DIR_SEPARATOR -#ifdef DIR_SEPARATOR_2 - && p[-1] != DIR_SEPARATOR_2 -#endif - ) + while (p > name && !IS_DIR_SEPARATOR (p[-1])) p--; return p; @@ -407,15 +402,16 @@ trim_filename (const char *name) /* Text to be emitted verbatim to the error message stream; this produces no prefix and disables line-wrapping. Use rarely. */ void -verbatim (const char *msgid, ...) +verbatim (const char *gmsgid, ...) { text_info text; va_list ap; - va_start (ap, msgid); + va_start (ap, gmsgid); text.err_no = errno; text.args_ptr = ≈ - text.format_spec = _(msgid); + text.format_spec = _(gmsgid); + text.locus = NULL; pp_format_verbatim (global_dc->printer, &text); pp_flush (global_dc->printer); va_end (ap); @@ -424,13 +420,13 @@ verbatim (const char *msgid, ...) /* An informative note. Use this for additional details on an error message. */ void -inform (const char *msgid, ...) +inform (const char *gmsgid, ...) { diagnostic_info diagnostic; va_list ap; - va_start (ap, msgid); - diagnostic_set_info (&diagnostic, msgid, &ap, input_location, DK_NOTE); + va_start (ap, gmsgid); + diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location, DK_NOTE); report_diagnostic (&diagnostic); va_end (ap); } @@ -438,13 +434,27 @@ inform (const char *msgid, ...) /* A warning. Use this for code which is correct according to the relevant language specification but is likely to be buggy anyway. */ void -warning (const char *msgid, ...) +warning (int opt, const char *gmsgid, ...) { diagnostic_info diagnostic; va_list ap; - va_start (ap, msgid); - diagnostic_set_info (&diagnostic, msgid, &ap, input_location, DK_WARNING); + va_start (ap, gmsgid); + diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location, DK_WARNING); + diagnostic.option_index = opt; + + report_diagnostic (&diagnostic); + va_end (ap); +} + +void +warning0 (const char *gmsgid, ...) +{ + diagnostic_info diagnostic; + va_list ap; + + va_start (ap, gmsgid); + diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location, DK_WARNING); report_diagnostic (&diagnostic); va_end (ap); } @@ -458,13 +468,13 @@ warning (const char *msgid, ...) of the -pedantic command-line switch. To get a warning enabled only with that switch, write "if (pedantic) pedwarn (...);" */ void -pedwarn (const char *msgid, ...) +pedwarn (const char *gmsgid, ...) { diagnostic_info diagnostic; va_list ap; - va_start (ap, msgid); - diagnostic_set_info (&diagnostic, msgid, &ap, input_location, + va_start (ap, gmsgid); + diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location, pedantic_error_kind ()); report_diagnostic (&diagnostic); va_end (ap); @@ -473,13 +483,13 @@ pedwarn (const char *msgid, ...) /* A hard error: the code is definitely ill-formed, and an object file will not be produced. */ void -error (const char *msgid, ...) +error (const char *gmsgid, ...) { diagnostic_info diagnostic; va_list ap; - va_start (ap, msgid); - diagnostic_set_info (&diagnostic, msgid, &ap, input_location, DK_ERROR); + va_start (ap, gmsgid); + diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location, DK_ERROR); report_diagnostic (&diagnostic); va_end (ap); } @@ -488,13 +498,13 @@ error (const char *msgid, ...) required by the relevant specification but not implemented by GCC. An object file will not be produced. */ void -sorry (const char *msgid, ...) +sorry (const char *gmsgid, ...) { diagnostic_info diagnostic; va_list ap; - va_start (ap, msgid); - diagnostic_set_info (&diagnostic, msgid, &ap, input_location, DK_SORRY); + va_start (ap, gmsgid); + diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location, DK_SORRY); report_diagnostic (&diagnostic); va_end (ap); } @@ -503,18 +513,17 @@ sorry (const char *msgid, ...) 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 *msgid, ...) +fatal_error (const char *gmsgid, ...) { diagnostic_info diagnostic; va_list ap; - va_start (ap, msgid); - diagnostic_set_info (&diagnostic, msgid, &ap, input_location, DK_FATAL); + va_start (ap, gmsgid); + diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location, DK_FATAL); report_diagnostic (&diagnostic); va_end (ap); - /* NOTREACHED */ - real_abort (); + gcc_unreachable (); } /* An internal consistency check has failed. We make no attempt to @@ -522,18 +531,17 @@ fatal_error (const char *msgid, ...) a more specific message, or some other good reason, you should use abort () instead of calling this function directly. */ void -internal_error (const char *msgid, ...) +internal_error (const char *gmsgid, ...) { diagnostic_info diagnostic; va_list ap; - va_start (ap, msgid); - diagnostic_set_info (&diagnostic, msgid, &ap, input_location, DK_ICE); + va_start (ap, gmsgid); + diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location, DK_ICE); report_diagnostic (&diagnostic); va_end (ap); - /* NOTREACHED */ - real_abort (); + gcc_unreachable (); } /* Special case error functions. Most are implemented in terms of the @@ -542,12 +550,12 @@ internal_error (const char *msgid, ...) /* Print a diagnostic MSGID on FILE. This is just fprintf, except it runs its second argument through gettext. */ void -fnotice (FILE *file, const char *msgid, ...) +fnotice (FILE *file, const char *cmsgid, ...) { va_list ap; - va_start (ap, msgid); - vfprintf (file, _(msgid), ap); + va_start (ap, cmsgid); + vfprintf (file, _(cmsgid), ap); va_end (ap); } @@ -559,13 +567,22 @@ fnotice (FILE *file, const char *msgid, ...) static void error_recursion (diagnostic_context *context) { + diagnostic_info diagnostic; + if (context->lock < 3) pp_flush (context->printer); fnotice (stderr, "Internal compiler error: Error reporting routines re-entered.\n"); - fnotice (stderr, bug_report_request, bug_report_url); - exit (FATAL_EXIT_CODE); + + /* Call diagnostic_action_after_output to get the "please submit a bug + report" message. It only looks at the kind field of diagnostic_info. */ + diagnostic.kind = DK_ICE; + diagnostic_action_after_output (context, &diagnostic); + + /* Do not use gcc_unreachable here; that goes through internal_error + and therefore would cause infinite recursion. */ + real_abort (); } /* Report an internal compiler error in a friendly manner. This is diff --git a/support/cpp2/diagnostic.h b/support/cpp2/diagnostic.h index daf24279..3a3204bd 100644 --- a/support/cpp2/diagnostic.h +++ b/support/cpp2/diagnostic.h @@ -1,5 +1,6 @@ /* Various declarations for language-independent diagnostics subroutines. - Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 + Free Software Foundation, Inc. Contributed by Gabriel Dos Reis This file is part of GCC. @@ -16,8 +17,8 @@ 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. */ +Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301, USA. */ #ifndef GCC_DIAGNOSTIC_H #define GCC_DIAGNOSTIC_H @@ -42,6 +43,8 @@ typedef struct location_t location; /* The kind of diagnostic it is about. */ diagnostic_t kind; + /* Which OPT_* directly controls this diagnostic. */ + int option_index; } diagnostic_info; #define pedantic_error_kind() (flag_pedantic_errors ? DK_ERROR : DK_WARNING) @@ -65,7 +68,14 @@ struct diagnostic_context /* True if we should display the "warnings are being tread as error" message, usually displayed once per compiler run. */ - bool warnings_are_errors_message; + bool issue_warnings_are_errors_message; + + /* True if it has been requested that warnings be treated as errors. */ + bool warning_as_error_requested; + + /* True if we should print the command line option which controls + each diagnostic, if known. */ + bool show_option_requested; /* True if we should raise a SIGABRT on errors. */ bool abort_on_error; @@ -94,9 +104,6 @@ struct diagnostic_context int last_module; int lock; - - /* Hook for front-end extensions. */ - void *x_data; }; /* Client supplied function to announce a diagnostic. */ @@ -113,11 +120,11 @@ struct diagnostic_context #define diagnostic_format_decoder(DC) ((DC)->printer->format_decoder) /* Same as output_prefixing_rule. Works on 'diagnostic_context *'. */ -#define diagnostic_prefixing_rule(DC) ((DC)->printer->prefixing_rule) +#define diagnostic_prefixing_rule(DC) ((DC)->printer->wrapping.rule) /* Maximum characters per line in automatic line wrapping mode. Zero means don't wrap lines. */ -#define diagnostic_line_cutoff(DC) ((DC)->printer->ideal_maximum_length) +#define diagnostic_line_cutoff(DC) ((DC)->printer->wrapping.line_cutoff) #define diagnostic_flush_buffer(DC) pp_base_flush ((DC)->printer) @@ -174,12 +181,27 @@ extern void diagnostic_report_current_module (diagnostic_context *); extern void diagnostic_report_current_function (diagnostic_context *); extern void diagnostic_report_diagnostic (diagnostic_context *, diagnostic_info *); +#ifdef ATTRIBUTE_GCC_DIAG extern void diagnostic_set_info (diagnostic_info *, const char *, va_list *, - location_t, diagnostic_t); + location_t, diagnostic_t) ATTRIBUTE_GCC_DIAG(2,0); +extern void diagnostic_set_info_translated (diagnostic_info *, const char *, + va_list *, location_t, + diagnostic_t) + ATTRIBUTE_GCC_DIAG(2,0); +#endif extern char *diagnostic_build_prefix (diagnostic_info *); /* Pure text formatting support functions. */ -extern void verbatim (const char *, ...); extern char *file_name_as_prefix (const char *); +/* In tree-pretty-print.c */ +extern int dump_generic_node (pretty_printer *, tree, int, int, bool); +extern void print_generic_stmt (FILE *, tree, int); +extern void print_generic_stmt_indented (FILE *, tree, int, int); +extern void print_generic_expr (FILE *, tree, int); +extern void print_generic_decl (FILE *, tree, int); + +extern void debug_generic_expr (tree); +extern void debug_generic_stmt (tree); +extern void debug_c_tree (tree); #endif /* ! GCC_DIAGNOSTIC_H */ diff --git a/support/cpp2/except.h b/support/cpp2/except.h index 5093a650..d5e391d9 100644 --- a/support/cpp2/except.h +++ b/support/cpp2/except.h @@ -1,5 +1,5 @@ /* Exception Handling interface routines. - Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 + Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Contributed by Mike Stump . @@ -17,14 +17,12 @@ 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. */ +Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301, USA. */ struct function; -struct inline_remap; - /* Per-function EH data. Used only in except.c, but GC and others manipulate pointers to the opaque type. */ struct eh_status; @@ -35,62 +33,25 @@ struct eh_region; /* Test: is exception handling turned on? */ extern int doing_eh (int); -/* Start an exception handling region. All instructions emitted after - this point are considered to be part of the region until an - expand_eh_region_end variant is invoked. */ -extern void expand_eh_region_start (void); - -/* End an exception handling region for a cleanup. HANDLER is an - expression to expand for the cleanup. */ -extern void expand_eh_region_end_cleanup (tree); - -/* End an exception handling region for a try block, and prepares - for subsequent calls to expand_start_catch. */ -extern void expand_start_all_catch (void); - -/* Begin a catch clause. TYPE is an object to be matched by the - runtime, or a list of such objects, or null if this is a catch-all - clause. */ -extern void expand_start_catch (tree); - -/* End a catch clause. Control will resume after the try/catch block. */ -extern void expand_end_catch (void); - -/* End a sequence of catch handlers for a try block. */ -extern void expand_end_all_catch (void); - -/* End an exception region for an exception type filter. ALLOWED is a - TREE_LIST of TREE_VALUE objects to be matched by the runtime. - FAILURE is a function to invoke if a mismatch occurs. */ -extern void expand_eh_region_end_allowed (tree, tree); - -/* End an exception region for a must-not-throw filter. FAILURE is a - function to invoke if an uncaught exception propagates this far. */ -extern void expand_eh_region_end_must_not_throw (tree); - -/* End an exception region for a throw. No handling goes on here, - but it's the easiest way for the front-end to indicate what type - is being thrown. */ -extern void expand_eh_region_end_throw (tree); - -/* End a fixup region. Within this region the cleanups for the immediately - enclosing region are _not_ run. This is used for goto cleanup to avoid - destroying an object twice. */ -extern void expand_eh_region_end_fixup (tree); - /* 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 (void); +extern void note_eh_region_may_contain_throw (struct eh_region *); +extern void note_current_region_may_contain_throw (void); /* 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 (rtx); +extern bool can_throw_external_1 (int, bool); extern bool can_throw_external (rtx); -/* Set current_function_nothrow and cfun->all_throwers_are_sibcalls. */ +/* Set TREE_NOTHROW and cfun->all_throwers_are_sibcalls. */ extern void set_nothrow_function_flags (void); /* After initial rtl generation, call back to finish generating @@ -119,10 +80,39 @@ 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 (struct function *); -extern int duplicate_eh_regions (struct function *, struct inline_remap *); +extern rtx get_exception_filter (struct function *); +typedef tree (*duplicate_eh_regions_map) (tree, void *); +extern int duplicate_eh_regions (struct function *, duplicate_eh_regions_map, void *, 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 *); + +/* tree-eh.c */ +extern void add_stmt_to_eh_region_fn (struct function *, tree, int); +extern bool remove_stmt_from_eh_region_fn (struct function *, tree); +extern int lookup_stmt_eh_region_fn (struct function *, tree); +extern int lookup_stmt_eh_region (tree); +extern bool verify_eh_edges (tree); /* If non-NULL, this is a function that returns an expression to be executed if an unhandled exception is propagated out of a cleanup @@ -145,7 +135,7 @@ extern tree (*lang_eh_runtime_type) (tree); #ifndef MUST_USE_SJLJ_EXCEPTIONS # if !(defined (EH_RETURN_DATA_REGNO) \ - && (defined (IA64_UNWIND_INFO) \ + && (defined (TARGET_UNWIND_INFO) \ || (DWARF2_UNWIND_INFO \ && (defined (EH_RETURN_HANDLER_RTX) \ || defined (HAVE_eh_return))))) @@ -167,10 +157,19 @@ extern tree (*lang_eh_runtime_type) (tree); # if !defined(EH_RETURN_HANDLER_RTX) && !defined(HAVE_eh_return) #error "EH_RETURN_HANDLER_RTX or eh_return required" # endif -# if !defined(DWARF2_UNWIND_INFO) && !defined(IA64_UNWIND_INFO) - #error "{DWARF2,IA64}_UNWIND_INFO required" +# if !defined(DWARF2_UNWIND_INFO) && !defined(TARGET_UNWIND_INFO) + #error "{DWARF2,TARGET}_UNWIND_INFO required" # endif # endif #else # define USING_SJLJ_EXCEPTIONS MUST_USE_SJLJ_EXCEPTIONS #endif + +struct throw_stmt_node GTY(()) +{ + tree 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/cpp2/hwint.h b/support/cpp2/hwint.h index 4fed004c..9b28a3ad 100644 --- a/support/cpp2/hwint.h +++ b/support/cpp2/hwint.h @@ -1,5 +1,5 @@ /* HOST_WIDE_INT definitions for the GNU compiler. - Copyright (C) 1998, 2002 Free Software Foundation, Inc. + Copyright (C) 1998, 2002, 2004 Free Software Foundation, Inc. This file is part of GCC. @@ -15,6 +15,12 @@ #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 @@ -74,10 +80,11 @@ extern char sizeof_long_long_must_be_8[sizeof(long long) == 8 ? 1 : -1]; # define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%lx%08lx" # endif #else -# define HOST_WIDE_INT_PRINT "ll" +# 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%llx%016llx" +# 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" @@ -109,11 +116,35 @@ extern char sizeof_long_long_must_be_8[sizeof(long long) == 8 ? 1 : -1]; #error "This line should be impossible to reach" # endif # endif -# define HOST_WIDEST_INT_PRINT_DEC "%lld" -# define HOST_WIDEST_INT_PRINT_DEC_C "%lldLL" -# define HOST_WIDEST_INT_PRINT_UNSIGNED "%llu" -# define HOST_WIDEST_INT_PRINT_HEX "0x%llx" -# define HOST_WIDEST_INT_PRINT_DOUBLE_HEX "0x%llx%016llx" +# 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 + autodect 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 wantted 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/cpp2/input.h b/support/cpp2/input.h index ff014f6d..0ca3ccfd 100644 --- a/support/cpp2/input.h +++ b/support/cpp2/input.h @@ -1,6 +1,6 @@ /* Declarations for variables relating to reading the source file. Used by parsers, lexical analyzers, and error message routines. - Copyright (C) 1993, 1997, 1998, 2000, 2003 Free Software Foundation, Inc. + Copyright (C) 1993, 1997, 1998, 2000, 2003, 2004 Free Software Foundation, Inc. This file is part of GCC. @@ -16,15 +16,40 @@ 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. */ +Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301, USA. */ #ifndef GCC_INPUT_H #define GCC_INPUT_H -/* The data structure used to record a location in a translation unit. */ -/* Long-term, we want to get rid of this and typedef fileline location_t. */ -struct location_s GTY (()) +#include "line-map.h" +extern struct line_maps line_table; + +/* The location for declarations in "" */ +#define BUILTINS_LOCATION ((source_location) 2) + +#ifdef USE_MAPPED_LOCATION + +typedef struct +{ + /* The name of the source file involved. */ + const char *file; + + /* The line-location in the source file. */ + int line; + + int column; +} expanded_location; + +extern expanded_location expand_location (source_location); + +#define UNKNOWN_LOCATION ((source_location) 0) +typedef source_location location_t; /* deprecated typedef */ +typedef source_location source_locus; /* to be removed */ + +#else /* ! USE_MAPPED_LOCATION */ + +struct location_s GTY(()) { /* The name of the source file involved. */ const char *file; @@ -32,7 +57,16 @@ struct location_s GTY (()) /* The line-location in the source file. */ int line; }; + +typedef struct location_s expanded_location; typedef struct location_s location_t; +typedef location_t *source_locus; + +#define expand_location(FILELINE) (FILELINE) +extern location_t unknown_location; +#define UNKNOWN_LOCATION unknown_location + +#endif /* ! USE_MAPPED_LOCATION */ struct file_stack { @@ -44,20 +78,24 @@ struct file_stack extern const char *main_input_filename; extern location_t input_location; -#define input_line (input_location.line) -#define input_filename (input_location.file) +#ifdef USE_MAPPED_LOCATION +extern void push_srcloc (location_t); +#else /* ! USE_MAPPED_LOCATION */ +extern void push_srcloc (const char *name, int line); +#endif /* ! USE_MAPPED_LOCATION */ +extern void pop_srcloc (void); + +#define LOCATION_FILE(LOC) ((expand_location (LOC)).file) +#define LOCATION_LINE(LOC) ((expand_location (LOC)).line) + +#define input_line LOCATION_LINE(input_location) +#define input_filename LOCATION_FILE(input_location) /* Stack of currently pending input files. The line member is not accurate for the innermost file on the stack. */ extern struct file_stack *input_file_stack; -/* Stack of EXPR_WITH_FILE_LOCATION nested expressions. */ -extern struct file_stack *expr_wfl_stack; - /* Incremented on each change to input_file_stack. */ extern int input_file_stack_tick; -extern void push_srcloc (const char *name, int line); -extern void pop_srcloc (void); - #endif diff --git a/support/cpp2/intl.h b/support/cpp2/intl.h index 80a945b4..a118c0a9 100644 --- a/support/cpp2/intl.h +++ b/support/cpp2/intl.h @@ -1,5 +1,5 @@ /* intl.h - internationalization - Copyright 1998, 2001, 2003 Free Software Foundation, Inc. + Copyright 1998, 2001, 2003, 2004 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 @@ -13,8 +13,8 @@ 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. */ + Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ #ifndef GCC_INTL_H #define GCC_INTL_H @@ -51,4 +51,11 @@ extern size_t gcc_gettext_width (const char *); # 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/cpp2/cppcharset.c b/support/cpp2/libcpp/charset.c similarity index 77% rename from support/cpp2/cppcharset.c rename to support/cpp2/libcpp/charset.c index a6a65ed7..78c89816 100644 --- a/support/cpp2/cppcharset.c +++ b/support/cpp2/libcpp/charset.c @@ -16,13 +16,12 @@ 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. */ +Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #include "system.h" #include "cpplib.h" -#include "cpphash.h" -#include "cppucnid.h" +#include "internal.h" /* Character set handling for C-family languages. @@ -81,8 +80,10 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #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 @@ -485,7 +486,7 @@ conversion_loop (int (*const one_conversion)(iconv_t, const uchar **, size_t *, outbytesleft += OUTBUF_BLOCK_SIZE; to->asize += OUTBUF_BLOCK_SIZE; - to->text = xrealloc (to->text, to->asize); + to->text = XRESIZEVEC (uchar, to->text, to->asize); outbuf = to->text + to->asize - outbytesleft; } } @@ -537,7 +538,7 @@ convert_no_conversion (iconv_t cd ATTRIBUTE_UNUSED, if (to->len + flen > to->asize) { to->asize = to->len + flen; - to->text = xrealloc (to->text, to->asize); + to->text = XRESIZEVEC (uchar, to->text, to->asize); } memcpy (to->text + to->len, from, flen); to->len += flen; @@ -577,7 +578,7 @@ convert_using_iconv (iconv_t cd, const uchar *from, size_t flen, outbytesleft += OUTBUF_BLOCK_SIZE; to->asize += OUTBUF_BLOCK_SIZE; - to->text = xrealloc (to->text, to->asize); + to->text = XRESIZEVEC (uchar, to->text, to->asize); outbuf = (char *)to->text + to->asize - outbytesleft; } } @@ -627,7 +628,7 @@ init_iconv_desc (cpp_reader *pfile, const char *to, const char *from) return ret; } - pair = alloca(strlen(to) + strlen(from) + 2); + pair = (char *) alloca(strlen(to) + strlen(from) + 2); strcpy(pair, from); strcat(pair, "/"); @@ -649,7 +650,7 @@ init_iconv_desc (cpp_reader *pfile, const char *to, const char *from) if (ret.cd == (iconv_t) -1) { if (errno == EINVAL) - cpp_error (pfile, CPP_DL_ERROR, /* XXX should be DL_SORRY */ + cpp_error (pfile, CPP_DL_ERROR, /* FIXME should be DL_SORRY */ "conversion from %s to %s not supported by iconv", from, to); else @@ -660,7 +661,7 @@ init_iconv_desc (cpp_reader *pfile, const char *to, const char *from) } else { - cpp_error (pfile, CPP_DL_ERROR, /* XXX should be DL_SORRY */ + 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; @@ -701,6 +702,7 @@ cpp_init_iconv (cpp_reader *pfile) pfile->wide_cset_desc = init_iconv_desc (pfile, wcset, SOURCE_CHARSET); } +/* Destroy iconv(3) descriptors set up by cpp_init_iconv, if necessary. */ void _cpp_destroy_iconv (cpp_reader *pfile) { @@ -713,6 +715,63 @@ _cpp_destroy_iconv (cpp_reader *pfile) } } +/* 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. */ @@ -726,45 +785,128 @@ width_to_mask (size_t width) 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. The algorithm is a simple binary search on the - table defined in cppucnid.h. */ + _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) +ucn_valid_in_identifier (cpp_reader *pfile, cppchar_t c, + struct normalize_state *nst) { int mn, mx, md; - mn = -1; - mx = ARRAY_SIZE (ucnranges); - while (mx - mn > 1) + if (c > 0xFFFF) + return 0; + + mn = 0; + mx = ARRAY_SIZE (ucnranges) - 1; + while (mx != mn) { md = (mn + mx) / 2; - if (c < ucnranges[md].lo) + if (c <= ucnranges[md].end) mx = md; - else if (c > ucnranges[md].hi) - mn = md; else - goto found; + mn = md + 1; } - return 0; - found: /* 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[md].flags & C99)) + && ((CPP_OPTION (pfile, c99) && !(ucnranges[mn].flags & C99)) || (CPP_OPTION (pfile, cplusplus) - && !(ucnranges[md].flags & CXX)))) + && !(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[md].flags & DIG)) + if (CPP_OPTION (pfile, c99) && (ucnranges[mn].flags & DIG)) return 2; return 1; @@ -781,9 +923,8 @@ ucn_valid_in_identifier (cpp_reader *pfile, cppchar_t c) program is ill-formed. *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 UCNs - are not part of the relevant standard, or if the string beginning - at *PSTR doesn't syntactically match the form 'NNNN' or 'NNNNNNNN'. + 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 @@ -791,12 +932,12 @@ ucn_valid_in_identifier (cpp_reader *pfile, cppchar_t c) invalid character. IDENTIFIER_POS is 0 when not in an identifier, 1 for the start of - an identifier, or 2 otherwise. -*/ + an identifier, or 2 otherwise. */ cppchar_t _cpp_valid_ucn (cpp_reader *pfile, const uchar **pstr, - const uchar *limit, int identifier_pos) + const uchar *limit, int identifier_pos, + struct normalize_state *nst) { cppchar_t result, c; unsigned int length; @@ -816,7 +957,10 @@ _cpp_valid_ucn (cpp_reader *pfile, const uchar **pstr, else if (str[-1] == 'U') length = 8; else - abort(); + { + cpp_error (pfile, CPP_DL_ICE, "In _cpp_valid_ucn but not a UCN"); + length = 4; + } result = 0; do @@ -829,10 +973,15 @@ _cpp_valid_ucn (cpp_reader *pfile, const uchar **pstr, } 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) { - /* We'll error when we try it out as the start of an identifier. */ cpp_error (pfile, CPP_DL_ERROR, "incomplete universal character name %.*s", (int) (str - base), base); @@ -850,9 +999,19 @@ _cpp_valid_ucn (cpp_reader *pfile, const uchar **pstr, (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); + int validity = ucn_valid_in_identifier (pfile, result, nst); if (validity == 0) cpp_error (pfile, CPP_DL_ERROR, @@ -873,8 +1032,6 @@ _cpp_valid_ucn (cpp_reader *pfile, const uchar **pstr, /* 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, bool wide) @@ -886,9 +1043,10 @@ convert_ucn (cpp_reader *pfile, const uchar *from, const uchar *limit, int rval; struct cset_converter cvt = wide ? pfile->wide_cset_desc : pfile->narrow_cset_desc; + struct normalize_state nst = INITIAL_NORMALIZE_STATE; from++; /* Skip u/U. */ - ucn = _cpp_valid_ucn (pfile, &from, limit, 0); + ucn = _cpp_valid_ucn (pfile, &from, limit, 0, &nst); rval = one_cppchar_to_utf8 (ucn, &bufp, &bytesleft); if (rval) @@ -904,6 +1062,11 @@ convert_ucn (cpp_reader *pfile, const uchar *from, const uchar *limit, 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, bool wide) @@ -924,7 +1087,7 @@ emit_numeric_escape (cpp_reader *pfile, cppchar_t n, if (tbuf->len + nbwc > tbuf->asize) { tbuf->asize += OUTBUF_BLOCK_SIZE; - tbuf->text = xrealloc (tbuf->text, tbuf->asize); + tbuf->text = XRESIZEVEC (uchar, tbuf->text, tbuf->asize); } for (i = 0; i < nbwc; i++) @@ -937,10 +1100,12 @@ emit_numeric_escape (cpp_reader *pfile, cppchar_t n, } 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 = xrealloc (tbuf->text, tbuf->asize); + tbuf->text = XRESIZEVEC (uchar, tbuf->text, tbuf->asize); } tbuf->text[tbuf->len++] = n; } @@ -1112,8 +1277,14 @@ convert_escape (cpp_reader *pfile, const uchar *from, const uchar *limit, cpp_error (pfile, CPP_DL_PEDWARN, "unknown escape sequence '\\%c'", (int) c); else - cpp_error (pfile, CPP_DL_PEDWARN, - "unknown escape sequence: '\\%03o'", (int) c); + { + /* 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. */ @@ -1141,7 +1312,7 @@ cpp_interpret_string (cpp_reader *pfile, const cpp_string *from, size_t count, = wide ? pfile->wide_cset_desc : pfile->narrow_cset_desc; tbuf.asize = MAX (OUTBUF_BLOCK_SIZE, from->len); - tbuf.text = xmalloc (tbuf.asize); + tbuf.text = XNEWVEC (uchar, tbuf.asize); tbuf.len = 0; for (i = 0; i < count; i++) @@ -1172,7 +1343,7 @@ cpp_interpret_string (cpp_reader *pfile, const cpp_string *from, size_t count, /* NUL-terminate the 'to' buffer and translate it to a cpp_string structure. */ emit_numeric_escape (pfile, 0, &tbuf, wide); - tbuf.text = xrealloc (tbuf.text, tbuf.len); + tbuf.text = XRESIZEVEC (uchar, tbuf.text, tbuf.len); to->text = tbuf.text; to->len = tbuf.len; return true; @@ -1186,8 +1357,8 @@ cpp_interpret_string (cpp_reader *pfile, const cpp_string *from, size_t count, /* 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 *in, - cpp_string *out) +cpp_interpret_string_notranslate (cpp_reader *pfile, const cpp_string *from, + size_t count, cpp_string *to, bool wide) { struct cset_converter save_narrow_cset_desc = pfile->narrow_cset_desc; bool retval; @@ -1195,7 +1366,7 @@ _cpp_interpret_string_notranslate (cpp_reader *pfile, const cpp_string *in, pfile->narrow_cset_desc.func = convert_no_conversion; pfile->narrow_cset_desc.cd = (iconv_t) -1; - retval = cpp_interpret_string (pfile, in, 1, out, false); + retval = cpp_interpret_string (pfile, from, count, to, wide); pfile->narrow_cset_desc = save_narrow_cset_desc; return retval; @@ -1352,8 +1523,71 @@ cpp_interpret_charconst (cpp_reader *pfile, const cpp_token *token, 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; + } + } -uchar * + 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, and *ST_SIZE is set to the length of + the meaningful data within the translated buffer. + + INPUT is expected to have been allocated with xmalloc. This function + will either return INPUT, or free it and return 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, off_t *st_size) { @@ -1370,7 +1604,7 @@ _cpp_convert_input (cpp_reader *pfile, const char *input_charset, else { to.asize = MAX (65536, len); - to.text = xmalloc (to.asize); + to.text = XNEWVEC (uchar, to.asize); to.len = 0; if (!APPLY_CONVERSION (input_cset, input, len, &to)) @@ -1388,19 +1622,46 @@ _cpp_convert_input (cpp_reader *pfile, const char *input_charset, /* 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 = xrealloc (to.text, to.len + 1); + 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.text[to.len - 1] == '\r') + to.text[to.len] = '\r'; + else + to.text[to.len] = '\n'; - to.text[to.len] = '\n'; *st_size = to.len; return to.text; } +/* Decide on the default encoding to assume for input files. */ const char * _cpp_default_encoding (void) { const char *current_encoding = NULL; -#if defined (HAVE_LOCALE_H) && defined (HAVE_LANGINFO_CODESET) + /* 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 + 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 diff --git a/support/cpp2/cpplib.c b/support/cpp2/libcpp/directives.c similarity index 81% rename from support/cpp2/cpplib.c rename to support/cpp2/libcpp/directives.c index 8a291125..26029229 100644 --- a/support/cpp2/cpplib.c +++ b/support/cpp2/libcpp/directives.c @@ -1,6 +1,7 @@ /* CPP Library. (Directive handling.) Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + 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 @@ -17,22 +18,15 @@ 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. */ +Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #include "system.h" #include "cpplib.h" -#include "cpphash.h" +#include "internal.h" +#include "mkdeps.h" #include "obstack.h" -/* Chained list of answers to an assertion. */ -struct answer -{ - struct answer *next; - unsigned int count; - cpp_token first[1]; -}; - /* Stack of conditionals currently in progress (including both successful and failing conditionals). */ struct if_stack @@ -51,7 +45,9 @@ struct pragma_entry { struct pragma_entry *next; const cpp_hashnode *pragma; /* Name and length. */ - int is_nspace; + bool is_nspace; + bool allow_expansion; + bool is_internal; union { pragma_cb handler; struct pragma_entry *space; @@ -100,7 +96,7 @@ 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 *); +static const char *parse_include (cpp_reader *, int *, const cpp_token ***); static void push_conditional (cpp_reader *, int, int, const cpp_hashnode *); static unsigned int read_flag (cpp_reader *, unsigned int); static int strtoul_for_line (const uchar *, unsigned int, unsigned long *); @@ -113,7 +109,10 @@ static struct pragma_entry *lookup_pragma_entry (struct pragma_entry *, static struct pragma_entry *insert_pragma_entry (cpp_reader *, struct pragma_entry **, const cpp_hashnode *, - pragma_cb); + pragma_cb, + bool, bool); +static void register_pragma (cpp_reader *, const char *, const char *, + pragma_cb, bool, bool); 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 *, @@ -162,7 +161,10 @@ D(ident, T_IDENT, EXTENSION, IN_I) /* 11 */ \ D(import, T_IMPORT, EXTENSION, INCL | EXPAND) /* 0 ObjC */ \ D(assert, T_ASSERT, EXTENSION, 0) /* 0 SVR4 */ \ D(unassert, T_UNASSERT, EXTENSION, 0) /* 0 SVR4 */ \ -D(sccs, T_SCCS, EXTENSION, 0) /* 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. */ @@ -222,6 +224,46 @@ check_eol (cpp_reader *pfile) 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) @@ -229,9 +271,10 @@ 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; + pfile->directive_line = pfile->line_table->highest_line; } /* Called when leaving a directive, _Pragma or command-line directive. */ @@ -330,7 +373,7 @@ directive_diagnostics (cpp_reader *pfile, const directive *dir, int indented) /* 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 cpplex.c. Returns + 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 @@ -339,8 +382,12 @@ _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, pedantic)) @@ -382,7 +429,7 @@ _cpp_handle_directive (cpp_reader *pfile, int indented) 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. cppmacro.c + -fpreprocessed mode only if the # is in column 1. macro.c puts a space in front of any '#' at the start of a macro. */ if (CPP_OPTION (pfile, preprocessed) && (indented || !(dir->flags & IN_I))) @@ -435,6 +482,8 @@ _cpp_handle_directive (cpp_reader *pfile, int indented) pfile->state.parsing_args = 2; pfile->state.prevent_expansion = 1; } + if (was_discarding_output) + pfile->state.prevent_expansion = 1; return skip; } @@ -446,7 +495,7 @@ 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); /* Disgusting hack. */ - if (dir_no == T_PRAGMA) + if (dir_no == T_PRAGMA && pfile->buffer->prev) pfile->buffer->file = pfile->buffer->prev->file; start_directive (pfile); @@ -501,7 +550,7 @@ lex_macro_node (cpp_reader *pfile) return NULL; } -/* Process a #define directive. Most work is done in cppmacro.c. */ +/* Process a #define directive. Most work is done in macro.c. */ static void do_define (cpp_reader *pfile) { @@ -552,30 +601,13 @@ do_undef (cpp_reader *pfile) /* Undefine a single macro/assertion/whatever. */ static int -undefine_macros (cpp_reader *pfile, cpp_hashnode *h, +undefine_macros (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *h, void *data_p ATTRIBUTE_UNUSED) { - switch (h->type) - { - case NT_VOID: - break; - - case NT_MACRO: - if (pfile->cb.undef) - (*pfile->cb.undef) (pfile, pfile->directive_line, h); - - if (CPP_OPTION (pfile, warn_unused_macros)) - _cpp_warn_if_unused_macro (pfile, h, NULL); - - /* And fall through.... */ - case NT_ASSERTION: - _cpp_free_definition (h); - break; - - default: - abort (); - } - h->flags &= ~NODE_POISONED; + /* 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); return 1; } @@ -600,7 +632,7 @@ glue_header_name (cpp_reader *pfile) /* To avoid lexed tokens overwriting our glued name, we can only allocate from the string pool once we've lexed everything. */ - buffer = xmalloc (capacity); + buffer = XNEWVEC (char, capacity); for (;;) { token = get_token_no_padding (pfile); @@ -617,13 +649,14 @@ glue_header_name (cpp_reader *pfile) if (total_len + len > capacity) { capacity = (capacity + len) * 2; - buffer = xrealloc (buffer, capacity); + buffer = XRESIZEVEC (char, buffer, capacity); } if (token->flags & PREV_WHITE) buffer[total_len++] = ' '; - total_len = (cpp_spell_token (pfile, token, (uchar *) &buffer[total_len]) + total_len = (cpp_spell_token (pfile, token, (uchar *) &buffer[total_len], + true) - (uchar *) buffer); } @@ -635,7 +668,8 @@ glue_header_name (cpp_reader *pfile) #pragma dependency. The string is malloced and the caller should free it. Returns NULL on error. */ static const char * -parse_include (cpp_reader *pfile, int *pangle_brackets) +parse_include (cpp_reader *pfile, int *pangle_brackets, + const cpp_token ***buf) { char *fname; const cpp_token *header; @@ -644,7 +678,7 @@ parse_include (cpp_reader *pfile, int *pangle_brackets) header = get_token_no_padding (pfile); if (header->type == CPP_STRING || header->type == CPP_HEADER_NAME) { - fname = xmalloc (header->val.str.len - 1); + 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; @@ -668,7 +702,15 @@ parse_include (cpp_reader *pfile, int *pangle_brackets) return NULL; } - check_eol (pfile); + if (buf == NULL || CPP_OPTION (pfile, discard_comments)) + check_eol (pfile); + else + { + /* If we are not discarding comments, then gather them while + doing the eol check. */ + *buf = check_eol_return_comments (pfile); + } + return fname; } @@ -678,21 +720,32 @@ do_include_common (cpp_reader *pfile, enum include_type type) { const char *fname; int angle_brackets; + const cpp_token **buf = NULL; + + /* 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); + fname = parse_include (pfile, &angle_brackets, &buf); if (!fname) - return; + { + if (buf) + XDELETEVEC (buf); + return; + } if (!*fname) { cpp_error (pfile, CPP_DL_ERROR, "empty filename in #%s", pfile->directive->name); - free ((void *) fname); + XDELETEVEC (fname); + if (buf) + XDELETEVEC (buf); return; } /* Prevent #include recursion. */ - if (pfile->line_maps.depth >= CPP_STACK_MAX) + if (pfile->line_table->depth >= CPP_STACK_MAX) cpp_error (pfile, CPP_DL_ERROR, "#include nested too deeply"); else { @@ -701,12 +754,15 @@ do_include_common (cpp_reader *pfile, enum include_type type) if (pfile->cb.include) pfile->cb.include (pfile, pfile->directive_line, - pfile->directive->name, fname, angle_brackets); + pfile->directive->name, fname, angle_brackets, + buf); _cpp_stack_include (pfile, fname, angle_brackets, type); } - free ((void *) fname); + XDELETEVEC (fname); + if (buf) + XDELETEVEC (buf); } static void @@ -788,8 +844,15 @@ strtoul_for_line (const uchar *str, unsigned int len, long unsigned int *nump) 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 = pfile->map->to_file; + const char *new_file = map->to_file; unsigned long new_lineno; /* C99 raised the minimum limit on #line numbers. */ @@ -814,7 +877,8 @@ do_line (cpp_reader *pfile) if (token->type == CPP_STRING) { cpp_string s = { 0, 0 }; - if (_cpp_interpret_string_notranslate (pfile, &token->val.str, &s)) + if (cpp_interpret_string_notranslate (pfile, &token->val.str, 1, + &s, false)) new_file = (const char *)s.text; check_eol (pfile); } @@ -827,7 +891,7 @@ do_line (cpp_reader *pfile) skip_rest_of_line (pfile); _cpp_do_file_change (pfile, LC_RENAME, new_file, new_lineno, - pfile->map->sysp); + map_sysp); } /* Interpret the # 44 "file" [flags] notation, which has slightly @@ -836,10 +900,12 @@ do_line (cpp_reader *pfile) 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 = pfile->map->to_file; + const char *new_file = map->to_file; unsigned long new_lineno; - unsigned int new_sysp = pfile->map->sysp; + unsigned int new_sysp = map->sysp; enum lc_reason reason = LC_RENAME; int flag; @@ -864,7 +930,8 @@ do_linemarker (cpp_reader *pfile) if (token->type == CPP_STRING) { cpp_string s = { 0, 0 }; - if (_cpp_interpret_string_notranslate (pfile, &token->val.str, &s)) + if (cpp_interpret_string_notranslate (pfile, &token->val.str, + 1, &s, false)) new_file = (const char *)s.text; new_sysp = 0; @@ -887,6 +954,7 @@ do_linemarker (cpp_reader *pfile) flag = read_flag (pfile, flag); if (flag == 4) new_sysp = 2; + pfile->buffer->sysp = new_sysp; } check_eol (pfile); @@ -911,11 +979,13 @@ _cpp_do_file_change (cpp_reader *pfile, enum lc_reason reason, const char *to_file, unsigned int file_line, unsigned int sysp) { - pfile->map = linemap_add (&pfile->line_maps, reason, sysp, - pfile->line, to_file, file_line); + 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, pfile->map); + pfile->cb.file_change (pfile, map); } /* Report a warning or error detected by the program we are @@ -923,9 +993,7 @@ _cpp_do_file_change (cpp_reader *pfile, enum lc_reason reason, static void do_diagnostic (cpp_reader *pfile, int code, int print_dir) { - if (_cpp_begin_message (pfile, code, - pfile->cur_token[-1].line, - pfile->cur_token[-1].col)) + if (_cpp_begin_message (pfile, code, pfile->cur_token[-1].src_loc, 0)) { if (print_dir) fprintf (stderr, "#%s ", pfile->directive->name); @@ -955,7 +1023,8 @@ 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 #ident directive"); + 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); @@ -976,38 +1045,45 @@ lookup_pragma_entry (struct pragma_entry *chain, const cpp_hashnode *pragma) /* Create and insert a pragma entry for NAME at the beginning of a singly-linked CHAIN. If handler is NULL, it is a namespace, - otherwise it is a pragma and its handler. */ + otherwise it is a pragma and its handler. If INTERNAL is true + this pragma is being inserted by libcpp itself. */ static struct pragma_entry * insert_pragma_entry (cpp_reader *pfile, struct pragma_entry **chain, - const cpp_hashnode *pragma, pragma_cb handler) + const cpp_hashnode *pragma, pragma_cb handler, + bool allow_expansion, bool internal) { - struct pragma_entry *new; + struct pragma_entry *new_entry; - new = (struct pragma_entry *) + new_entry = (struct pragma_entry *) _cpp_aligned_alloc (pfile, sizeof (struct pragma_entry)); - new->pragma = pragma; + new_entry->pragma = pragma; if (handler) { - new->is_nspace = 0; - new->u.handler = handler; + new_entry->is_nspace = 0; + new_entry->u.handler = handler; } else { - new->is_nspace = 1; - new->u.space = NULL; + new_entry->is_nspace = 1; + new_entry->u.space = NULL; } - new->next = *chain; - *chain = new; - return new; + new_entry->allow_expansion = allow_expansion; + new_entry->is_internal = internal; + 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. HANDLER is the handler it will call, - which must be non-NULL. */ -void -cpp_register_pragma (cpp_reader *pfile, const char *space, const char *name, - pragma_cb handler) + which must be non-NULL. If ALLOW_EXPANSION is set, allow macro + expansion while parsing pragma NAME. INTERNAL is true if this is a + pragma registered by cpplib itself, false if it is registered via + cpp_register_pragma */ +static void +register_pragma (cpp_reader *pfile, const char *space, const char *name, + pragma_cb handler, bool allow_expansion, bool internal) { struct pragma_entry **chain = &pfile->pragmas; struct pragma_entry *entry; @@ -1021,7 +1097,8 @@ cpp_register_pragma (cpp_reader *pfile, const char *space, const char *name, node = cpp_lookup (pfile, U space, strlen (space)); entry = lookup_pragma_entry (*chain, node); if (!entry) - entry = insert_pragma_entry (pfile, chain, node, NULL); + entry = insert_pragma_entry (pfile, chain, node, NULL, + allow_expansion, internal); else if (!entry->is_nspace) goto clash; chain = &entry->u.space; @@ -1044,7 +1121,20 @@ cpp_register_pragma (cpp_reader *pfile, const char *space, const char *name, cpp_error (pfile, CPP_DL_ICE, "#pragma %s is already registered", name); } else - insert_pragma_entry (pfile, chain, node, handler); + insert_pragma_entry (pfile, chain, node, handler, allow_expansion, + internal); +} + +/* 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) +{ + register_pragma (pfile, space, name, handler, allow_expansion, false); } /* Register the pragmas the preprocessor itself handles. */ @@ -1052,19 +1142,21 @@ void _cpp_init_internal_pragmas (cpp_reader *pfile) { /* Pragmas in the global namespace. */ - cpp_register_pragma (pfile, 0, "once", do_pragma_once); + register_pragma (pfile, 0, "once", do_pragma_once, false, true); /* New GCC-specific pragmas should be put in the GCC namespace. */ - cpp_register_pragma (pfile, "GCC", "poison", do_pragma_poison); - cpp_register_pragma (pfile, "GCC", "system_header", do_pragma_system_header); - cpp_register_pragma (pfile, "GCC", "dependency", do_pragma_dependency); + register_pragma (pfile, "GCC", "poison", do_pragma_poison, false, true); + register_pragma (pfile, "GCC", "system_header", do_pragma_system_header, + false, true); + register_pragma (pfile, "GCC", "dependency", do_pragma_dependency, + false, true); /* Kevin abuse for SDCC. */ - cpp_register_pragma(pfile, 0, "sdcc_hash", do_pragma_sdcc_hash); + cpp_register_pragma(pfile, 0, "sdcc_hash", do_pragma_sdcc_hash, false); /* SDCC _asm specific */ - cpp_register_pragma(pfile, 0, "preproc_asm", do_pragma_preproc_asm); + cpp_register_pragma(pfile, 0, "preproc_asm", do_pragma_preproc_asm, false); /* SDCC specific */ - cpp_register_pragma(pfile, 0, "pedantic_parse_number", do_pragma_pedantic_parse_number); + cpp_register_pragma(pfile, 0, "pedantic_parse_number", do_pragma_pedantic_parse_number, false); } /* Return the number of registered pragmas in PE. */ @@ -1092,9 +1184,9 @@ save_registered_pragmas (struct pragma_entry *pe, char **sd) { if (pe->is_nspace) sd = save_registered_pragmas (pe->u.space, sd); - *sd++ = xmemdup (HT_STR (&pe->pragma->ident), - HT_LEN (&pe->pragma->ident), - HT_LEN (&pe->pragma->ident) + 1); + *sd++ = (char *) xmemdup (HT_STR (&pe->pragma->ident), + HT_LEN (&pe->pragma->ident), + HT_LEN (&pe->pragma->ident) + 1); } return sd; } @@ -1106,7 +1198,7 @@ char ** _cpp_save_pragma_names (cpp_reader *pfile) { int ct = count_registered_pragmas (pfile->pragmas); - char **result = xnewvec (char *, ct); + char **result = XNEWVEC (char *, ct); (void) save_registered_pragmas (pfile->pragmas, result); return result; } @@ -1142,7 +1234,11 @@ _cpp_restore_pragma_names (cpp_reader *pfile, char **saved) front end. C99 defines three pragmas and says that no macro expansion is to be performed on them; whether or not macro expansion happens for other pragmas is implementation defined. - This implementation never macro-expands the text after #pragma. */ + This implementation never macro-expands the text after #pragma. + + The library user has the option of deferring execution of + #pragmas not handled by cpplib, in which case they are converted + to CPP_PRAGMA tokens and inserted into the output stream. */ static void do_pragma (cpp_reader *pfile) { @@ -1150,6 +1246,11 @@ do_pragma (cpp_reader *pfile) const cpp_token *token, *pragma_token = pfile->cur_token; unsigned int count = 1; + /* Save the current position so that defer_pragmas mode can + copy the entire current line to a string. It will not work + to use _cpp_backup_tokens as that does not reverse buffer->cur. */ + const uchar *line_start = CPP_BUFFER (pfile)->cur; + pfile->state.prevent_expansion++; token = cpp_get_token (pfile); @@ -1169,12 +1270,90 @@ do_pragma (cpp_reader *pfile) if (p) { - /* 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); - (*p->u.handler) (pfile); + if (p->is_internal || !CPP_OPTION (pfile, defer_pragmas)) + { + /* 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); + /* Never expand macros if handling a deferred pragma, since + the macro definitions now applicable may be different + from those at the point the pragma appeared. */ + if (p->allow_expansion && !pfile->state.in_deferred_pragma) + pfile->state.prevent_expansion--; + (*p->u.handler) (pfile); + if (p->allow_expansion && !pfile->state.in_deferred_pragma) + pfile->state.prevent_expansion++; + } + else + { + /* Squirrel away the pragma text. Pragmas are + newline-terminated. */ + const uchar *line_end; + uchar *s, c, cc; + cpp_string body; + cpp_token *ptok; + + for (line_end = line_start; (c = *line_end) != '\n'; line_end++) + if (c == '"' || c == '\'') + { + /* Skip over string literal. */ + do + { + cc = *++line_end; + if (cc == '\\' && line_end[1] != '\n') + line_end++; + else if (cc == '\n') + { + line_end--; + break; + } + } + while (cc != c); + } + else if (c == '/') + { + if (line_end[1] == '*') + { + /* Skip over C block comment, unless it is multi-line. + When encountering multi-line block comment, terminate + the pragma token right before that block comment. */ + const uchar *le = line_end + 2; + while (*le != '\n') + if (*le++ == '*' && *le == '/') + { + line_end = le; + break; + } + if (line_end < le) + break; + } + else if (line_end[1] == '/' + && (CPP_OPTION (pfile, cplusplus_comments) + || cpp_in_system_header (pfile))) + { + line_end += 2; + while (*line_end != '\n') + line_end++; + break; + } + } + + body.len = (line_end - line_start) + 1; + s = _cpp_unaligned_alloc (pfile, body.len + 1); + memcpy (s, line_start, body.len - 1); + s[body.len - 1] = '\n'; + s[body.len] = '\0'; + body.text = s; + + /* Create a CPP_PRAGMA token. */ + ptok = &pfile->directive_result; + ptok->src_loc = pragma_token->src_loc; + ptok->type = CPP_PRAGMA; + ptok->flags = pragma_token->flags | NO_EXPAND; + ptok->val.str = body; + } } else if (pfile->cb.def_pragma) { @@ -1327,7 +1506,7 @@ do_pragma_dependency (cpp_reader *pfile) const char *fname; int angle_brackets, ordering; - fname = parse_include (pfile, &angle_brackets); + fname = parse_include (pfile, &angle_brackets, NULL); if (!fname) return; @@ -1388,7 +1567,7 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in) const unsigned char *src, *limit; char *dest, *result; - dest = result = alloca (in->len - 1); + dest = result = (char *) alloca (in->len - 1); src = in->text + 1 + (in->text[0] == 'L'); limit = in->text + in->len - 1; while (src < limit) @@ -1413,15 +1592,14 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in) cpp_token *saved_cur_token = pfile->cur_token; tokenrun *saved_cur_run = pfile->cur_run; - pfile->context = xnew (cpp_context); + pfile->context = XNEW (cpp_context); pfile->context->macro = 0; pfile->context->prev = 0; run_directive (pfile, T_PRAGMA, result, dest - result); - free (pfile->context); + XDELETE (pfile->context); pfile->context = saved_context; pfile->cur_token = saved_cur_token; pfile->cur_run = saved_cur_run; - pfile->line--; } /* See above comment. For the moment, we'd like @@ -1446,6 +1624,7 @@ void _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); @@ -1454,10 +1633,33 @@ _cpp_do__Pragma (cpp_reader *pfile) "_Pragma takes a parenthesized string literal"); } -/* Ignore #sccs on all systems. */ -static void -do_sccs (cpp_reader *pfile ATTRIBUTE_UNUSED) +/* Handle a pragma that the front end deferred until now. */ +void +cpp_handle_deferred_pragma (cpp_reader *pfile, const cpp_string *s) { + cpp_context *saved_context = pfile->context; + cpp_token *saved_cur_token = pfile->cur_token; + tokenrun *saved_cur_run = pfile->cur_run; + bool saved_defer_pragmas = CPP_OPTION (pfile, defer_pragmas); + void (*saved_line_change) (cpp_reader *, const cpp_token *, int) + = pfile->cb.line_change; + + pfile->context = XNEW (cpp_context); + pfile->context->macro = 0; + pfile->context->prev = 0; + pfile->cb.line_change = NULL; + pfile->state.in_deferred_pragma = true; + CPP_OPTION (pfile, defer_pragmas) = false; + + run_directive (pfile, T_PRAGMA, (const char *)s->text, s->len); + + XDELETE (pfile->context); + pfile->context = saved_context; + pfile->cur_token = saved_cur_token; + pfile->cur_run = saved_cur_run; + pfile->cb.line_change = saved_line_change; + pfile->state.in_deferred_pragma = false; + CPP_OPTION (pfile, defer_pragmas) = saved_defer_pragmas; } /* Handle #ifdef. */ @@ -1628,7 +1830,7 @@ push_conditional (cpp_reader *pfile, int skip, int type, struct if_stack *ifs; cpp_buffer *buffer = pfile->buffer; - ifs = xobnew (&pfile->buffer_ob, struct if_stack); + 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; @@ -1742,7 +1944,7 @@ parse_assertion (cpp_reader *pfile, struct answer **answerp, int type) else if (parse_answer (pfile, answerp, type) == 0) { unsigned int len = NODE_LEN (predicate->val.node); - unsigned char *sym = alloca (len + 1); + unsigned char *sym = (unsigned char *) alloca (len + 1); /* Prefix '#' to get it out of macro namespace. */ sym[0] = '#'; @@ -1815,6 +2017,8 @@ do_assert (cpp_reader *pfile) 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; @@ -1829,11 +2033,21 @@ do_assert (cpp_reader *pfile) 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; - BUFF_FRONT (pfile->a_buff) += (sizeof (struct answer) - + (new_answer->count - 1) - * sizeof (cpp_token)); check_eol (pfile); } } @@ -1888,7 +2102,7 @@ cpp_define (cpp_reader *pfile, const char *str) tack " 1" on the end. */ count = strlen (str); - buf = alloca (count + 3); + buf = (char *) alloca (count + 3); memcpy (buf, str, count); p = strchr (str, '='); @@ -1909,7 +2123,7 @@ void _cpp_define_builtin (cpp_reader *pfile, const char *str) { size_t len = strlen (str); - char *buf = alloca (len + 1); + char *buf = (char *) alloca (len + 1); memcpy (buf, str, len); buf[len] = '\n'; run_directive (pfile, T_DEFINE, buf, len); @@ -1920,7 +2134,7 @@ void cpp_undef (cpp_reader *pfile, const char *macro) { size_t len = strlen (macro); - char *buf = alloca (len + 1); + char *buf = (char *) alloca (len + 1); memcpy (buf, macro, len); buf[len] = '\n'; run_directive (pfile, T_UNDEF, buf, len); @@ -1949,7 +2163,7 @@ handle_assertion (cpp_reader *pfile, const char *str, int type) /* 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 = alloca (count + 2); + char *buf = (char *) alloca (count + 2); memcpy (buf, str, count); if (p) @@ -1984,13 +2198,6 @@ cpp_get_callbacks (cpp_reader *pfile) return &pfile->cb; } -/* The line map set. */ -struct line_maps * -cpp_get_line_maps (cpp_reader *pfile) -{ - return &pfile->line_maps; -} - /* Copy the given callbacks structure to our own. */ void cpp_set_callbacks (cpp_reader *pfile, cpp_callbacks *cb) @@ -1998,6 +2205,15 @@ 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. */ @@ -2005,19 +2221,20 @@ cpp_buffer * cpp_push_buffer (cpp_reader *pfile, const uchar *buffer, size_t len, int from_stage3) { - cpp_buffer *new = xobnew (&pfile->buffer_ob, cpp_buffer); + cpp_buffer *new_buffer = XOBNEW (&pfile->buffer_ob, cpp_buffer); /* Clears, amongst other things, if_stack and mi_cmacro. */ - memset (new, 0, sizeof (cpp_buffer)); + 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; - new->next_line = new->buf = buffer; - new->rlimit = buffer + len; - new->from_stage3 = from_stage3; - new->prev = pfile->buffer; - new->need_line = true; + pfile->buffer = new_buffer; - pfile->buffer = new; - return new; + return new_buffer; } /* Pops a single buffer, with a file change call-back if appropriate. diff --git a/support/cpp2/cpperror.c b/support/cpp2/libcpp/errors.c similarity index 68% rename from support/cpp2/cpperror.c rename to support/cpp2/libcpp/errors.c index 61763cc1..97de4900 100644 --- a/support/cpp2/cpperror.c +++ b/support/cpp2/libcpp/errors.c @@ -1,6 +1,6 @@ /* Default error handlers for CPP Library. Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1998, 1999, 2000, - 2001, 2002 Free Software Foundation, Inc. + 2001, 2002, 2004 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 @@ -17,7 +17,7 @@ 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. +Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 @@ -26,17 +26,16 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "config.h" #include "system.h" #include "cpplib.h" -#include "cpphash.h" -#include "intl.h" +#include "internal.h" -static void print_location (cpp_reader *, fileline, unsigned int); +static void print_location (cpp_reader *, source_location, unsigned int); /* 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, fileline line, unsigned int col) +print_location (cpp_reader *pfile, source_location line, unsigned int col) { if (line == 0) fprintf (stderr, "%s: ", progname); @@ -45,12 +44,16 @@ print_location (cpp_reader *pfile, fileline line, unsigned int col) const struct line_map *map; unsigned int lin; - map = linemap_lookup (&pfile->line_maps, line); - linemap_print_containing_files (&pfile->line_maps, map); + map = linemap_lookup (pfile->line_table, line); + linemap_print_containing_files (pfile->line_table, map); lin = SOURCE_LINE (map, line); if (col == 0) - col = 1; + { + col = SOURCE_COLUMN (map, line); + if (col == 0) + col = 1; + } if (lin == 0) fprintf (stderr, "%s:", map->to_file); @@ -64,13 +67,18 @@ print_location (cpp_reader *pfile, fileline line, unsigned int col) } /* Set up for a diagnostic: print the file and line, bump the error - counter, etc. LINE is the logical line number; zero means to print + counter, etc. SRC_LOC is the logical line number; zero means to print at the location of the previously lexed token, which tends to be - the correct place by default. Returns 0 if the error has been - suppressed. */ + the correct place by default. The column number can be specified either + using COLUMN or (if COLUMN==0) extracting SOURCE_COLUMN from SRC_LOC. + (This may seem redundant, but is useful when pre-scanning (cleaning) a line, + when we haven't yet verified whether the current line_map has a + big enough max_column_hint.) + + Returns 0 if the error has been suppressed. */ int -_cpp_begin_message (cpp_reader *pfile, int code, fileline line, - unsigned int column) +_cpp_begin_message (cpp_reader *pfile, int code, + source_location src_loc, unsigned int column) { int level = CPP_DL_EXTRACT (code); @@ -78,7 +86,7 @@ _cpp_begin_message (cpp_reader *pfile, int code, fileline line, { case CPP_DL_WARNING: case CPP_DL_PEDWARN: - if (CPP_IN_SYSTEM_HEADER (pfile) + if (cpp_in_system_header (pfile) && ! CPP_OPTION (pfile, warn_system_headers)) return 0; /* Fall through. */ @@ -105,11 +113,13 @@ _cpp_begin_message (cpp_reader *pfile, int code, fileline line, break; } - print_location (pfile, line, column); + print_location (pfile, src_loc, column); if (CPP_DL_WARNING_P (level)) fputs (_("warning: "), stderr); else if (level == CPP_DL_ICE) fputs (_("internal error: "), stderr); + else + fputs (_("error: "), stderr); return 1; } @@ -125,28 +135,30 @@ _cpp_begin_message (cpp_reader *pfile, int code, fileline line, void cpp_error (cpp_reader * pfile, int level, const char *msgid, ...) { - fileline line; - unsigned int column; + source_location src_loc; va_list ap; va_start (ap, msgid); - if (CPP_OPTION (pfile, traditional)) - { - if (pfile->state.in_directive) - line = pfile->directive_line; - else - line = pfile->line; - column = 0; - } + if (CPP_OPTION (pfile, client_diagnostic)) + pfile->cb.error (pfile, level, _(msgid), &ap); else { - line = pfile->cur_token[-1].line; - column = pfile->cur_token[-1].col; - } + if (CPP_OPTION (pfile, traditional)) + { + if (pfile->state.in_directive) + src_loc = pfile->directive_line; + else + src_loc = pfile->line_table->highest_line; + } + else + { + src_loc = pfile->cur_token[-1].src_loc; + } - if (_cpp_begin_message (pfile, level, line, column)) - v_message (msgid, ap); + if (_cpp_begin_message (pfile, level, src_loc, 0)) + v_message (msgid, ap); + } va_end (ap); } @@ -154,14 +166,14 @@ cpp_error (cpp_reader * pfile, int level, const char *msgid, ...) /* Print an error at a specific location. */ void cpp_error_with_line (cpp_reader *pfile, int level, - fileline line, unsigned int column, + source_location src_loc, unsigned int column, const char *msgid, ...) { va_list ap; va_start (ap, msgid); - if (_cpp_begin_message (pfile, level, line, column)) + if (_cpp_begin_message (pfile, level, src_loc, column)) v_message (msgid, ap); va_end (ap); diff --git a/support/cpp2/cppexp.c b/support/cpp2/libcpp/expr.c similarity index 97% rename from support/cpp2/cppexp.c rename to support/cpp2/libcpp/expr.c index cb35b6c7..32b17238 100644 --- a/support/cpp2/cppexp.c +++ b/support/cpp2/libcpp/expr.c @@ -1,6 +1,6 @@ /* Parse C expressions for cpplib. Copyright (C) 1987, 1992, 1994, 1995, 1997, 1998, 1999, 2000, 2001, - 2002 Free Software Foundation. + 2002, 2004 Free Software Foundation. Contributed by Per Bothner, 1994. This program is free software; you can redistribute it and/or modify it @@ -15,13 +15,13 @@ 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. */ +Foundation, 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. */ #include "config.h" #include "system.h" #include "cpplib.h" -#include "cpphash.h" +#include "internal.h" #define PART_PRECISION (sizeof (cpp_num_part) * CHAR_BIT) #define HALF_MASK (~(cpp_num_part) 0 >> (PART_PRECISION / 2)) @@ -65,8 +65,8 @@ 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 (CPP_LAST_CPP_OP + 1) -#define CPP_UMINUS (CPP_LAST_CPP_OP + 2) +#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. */ @@ -408,6 +408,7 @@ append_digit (cpp_num num, int digit, int base, size_t precision) result.high = num.high << shift; result.low = num.low << shift; result.high |= num.low >> (PART_PRECISION - shift); + result.unsignedp = num.unsignedp; if (base == 10) { @@ -428,6 +429,7 @@ append_digit (cpp_num num, int digit, int base, size_t precision) 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. */ @@ -435,10 +437,8 @@ append_digit (cpp_num num, int digit, int base, size_t precision) num.high = result.high; result = num_trim (result, precision); if (!num_eq (result, num)) - overflow = true; + result.overflow = true; - result.unsignedp = num.unsignedp; - result.overflow = overflow; return result; } @@ -520,6 +520,9 @@ eval_token (cpp_reader *pfile, const cpp_token *token) unsigned int temp; int unsignedp = 0; + result.unsignedp = false; + result.overflow = false; + switch (token->type) { case CPP_NUMBER: @@ -591,7 +594,6 @@ eval_token (cpp_reader *pfile, const cpp_token *token) } result.unsignedp = !!unsignedp; - result.overflow = false; return result; } @@ -625,7 +627,7 @@ extra semantics need to be handled with operator-specific code. */ /* Operator to priority map. Must be in the same order as the first N entries of enum cpp_ttype. */ -static const struct operator +static const struct cpp_operator { uchar prio; uchar flags; @@ -751,11 +753,11 @@ _cpp_parse_expr (cpp_reader *pfile) SYNTAX_ERROR ("missing expression between '(' and ')'"); if (op.op == CPP_EOF && top->op == CPP_EOF) - SYNTAX_ERROR ("#if with no expression"); + SYNTAX_ERROR ("#if with no expression"); - 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)); + 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 @@ -973,7 +975,7 @@ _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 = xrealloc (pfile->op_stack, new_size * sizeof (struct op)); + 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; @@ -1170,8 +1172,9 @@ 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 || num_positive (num, precision)) + if (num.unsignedp || x) sign_mask = 0; else sign_mask = ~(cpp_num_part) 0; @@ -1336,12 +1339,11 @@ num_binary_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op) 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); - result.unsignedp = lhs.unsignedp || rhs.unsignedp; - if (result.unsignedp) - result.overflow = false; - else + if (!result.unsignedp) { bool lhsp = num_positive (lhs, precision); result.overflow = (lhsp == num_positive (rhs, precision) @@ -1388,7 +1390,8 @@ num_part_mul (cpp_num_part lhs, cpp_num_part rhs) result.high += HIGH_PART (middle[0]); result.high += HIGH_PART (middle[1]); - result.unsignedp = 1; + result.unsignedp = true; + result.overflow = false; return result; } @@ -1520,9 +1523,8 @@ num_div_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op) if (op == CPP_DIV) { result.unsignedp = unsignedp; - if (unsignedp) - result.overflow = false; - else + result.overflow = false; + if (!unsignedp) { if (negate) result = num_negate (result, precision); diff --git a/support/cpp2/cppfiles.c b/support/cpp2/libcpp/files.c similarity index 75% rename from support/cpp2/cppfiles.c rename to support/cpp2/libcpp/files.c index e757a40d..702aa4c8 100644 --- a/support/cpp2/cppfiles.c +++ b/support/cpp2/libcpp/files.c @@ -1,6 +1,6 @@ /* Part of CPP library. File handling. Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1998, - 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005 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 @@ -19,15 +19,15 @@ 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. */ +Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #include "system.h" #include "cpplib.h" -#include "cpphash.h" -#include "intl.h" +#include "internal.h" #include "mkdeps.h" #include "hashtab.h" +#include "md5.h" #include /* Variable length record files on VMS will have a stat size that includes @@ -40,6 +40,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #endif #ifdef __DJGPP__ +#include /* For DJGPP redirected input is opened in text mode. */ # define set_stdin_to_binary_mode() \ if (! isatty (0)) setmode (0, O_BINARY) @@ -47,10 +48,6 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ # define set_stdin_to_binary_mode() /* Nothing */ #endif -#ifndef O_BINARY -# define O_BINARY 0 -#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. */ @@ -108,11 +105,8 @@ struct _cpp_file /* If BUFFER above contains the true contents of the file. */ bool buffer_valid; - /* 0: file not known to be a PCH. - 1: file is a PCH (on return from find_include_file). - 2: file is not and never will be a valid precompiled header. - 3: file is always a valid precompiled header. */ - uchar pch; + /* File is a PCH (on return from find_include_file). */ + bool pch; }; /* A singly-linked list for all searches for a given file name, with @@ -180,7 +174,9 @@ 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 bool include_pch_p (_cpp_file *file); +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 , open it. @@ -259,7 +255,7 @@ pch_open_file (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch) flen = strlen (path); len = flen + sizeof (extension); - pchname = xmalloc (len); + pchname = XNEWVEC (char, len); memcpy (pchname, path, flen); memcpy (pchname + flen, extension, sizeof (extension)); @@ -283,7 +279,7 @@ pch_open_file (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch) if (dlen + plen > len) { len += dlen + 64; - pchname = xrealloc (pchname, len); + pchname = XRESIZEVEC (char, pchname, len); } memcpy (pchname + plen, d->d_name, dlen); valid = validate_pch (pfile, file, pchname); @@ -319,23 +315,58 @@ find_file_in_dir (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch) if (CPP_OPTION (pfile, remap) && (path = remap_filename (pfile, file))) ; else - path = append_file_to_dir (file->name, file->dir); + if (file->dir->construct) + path = file->dir->construct (file->name, file->dir); + else + path = append_file_to_dir (file->name, file->dir); - file->path = path; - if (pch_open_file (pfile, file, invalid_pch)) - return true; + if (path) + { + file->path = path; + if (pch_open_file (pfile, file, invalid_pch)) + return true; - if (open_file (file)) - return true; + if (open_file (file)) + return true; + + if (file->err_no != ENOENT) + { + open_file_failed (pfile, file, 0); + return true; + } - if (file->err_no != ENOENT) + free (path); + file->path = file->name; + } + else { - open_file_failed (pfile, file, 0); - return true; + 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; } - free (path); - file->path = file->name; return false; } @@ -347,7 +378,7 @@ _cpp_find_failed (_cpp_file *file) /* 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_seach_path. + 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. @@ -391,6 +422,17 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool f 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; + } + open_file_failed (pfile, file, angle_brackets); if (invalid_pch) { @@ -487,7 +529,7 @@ read_file_guts (cpp_reader *pfile, _cpp_file *file) the majority of C source files. */ size = 8 * 1024; - buf = xmalloc (size + 1); + buf = XNEWVEC (uchar, size + 1); total = 0; while ((count = read (file->fd, buf + total, size - total)) > 0) { @@ -498,7 +540,7 @@ read_file_guts (cpp_reader *pfile, _cpp_file *file) if (regular) break; size *= 2; - buf = xrealloc (buf, size + 1); + buf = XRESIZEVEC (uchar, buf, size + 1); } } @@ -584,9 +626,9 @@ should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import) return false; /* Handle PCH files immediately; don't stack them. */ - if (include_pch_p (file)) + if (file->pch) { - pfile->cb.read_pch (pfile, file->path, file->fd, file->pchname); + pfile->cb.read_pch (pfile, file->pchname, file->fd, file->path); close (file->fd); file->fd = -1; return false; @@ -595,6 +637,19 @@ should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import) 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) @@ -660,8 +715,10 @@ _cpp_stack_file (cpp_reader *pfile, _cpp_file *file, bool import) if (!should_stack_file (pfile, file, import)) return false; - sysp = MAX ((pfile->map ? pfile->map->sysp : 0), - (file->dir ? file->dir->sysp : 0)); + 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) @@ -678,6 +735,7 @@ _cpp_stack_file (cpp_reader *pfile, _cpp_file *file, bool import) buffer = cpp_push_buffer (pfile, file->buffer, file->st.st_size, CPP_OPTION (pfile, preprocessed)); buffer->file = file; + buffer->sysp = sysp; /* Initialize controlling macro state. */ pfile->mi_valid = true; @@ -727,7 +785,8 @@ search_path_head (cpp_reader *pfile, const char *fname, int angle_brackets, else if (pfile->quote_ignores_source_dir) dir = pfile->quote_include; else - return make_cpp_dir (pfile, dir_name_of_file (file), pfile->map->sysp); + 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, @@ -745,7 +804,7 @@ dir_name_of_file (_cpp_file *file) if (!file->dir_name) { size_t len = lbasename (file->path) - file->path; - char *dir_name = xmalloc (len + 1); + char *dir_name = XNEWVEC (char, len + 1); memcpy (dir_name, file->path, len); dir_name[len] = '\0'; @@ -763,21 +822,32 @@ _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; - return _cpp_stack_file (pfile, _cpp_find_file (pfile, fname, dir, false, - angle_brackets), - type == IT_IMPORT); + file = _cpp_find_file (pfile, fname, dir, false, angle_brackets); + + /* Compensate for the increment in linemap_add. 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->pch && 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->map ? pfile->map->sysp: 0; + 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; @@ -811,7 +881,7 @@ make_cpp_file (cpp_reader *pfile, cpp_dir *dir, const char *fname) { _cpp_file *file; - file = xcalloc (1, sizeof (_cpp_file)); + file = XCNEW (_cpp_file); file->main_file = !pfile->buffer; file->fd = -1; file->dir = dir; @@ -853,11 +923,12 @@ make_cpp_dir (cpp_reader *pfile, const char *dir_name, int sysp) if (entry->start_dir == NULL) return entry->u.dir; - dir = xcalloc (1, sizeof (cpp_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); @@ -875,8 +946,8 @@ allocate_file_hash_entries (cpp_reader *pfile) { pfile->file_hash_entries_used = 0; pfile->file_hash_entries_allocated = 127; - pfile->file_hash_entries = xmalloc - (pfile->file_hash_entries_allocated * sizeof (struct file_hash_entry)); + pfile->file_hash_entries = XNEWVEC (struct file_hash_entry, + pfile->file_hash_entries_allocated); } /* Return a new file hash entry. */ @@ -897,8 +968,8 @@ cpp_included (cpp_reader *pfile, const char *fname) { struct file_hash_entry *entry; - entry = htab_find_with_hash (pfile->file_hash, fname, - htab_hash_string (fname)); + 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; @@ -970,12 +1041,15 @@ 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); - _cpp_do_file_change (pfile, LC_RENAME, pfile->map->to_file, - SOURCE_LINE (pfile->map, pfile->line), flags); + 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 @@ -1060,8 +1134,6 @@ _cpp_compare_file_date (cpp_reader *pfile, const char *fname, bool cpp_push_include (cpp_reader *pfile, const char *fname) { - /* Make the command line directive take up a line. */ - pfile->line++; return _cpp_stack_include (pfile, fname, false, IT_CMDLINE); } @@ -1118,7 +1190,7 @@ append_file_to_dir (const char *fname, cpp_dir *dir) dlen = dir->len; flen = strlen (fname); - path = xmalloc (dlen + 1 + flen + 1); + path = XNEWVEC (char, dlen + 1 + flen + 1); memcpy (path, dir->name, dlen); if (dlen && path[dlen - 1] != '/') path[dlen++] = '/'; @@ -1136,7 +1208,7 @@ read_filename_string (int ch, FILE *f) int len; len = 20; - set = alloc = xmalloc (len + 1); + set = alloc = XNEWVEC (char, len + 1); if (! is_space (ch)) { *set++ = ch; @@ -1145,7 +1217,7 @@ read_filename_string (int ch, FILE *f) if (set - alloc == len) { len *= 2; - alloc = xrealloc (alloc, len + 1); + alloc = XRESIZEVEC (char, alloc, len + 1); set = alloc + len / 2; } *set++ = ch; @@ -1166,14 +1238,14 @@ read_name_map (cpp_dir *dir) size_t len, count = 0, room = 9; len = dir->len; - name = alloca (len + sizeof (FILE_NAME_MAP_FILE) + 1); + 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 = xmalloc (room * sizeof (char *)); + dir->name_map = XNEWVEC (const char *, room); /* Silently return NULL if we cannot open. */ if (f) @@ -1190,7 +1262,7 @@ read_name_map (cpp_dir *dir) if (count + 2 > room) { room += 8; - dir->name_map = xrealloc (dir->name_map, room * sizeof (char *)); + dir->name_map = XRESIZEVEC (const char *, dir->name_map, room); } dir->name_map[count] = read_filename_string (ch, f); @@ -1247,7 +1319,7 @@ remap_filename (cpp_reader *pfile, _cpp_file *file) return NULL; len = dir->len + (p - fname + 1); - new_dir = xmalloc (len + 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'; @@ -1257,13 +1329,6 @@ remap_filename (cpp_reader *pfile, _cpp_file *file) } } -/* Return true if FILE is usable by PCH. */ -static bool -include_pch_p (_cpp_file *file) -{ - return file->pch & 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) @@ -1285,7 +1350,7 @@ validate_pch (cpp_reader *pfile, _cpp_file *file, const char *pchname) if (CPP_OPTION (pfile, print_include_names)) { unsigned int i; - for (i = 1; i < pfile->line_maps.depth; i++) + for (i = 1; i < pfile->line_table->depth; i++) putc ('.', stderr); fprintf (stderr, "%c %s\n", valid ? '!' : 'x', pchname); @@ -1295,3 +1360,247 @@ validate_pch (cpp_reader *pfile, _cpp_file *file, const char *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/cpp2/cpphash.c b/support/cpp2/libcpp/identifiers.c similarity index 95% rename from support/cpp2/cpphash.c rename to support/cpp2/libcpp/identifiers.c index 9d2f51ae..18070b13 100644 --- a/support/cpp2/cpphash.c +++ b/support/cpp2/libcpp/identifiers.c @@ -17,7 +17,7 @@ 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. +Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 @@ -26,7 +26,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "config.h" #include "system.h" #include "cpplib.h" -#include "cpphash.h" +#include "internal.h" static cpp_hashnode *alloc_node (hash_table *); @@ -37,7 +37,7 @@ alloc_node (hash_table *table) { cpp_hashnode *node; - node = obstack_alloc (&table->pfile->hash_ob, sizeof (cpp_hashnode)); + node = XOBNEW (&table->pfile->hash_ob, cpp_hashnode); memset (node, 0, sizeof (cpp_hashnode)); return node; } @@ -75,7 +75,6 @@ _cpp_init_hashtable (cpp_reader *pfile, hash_table *table) s->n__VA_ARGS__->flags |= NODE_DIAGNOSTIC; /* SDCC _asm specific */ s->n__asm = cpp_lookup (pfile, DSC("_asm")); - } /* Tear down the identifier hash table. */ diff --git a/support/cpp2/libcpp/include/cpp-id-data.h b/support/cpp2/libcpp/include/cpp-id-data.h new file mode 100644 index 00000000..2445186c --- /dev/null +++ b/support/cpp2/libcpp/include/cpp-id-data.h @@ -0,0 +1,78 @@ +/* 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 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. */ + +#include "cpplib.h" + +#if !defined (HAVE_UCHAR) && !defined (IN_GCC) +typedef unsigned char uchar; +#endif + +#define U (const unsigned char *) /* Intended use: U"string" */ + +/* Chained list of answers to an assertion. */ +struct answer GTY(()) +{ + 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 cpp_macro GTY(()) +{ + /* 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; +}; diff --git a/support/cpp2/cpplib.h b/support/cpp2/libcpp/include/cpplib.h similarity index 71% rename from support/cpp2/cpplib.h rename to support/cpp2/libcpp/include/cpplib.h index 4ce262c4..4e879b9d 100644 --- a/support/cpp2/cpplib.h +++ b/support/cpp2/libcpp/include/cpplib.h @@ -1,5 +1,6 @@ /* Definitions for CPP library. - Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 + Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, + 2004, 2005 Free Software Foundation, Inc. Written by Per Bothner, 1994-95. @@ -15,16 +16,16 @@ 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. +Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. In other words, you are welcome to use, share and improve this program. You are forbidden to forbid anyone else to use, share and improve what you give them. Help stamp out software-hoarding! */ -#ifndef GCC_CPPLIB_H -#define GCC_CPPLIB_H +#ifndef LIBCPP_CPPLIB_H +#define LIBCPP_CPPLIB_H #include -#include "hashtable.h" +#include "symtab.h" #include "line-map.h" #ifdef __cplusplus @@ -42,6 +43,7 @@ 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.). @@ -51,113 +53,115 @@ struct answer; '='. The lexer needs operators ending in '=', like ">>=", to be in the same order as their counterparts without the '=', like ">>". */ -/* Positions in the table. */ -#define CPP_LAST_EQ CPP_MAX -#define CPP_FIRST_DIGRAPH CPP_HASH -#define CPP_LAST_PUNCTUATOR CPP_DOT_STAR -#define CPP_LAST_CPP_OP CPP_LESS_EQ - -#define TTYPE_TABLE \ - OP(CPP_EQ = 0, "=") \ - OP(CPP_NOT, "!") \ - OP(CPP_GREATER, ">") /* compare */ \ - OP(CPP_LESS, "<") \ - OP(CPP_PLUS, "+") /* math */ \ - OP(CPP_MINUS, "-") \ - OP(CPP_MULT, "*") \ - OP(CPP_DIV, "/") \ - OP(CPP_MOD, "%") \ - OP(CPP_AND, "&") /* bit ops */ \ - OP(CPP_OR, "|") \ - OP(CPP_XOR, "^") \ - OP(CPP_RSHIFT, ">>") \ - OP(CPP_LSHIFT, "<<") \ - OP(CPP_MIN, "?") \ -\ - OP(CPP_COMPL, "~") \ - OP(CPP_AND_AND, "&&") /* logical */ \ - OP(CPP_OR_OR, "||") \ - OP(CPP_QUERY, "?") \ - OP(CPP_COLON, ":") \ - OP(CPP_COMMA, ",") /* grouping */ \ - OP(CPP_OPEN_PAREN, "(") \ - OP(CPP_CLOSE_PAREN, ")") \ - TK(CPP_EOF, SPELL_NONE) \ - OP(CPP_EQ_EQ, "==") /* compare */ \ - OP(CPP_NOT_EQ, "!=") \ - OP(CPP_GREATER_EQ, ">=") \ - OP(CPP_LESS_EQ, "<=") \ -\ - /* These two are unary + / - in preprocessor expressions. */ \ - OP(CPP_PLUS_EQ, "+=") /* math */ \ - OP(CPP_MINUS_EQ, "-=") \ -\ - OP(CPP_MULT_EQ, "*=") \ - OP(CPP_DIV_EQ, "/=") \ - OP(CPP_MOD_EQ, "%=") \ - OP(CPP_AND_EQ, "&=") /* bit ops */ \ - OP(CPP_OR_EQ, "|=") \ - OP(CPP_XOR_EQ, "^=") \ - OP(CPP_RSHIFT_EQ, ">>=") \ - OP(CPP_LSHIFT_EQ, "<<=") \ - OP(CPP_MIN_EQ, "?=") \ - /* Digraphs together, beginning with CPP_FIRST_DIGRAPH. */ \ - OP(CPP_HASH, "#") /* digraphs */ \ - OP(CPP_PASTE, "##") \ - OP(CPP_OPEN_SQUARE, "[") \ - OP(CPP_CLOSE_SQUARE, "]") \ - OP(CPP_OPEN_BRACE, "{") \ - OP(CPP_CLOSE_BRACE, "}") \ - /* The remainder of the punctuation. Order is not significant. */ \ - OP(CPP_SEMICOLON, ";") /* structure */ \ - OP(CPP_ELLIPSIS, "...") \ - OP(CPP_PLUS_PLUS, "++") /* increment */ \ - OP(CPP_MINUS_MINUS, "--") \ - OP(CPP_DEREF, "->") /* accessors */ \ - OP(CPP_DOT, ".") \ - OP(CPP_SCOPE, "::") \ - OP(CPP_DEREF_STAR, "->*") \ - OP(CPP_DOT_STAR, ".*") \ - OP(CPP_ATSIGN, "@") /* used in Objective-C */ \ -\ - TK(CPP_NAME, SPELL_IDENT) /* word */ \ - TK(CPP_AT_NAME, SPELL_IDENT) /* @word - Objective-C */ \ - TK(CPP_NUMBER, SPELL_LITERAL) /* 34_be+ta */ \ -\ - TK(CPP_CHAR, SPELL_LITERAL) /* 'char' */ \ - TK(CPP_WCHAR, SPELL_LITERAL) /* L'char' */ \ - TK(CPP_OTHER, SPELL_LITERAL) /* stray punctuation */ \ -\ - TK(CPP_STRING, SPELL_LITERAL) /* "string" */ \ - TK(CPP_WSTRING, SPELL_LITERAL) /* L"string" */ \ - TK(CPP_OBJC_STRING, SPELL_LITERAL) /* @"string" - Objective-C */ \ - TK(CPP_HEADER_NAME, SPELL_LITERAL) /* in #include */ \ -\ - TK(CPP_COMMENT, SPELL_LITERAL) /* Only if output comments. */ \ - /* SPELL_LITERAL happens to DTRT. */ \ - TK(CPP_MACRO_ARG, SPELL_NONE) /* Macro argument. */ \ - TK(CPP_PADDING, SPELL_NONE) /* Whitespace for cpp0. */ \ +#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(MIN, "?") \ + \ + 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, "<<=") \ + OP(MIN_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(OTHER, LITERAL) /* stray punctuation */ \ + \ + TK(STRING, LITERAL) /* "string" */ \ + TK(WSTRING, LITERAL) /* L"string" */ \ + TK(OBJC_STRING, LITERAL) /* @"string" - Objective-C */ \ + TK(HEADER_NAME, LITERAL) /* in #include */ \ + \ + TK(COMMENT, LITERAL) /* Only if output comments. */ \ + /* SPELL_LITERAL happens to DTRT. */ \ + TK(MACRO_ARG, NONE) /* Macro argument. */ \ + TK(PRAGMA, NONE) /* Only if deferring pragmas */ \ + TK(PADDING, NONE) /* Whitespace for -E. */ \ \ /* SDCC _asm specific */ \ - TK(CPP_ASM, SPELL_LITERAL) /* _asm ... _endasm ; */ -#define OP(e, s) e, -#define TK(e, s) e, + TK(ASM, LITERAL) /* _asm ... _endasm ; */ + +#define OP(e, s) CPP_ ## e, +#define TK(e, s) CPP_ ## e, enum cpp_ttype { TTYPE_TABLE - N_TTYPES + N_TTYPES, + + /* Positions in the table. */ + CPP_LAST_EQ = CPP_MAX, + CPP_FIRST_DIGRAPH = CPP_HASH, + CPP_LAST_PUNCTUATOR= CPP_DOT_STAR, + CPP_LAST_CPP_OP = CPP_LESS_EQ }; #undef OP #undef TK -/* C language kind, used when calling cpp_reader_init. */ +/* C language kind, used when calling cpp_create_reader. */ enum c_lang {CLK_GNUC89 = 0, CLK_GNUC99, CLK_STDC89, CLK_STDC94, CLK_STDC99, CLK_GNUCXX, CLK_CXX98, CLK_ASM}; /* Payload of a NUMBER, STRING, CHAR or COMMENT token. */ -struct cpp_string +struct cpp_string GTY(()) { unsigned int len; const unsigned char *text; @@ -172,24 +176,48 @@ struct cpp_string #define NO_EXPAND (1 << 5) /* Do not macro-expand this token. */ #define BOL (1 << 6) /* Token at beginning of line. */ +/* 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_NONE +}; + /* 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 cpp_token +struct cpp_token GTY(()) { - fileline line; /* Logical line of first char of token. */ - unsigned short col; /* Column of first char of token. */ + source_location src_loc; /* Location of first char of token. */ ENUM_BITFIELD(cpp_ttype) type : CHAR_BIT; /* token type */ unsigned char flags; /* flags - see above */ - union + union cpp_token_u { - cpp_hashnode *node; /* An identifier. */ - const cpp_token *source; /* Inherit padding from this token. */ - struct cpp_string str; /* A string, or number. */ - unsigned int arg_no; /* Argument no. for a CPP_MACRO_ARG. */ - } val; + /* An 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"), + 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. */ + unsigned int GTY ((tag ("CPP_TOKEN_FLD_ARG_NO"))) arg_no; + } 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. @@ -208,6 +236,22 @@ struct cpp_token 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 @@ -266,6 +310,10 @@ struct cpp_options /* 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; @@ -286,6 +334,10 @@ struct cpp_options 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 turn warnings into errors. */ unsigned char warnings_are_errors; @@ -296,6 +348,9 @@ struct cpp_options /* 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; @@ -337,6 +392,10 @@ struct cpp_options /* 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; @@ -364,7 +423,7 @@ struct cpp_options struct { /* Style of header dependencies to generate. */ - enum {DEPS_NONE = 0, DEPS_USER, DEPS_SYSTEM } style; + enum cpp_deps_style style; /* Assume missing files are generated files. */ bool missing_files; @@ -392,8 +451,23 @@ struct cpp_options /* Nonzero means __STDC__ should have the value 0 in system headers. */ unsigned char stdc_0_in_system_headers; + + /* True means return pragmas as tokens rather than processing + them directly. */ + bool defer_pragmas; + + /* True means error callback should be used for diagnostics. */ + bool client_diagnostic; }; +/* 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 { @@ -408,13 +482,19 @@ struct cpp_callbacks void (*dir_change) (cpp_reader *, const char *); void (*include) (cpp_reader *, unsigned int, const unsigned char *, - const char *, int); + 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; + + /* Called to emit a diagnostic if client_diagnostic option is true. + This callback receives the translated message. */ + void (*error) (cpp_reader *, int, const char *, va_list *) + ATTRIBUTE_FPTR_PRINTF(3,0); }; /* Chain of directories to look for include files in. */ @@ -435,10 +515,19 @@ struct cpp_dir 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 ino; dev_t dev; + + /* Is this a user-supplied directory? */ + bool user_supplied_p; }; /* Name under which this program was invoked. */ @@ -491,9 +580,39 @@ enum builtin_type #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 _cpp_hashnode_value GTY(()) +{ + /* 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 builtin_type GTY ((tag ("NTV_BUILTIN"))) builtin; + /* Macro argument index. */ + unsigned short GTY ((tag ("NTV_ARGUMENT"))) arg_index; +}; + struct cpp_hashnode GTY(()) { struct ht_identifier ident; @@ -505,17 +624,7 @@ struct cpp_hashnode GTY(()) ENUM_BITFIELD(node_type) type : 8; /* CPP node type. */ unsigned char flags; /* CPP flags. */ - union _cpp_hashnode_value - { - /* If a macro. */ - cpp_macro * GTY((skip (""))) macro; - /* Answers to an assertion. */ - struct answer * GTY ((skip (""))) answers; - /* Code for a builtin macro. */ - enum builtin_type GTY ((tag ("1"))) builtin; - /* Macro argument index. */ - unsigned short GTY ((tag ("0"))) arg_index; - } GTY ((desc ("0"))) value; + union _cpp_hashnode_value GTY ((desc ("CPP_HASHNODE_VALUE_IDX (%1)"))) value; }; /* Call this first to get a handle to pass to other functions. @@ -524,36 +633,31 @@ struct cpp_hashnode GTY(()) 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 *); +extern cpp_reader *cpp_create_reader (enum c_lang, struct ht *, + 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); -/* Add a dependency TARGET. Quote it for "make" if QUOTE. Can be - called any number of times before cpp_read_main_file(). If no - targets have been added before cpp_read_main_file(), then the - default target is used. */ -extern void cpp_add_dependency_target (cpp_reader *, const char *, int); - /* 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 and callback structures - for a given reader. These pointers are good until you call - cpp_finish on that reader. You can either edit the callbacks +/* 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 struct line_maps *cpp_get_line_maps (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. */ + 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 like __FILE__. */ @@ -584,9 +688,10 @@ extern unsigned int cpp_errors (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 *); + unsigned char *, bool); extern void cpp_register_pragma (cpp_reader *, const char *, const char *, - void (*) (cpp_reader *)); + void (*) (cpp_reader *), bool); +extern void cpp_handle_deferred_pragma (cpp_reader *, const cpp_string *); extern int cpp_avoid_paste (cpp_reader *, const cpp_token *, const cpp_token *); extern const cpp_token *cpp_get_token (cpp_reader *); @@ -601,6 +706,12 @@ extern cppchar_t cpp_interpret_charconst (cpp_reader *, const cpp_token *, extern bool cpp_interpret_string (cpp_reader *, const cpp_string *, size_t, cpp_string *, bool); +extern bool cpp_interpret_string_notranslate (cpp_reader *, + const cpp_string *, size_t, + cpp_string *, bool); + +/* 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. */ @@ -686,12 +797,6 @@ cpp_num cpp_num_sign_extend (cpp_num, size_t); #define CPP_DL_WARNING_P(l) (CPP_DL_EXTRACT (l) >= CPP_DL_WARNING \ && CPP_DL_EXTRACT (l) <= CPP_DL_PEDWARN) -/* N.B. The error-message-printer prototypes have not been nicely - formatted because exgettext needs to see 'msgid' on the same line - as the name of the function in order to work properly. Only the - string argument gets a name in an effort to keep the lines from - getting ridiculously oversized. */ - /* Output a diagnostic of some kind. */ extern void cpp_error (cpp_reader *, int, const char *msgid, ...) ATTRIBUTE_PRINTF_3; @@ -703,7 +808,7 @@ extern void 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 void cpp_error_with_line (cpp_reader *, int, fileline, unsigned, +extern void cpp_error_with_line (cpp_reader *, int, source_location, unsigned, const char *msgid, ...) ATTRIBUTE_PRINTF_5; /* In cpplex.c */ @@ -740,6 +845,11 @@ extern bool cpp_included (cpp_reader *, const char *); 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 *); /* In cpppch.c */ struct save_macro_data; @@ -755,4 +865,4 @@ extern int cpp_read_state (cpp_reader *, const char *, FILE *, } #endif -#endif /* ! GCC_CPPLIB_H */ +#endif /* ! LIBCPP_CPPLIB_H */ diff --git a/support/cpp2/line-map.h b/support/cpp2/libcpp/include/line-map.h similarity index 50% rename from support/cpp2/line-map.h rename to support/cpp2/libcpp/include/line-map.h index c57f51a6..7e9ede01 100644 --- a/support/cpp2/line-map.h +++ b/support/cpp2/libcpp/include/line-map.h @@ -1,5 +1,5 @@ /* Map logical line numbers to (source file, line number) pairs. - Copyright (C) 2001, 2003 + Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it @@ -14,14 +14,14 @@ 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. +Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. In other words, you are welcome to use, share and improve this program. You are forbidden to forbid anyone else to use, share and improve what you give them. Help stamp out software-hoarding! */ -#ifndef GCC_LINE_MAP_H -#define GCC_LINE_MAP_H +#ifndef LIBCPP_LINE_MAP_H +#define LIBCPP_LINE_MAP_H /* 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. @@ -30,28 +30,34 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. (e.g. a #line directive in C). */ enum lc_reason {LC_ENTER = 0, LC_LEAVE, LC_RENAME}; -/* A logical line number, i,e, an "index" into a line_map. */ +/* A logical line/column number, i.e. an "index" into a line_map. */ /* Long-term, we want to use this to replace struct location_s (in input.h), and effectively typedef source_location location_t. */ typedef unsigned int source_location; -typedef source_location fileline; /* deprecated name */ - -/* The logical line FROM_LINE maps to physical source file TO_FILE at - line TO_LINE, and subsequently one-to-one until the next line_map - structure in the set. 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. */ + +/* 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<to_line - (MAP)->from_line) +/* Converts a map and a source_location to source line. */ +#define SOURCE_LINE(MAP, LINE) \ + ((((LINE) - (MAP)->start_location) >> (MAP)->column_bits) + (MAP)->to_line) + +#define SOURCE_COLUMN(MAP, LINE) \ + (((LINE) - (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), (MAP)[1].from_line - 1) +#define LAST_SOURCE_LINE(MAP) \ + SOURCE_LINE (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]) @@ -119,8 +158,23 @@ extern void linemap_print_containing_files (struct line_maps *, /* Nonzero if the map is at the bottom of the include stack. */ #define MAIN_FILE_P(MAP) ((MAP)->included_from < 0) -/* The current line map. Saves a call to lookup_line if the caller is - sure he is in the scope of the current map. */ -#define CURRENT_LINE_MAP(MAPS) ((MAPS)->maps + (MAPS)->used - 1) - -#endif /* !GCC_LINE_MAP_H */ +/* 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) { \ + 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; \ + }} + + +extern source_location +linemap_position_for_column (struct line_maps *set, unsigned int to_column); +#endif /* !LIBCPP_LINE_MAP_H */ diff --git a/support/cpp2/mkdeps.h b/support/cpp2/libcpp/include/mkdeps.h similarity index 85% rename from support/cpp2/mkdeps.h rename to support/cpp2/libcpp/include/mkdeps.h index db2e00e0..02649701 100644 --- a/support/cpp2/mkdeps.h +++ b/support/cpp2/libcpp/include/mkdeps.h @@ -14,14 +14,14 @@ 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. +Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. In other words, you are welcome to use, share and improve this program. You are forbidden to forbid anyone else to use, share and improve what you give them. Help stamp out software-hoarding! */ -#ifndef GCC_MKDEPS_H -#define GCC_MKDEPS_H +#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. */ @@ -35,6 +35,13 @@ 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); @@ -70,4 +77,4 @@ extern int deps_restore (struct deps *, FILE *, const char *); automatic dependency schemes. */ extern void deps_phony_targets (const struct deps *, FILE *); -#endif /* ! GCC_MKDEPS_H */ +#endif /* ! LIBCPP_MKDEPS_H */ diff --git a/support/cpp2/hashtable.h b/support/cpp2/libcpp/include/symtab.h similarity index 71% rename from support/cpp2/hashtable.h rename to support/cpp2/libcpp/include/symtab.h index 068341c0..cbcf230d 100644 --- a/support/cpp2/hashtable.h +++ b/support/cpp2/libcpp/include/symtab.h @@ -1,5 +1,5 @@ /* Hash tables. - Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc. + Copyright (C) 2000, 2001, 2003, 2004 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 @@ -13,10 +13,10 @@ 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. */ +Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef GCC_HASHTABLE_H -#define GCC_HASHTABLE_H +#ifndef LIBCPP_SYMTAB_H +#define LIBCPP_SYMTAB_H #if defined(__APPLE__) && defined(__MACH__) #include "libiberty/obstack.h" @@ -50,8 +50,11 @@ struct ht struct obstack stack; hashnode *entries; - /* Call back. */ + /* 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. */ @@ -62,6 +65,9 @@ struct ht /* 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. */ @@ -72,6 +78,11 @@ 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 @@ -79,7 +90,11 @@ extern hashnode ht_lookup (hash_table *, const unsigned char *, typedef int (*ht_cb) (struct cpp_reader *, hashnode, const void *); extern void ht_forall (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 /* GCC_HASHTABLE_H */ +#endif /* LIBCPP_SYMTAB_H */ diff --git a/support/cpp2/cppinit.c b/support/cpp2/libcpp/init.c similarity index 88% rename from support/cpp2/cppinit.c rename to support/cpp2/libcpp/init.c index fab2da2b..726dafd6 100644 --- a/support/cpp2/cppinit.c +++ b/support/cpp2/libcpp/init.c @@ -1,6 +1,6 @@ /* CPP Library. Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005 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 @@ -17,13 +17,16 @@ 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. */ +Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #include "system.h" #include "cpplib.h" -#include "cpphash.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 *); @@ -71,21 +74,26 @@ struct lang_flags char c99; char cplusplus; char extended_numbers; + char extended_identifiers; char std; char cplusplus_comments; char digraphs; }; static const struct lang_flags lang_defaults[] = -{ /* c99 c++ xnum std // digr */ - /* GNUC89 */ { 0, 0, 1, 0, 1, 1 }, - /* GNUC99 */ { 1, 0, 1, 0, 1, 1 }, - /* STDC89 */ { 0, 0, 0, 1, 0, 0 }, - /* STDC94 */ { 0, 0, 0, 1, 0, 1 }, - /* STDC99 */ { 1, 0, 1, 1, 1, 1 }, - /* GNUCXX */ { 0, 1, 1, 0, 1, 1 }, - /* CXX98 */ { 0, 1, 1, 1, 1, 1 }, - /* ASM */ { 0, 0, 1, 0, 1, 0 } +{ /* c99 c++ xnum xid std // digr */ + /* GNUC89 */ { 0, 0, 1, 0, 0, 1, 1 }, + /* GNUC99 */ { 1, 0, 1, 0, 0, 1, 1 }, + /* STDC89 */ { 0, 0, 0, 0, 1, 0, 0 }, + /* STDC94 */ { 0, 0, 0, 0, 1, 0, 1 }, + /* STDC99 */ { 1, 0, 1, 0, 1, 1, 1 }, + /* GNUCXX */ { 0, 1, 1, 0, 0, 1, 1 }, + /* CXX98 */ { 0, 1, 1, 0, 1, 1, 1 }, + /* ASM */ { 0, 0, 1, 0, 0, 1, 0 } + /* xid should be 1 for GNUC99, STDC99, GNUCXX and CXX98 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. */ @@ -96,13 +104,14 @@ cpp_set_lang (cpp_reader *pfile, enum c_lang 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, std) = l->std; - CPP_OPTION (pfile, trigraphs) = l->std; - CPP_OPTION (pfile, cplusplus_comments) = l->cplusplus_comments; - CPP_OPTION (pfile, digraphs) = l->digraphs; + 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; + CPP_OPTION (pfile, trigraphs) = l->std; + CPP_OPTION (pfile, cplusplus_comments) = l->cplusplus_comments; + CPP_OPTION (pfile, digraphs) = l->digraphs; } /* Initialize library global state. */ @@ -119,19 +128,24 @@ init_library (void) 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) +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 = xcalloc (1, sizeof (cpp_reader)); + pfile = XCNEW (cpp_reader); cpp_set_lang (pfile, lang); CPP_OPTION (pfile, warn_multichar) = 1; @@ -146,6 +160,8 @@ cpp_create_reader (enum c_lang lang, hash_table *table) CPP_OPTION (pfile, warn_long_long) = !CPP_OPTION (pfile, c99); CPP_OPTION (pfile, dollars_in_ident) = 1; CPP_OPTION (pfile, warn_dollars) = 1; + CPP_OPTION (pfile, warn_variadic_macros) = 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. */ @@ -157,9 +173,11 @@ cpp_create_reader (enum c_lang lang, hash_table *table) CPP_OPTION (pfile, unsigned_wchar) = 1; CPP_OPTION (pfile, bytes_big_endian) = 1; /* does not matter */ - /* Default to locale/UTF-8. */ + /* 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 (); /* SDCC specific */ @@ -173,10 +191,8 @@ cpp_create_reader (enum c_lang lang, hash_table *table) other entries are correct zero-initialized. */ pfile->no_search_path.name = (char *) ""; - /* Initialize the line map. Start at logical line 1, so we can use - a line number of zero for special states. */ - linemap_init (&pfile->line_maps); - pfile->line = 1; + /* Initialize the line map. */ + pfile->line_table = line_table; /* Initialize lexer state. */ pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments); @@ -265,7 +281,6 @@ cpp_destroy (cpp_reader *pfile) free (context); } - linemap_free (&pfile->line_maps); free (pfile); } @@ -274,7 +289,7 @@ cpp_destroy (cpp_reader *pfile) There are two tables of these. builtin_array holds all the "builtin" macros: these are handled by builtin_macro() in - cppmacro.c. Builtin is somewhat of a misnomer -- the property of + 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 "builtin_type" enumerator. @@ -349,13 +364,19 @@ cpp_init_builtins (cpp_reader *pfile, int hosted) if (CPP_OPTION (pfile, traditional)) n -= 2; + else if (! CPP_OPTION (pfile, stdc_0_in_system_headers) + || CPP_OPTION (pfile, std)) + { + n--; + _cpp_define_builtin (pfile, "__STDC__ 1"); + } - for(b = builtin_array; b < builtin_array + n; b++) + 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 | NODE_WARN; - hp->value.builtin = b->value; + hp->value.builtin = (enum builtin_type) b->value; } if (CPP_OPTION (pfile, cplusplus)) @@ -369,7 +390,7 @@ cpp_init_builtins (cpp_reader *pfile, int hosted) if (hosted) _cpp_define_builtin (pfile, "__STDC_HOSTED__ 1"); - else + else _cpp_define_builtin (pfile, "__STDC_HOSTED__ 0"); if (CPP_OPTION (pfile, objc)) @@ -429,18 +450,6 @@ static void sanity_checks (cpp_reader *pfile) # define sanity_checks(PFILE) #endif -/* Add a dependency target. Can be called any number of times before - cpp_read_main_file(). If no targets have been added before - cpp_read_main_file(), then the default target is used. */ -void -cpp_add_dependency_target (cpp_reader *pfile, const char *target, int quote) -{ - if (!pfile->deps) - pfile->deps = deps_init (); - - deps_add_target (pfile->deps, target, quote); -} - /* This is called after options have been parsed, and partially processed. */ void @@ -453,7 +462,7 @@ cpp_post_options (cpp_reader *pfile) /* Mark named operators before handling command line macros. */ if (CPP_OPTION (pfile, cplusplus) && CPP_OPTION (pfile, operator_names)) mark_named_operators (pfile); - } +} /* Setup for processing input from the file named FNAME, or stdin if it is the empty string. Return the original filename @@ -482,9 +491,7 @@ cpp_read_main_file (cpp_reader *pfile, const char *fname) if (CPP_OPTION (pfile, preprocessed)) { read_original_filename (pfile); - if (!pfile->map) - return NULL; - fname = pfile->map->to_file; + fname = pfile->line_table->maps[pfile->line_table->used-1].to_file; } return fname; } @@ -559,7 +566,7 @@ read_original_directory (cpp_reader *pfile) if (pfile->cb.dir_change) { - char *debugdir = alloca (token->val.str.len - 3); + char *debugdir = (char *) alloca (token->val.str.len - 3); memcpy (debugdir, (const char *) token->val.str.text + 1, token->val.str.len - 4); @@ -582,7 +589,7 @@ cpp_finish (cpp_reader *pfile, FILE *deps_stream) if (CPP_OPTION (pfile, warn_unused_macros)) cpp_forall_identifiers (pfile, _cpp_warn_if_unused_macro, NULL); - /* cpplex.c leaves the final buffer on the stack. This it so that + /* 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 diff --git a/support/cpp2/cpphash.h b/support/cpp2/libcpp/internal.h similarity index 72% rename from support/cpp2/cpphash.h rename to support/cpp2/libcpp/internal.h index afe4c832..960f153e 100644 --- a/support/cpp2/cpphash.h +++ b/support/cpp2/libcpp/internal.h @@ -1,5 +1,5 @@ /* Part of CPP library. - Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it @@ -14,18 +14,23 @@ 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. */ +Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* This header defines all the internal data structures and functions - that need to be visible across files. It's called cpphash.h for - historical reasons. */ + that need to be visible across files. It should not be used outside + cpplib. */ -#ifndef GCC_CPPHASH_H -#define GCC_CPPHASH_H +#ifndef LIBCPP_INTERNAL_H +#define LIBCPP_INTERNAL_H -#include "hashtable.h" +#include "symtab.h" +#include "cpp-id-data.h" -#if defined HAVE_ICONV_H && defined HAVE_ICONV +#ifndef HAVE_ICONV_H +#undef HAVE_ICONV +#endif + +#if HAVE_ICONV #include #else #define HAVE_ICONV 0 @@ -45,11 +50,6 @@ struct cset_converter iconv_t cd; }; -#ifndef HAVE_UCHAR -typedef unsigned char uchar; -#endif -#define U (const uchar *) /* Intended use: U"string" */ - #define BITS_PER_CPPCHAR_T (CHAR_BIT * sizeof (cppchar_t)) /* Test if a sign is valid within a preprocessing number. */ @@ -64,6 +64,13 @@ typedef unsigned char uchar; #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]; \ + unsigned int 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 @@ -83,44 +90,6 @@ struct dummy #define CPP_ALIGN2(size, align) (((size) + ((align) - 1)) & ~((align) - 1)) #define CPP_ALIGN(size) CPP_ALIGN2 (size, DEFAULT_ALIGNMENT) -/* Each macro definition is recorded in a cpp_macro structure. - Variadic macros cannot occur with traditional cpp. */ -struct cpp_macro -{ - /* Parameters, if any. */ - cpp_hashnode **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_token *tokens; - const uchar *text; - } exp; - - /* Definition line number. */ - fileline 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; -}; - #define _cpp_mark_macro_used(NODE) do { \ if ((NODE)->type == NT_MACRO && !((NODE)->flags & NODE_BUILTIN)) \ (NODE)->value.macro->used = 1; } while (0) @@ -188,8 +157,8 @@ struct cpp_context /* For traditional macro expansion. */ struct { - const uchar *cur; - const uchar *rlimit; + const unsigned char *cur; + const unsigned char *rlimit; } trad; } u; @@ -236,9 +205,16 @@ struct lexer_state /* Nonzero to prevent macro expansion. */ unsigned char prevent_expansion; + /* Nonzero when handling a deferred pragma. */ + unsigned char in_deferred_pragma; + /* 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; }; @@ -258,7 +234,7 @@ typedef struct _cpp_line_note _cpp_line_note; struct _cpp_line_note { /* Location in the clean line the note refers to. */ - const uchar *pos; + const unsigned char *pos; /* Type of note. The 9 'from' trigraph characters represent those trigraphs, '\\' an escaped newline, ' ' an escaped newline with @@ -269,17 +245,17 @@ struct _cpp_line_note /* Represents the contents of a file cpplib has read in. */ struct cpp_buffer { - const uchar *cur; /* Current location. */ - const uchar *line_base; /* Start of current physical line. */ - const uchar *next_line; /* Start of to-be-cleaned logical line. */ + 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 uchar *buf; /* Entire character buffer. */ - const uchar *rlimit; /* Writable byte at end of file. */ + 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. */ + _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; @@ -298,24 +274,29 @@ struct cpp_buffer The warning happens only for C89 extended mode with -pedantic on, or for -Wtraditional, and only once per file (otherwise it would be far too noisy). */ - unsigned char warned_cplusplus_comments; + 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 char from_stage3; + 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; - /* Used for buffer overlays by cpptrad.c. */ - const uchar *saved_cur, *saved_rlimit; + /* Descriptor for converting from the input character set to the + source character set. */ + struct cset_converter input_cset_desc; }; /* A cpp_reader encapsulates the "state" of a pre-processor run. @@ -333,12 +314,10 @@ struct cpp_reader struct lexer_state state; /* Source line tracking. */ - struct line_maps line_maps; - const struct line_map *map; - fileline line; + struct line_maps *line_table; /* The line of the '#' of the current directive. */ - fileline directive_line; + source_location directive_line; /* Memory buffers. */ _cpp_buff *a_buff; /* Aligned permanent storage. */ @@ -352,6 +331,9 @@ struct cpp_reader /* If in_directive, the directive if known. */ const struct directive *directive; + /* Token generated while handling a directive, if any. */ + cpp_token directive_result; + /* Search paths for include files. */ struct cpp_dir *quote_include; /* "" */ struct cpp_dir *bracket_include; /* <> */ @@ -405,8 +387,8 @@ struct cpp_reader struct cset_converter wide_cset_desc; /* Date and time text. Calculated together if either is requested. */ - const uchar *date; - const uchar *time; + const unsigned char *date; + const unsigned char *time; /* EOF token, and a token forcing paste avoidance. */ cpp_token avoid_paste; @@ -416,11 +398,11 @@ struct cpp_reader struct deps *deps; /* Obstack holding all macro hash nodes. This never shrinks. - See cpphash.c */ + See identifiers.c */ struct obstack hash_ob; /* Obstack holding buffer and conditional structures. This is a - real stack. See cpplib.c. */ + real stack. See directives.c. */ struct obstack buffer_ob; /* Pragma table - dynamic, because a library user can add to the @@ -449,15 +431,14 @@ struct cpp_reader /* Traditional preprocessing output buffer (a logical line). */ struct { - uchar *base; - uchar *limit; - uchar *cur; - fileline first_line; + unsigned char *base; + unsigned char *limit; + unsigned char *cur; + source_location first_line; } out; - /* Used to save the original line number during traditional - preprocessing. */ - unsigned int saved_line; + /* 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. */ @@ -469,7 +450,7 @@ struct cpp_reader definition of a pp-number in the C standard [section 6.4.8 of C99]. In the unlikely event that characters other than \r and \n enter - the set is_vspace, the macro handle_newline() in cpplex.c must be + 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)) @@ -493,32 +474,39 @@ extern unsigned char _cpp_trigraph_map[UCHAR_MAX + 1]; /* Macros. */ -#define CPP_IN_SYSTEM_HEADER(PFILE) ((PFILE)->map && (PFILE)->map->sysp) +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, pedantic) #define CPP_WTRADITIONAL(PF) CPP_OPTION (PF, warn_traditional) -/* In cpperror.c */ -extern int _cpp_begin_message (cpp_reader *, int, fileline, unsigned int); +/* In errors.c */ +extern int _cpp_begin_message (cpp_reader *, int, + source_location, unsigned int); -/* In cppmacro.c */ +/* 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 uchar *, size_t); + 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 uchar *_cpp_builtin_macro_text (cpp_reader *, cpp_hashnode *); +extern const unsigned char *_cpp_builtin_macro_text (cpp_reader *, + cpp_hashnode *); int _cpp_warn_if_unused_macro (cpp_reader *, cpp_hashnode *, void *); -/* In cpphash.c */ +/* In identifiers.c */ extern void _cpp_init_hashtable (cpp_reader *, hash_table *); extern void _cpp_destroy_hashtable (cpp_reader *); -/* In cppfiles.c */ +/* In files.c */ typedef struct _cpp_file _cpp_file; -extern _cpp_file *_cpp_find_file (cpp_reader *, const char *fname, - cpp_dir *start_dir, bool fake, int); +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 *); @@ -530,12 +518,14 @@ 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 *); -/* In cppexp.c */ +/* In expr.c */ extern bool _cpp_parse_expr (cpp_reader *); extern struct op *_cpp_expand_op_stack (cpp_reader *); -/* In cpplex.c */ +/* In lex.c */ extern void _cpp_process_line_notes (cpp_reader *, int); extern void _cpp_clean_line (cpp_reader *); extern bool _cpp_get_fresh_line (cpp_reader *); @@ -546,10 +536,10 @@ 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); -/* In cppinit.c. */ +/* In init.c. */ extern void _cpp_maybe_push_include_file (cpp_reader *); -/* In cpplib.c */ +/* 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 *); @@ -562,80 +552,110 @@ extern void _cpp_do_file_change (cpp_reader *, enum lc_reason, const char *, unsigned int, unsigned int); extern void _cpp_pop_buffer (cpp_reader *); -/* In cpptrad.c. */ +/* 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 uchar *, size_t); +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 uchar *_cpp_copy_replacement_text (const cpp_macro *, uchar *); +extern unsigned char *_cpp_copy_replacement_text (const cpp_macro *, + unsigned char *); extern size_t _cpp_replacement_text_len (const cpp_macro *); -/* In cppcharset.c. */ -extern cppchar_t _cpp_valid_ucn (cpp_reader *, const uchar **, - const uchar *, int); +/* 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 bool _cpp_interpret_string_notranslate (cpp_reader *, - const cpp_string *, - cpp_string *); -extern uchar *_cpp_convert_input (cpp_reader *, const char *, uchar *, - size_t, size_t, off_t *); +extern unsigned char *_cpp_convert_input (cpp_reader *, const char *, + unsigned char *, size_t, size_t, + 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 uchar *)str, sizeof str - 1 -#define xnew(T) (T *) xmalloc (sizeof(T)) -#define xcnew(T) (T *) xcalloc (1, sizeof(T)) -#define xnewvec(T, N) (T *) xmalloc (sizeof(T) * (N)) -#define xcnewvec(T, N) (T *) xcalloc (N, sizeof(T)) -#define xobnew(O, T) (T *) obstack_alloc (O, sizeof(T)) +#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 uchar *, const uchar *); -static inline int ustrncmp (const uchar *, const uchar *, size_t); -static inline size_t ustrlen (const uchar *); -static inline uchar *uxstrdup (const uchar *); -static inline uchar *ustrchr (const uchar *, int); -static inline int ufputs (const uchar *, FILE *); +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 uchar *s1, const uchar *s2) +ustrcmp (const unsigned char *s1, const unsigned char *s2) { return strcmp ((const char *)s1, (const char *)s2); } static inline int -ustrncmp (const uchar *s1, const uchar *s2, size_t n) +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 uchar *s1) +ustrlen (const unsigned char *s1) { return strlen ((const char *)s1); } -static inline uchar * -uxstrdup (const uchar *s1) +static inline unsigned char * +uxstrdup (const unsigned char *s1) { - return (uchar *) xstrdup ((const char *)s1); + return (unsigned char *) xstrdup ((const char *)s1); } -static inline uchar * -ustrchr (const uchar *s1, int c) +static inline unsigned char * +ustrchr (const unsigned char *s1, int c) { - return (uchar *) strchr ((const char *)s1, c); + return (unsigned char *) strchr ((const char *)s1, c); } static inline int -ufputs (const uchar *s, FILE *f) +ufputs (const unsigned char *s, FILE *f) { return fputs ((const char *)s, f); } -#endif /* ! GCC_CPPHASH_H */ +#endif /* ! LIBCPP_INTERNAL_H */ diff --git a/support/cpp2/cpplex.c b/support/cpp2/libcpp/lex.c similarity index 86% rename from support/cpp2/cpplex.c rename to support/cpp2/libcpp/lex.c index 610d5b13..c4a56380 100644 --- a/support/cpp2/cpplex.c +++ b/support/cpp2/libcpp/lex.c @@ -1,5 +1,5 @@ /* CPP Library - lexical analysis. - Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 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 @@ -17,12 +17,12 @@ 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. */ +Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #include "system.h" #include "cpplib.h" -#include "cpphash.h" +#include "internal.h" #include enum spell_type @@ -42,8 +42,8 @@ struct token_spelling static const unsigned char *const digraph_spellings[] = { U"%:", U"%:%:", U"<:", U":>", U"<%", U"%>" }; -#define OP(e, s) { SPELL_OPERATOR, U s }, -#define TK(e, s) { s, U #e }, +#define OP(e, s) { SPELL_OPERATOR, U s }, +#define TK(e, s) { SPELL_ ## s, U #e }, static const struct token_spelling token_spellings[N_TTYPES] = { TTYPE_TABLE }; #undef OP #undef TK @@ -54,9 +54,6 @@ static const struct token_spelling token_spellings[N_TTYPES] = { TTYPE_TABLE }; 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 cpp_hashnode *lex_identifier (cpp_reader *, const uchar *); -static void lex_number (cpp_reader *, cpp_string *); -static bool forms_identifier_p (cpp_reader *, int); static void lex_string (cpp_reader *, cpp_token *, const uchar *); static void save_comment (cpp_reader *, cpp_token *, const uchar *, cppchar_t); static void create_literal (cpp_reader *, cpp_token *, const uchar *, @@ -89,8 +86,8 @@ 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 = xrealloc (buffer->notes, - buffer->notes_cap * sizeof (_cpp_line_note)); + buffer->notes = XRESIZEVEC (_cpp_line_note, buffer->notes, + buffer->notes_cap); } buffer->notes[buffer->notes_used].pos = pos; @@ -271,19 +268,19 @@ _cpp_process_line_notes (cpp_reader *pfile, int in_comment) if (note->type == '\\' || note->type == ' ') { if (note->type == ' ' && !in_comment) - cpp_error_with_line (pfile, CPP_DL_WARNING, pfile->line, col, + 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, col, + 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; } buffer->line_base = note->pos; - pfile->line++; + CPP_INCREMENT_LINE (pfile, 0); } else if (_cpp_trigraph_map[note->type]) { @@ -291,14 +288,14 @@ _cpp_process_line_notes (cpp_reader *pfile, int in_comment) && (!in_comment || warn_in_comment (pfile, note))) { if (CPP_OPTION (pfile, trigraphs)) - cpp_error_with_line (pfile, CPP_DL_WARNING, pfile->line, col, + cpp_error_with_line (pfile, CPP_DL_WARNING, pfile->line_table->highest_line, col, "trigraph ??%c converted to %c", note->type, (int) _cpp_trigraph_map[note->type]); else { cpp_error_with_line - (pfile, CPP_DL_WARNING, pfile->line, col, + (pfile, CPP_DL_WARNING, pfile->line_table->highest_line, col, "trigraph ??%c ignored, use -trigraphs to enable", note->type); } @@ -341,12 +338,15 @@ skip_asm_block (cpp_reader *pfile) } 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); - pfile->line++; + + cols = buffer->next_line - buffer->line_base; + CPP_INCREMENT_LINE (pfile, cols); } } @@ -389,18 +389,22 @@ _cpp_skip_block_comment (cpp_reader *pfile) { buffer->cur = cur; cpp_error_with_line (pfile, CPP_DL_WARNING, - pfile->line, CPP_BUF_COL (buffer), + 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); - pfile->line++; + + cols = buffer->next_line - buffer->line_base; + CPP_INCREMENT_LINE (pfile, cols); + cur = buffer->cur; } } @@ -417,13 +421,13 @@ static int skip_line_comment (cpp_reader *pfile) { cpp_buffer *buffer = pfile->buffer; - unsigned int orig_line = pfile->line; + unsigned int orig_line = pfile->line_table->highest_line; while (*buffer->cur != '\n') buffer->cur++; _cpp_process_line_notes (pfile, true); - return orig_line != pfile->line; + return orig_line != pfile->line_table->highest_line; } /* Skips whitespace, saving the next non-whitespace character. */ @@ -442,7 +446,7 @@ skip_whitespace (cpp_reader *pfile, cppchar_t c) 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, + 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"); @@ -472,10 +476,36 @@ name_p (cpp_reader *pfile, const cpp_string *string) 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_error_with_line (pfile, CPP_DL_WARNING, token->src_loc, 0, + "`%.*s' is not in NFKC", (int) sz, buf); + else + cpp_error_with_line (pfile, CPP_DL_WARNING, 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) +forms_identifier_p (cpp_reader *pfile, int first, + struct normalize_state *state) { cpp_buffer *buffer = pfile->buffer; @@ -495,11 +525,13 @@ forms_identifier_p (cpp_reader *pfile, int first) } /* Is this a syntactically valid UCN? */ - if (0 && *buffer->cur == '\\' + 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)) + if (_cpp_valid_ucn (pfile, &buffer->cur, buffer->rlimit, 1 + !first, + state)) return true; buffer->cur -= 2; } @@ -509,25 +541,43 @@ forms_identifier_p (cpp_reader *pfile, int first) /* Lex an identifier starting at BUFFER->CUR - 1. */ static cpp_hashnode * -lex_identifier (cpp_reader *pfile, const uchar *base) +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); - do - { - cur = pfile->buffer->cur; - - /* N.B. ISIDNUM does not include $. */ - while (ISIDNUM (*cur)) + cur = pfile->buffer->cur; + if (! starts_ucn) + while (ISIDNUM (*cur)) + { + hash = HT_HASHSTEP (hash, *cur); cur++; - - pfile->buffer->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); } - while (forms_identifier_p (pfile, false)); + else + { + len = cur - base; + hash = HT_HASHFINISH (hash, len); - result = (cpp_hashnode *) - ht_lookup (pfile->hash_table, base, cur - base, HT_ALLOC); + 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) @@ -579,7 +629,7 @@ pedantic_lex_number (cpp_reader *pfile, cpp_string *number) } else { - if ('0' == c) + if ('0' == c) { has_whole = 1; ++len; @@ -725,7 +775,7 @@ pedantic_lex_number (cpp_reader *pfile, cpp_string *number) } num_part = NP_FLOAT_SUFFIX; continue; - + case NP_EXP: if ('+' == c || '-' == c) { @@ -795,7 +845,8 @@ pedantic_lex_number (cpp_reader *pfile, cpp_string *number) /* Lex a number to NUMBER starting at BUFFER->CUR - 1. */ static void -lex_number (cpp_reader *pfile, cpp_string *number) +lex_number (cpp_reader *pfile, cpp_string *number, + struct normalize_state *nst) { const uchar *cur; const uchar *base; @@ -808,11 +859,14 @@ lex_number (cpp_reader *pfile, cpp_string *number) /* N.B. ISIDNUM does not include $. */ while (ISIDNUM (*cur) || *cur == '.' || VALID_SIGN (*cur, cur[-1])) - cur++; + { + cur++; + NORMALIZE_STATE_UPDATE_IDNUM (nst); + } pfile->buffer->cur = cur; } - while (forms_identifier_p (pfile, false)); + while (forms_identifier_p (pfile, false, nst)); number->len = cur - base; dest = _cpp_unaligned_alloc (pfile, number->len + 1); @@ -986,7 +1040,7 @@ save_comment (cpp_reader *pfile, cpp_token *token, const unsigned char *from, void _cpp_init_tokenrun (tokenrun *run, unsigned int count) { - run->base = xnewvec (cpp_token, count); + run->base = XNEWVEC (cpp_token, count); run->limit = run->base + count; run->next = NULL; } @@ -997,7 +1051,7 @@ next_tokenrun (tokenrun *run) { if (run->next == NULL) { - run->next = xnew (tokenrun); + run->next = XNEW (tokenrun); run->next->prev = run; _cpp_init_tokenrun (run->next, 250); } @@ -1022,8 +1076,7 @@ _cpp_temp_token (cpp_reader *pfile) } result = pfile->cur_token++; - result->line = old->line; - result->col = old->col; + result->src_loc = old->src_loc; return result; } @@ -1061,7 +1114,16 @@ _cpp_lex_token (cpp_reader *pfile) handles the directive as normal. */ && pfile->state.parsing_args != 1 && _cpp_handle_directive (pfile, result->flags & PREV_WHITE)) - continue; + { + if (pfile->directive_result.type == CPP_PADDING) + continue; + else + { + result = &pfile->directive_result; + break; + } + } + if (pfile->cb.line_change && !pfile->state.skipping) pfile->cb.line_change (pfile, result, pfile->state.parsing_args); } @@ -1116,7 +1178,7 @@ _cpp_get_fresh_line (cpp_reader *pfile) { /* Only warn once. */ buffer->next_line = buffer->rlimit; - cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line - 1, + cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line_table->highest_line, CPP_BUF_COLUMN (buffer, buffer->cur), "no newline at end of file"); } @@ -1167,7 +1229,7 @@ _cpp_lex_direct (cpp_reader *pfile) if (!pfile->state.in_directive) { /* Tell the compiler the line number of the EOF token. */ - result->line = pfile->line; + result->src_loc = pfile->line_table->highest_line; result->flags = BOL; } return result; @@ -1184,17 +1246,19 @@ _cpp_lex_direct (cpp_reader *pfile) } buffer = pfile->buffer; update_tokens_line: - result->line = pfile->line; + result->src_loc = pfile->line_table->highest_line; skipped_white: if (buffer->cur >= buffer->notes[buffer->cur_note].pos && !pfile->overlaid_buffer) { _cpp_process_line_notes (pfile, false); - result->line = pfile->line; + result->src_loc = pfile->line_table->highest_line; } c = *buffer->cur++; - result->col = CPP_BUF_COLUMN (buffer, buffer->cur); + + LINEMAP_POSITION_FOR_COLUMN (result->src_loc, pfile->line_table, + CPP_BUF_COLUMN (buffer, buffer->cur)); switch (c) { @@ -1204,18 +1268,23 @@ _cpp_lex_direct (cpp_reader *pfile) goto skipped_white; case '\n': - pfile->line++; + 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': - result->type = CPP_NUMBER; - if (CPP_OPTION(pfile, pedantic_parse_number)) - pedantic_lex_number (pfile, &result->val.str); - else - lex_number (pfile, &result->val.str); - break; + { + struct normalize_state nst = INITIAL_NORMALIZE_STATE; + result->type = CPP_NUMBER; + 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': /* 'L' may introduce wide characters or strings. */ @@ -1238,7 +1307,12 @@ _cpp_lex_direct (cpp_reader *pfile) case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': result->type = CPP_NAME; - result->val.node = lex_identifier (pfile, buffer->cur - 1); + { + struct normalize_state nst = INITIAL_NORMALIZE_STATE; + result->val.node = lex_identifier (pfile, buffer->cur - 1, false, + &nst); + warn_about_normalization (pfile, result, &nst); + } /* SDCC _asm specific */ /* handle _asm ... _endasm ; */ @@ -1254,7 +1328,7 @@ _cpp_lex_direct (cpp_reader *pfile) else if (result->val.node->flags & NODE_OPERATOR) { result->flags |= NAMED_OP; - result->type = result->val.node->directive_index; + result->type = (enum cpp_ttype) result->val.node->directive_index; } break; @@ -1274,7 +1348,7 @@ _cpp_lex_direct (cpp_reader *pfile) cpp_error (pfile, CPP_DL_ERROR, "unterminated comment"); } else if (c == '/' && (CPP_OPTION (pfile, cplusplus_comments) - || CPP_IN_SYSTEM_HEADER (pfile))) + || cpp_in_system_header (pfile))) { /* Warn about comments only if pedantically GNUC89, and not in system headers. */ @@ -1393,11 +1467,13 @@ _cpp_lex_direct (cpp_reader *pfile) result->type = CPP_DOT; if (ISDIGIT (*buffer->cur)) { + struct normalize_state nst = INITIAL_NORMALIZE_STATE; result->type = CPP_NUMBER; - if (CPP_OPTION(pfile, pedantic_parse_number)) - pedantic_lex_number (pfile, &result->val.str); - else - lex_number (pfile, &result->val.str); + 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; @@ -1480,11 +1556,13 @@ _cpp_lex_direct (cpp_reader *pfile) case '\\': { const uchar *base = --buffer->cur; + struct normalize_state nst = INITIAL_NORMALIZE_STATE; - if (forms_identifier_p (pfile, true)) + if (forms_identifier_p (pfile, true, &nst)) { result->type = CPP_NAME; - result->val.node = lex_identifier (pfile, base); + result->val.node = lex_identifier (pfile, base, true, &nst); + warn_about_normalization (pfile, result, &nst); break; } buffer->cur++; @@ -1509,19 +1587,56 @@ cpp_token_len (const cpp_token *token) { default: len = 4; break; case SPELL_LITERAL: len = token->val.str.len; break; - case SPELL_IDENT: len = NODE_LEN (token->val.node); break; + case SPELL_IDENT: len = NODE_LEN (token->val.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; +} + + /* 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) + unsigned char *buffer, bool forstring) { switch (TOKEN_SPELL (token)) { @@ -1545,8 +1660,26 @@ cpp_spell_token (cpp_reader *pfile, const cpp_token *token, spell_ident: case SPELL_IDENT: - memcpy (buffer, NODE_NAME (token->val.node), NODE_LEN (token->val.node)); - buffer += NODE_LEN (token->val.node); + if (forstring) + { + memcpy (buffer, NODE_NAME (token->val.node), + NODE_LEN (token->val.node)); + buffer += NODE_LEN (token->val.node); + } + else + { + size_t i; + const unsigned char * name = NODE_NAME (token->val.node); + + for (i = 0; i < NODE_LEN (token->val.node); i++) + if (name[i] & ~0x7F) + { + i += utf8_to_ucn (buffer, name + i) - 1; + buffer += 10; + } + else + *buffer++ = NODE_NAME (token->val.node)[i]; + } break; case SPELL_LITERAL: @@ -1571,7 +1704,7 @@ 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); + end = cpp_spell_token (pfile, token, start, false); end[0] = '\0'; return start; @@ -1615,8 +1748,21 @@ cpp_output_token (const cpp_token *token, FILE *fp) spell_ident: case SPELL_IDENT: - fwrite (NODE_NAME (token->val.node), 1, NODE_LEN (token->val.node), fp); - break; + { + size_t i; + const unsigned char * name = NODE_NAME (token->val.node); + + for (i = 0; i < NODE_LEN (token->val.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)[i], fp); + } + break; case SPELL_LITERAL: fwrite (token->val.str.text, 1, token->val.str.len, fp); @@ -1756,7 +1902,7 @@ new_buff (size_t len) len = MIN_BUFF_SIZE; len = CPP_ALIGN (len); - base = xmalloc (len + sizeof (_cpp_buff)); + base = XNEWVEC (unsigned char, len + sizeof (_cpp_buff)); result = (_cpp_buff *) (base + len); result->base = base; result->cur = base; @@ -1894,3 +2040,27 @@ _cpp_aligned_alloc (cpp_reader *pfile, size_t len) 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_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_STR; + /* else fall through */ + default: + return CPP_TOKEN_FLD_NONE; + } +} diff --git a/support/cpp2/line-map.c b/support/cpp2/libcpp/line-map.c similarity index 57% rename from support/cpp2/line-map.c rename to support/cpp2/libcpp/line-map.c index 521c4e5c..c95eacde 100644 --- a/support/cpp2/line-map.c +++ b/support/cpp2/libcpp/line-map.c @@ -1,5 +1,5 @@ /* Map logical line numbers to (source file, line number) pairs. - Copyright (C) 2001, 2003 + Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it @@ -14,7 +14,7 @@ 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. +Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 @@ -23,7 +23,6 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "config.h" #include "system.h" #include "line-map.h" -#include "intl.h" static void trace_include (const struct line_maps *, const struct line_map *); @@ -32,14 +31,32 @@ static void trace_include (const struct line_maps *, const struct line_map *); void linemap_init (struct line_maps *set) { - set->maps = 0; + 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 = 0; + set->highest_line = 0; + set->max_column_hint = 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 @@ -47,14 +64,7 @@ linemap_free (struct line_maps *set) { if (set->maps) { - 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 = CURRENT_LINE_MAP (set); ! MAIN_FILE_P (map); - map = INCLUDED_FROM (set, map)) - fprintf (stderr, "line-map.c: file \"%s\" entered but not left\n", - map->to_file); + linemap_check_files_exited (set); free (set->maps); } @@ -71,25 +81,26 @@ linemap_free (struct line_maps *set) FROM_LINE should be monotonic increasing across calls to this function. A call to this function can relocate the previous set of + 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, source_location from_line, - const char *to_file, unsigned int to_line) + unsigned int sysp, const char *to_file, unsigned int to_line) { struct line_map *map; + source_location start_location = set->highest_location + 1; - if (set->used && from_line < set->maps[set->used - 1].from_line) + if (set->used && start_location < set->maps[set->used - 1].start_location) abort (); if (set->used == set->allocated) { set->allocated = 2 * set->allocated + 256; - set->maps = xrealloc (set->maps, set->allocated * sizeof (struct line_map)); + set->maps = XRESIZEVEC (struct line_map, set->maps, set->allocated); } - map = &set->maps[set->used++]; + map = &set->maps[set->used]; if (to_file && *to_file == '\0') to_file = ""; @@ -108,7 +119,6 @@ linemap_add (struct line_maps *set, enum lc_reason reason, if (to_file == NULL) { set->depth--; - set->used--; return NULL; } error = true; @@ -131,16 +141,21 @@ linemap_add (struct line_maps *set, enum lc_reason reason, if (error || to_file == NULL) { to_file = from->to_file; - to_line = LAST_SOURCE_LINE (from) + 1; + to_line = SOURCE_LINE (from, from[1].start_location); sysp = from->sysp; } } map->reason = reason; map->sysp = sysp; - map->from_line = from_line; + 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) { @@ -160,6 +175,87 @@ linemap_add (struct line_maps *set, enum lc_reason reason, return map; } +source_location +linemap_line_start (struct line_maps *set, unsigned int 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; + unsigned int 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 @@ -168,20 +264,35 @@ linemap_add (struct line_maps *set, enum lc_reason reason, const struct line_map * linemap_lookup (struct line_maps *set, source_location line) { - unsigned int md, mn = 0, mx = set->used; - - if (mx == 0) - abort (); + 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].from_line > line) + if (set->maps[md].start_location > line) mx = md; else mn = md; } + set->cache = mn; return &set->maps[mn]; } diff --git a/support/cpp2/cppmacro.c b/support/cpp2/libcpp/macro.c similarity index 90% rename from support/cpp2/cppmacro.c rename to support/cpp2/libcpp/macro.c index 59e3f582..b4143110 100644 --- a/support/cpp2/cppmacro.c +++ b/support/cpp2/libcpp/macro.c @@ -1,6 +1,6 @@ /* Part of CPP library. (Macro and #define handling.) Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1998, - 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005 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 @@ -17,7 +17,7 @@ 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. +Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 @@ -26,7 +26,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "config.h" #include "system.h" #include "cpplib.h" -#include "cpphash.h" +#include "internal.h" typedef struct macro_arg macro_arg; struct macro_arg @@ -80,7 +80,7 @@ _cpp_warn_if_unused_macro (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro = node->value.macro; if (!macro->used - && MAIN_FILE_P (linemap_lookup (&pfile->line_maps, macro->line))) + && MAIN_FILE_P (linemap_lookup (pfile->line_table, macro->line))) cpp_error_with_line (pfile, CPP_DL_WARNING, macro->line, 0, "macro \"%s\" is not used", NODE_NAME (node)); } @@ -109,13 +109,12 @@ static const char * const monthnames[] = "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; -/* Handle builtin macros like __FILE__, and push the resulting token - on the context stack. Also handles _Pragma, for which no new token - is created. Returns 1 if it generates a new token context, 0 to - return the token to the caller. */ +/* 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; unsigned int number = 1; @@ -132,15 +131,15 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node) unsigned int len; const char *name; uchar *buf; - const struct line_map *map = pfile->map; + 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_maps, map); + map = INCLUDED_FROM (pfile->line_table, map); name = map->to_file; len = strlen (name); - buf = _cpp_unaligned_alloc (pfile, len * 4 + 3); + buf = _cpp_unaligned_alloc (pfile, len * 2 + 3); result = buf; *buf = '"'; buf = cpp_quote_string (buf + 1, (const unsigned char *) name, len); @@ -153,34 +152,31 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node) /* 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_maps.depth - 1; + 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. */ if (CPP_OPTION (pfile, traditional)) - number = pfile->line; + number = pfile->line_table->highest_line; else - number = pfile->cur_token[-1].line; - number = SOURCE_LINE (pfile->map, number); + number = pfile->cur_token[-1].src_loc; + number = SOURCE_LINE (map, number); 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. */ + value 0. (b) and (c) are already checked in cpp_init_builtins. */ case BT_STDC: - { - if (CPP_IN_SYSTEM_HEADER (pfile) - && CPP_OPTION (pfile, stdc_0_in_system_headers) - && !CPP_OPTION (pfile,std)) - number = 0; - else - number = 1; - } + if (cpp_in_system_header (pfile)) + number = 0; + else + number = 1; break; case BT_DATE: @@ -219,7 +215,7 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node) { cpp_errno (pfile, CPP_DL_WARNING, "could not determine date and time"); - + pfile->date = U"\"??? ?? ????\""; pfile->time = U"\"??:??:??\""; } @@ -239,12 +235,12 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node) sprintf ((char *) result, "%u", number); } - return result; + return result; } /* Convert builtin macros like __FILE__ to a token and push it on the - context stack. Also handles _Pragma, for which no new token is - created. Returns 1 if it generates a new token context, 0 to + 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) @@ -261,12 +257,19 @@ builtin_macro (cpp_reader *pfile, cpp_hashnode *node) return 0; _cpp_do__Pragma (pfile); + if (pfile->directive_result.type == CPP_PRAGMA) + { + cpp_token *tok = _cpp_temp_token (pfile); + *tok = pfile->directive_result; + push_token_context (pfile, NULL, tok, 1); + } + return 1; } buf = _cpp_builtin_macro_text (pfile, node); len = ustrlen (buf); - nbuf = alloca (len + 1); + nbuf = (char *) alloca (len + 1); memcpy (nbuf, buf, len); nbuf[len]='\n'; @@ -285,9 +288,8 @@ builtin_macro (cpp_reader *pfile, cpp_hashnode *node) } /* Copies SRC, of length LEN, to DEST, adding backslashes before all - backslashes and double quotes. Non-printable characters are - converted to octal. DEST must be of sufficient size. Returns - a pointer to the end of the string. */ + 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) { @@ -301,15 +303,7 @@ cpp_quote_string (uchar *dest, const uchar *src, unsigned int len) *dest++ = c; } else - { - if (ISPRINT (c)) - *dest++ = c; - else - { - sprintf ((char *) dest, "\\%03o", c); - dest += 4; - } - } + *dest++ = c; } return dest; @@ -373,12 +367,12 @@ stringify_arg (cpp_reader *pfile, macro_arg *arg) { _cpp_buff *buff = _cpp_get_buff (pfile, len); unsigned char *buf = BUFF_FRONT (buff); - len = cpp_spell_token (pfile, token, buf) - buf; + 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); + dest = cpp_spell_token (pfile, token, dest, true); if (token->type == CPP_OTHER && token->val.str.text[0] == '\\') backslash_count++; @@ -414,8 +408,8 @@ paste_tokens (cpp_reader *pfile, const cpp_token **plhs, const cpp_token *rhs) lhs = *plhs; len = cpp_token_len (lhs) + cpp_token_len (rhs) + 1; - buf = alloca (len); - end = cpp_spell_token (pfile, lhs, buf); + buf = (unsigned char *) alloca (len); + end = cpp_spell_token (pfile, lhs, 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 @@ -423,7 +417,7 @@ paste_tokens (cpp_reader *pfile, const cpp_token **plhs, const cpp_token *rhs) false doesn't work, since we want to clear the PASTE_LEFT flag. */ if (lhs->type == CPP_DIV && rhs->type != CPP_EQ) *end++ = ' '; - end = cpp_spell_token (pfile, rhs, end); + end = cpp_spell_token (pfile, rhs, end, false); *end = '\n'; cpp_push_buffer (pfile, buf, end - buf, /* from_stage3 */ true); @@ -879,7 +873,7 @@ replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro, macro_arg { cpp_token *token = _cpp_temp_token (pfile); token->type = (*paste_flag)->type; - token->val.str = (*paste_flag)->val.str; + token->val = (*paste_flag)->val; if (src->flags & PASTE_LEFT) token->flags = (*paste_flag)->flags | PASTE_LEFT; else @@ -903,7 +897,10 @@ padding_token (cpp_reader *pfile, const cpp_token *source) cpp_token *result = _cpp_temp_token (pfile); result->type = CPP_PADDING; - result->val.source = source; + + /* 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; } @@ -917,7 +914,7 @@ next_context (cpp_reader *pfile) if (result == 0) { - result = xnew (cpp_context); + result = XNEW (cpp_context); result->prev = pfile->context; result->next = 0; pfile->context->next = result; @@ -991,7 +988,7 @@ expand_arg (cpp_reader *pfile, macro_arg *arg) /* Loop, reading in the arguments. */ capacity = 256; - arg->expanded = xmalloc (capacity * sizeof (cpp_token *)); + arg->expanded = XNEWVEC (const cpp_token *, capacity); push_ptoken_context (pfile, NULL, NULL, arg->first, arg->count + 1); for (;;) @@ -1001,8 +998,8 @@ expand_arg (cpp_reader *pfile, macro_arg *arg) if (arg->expanded_count + 1 >= capacity) { capacity *= 2; - arg->expanded = xrealloc (arg->expanded, - capacity * sizeof (cpp_token *)); + arg->expanded = XRESIZEVEC (const cpp_token *, arg->expanded, + capacity); } token = cpp_get_token (pfile); @@ -1110,7 +1107,7 @@ cpp_get_token (cpp_reader *pfile) cpp_token *t = _cpp_temp_token (pfile); t->type = result->type; t->flags = result->flags | NO_EXPAND; - t->val.str = result->val.str; + t->val = result->val; result = t; } @@ -1140,12 +1137,18 @@ cpp_scan_nooutput (cpp_reader *pfile) 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. Can only step mack more than 1 if @@ -1256,12 +1259,13 @@ _cpp_save_parameter (cpp_reader *pfile, cpp_macro *macro, cpp_hashnode *node) len = macro->paramc * sizeof (union _cpp_hashnode_value); if (len > pfile->macro_buffer_len) { - pfile->macro_buffer = xrealloc (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; } @@ -1325,11 +1329,14 @@ parse_params (cpp_reader *pfile, cpp_macro *macro) _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, pedantic)) + if (! CPP_OPTION (pfile, c99) + && CPP_OPTION (pfile, pedantic) + && CPP_OPTION (pfile, warn_variadic_macros)) cpp_error (pfile, CPP_DL_PEDWARN, "anonymous variadic macros were introduced in C99"); } - else if (CPP_OPTION (pfile, pedantic)) + else if (CPP_OPTION (pfile, pedantic) + && CPP_OPTION (pfile, warn_variadic_macros)) cpp_error (pfile, CPP_DL_PEDWARN, "ISO C does not permit named variadic macros"); @@ -1397,13 +1404,54 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro) if (!ok) return false; - /* Success. Commit the parameter array. */ - BUFF_FRONT (pfile->a_buff) = (uchar *) ¯o->params[macro->paramc]; + /* 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)) - cpp_error (pfile, CPP_DL_PEDWARN, - "ISO C requires whitespace after the macro name"); + { + /* 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); @@ -1462,6 +1510,7 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro) } macro->exp.tokens = (cpp_token *) BUFF_FRONT (pfile->a_buff); + macro->traditional = 0; /* Don't count the CPP_EOF. */ macro->count--; @@ -1470,8 +1519,17 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro) if (macro->count) macro->exp.tokens[0].flags &= ~PREV_WHITE; - /* Commit the memory. */ - BUFF_FRONT (pfile->a_buff) = (uchar *) ¯o->exp.tokens[macro->count]; + /* 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); + 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; } @@ -1484,7 +1542,11 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node) unsigned int i; bool ok; - macro = (cpp_macro *) _cpp_aligned_alloc (pfile, sizeof (cpp_macro)); + 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; @@ -1493,7 +1555,7 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node) macro->count = 0; macro->fun_like = 0; /* To suppress some diagnostics. */ - macro->syshdr = pfile->map->sysp != 0; + macro->syshdr = pfile->buffer && pfile->buffer->sysp != 0; if (CPP_OPTION (pfile, traditional)) ok = _cpp_create_trad_definition (pfile, macro); @@ -1505,7 +1567,7 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node) /* Restore lexer position because of games lex_expansion_token() plays lexing the macro. We set the type for SEEN_EOL() in - cpplib.c. + directives.c. Longer term we should lex the whole line before coming here, and just copy the expansion. */ @@ -1652,7 +1714,8 @@ cpp_macro_definition (cpp_reader *pfile, const cpp_hashnode *node) if (len > pfile->macro_buffer_len) { - pfile->macro_buffer = xrealloc (pfile->macro_buffer, len); + pfile->macro_buffer = XRESIZEVEC (unsigned char, + pfile->macro_buffer, len); pfile->macro_buffer_len = len; } @@ -1712,7 +1775,7 @@ cpp_macro_definition (cpp_reader *pfile, const cpp_hashnode *node) buffer += NODE_LEN (macro->params[token->val.arg_no - 1]); } else - buffer = cpp_spell_token (pfile, token, buffer); + buffer = cpp_spell_token (pfile, token, buffer, false); if (token->flags & PASTE_LEFT) { diff --git a/support/cpp2/mkdeps.c b/support/cpp2/libcpp/mkdeps.c similarity index 99% rename from support/cpp2/mkdeps.c rename to support/cpp2/libcpp/mkdeps.c index d50d2bf7..31feb826 100644 --- a/support/cpp2/mkdeps.c +++ b/support/cpp2/libcpp/mkdeps.c @@ -23,8 +23,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "config.h" #include "system.h" #include "mkdeps.h" -#include "cpplib.h" -#include "cpphash.h" +#include "internal.h" /* Keep this structure local to this file, so clients don't find it easy to start making assumptions. */ diff --git a/support/cpp2/hashtable.c b/support/cpp2/libcpp/symtab.c similarity index 84% rename from support/cpp2/hashtable.c rename to support/cpp2/libcpp/symtab.c index 58f19d05..ffa28f5f 100644 --- a/support/cpp2/hashtable.c +++ b/support/cpp2/libcpp/symtab.c @@ -1,5 +1,5 @@ /* Hash tables. - Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc. + Copyright (C) 2000, 2001, 2003, 2004 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 @@ -13,7 +13,7 @@ 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. +Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 @@ -21,7 +21,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "config.h" #include "system.h" -#include "hashtable.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 @@ -41,13 +41,11 @@ calc_hash (const unsigned char *str, size_t len) { size_t n = len; unsigned int r = 0; -#define HASHSTEP(r, c) ((r) * 67 + ((c) - 113)); while (n--) - r = HASHSTEP (r, *str++); + r = HT_HASHSTEP (r, *str++); - return r + len; -#undef HASHSTEP + return HT_HASHFINISH (r, len); } /* Initialize an identifier hashtable. */ @@ -58,7 +56,7 @@ ht_create (unsigned int order) unsigned int nslots = 1 << order; hash_table *table; - table = xcalloc (1, sizeof (hash_table)); + table = XCNEW (hash_table); /* Strings need no alignment. */ _obstack_begin (&table->stack, 0, 0, @@ -67,7 +65,8 @@ ht_create (unsigned int order) obstack_alignment_mask (&table->stack) = 0; - table->entries = xcalloc (nslots, sizeof (hashnode)); + table->entries = XCNEWVEC (hashnode, nslots); + table->entries_owned = true; table->nslots = nslots; return table; } @@ -78,7 +77,8 @@ void ht_destroy (hash_table *table) { obstack_free (&table->stack, NULL); - free (table->entries); + if (table->entries_owned) + free (table->entries); free (table); } @@ -94,7 +94,15 @@ hashnode ht_lookup (hash_table *table, const unsigned char *str, size_t len, enum ht_lookup_option insert) { - unsigned int hash = calc_hash (str, len); + 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; size_t sizemask; @@ -153,7 +161,8 @@ ht_lookup (hash_table *table, const unsigned char *str, size_t len, HT_LEN (node) = (unsigned int) len; node->hash_value = hash; if (insert == HT_ALLOC) - HT_STR (node) = obstack_copy0 (&table->stack, str, len); + HT_STR (node) = (const unsigned char *) obstack_copy0 (&table->stack, + str, len); else HT_STR (node) = str; @@ -173,7 +182,7 @@ ht_expand (hash_table *table) unsigned int size, sizemask; size = table->nslots * 2; - nentries = xcalloc (size, sizeof (hashnode)); + nentries = XCNEWVEC (hashnode, size); sizemask = size - 1; p = table->entries; @@ -199,7 +208,9 @@ ht_expand (hash_table *table) } while (++p < limit); - free (table->entries); + if (table->entries_owned) + free (table->entries); + table->entries_owned = true; table->entries = nentries; table->nslots = size; } @@ -222,14 +233,28 @@ ht_forall (hash_table *table, ht_cb cb, const void *v) 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, sum_of_squares; - double exp_len, exp_len2, exp2_len; + size_t total_bytes, longest; + double sum_of_squares, exp_len, exp_len2, exp2_len; hashnode *p, *limit; #define SCALE(x) ((unsigned long) ((x) < 1024*10 \ @@ -248,7 +273,7 @@ ht_dump_statistics (hash_table *table) size_t n = HT_LEN (*p); total_bytes += n; - sum_of_squares += n * n; + sum_of_squares += (double) n * n; if (n > longest) longest = n; nids++; diff --git a/support/cpp2/libcpp/system.h b/support/cpp2/libcpp/system.h new file mode 100644 index 00000000..3e0d89da --- /dev/null +++ b/support/cpp2/libcpp/system.h @@ -0,0 +1,437 @@ +/* Get common system includes and various definitions and declarations based + on autoconf macros. + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 + Free Software Foundation, Inc. + +This file is part of libcpp (aka cpplib). + +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. */ + + +#ifndef LIBCPP_SYSTEM_H +#define LIBCPP_SYSTEM_H + +/* We must include stdarg.h before stdio.h. */ +#include + +#ifdef HAVE_STDDEF_H +# include +#endif + +#include + +/* Define a generic NULL if one hasn't already been defined. */ +#ifndef NULL +#define NULL 0 +#endif + +/* Use the unlocked open routines from libiberty. */ +#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 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 + +#endif + +/* ??? Glibc's fwrite/fread_unlocked macros cause + "warning: signed and unsigned type in conditional expression". */ +#undef fread_unlocked +#undef fwrite_unlocked + +#include +#include + +#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 +# include +#else +# ifdef HAVE_STRING_H +# include +# else +# ifdef HAVE_STRINGS_H +# include +# endif +# endif +#endif + +#ifdef HAVE_STDLIB_H +# include +#endif + +#ifdef HAVE_UNISTD_H +# include +#endif + +#if HAVE_LIMITS_H +# include +#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 +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# ifdef HAVE_TIME_H +# include +# endif +# endif +#endif + +#ifdef HAVE_FCNTL_H +# include +#else +# ifdef HAVE_SYS_FILE_H +# include +# endif +#endif + +#ifdef HAVE_LOCALE_H +# include +#endif + +#ifdef HAVE_LANGINFO_CODESET +# include +#endif + +#ifndef HAVE_SETLOCALE +# define setlocale(category, locale) (locale) +#endif + +#ifdef ENABLE_NLS +#include +#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_*)". */ + +#if defined (HAVE_DECL_ABORT) && !HAVE_DECL_ABORT +extern void abort (void); +#endif + +#if HAVE_SYS_STAT_H +# include +#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" +#if defined(__APPLE__) && defined(__MACH__) +#include +#else +#include +#endif + +/* 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) +#if defined(__APPLE__) && (__MACH__) +#define HAVE_DESIGNATED_INITIALIZERS 0 +#else +#define HAVE_DESIGNATED_INITIALIZERS \ + ((!defined(__cplusplus) && (GCC_VERSION >= 2007)) \ + || (__STDC_VERSION__ >= 199901L)) +#endif +#endif + +/* Be conservative and only use enum bitfields with GCC. + FIXME: provide a complete autoconf test for buggy enum bitfields. */ + +#if (GCC_VERSION > 2000) +#define ENUM_BITFIELD(TYPE) __extension__ enum TYPE +#else +#define ENUM_BITFIELD(TYPE) unsigned int +#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/cpp2/cpptrad.c b/support/cpp2/libcpp/traditional.c similarity index 96% rename from support/cpp2/cpptrad.c rename to support/cpp2/libcpp/traditional.c index 6315b107..a543348d 100644 --- a/support/cpp2/cpptrad.c +++ b/support/cpp2/libcpp/traditional.c @@ -1,5 +1,5 @@ /* CPP Library - traditional lexical analysis and macro expansion. - Copyright (C) 2002, 2004 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. Contributed by Neil Booth, May 2002 This program is free software; you can redistribute it and/or modify it @@ -14,12 +14,12 @@ 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. */ +Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #include "system.h" #include "cpplib.h" -#include "cpphash.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 @@ -76,7 +76,7 @@ enum ls {ls_none = 0, /* Normal state. */ ls_predicate, /* After the predicate, maybe paren? */ ls_answer}; /* In answer to predicate. */ -/* Lexing TODO: Maybe handle space in escaped newlines. Stop cpplex.c +/* 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); @@ -107,7 +107,7 @@ check_output_buffer (cpp_reader *pfile, size_t n) size_t size = pfile->out.cur - pfile->out.base; size_t new_size = (size + n) * 3 / 2; - pfile->out.base = xrealloc (pfile->out.base, new_size); + 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; } @@ -148,7 +148,7 @@ static const uchar * copy_comment (cpp_reader *pfile, const uchar *cur, int in_define) { bool unterminated, copy = false; - unsigned int from_line = pfile->line; + source_location src_loc = pfile->line_table->highest_line; cpp_buffer *buffer = pfile->buffer; buffer->cur = cur; @@ -158,7 +158,7 @@ copy_comment (cpp_reader *pfile, const uchar *cur, int in_define) unterminated = _cpp_skip_block_comment (pfile); if (unterminated) - cpp_error_with_line (pfile, CPP_DL_ERROR, from_line, 0, + cpp_error_with_line (pfile, CPP_DL_ERROR, src_loc, 0, "unterminated comment"); /* Comments in directives become spaces so that tokens are properly @@ -268,13 +268,13 @@ _cpp_overlay_buffer (cpp_reader *pfile, const uchar *start, size_t len) cpp_buffer *buffer = pfile->buffer; pfile->overlaid_buffer = buffer; - buffer->saved_cur = buffer->cur; - buffer->saved_rlimit = buffer->rlimit; - /* Prevent the ISO lexer from scanning a fresh line. */ - pfile->saved_line = pfile->line--; + 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; } @@ -284,12 +284,12 @@ _cpp_remove_overlay (cpp_reader *pfile) { cpp_buffer *buffer = pfile->overlaid_buffer; - buffer->cur = buffer->saved_cur; - buffer->rlimit = buffer->saved_rlimit; + 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; - pfile->line = pfile->saved_line; } /* Reads a logical line into the output buffer. Returns TRUE if there @@ -359,7 +359,7 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro) CUR (pfile->context) = pfile->buffer->cur; RLIMIT (pfile->context) = pfile->buffer->rlimit; pfile->out.cur = pfile->out.base; - pfile->out.first_line = pfile->line; + 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; @@ -404,7 +404,7 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro) pfile->out.cur = out - 1; pfile->buffer->cur = cur; pfile->buffer->need_line = true; - pfile->line++; + CPP_INCREMENT_LINE (pfile, 0); if ((lex_state == ls_fun_open || lex_state == ls_fun_close) && !pfile->state.in_directive @@ -487,7 +487,7 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro) { maybe_start_funlike (pfile, node, out_start, &fmacro); lex_state = ls_fun_open; - fmacro.line = pfile->line; + fmacro.line = pfile->line_table->highest_line; continue; } else if (!recursive_macro (pfile, node)) @@ -605,7 +605,7 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro) /* Null directive. Ignore it and don't invalidate the MI optimization. */ pfile->buffer->need_line = true; - pfile->line++; + CPP_INCREMENT_LINE (pfile, 0); result = false; goto done; } @@ -701,6 +701,7 @@ push_replacement_text (cpp_reader *pfile, cpp_hashnode *node) cpp_macro *macro = node->value.macro; macro->used = 1; text = macro->exp.text; + macro->traditional = 1; len = macro->count; } @@ -934,6 +935,7 @@ save_replacement_text (cpp_reader *pfile, cpp_macro *macro, memcpy (exp, pfile->out.base, len); exp[len] = '\n'; macro->exp.text = exp; + macro->traditional = 1; macro->count = len; } else @@ -949,6 +951,7 @@ save_replacement_text (cpp_reader *pfile, cpp_macro *macro, 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; @@ -1066,7 +1069,7 @@ bool _cpp_expansions_different_trad (const cpp_macro *macro1, const cpp_macro *macro2) { - uchar *p1 = xmalloc (macro1->count + macro2->count); + uchar *p1 = XNEWVEC (uchar, macro1->count + macro2->count); uchar *p2 = p1 + macro1->count; uchar quote1 = 0, quote2 = 0; bool mismatch; diff --git a/support/cpp2/libcpp/ucnid.h b/support/cpp2/libcpp/ucnid.h new file mode 100644 index 00000000..7323dccb --- /dev/null +++ b/support/cpp2/libcpp/ucnid.h @@ -0,0 +1,801 @@ +/* Unicode characters and various properties. + Copyright (C) 2003, 2005 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. + + + 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/cpp2/libiberty/fopen_unlocked.c b/support/cpp2/libiberty/fopen_unlocked.c new file mode 100644 index 00000000..3c3cefed --- /dev/null +++ b/support/cpp2/libiberty/fopen_unlocked.c @@ -0,0 +1,126 @@ +/* Implement fopen_unlocked and related functions. + Copyright (C) 2005 Free Software Foundation, Inc. + Written by Kaveh R. Ghazi . + +This file is part of the libiberty library. +Libiberty is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +Libiberty is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with libiberty; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ + +/* + +@deftypefn Extension void unlock_stream (FILE * @var{stream}) + +If the OS supports it, ensure that the supplied stream is setup to +avoid any multi-threaded locking. Otherwise leave the @code{FILE} +pointer unchanged. If the @var{stream} is @code{NULL} do nothing. + +@end deftypefn + +@deftypefn Extension void unlock_std_streams (void) + +If the OS supports it, ensure that the standard I/O streams, +@code{stdin}, @code{stdout} and @code{stderr} are setup to avoid any +multi-threaded locking. Otherwise do nothing. + +@end deftypefn + +@deftypefn Extension {FILE *} fopen_unlocked (const char *@var{path}, const char * @var{mode}) + +Opens and returns a @code{FILE} pointer via @code{fopen}. If the +operating system supports it, ensure that the stream is setup to avoid +any multi-threaded locking. Otherwise return the @code{FILE} pointer +unchanged. + +@end deftypefn + +@deftypefn Extension {FILE *} fdopen_unlocked (int @var{fildes}, const char * @var{mode}) + +Opens and returns a @code{FILE} pointer via @code{fdopen}. If the +operating system supports it, ensure that the stream is setup to avoid +any multi-threaded locking. Otherwise return the @code{FILE} pointer +unchanged. + +@end deftypefn + +@deftypefn Extension {FILE *} freopen_unlocked (const char * @var{path}, const char * @var{mode}, FILE * @var{stream}) + +Opens and returns a @code{FILE} pointer via @code{freopen}. If the +operating system supports it, ensure that the stream is setup to avoid +any multi-threaded locking. Otherwise return the @code{FILE} pointer +unchanged. + +@end deftypefn + +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include +#ifdef HAVE_STDIO_EXT_H +#include +#endif + +#include "libiberty.h" + +/* This is an inline helper function to consolidate attempts to unlock + a stream. */ + +static inline void +unlock_1 (FILE *const fp ATTRIBUTE_UNUSED) +{ +#if defined(HAVE___FSETLOCKING) && defined(FSETLOCKING_BYCALLER) + if (fp) + __fsetlocking (fp, FSETLOCKING_BYCALLER); +#endif +} + +void +unlock_stream (FILE *fp) +{ + unlock_1 (fp); +} + +void +unlock_std_streams (void) +{ + unlock_1 (stdin); + unlock_1 (stdout); + unlock_1 (stderr); +} + +FILE * +fopen_unlocked (const char *path, const char *mode) +{ + FILE *const fp = fopen (path, mode); + unlock_1 (fp); + return fp; +} + +FILE * +fdopen_unlocked (int fildes, const char *mode) +{ + FILE *const fp = fdopen (fildes, mode); + unlock_1 (fp); + return fp; +} + +FILE * +freopen_unlocked (const char *path, const char *mode, FILE *stream) +{ + FILE *const fp = freopen (path, mode, stream); + unlock_1 (fp); + return fp; +} diff --git a/support/cpp2/hashtab.c b/support/cpp2/libiberty/hashtab.c similarity index 60% rename from support/cpp2/hashtab.c rename to support/cpp2/libiberty/hashtab.c index 231fbc0d..a5671a0a 100644 --- a/support/cpp2/hashtab.c +++ b/support/cpp2/libiberty/hashtab.c @@ -1,5 +1,6 @@ /* An expandable hash tables datatype. - Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 + Free Software Foundation, Inc. Contributed by Vladimir Makarov (vmakarov@cygnus.com). This file is part of the libiberty library. @@ -15,8 +16,8 @@ Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ /* This package implements basic hash table functionality. It is possible to search for an entry, create an entry and destroy an entry. @@ -40,34 +41,37 @@ Boston, MA 02111-1307, USA. */ #ifdef HAVE_STDLIB_H #include #endif - #ifdef HAVE_STRING_H #include #endif - #ifdef HAVE_MALLOC_H #include #endif +#ifdef HAVE_LIMITS_H +#include +#endif +#ifdef HAVE_STDINT_H +#include +#endif #include #include "libiberty.h" +#include "ansidecl.h" #include "hashtab.h" -/* This macro defines reserved value for empty table entry. */ - -#define EMPTY_ENTRY ((PTR) 0) - -/* This macro defines reserved value for table entry which contained - a deleted element. */ - -#define DELETED_ENTRY ((PTR) 1) +#ifndef CHAR_BIT +#define CHAR_BIT 8 +#endif -static unsigned long higher_prime_number PARAMS ((unsigned long)); -static hashval_t hash_pointer PARAMS ((const void *)); -static int eq_pointer PARAMS ((const void *, const void *)); -static int htab_expand PARAMS ((htab_t)); -static PTR *find_empty_slot_for_expand PARAMS ((htab_t, hashval_t)); +static unsigned int higher_prime_index (unsigned long); +static hashval_t htab_mod_1 (hashval_t, hashval_t, hashval_t, int); +static hashval_t htab_mod (hashval_t, htab_t); +static hashval_t htab_mod_m2 (hashval_t, htab_t); +static hashval_t hash_pointer (const void *); +static int eq_pointer (const void *, const void *); +static int htab_expand (htab_t); +static PTR *find_empty_slot_for_expand (htab_t, hashval_t); /* At some point, we could make these be NULL, and modify the hash-table routines to handle NULL specially; that would avoid @@ -75,76 +79,122 @@ static PTR *find_empty_slot_for_expand PARAMS ((htab_t, hashval_t)); htab_hash htab_hash_pointer = hash_pointer; htab_eq htab_eq_pointer = eq_pointer; -/* The following function returns a nearest prime number which is - greater than N, and near a power of two. */ - -static unsigned long -higher_prime_number (n) - unsigned long n; -{ - /* These are primes that are near, but slightly smaller than, a - power of two. */ - static const unsigned long primes[] = { - (unsigned long) 7, - (unsigned long) 13, - (unsigned long) 31, - (unsigned long) 61, - (unsigned long) 127, - (unsigned long) 251, - (unsigned long) 509, - (unsigned long) 1021, - (unsigned long) 2039, - (unsigned long) 4093, - (unsigned long) 8191, - (unsigned long) 16381, - (unsigned long) 32749, - (unsigned long) 65521, - (unsigned long) 131071, - (unsigned long) 262139, - (unsigned long) 524287, - (unsigned long) 1048573, - (unsigned long) 2097143, - (unsigned long) 4194301, - (unsigned long) 8388593, - (unsigned long) 16777213, - (unsigned long) 33554393, - (unsigned long) 67108859, - (unsigned long) 134217689, - (unsigned long) 268435399, - (unsigned long) 536870909, - (unsigned long) 1073741789, - (unsigned long) 2147483647, - /* 4294967291L */ - ((unsigned long) 2147483647) + ((unsigned long) 2147483644), - }; - - const unsigned long *low = &primes[0]; - const unsigned long *high = &primes[sizeof(primes) / sizeof(primes[0])]; +/* Table of primes and multiplicative inverses. + + Note that these are not minimally reduced inverses. Unlike when generating + code to divide by a constant, we want to be able to use the same algorithm + all the time. All of these inverses (are implied to) have bit 32 set. + + For the record, here's the function that computed the table; it's a + vastly simplified version of the function of the same name from gcc. */ + +#if 0 +unsigned int +ceil_log2 (unsigned int x) +{ + int i; + for (i = 31; i >= 0 ; --i) + if (x > (1u << i)) + return i+1; + abort (); +} + +unsigned int +choose_multiplier (unsigned int d, unsigned int *mlp, unsigned char *shiftp) +{ + unsigned long long mhigh; + double nx; + int lgup, post_shift; + int pow, pow2; + int n = 32, precision = 32; + + lgup = ceil_log2 (d); + pow = n + lgup; + pow2 = n + lgup - precision; + + nx = ldexp (1.0, pow) + ldexp (1.0, pow2); + mhigh = nx / d; + + *shiftp = lgup - 1; + *mlp = mhigh; + return mhigh >> 32; +} +#endif + +struct prime_ent +{ + hashval_t prime; + hashval_t inv; + hashval_t inv_m2; /* inverse of prime-2 */ + hashval_t shift; +}; + +static struct prime_ent const prime_tab[] = { + { 7, 0x24924925, 0x9999999b, 2 }, + { 13, 0x3b13b13c, 0x745d1747, 3 }, + { 31, 0x08421085, 0x1a7b9612, 4 }, + { 61, 0x0c9714fc, 0x15b1e5f8, 5 }, + { 127, 0x02040811, 0x0624dd30, 6 }, + { 251, 0x05197f7e, 0x073260a5, 7 }, + { 509, 0x01824366, 0x02864fc8, 8 }, + { 1021, 0x00c0906d, 0x014191f7, 9 }, + { 2039, 0x0121456f, 0x0161e69e, 10 }, + { 4093, 0x00300902, 0x00501908, 11 }, + { 8191, 0x00080041, 0x00180241, 12 }, + { 16381, 0x000c0091, 0x00140191, 13 }, + { 32749, 0x002605a5, 0x002a06e6, 14 }, + { 65521, 0x000f00e2, 0x00110122, 15 }, + { 131071, 0x00008001, 0x00018003, 16 }, + { 262139, 0x00014002, 0x0001c004, 17 }, + { 524287, 0x00002001, 0x00006001, 18 }, + { 1048573, 0x00003001, 0x00005001, 19 }, + { 2097143, 0x00004801, 0x00005801, 20 }, + { 4194301, 0x00000c01, 0x00001401, 21 }, + { 8388593, 0x00001e01, 0x00002201, 22 }, + { 16777213, 0x00000301, 0x00000501, 23 }, + { 33554393, 0x00001381, 0x00001481, 24 }, + { 67108859, 0x00000141, 0x000001c1, 25 }, + { 134217689, 0x000004e1, 0x00000521, 26 }, + { 268435399, 0x00000391, 0x000003b1, 27 }, + { 536870909, 0x00000019, 0x00000029, 28 }, + { 1073741789, 0x0000008d, 0x00000095, 29 }, + { 2147483647, 0x00000003, 0x00000007, 30 }, + /* Avoid "decimal constant so large it is unsigned" for 4294967291. */ + { 0xfffffffb, 0x00000006, 0x00000008, 31 } +}; + +/* The following function returns an index into the above table of the + nearest prime number which is greater than N, and near a power of two. */ + +static unsigned int +higher_prime_index (unsigned long n) +{ + unsigned int low = 0; + unsigned int high = sizeof(prime_tab) / sizeof(prime_tab[0]); while (low != high) { - const unsigned long *mid = low + (high - low) / 2; - if (n > *mid) + unsigned int mid = low + (high - low) / 2; + if (n > prime_tab[mid].prime) low = mid + 1; else high = mid; } /* If we've run out of primes, abort. */ - if (n > *low) + if (n > prime_tab[low].prime) { fprintf (stderr, "Cannot find prime bigger than %lu\n", n); abort (); } - return *low; + return low; } /* Returns a hash code for P. */ static hashval_t -hash_pointer (p) - const PTR p; +hash_pointer (const PTR p) { return (hashval_t) ((long)p >> 3); } @@ -152,30 +202,98 @@ hash_pointer (p) /* Returns non-zero if P1 and P2 are equal. */ static int -eq_pointer (p1, p2) - const PTR p1; - const PTR p2; +eq_pointer (const PTR p1, const PTR p2) { return p1 == p2; } + +/* The parens around the function names in the next two definitions + are essential in order to prevent macro expansions of the name. + The bodies, however, are expanded as expected, so they are not + recursive definitions. */ + +/* Return the current size of given hash table. */ + +#define htab_size(htab) ((htab)->size) + +size_t +(htab_size) (htab_t htab) +{ + return htab_size (htab); +} + +/* Return the current number of elements in given hash table. */ + +#define htab_elements(htab) ((htab)->n_elements - (htab)->n_deleted) + +size_t +(htab_elements) (htab_t htab) +{ + return htab_elements (htab); +} + +/* Return X % Y. */ + +static inline hashval_t +htab_mod_1 (hashval_t x, hashval_t y, hashval_t inv, int shift) +{ + /* The multiplicative inverses computed above are for 32-bit types, and + requires that we be able to compute a highpart multiply. */ +#ifdef UNSIGNED_64BIT_TYPE + __extension__ typedef UNSIGNED_64BIT_TYPE ull; + if (sizeof (hashval_t) * CHAR_BIT <= 32) + { + hashval_t t1, t2, t3, t4, q, r; + + t1 = ((ull)x * inv) >> 32; + t2 = x - t1; + t3 = t2 >> 1; + t4 = t1 + t3; + q = t4 >> shift; + r = x - (q * y); + + return r; + } +#endif + + /* Otherwise just use the native division routines. */ + return x % y; +} + +/* Compute the primary hash for HASH given HTAB's current size. */ + +static inline hashval_t +htab_mod (hashval_t hash, htab_t htab) +{ + const struct prime_ent *p = &prime_tab[htab->size_prime_index]; + return htab_mod_1 (hash, p->prime, p->inv, p->shift); +} + +/* Compute the secondary hash for HASH given HTAB's current size. */ + +static inline hashval_t +htab_mod_m2 (hashval_t hash, htab_t htab) +{ + const struct prime_ent *p = &prime_tab[htab->size_prime_index]; + return 1 + htab_mod_1 (hash, p->prime - 2, p->inv_m2, p->shift); +} + /* This function creates table with length slightly longer than given source length. Created hash table is initiated as empty (all the - hash table entries are EMPTY_ENTRY). The function returns the + hash table entries are HTAB_EMPTY_ENTRY). The function returns the created hash table, or NULL if memory allocation fails. */ htab_t -htab_create_alloc (size, hash_f, eq_f, del_f, alloc_f, free_f) - size_t size; - htab_hash hash_f; - htab_eq eq_f; - htab_del del_f; - htab_alloc alloc_f; - htab_free free_f; +htab_create_alloc (size_t size, htab_hash hash_f, htab_eq eq_f, + htab_del del_f, htab_alloc alloc_f, htab_free free_f) { htab_t result; + unsigned int size_prime_index; + + size_prime_index = higher_prime_index (size); + size = prime_tab[size_prime_index].prime; - size = higher_prime_number (size); result = (htab_t) (*alloc_f) (1, sizeof (struct htab)); if (result == NULL) return NULL; @@ -187,6 +305,7 @@ htab_create_alloc (size, hash_f, eq_f, del_f, alloc_f, free_f) return NULL; } result->size = size; + result->size_prime_index = size_prime_index; result->hash_f = hash_f; result->eq_f = eq_f; result->del_f = del_f; @@ -199,19 +318,17 @@ htab_create_alloc (size, hash_f, eq_f, del_f, alloc_f, free_f) an extra argument. */ htab_t -htab_create_alloc_ex (size, hash_f, eq_f, del_f, alloc_arg, alloc_f, - free_f) - size_t size; - htab_hash hash_f; - htab_eq eq_f; - htab_del del_f; - PTR alloc_arg; - htab_alloc_with_arg alloc_f; - htab_free_with_arg free_f; +htab_create_alloc_ex (size_t size, htab_hash hash_f, htab_eq eq_f, + htab_del del_f, void *alloc_arg, + htab_alloc_with_arg alloc_f, + htab_free_with_arg free_f) { htab_t result; + unsigned int size_prime_index; + + size_prime_index = higher_prime_index (size); + size = prime_tab[size_prime_index].prime; - size = higher_prime_number (size); result = (htab_t) (*alloc_f) (alloc_arg, 1, sizeof (struct htab)); if (result == NULL) return NULL; @@ -223,6 +340,7 @@ htab_create_alloc_ex (size, hash_f, eq_f, del_f, alloc_arg, alloc_f, return NULL; } result->size = size; + result->size_prime_index = size_prime_index; result->hash_f = hash_f; result->eq_f = eq_f; result->del_f = del_f; @@ -235,14 +353,9 @@ htab_create_alloc_ex (size, hash_f, eq_f, del_f, alloc_arg, alloc_f, /* Update the function pointers and allocation parameter in the htab_t. */ void -htab_set_functions_ex (htab, hash_f, eq_f, del_f, alloc_arg, alloc_f, free_f) - htab_t htab; - htab_hash hash_f; - htab_eq eq_f; - htab_del del_f; - PTR alloc_arg; - htab_alloc_with_arg alloc_f; - htab_free_with_arg free_f; +htab_set_functions_ex (htab_t htab, htab_hash hash_f, htab_eq eq_f, + htab_del del_f, PTR alloc_arg, + htab_alloc_with_arg alloc_f, htab_free_with_arg free_f) { htab->hash_f = hash_f; htab->eq_f = eq_f; @@ -256,21 +369,13 @@ htab_set_functions_ex (htab, hash_f, eq_f, del_f, alloc_arg, alloc_f, free_f) #undef htab_create htab_t -htab_create (size, hash_f, eq_f, del_f) - size_t size; - htab_hash hash_f; - htab_eq eq_f; - htab_del del_f; +htab_create (size_t size, htab_hash hash_f, htab_eq eq_f, htab_del del_f) { return htab_create_alloc (size, hash_f, eq_f, del_f, xcalloc, free); } htab_t -htab_try_create (size, hash_f, eq_f, del_f) - size_t size; - htab_hash hash_f; - htab_eq eq_f; - htab_del del_f; +htab_try_create (size_t size, htab_hash hash_f, htab_eq eq_f, htab_del del_f) { return htab_create_alloc (size, hash_f, eq_f, del_f, calloc, free); } @@ -279,25 +384,25 @@ htab_try_create (size, hash_f, eq_f, del_f) Naturally the hash table must already exist. */ void -htab_delete (htab) - htab_t htab; +htab_delete (htab_t htab) { + size_t size = htab_size (htab); + PTR *entries = htab->entries; int i; if (htab->del_f) - for (i = htab->size - 1; i >= 0; i--) - if (htab->entries[i] != EMPTY_ENTRY - && htab->entries[i] != DELETED_ENTRY) - (*htab->del_f) (htab->entries[i]); + for (i = size - 1; i >= 0; i--) + if (entries[i] != HTAB_EMPTY_ENTRY && entries[i] != HTAB_DELETED_ENTRY) + (*htab->del_f) (entries[i]); if (htab->free_f != NULL) { - (*htab->free_f) (htab->entries); + (*htab->free_f) (entries); (*htab->free_f) (htab); } else if (htab->free_with_arg_f != NULL) { - (*htab->free_with_arg_f) (htab->alloc_arg, htab->entries); + (*htab->free_with_arg_f) (htab->alloc_arg, entries); (*htab->free_with_arg_f) (htab->alloc_arg, htab); } } @@ -305,18 +410,18 @@ htab_delete (htab) /* This function clears all entries in the given hash table. */ void -htab_empty (htab) - htab_t htab; +htab_empty (htab_t htab) { + size_t size = htab_size (htab); + PTR *entries = htab->entries; int i; if (htab->del_f) - for (i = htab->size - 1; i >= 0; i--) - if (htab->entries[i] != EMPTY_ENTRY - && htab->entries[i] != DELETED_ENTRY) - (*htab->del_f) (htab->entries[i]); + for (i = size - 1; i >= 0; i--) + if (entries[i] != HTAB_EMPTY_ENTRY && entries[i] != HTAB_DELETED_ENTRY) + (*htab->del_f) (entries[i]); - memset (htab->entries, 0, htab->size * sizeof (PTR)); + memset (entries, 0, size * sizeof (PTR)); } /* Similar to htab_find_slot, but without several unwanted side effects: @@ -327,21 +432,19 @@ htab_empty (htab) HASH is the hash value for the element to be inserted. */ static PTR * -find_empty_slot_for_expand (htab, hash) - htab_t htab; - hashval_t hash; +find_empty_slot_for_expand (htab_t htab, hashval_t hash) { - size_t size = htab->size; - unsigned int index = hash % size; + hashval_t index = htab_mod (hash, htab); + size_t size = htab_size (htab); PTR *slot = htab->entries + index; hashval_t hash2; - if (*slot == EMPTY_ENTRY) + if (*slot == HTAB_EMPTY_ENTRY) return slot; - else if (*slot == DELETED_ENTRY) + else if (*slot == HTAB_DELETED_ENTRY) abort (); - hash2 = 1 + hash % (size - 2); + hash2 = htab_mod_m2 (hash, htab); for (;;) { index += hash2; @@ -349,9 +452,9 @@ find_empty_slot_for_expand (htab, hash) index -= size; slot = htab->entries + index; - if (*slot == EMPTY_ENTRY) + if (*slot == HTAB_EMPTY_ENTRY) return slot; - else if (*slot == DELETED_ENTRY) + else if (*slot == HTAB_DELETED_ENTRY) abort (); } } @@ -365,26 +468,33 @@ find_empty_slot_for_expand (htab, hash) expanded. If all goes well, it will return a non-zero value. */ static int -htab_expand (htab) - htab_t htab; +htab_expand (htab_t htab) { PTR *oentries; PTR *olimit; PTR *p; PTR *nentries; - size_t nsize; + size_t nsize, osize, elts; + unsigned int oindex, nindex; oentries = htab->entries; - olimit = oentries + htab->size; + oindex = htab->size_prime_index; + osize = htab->size; + olimit = oentries + osize; + elts = htab_elements (htab); /* Resize only when table after removal of unused elements is either too full or too empty. */ - if ((htab->n_elements - htab->n_deleted) * 2 > htab->size - || ((htab->n_elements - htab->n_deleted) * 8 < htab->size - && htab->size > 32)) - nsize = higher_prime_number ((htab->n_elements - htab->n_deleted) * 2); + if (elts * 2 > osize || (elts * 8 < osize && osize > 32)) + { + nindex = higher_prime_index (elts * 2); + nsize = prime_tab[nindex].prime; + } else - nsize = htab->size; + { + nindex = oindex; + nsize = osize; + } if (htab->alloc_with_arg_f != NULL) nentries = (PTR *) (*htab->alloc_with_arg_f) (htab->alloc_arg, nsize, @@ -395,7 +505,7 @@ htab_expand (htab) return 0; htab->entries = nentries; htab->size = nsize; - + htab->size_prime_index = nindex; htab->n_elements -= htab->n_deleted; htab->n_deleted = 0; @@ -404,7 +514,7 @@ htab_expand (htab) { PTR x = *p; - if (x != EMPTY_ENTRY && x != DELETED_ENTRY) + if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY) { PTR *q = find_empty_slot_for_expand (htab, (*htab->hash_f) (x)); @@ -426,27 +536,22 @@ htab_expand (htab) element. It cannot be used to insert or delete an element. */ PTR -htab_find_with_hash (htab, element, hash) - htab_t htab; - const PTR element; - hashval_t hash; +htab_find_with_hash (htab_t htab, const PTR element, hashval_t hash) { - unsigned int index; - hashval_t hash2; + hashval_t index, hash2; size_t size; PTR entry; htab->searches++; - size = htab->size; - index = hash % size; + size = htab_size (htab); + index = htab_mod (hash, htab); entry = htab->entries[index]; - if (entry == EMPTY_ENTRY - || (entry != DELETED_ENTRY && (*htab->eq_f) (entry, element))) + if (entry == HTAB_EMPTY_ENTRY + || (entry != HTAB_DELETED_ENTRY && (*htab->eq_f) (entry, element))) return entry; - hash2 = 1 + hash % (size - 2); - + hash2 = htab_mod_m2 (hash, htab); for (;;) { htab->collisions++; @@ -455,8 +560,8 @@ htab_find_with_hash (htab, element, hash) index -= size; entry = htab->entries[index]; - if (entry == EMPTY_ENTRY - || (entry != DELETED_ENTRY && (*htab->eq_f) (entry, element))) + if (entry == HTAB_EMPTY_ENTRY + || (entry != HTAB_DELETED_ENTRY && (*htab->eq_f) (entry, element))) return entry; } } @@ -465,53 +570,50 @@ htab_find_with_hash (htab, element, hash) element. */ PTR -htab_find (htab, element) - htab_t htab; - const PTR element; +htab_find (htab_t htab, const PTR element) { return htab_find_with_hash (htab, element, (*htab->hash_f) (element)); } /* This function searches for a hash table slot containing an entry equal to the given element. To delete an entry, call this with - INSERT = 0, then call htab_clear_slot on the slot returned (possibly - after doing some checks). To insert an entry, call this with - INSERT = 1, then write the value you want into the returned slot. - When inserting an entry, NULL may be returned if memory allocation - fails. */ + insert=NO_INSERT, then call htab_clear_slot on the slot returned + (possibly after doing some checks). To insert an entry, call this + with insert=INSERT, then write the value you want into the returned + slot. When inserting an entry, NULL may be returned if memory + allocation fails. */ PTR * -htab_find_slot_with_hash (htab, element, hash, insert) - htab_t htab; - const PTR element; - hashval_t hash; - enum insert_option insert; +htab_find_slot_with_hash (htab_t htab, const PTR element, + hashval_t hash, enum insert_option insert) { PTR *first_deleted_slot; - unsigned int index; - hashval_t hash2; + hashval_t index, hash2; size_t size; PTR entry; - if (insert == INSERT && htab->size * 3 <= htab->n_elements * 4 - && htab_expand (htab) == 0) - return NULL; + size = htab_size (htab); + if (insert == INSERT && size * 3 <= htab->n_elements * 4) + { + if (htab_expand (htab) == 0) + return NULL; + size = htab_size (htab); + } - size = htab->size; - index = hash % size; + index = htab_mod (hash, htab); htab->searches++; first_deleted_slot = NULL; entry = htab->entries[index]; - if (entry == EMPTY_ENTRY) + if (entry == HTAB_EMPTY_ENTRY) goto empty_entry; - else if (entry == DELETED_ENTRY) + else if (entry == HTAB_DELETED_ENTRY) first_deleted_slot = &htab->entries[index]; else if ((*htab->eq_f) (entry, element)) return &htab->entries[index]; - hash2 = 1 + hash % (size - 2); + hash2 = htab_mod_m2 (hash, htab); for (;;) { htab->collisions++; @@ -520,9 +622,9 @@ htab_find_slot_with_hash (htab, element, hash, insert) index -= size; entry = htab->entries[index]; - if (entry == EMPTY_ENTRY) + if (entry == HTAB_EMPTY_ENTRY) goto empty_entry; - else if (entry == DELETED_ENTRY) + else if (entry == HTAB_DELETED_ENTRY) { if (!first_deleted_slot) first_deleted_slot = &htab->entries[index]; @@ -538,7 +640,7 @@ htab_find_slot_with_hash (htab, element, hash, insert) if (first_deleted_slot) { htab->n_deleted--; - *first_deleted_slot = EMPTY_ENTRY; + *first_deleted_slot = HTAB_EMPTY_ENTRY; return first_deleted_slot; } @@ -550,34 +652,40 @@ htab_find_slot_with_hash (htab, element, hash, insert) element. */ PTR * -htab_find_slot (htab, element, insert) - htab_t htab; - const PTR element; - enum insert_option insert; +htab_find_slot (htab_t htab, const PTR element, enum insert_option insert) { return htab_find_slot_with_hash (htab, element, (*htab->hash_f) (element), insert); } +/* This function deletes an element with the given value from hash + table (the hash is computed from the element). If there is no matching + element in the hash table, this function does nothing. */ + +void +htab_remove_elt (htab_t htab, PTR element) +{ + htab_remove_elt_with_hash (htab, element, (*htab->hash_f) (element)); +} + + /* This function deletes an element with the given value from hash table. If there is no matching element in the hash table, this function does nothing. */ void -htab_remove_elt (htab, element) - htab_t htab; - PTR element; +htab_remove_elt_with_hash (htab_t htab, PTR element, hashval_t hash) { PTR *slot; - slot = htab_find_slot (htab, element, NO_INSERT); - if (*slot == EMPTY_ENTRY) + slot = htab_find_slot_with_hash (htab, element, hash, NO_INSERT); + if (*slot == HTAB_EMPTY_ENTRY) return; if (htab->del_f) (*htab->del_f) (*slot); - *slot = DELETED_ENTRY; + *slot = HTAB_DELETED_ENTRY; htab->n_deleted++; } @@ -586,18 +694,16 @@ htab_remove_elt (htab, element) again. */ void -htab_clear_slot (htab, slot) - htab_t htab; - PTR *slot; +htab_clear_slot (htab_t htab, PTR *slot) { - if (slot < htab->entries || slot >= htab->entries + htab->size - || *slot == EMPTY_ENTRY || *slot == DELETED_ENTRY) + if (slot < htab->entries || slot >= htab->entries + htab_size (htab) + || *slot == HTAB_EMPTY_ENTRY || *slot == HTAB_DELETED_ENTRY) abort (); if (htab->del_f) (*htab->del_f) (*slot); - *slot = DELETED_ENTRY; + *slot = HTAB_DELETED_ENTRY; htab->n_deleted++; } @@ -607,22 +713,19 @@ htab_clear_slot (htab, slot) argument. */ void -htab_traverse_noresize (htab, callback, info) - htab_t htab; - htab_trav callback; - PTR info; +htab_traverse_noresize (htab_t htab, htab_trav callback, PTR info) { PTR *slot; PTR *limit; - + slot = htab->entries; - limit = slot + htab->size; + limit = slot + htab_size (htab); do { PTR x = *slot; - if (x != EMPTY_ENTRY && x != DELETED_ENTRY) + if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY) if (!(*callback) (slot, info)) break; } @@ -633,41 +736,19 @@ htab_traverse_noresize (htab, callback, info) too empty to improve effectivity of subsequent calls. */ void -htab_traverse (htab, callback, info) - htab_t htab; - htab_trav callback; - PTR info; +htab_traverse (htab_t htab, htab_trav callback, PTR info) { - if ((htab->n_elements - htab->n_deleted) * 8 < htab->size) + if (htab_elements (htab) * 8 < htab_size (htab)) htab_expand (htab); htab_traverse_noresize (htab, callback, info); } -/* Return the current size of given hash table. */ - -size_t -htab_size (htab) - htab_t htab; -{ - return htab->size; -} - -/* Return the current number of elements in given hash table. */ - -size_t -htab_elements (htab) - htab_t htab; -{ - return htab->n_elements - htab->n_deleted; -} - /* Return the fraction of fixed collisions during all work with given hash table. */ double -htab_collisions (htab) - htab_t htab; +htab_collisions (htab_t htab) { if (htab->searches == 0) return 0.0; @@ -701,8 +782,7 @@ htab_collisions (htab) function they just started using for Perl's hashes. */ hashval_t -htab_hash_string (p) - const PTR p; +htab_hash_string (const PTR p) { const unsigned char *str = (const unsigned char *) p; hashval_t r = 0; @@ -791,10 +871,11 @@ acceptable. Do NOT use for cryptographic purposes. -------------------------------------------------------------------- */ -hashval_t iterative_hash (k_in, length, initval) - const PTR k_in; /* the key */ - register size_t length; /* the length of the key */ - register hashval_t initval; /* the previous hash, or an arbitrary value */ +hashval_t +iterative_hash (const PTR k_in /* the key */, + register size_t length /* the length of the key */, + register hashval_t initval /* the previous hash, or + an arbitrary value */) { register const unsigned char *k = (const unsigned char *)k_in; register hashval_t a,b,c,len; diff --git a/support/cpp2/hashtab.h b/support/cpp2/libiberty/hashtab.h similarity index 61% rename from support/cpp2/hashtab.h rename to support/cpp2/libiberty/hashtab.h index f7bd4ae6..77eee14e 100644 --- a/support/cpp2/hashtab.h +++ b/support/cpp2/libiberty/hashtab.h @@ -1,5 +1,5 @@ /* An expandable hash tables datatype. - Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2002, 2003, 2004 Free Software Foundation, Inc. Contributed by Vladimir Makarov (vmakarov@cygnus.com). This program is free software; you can redistribute it and/or modify @@ -14,7 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ /* This package implements basic hash table functionality. It is possible to search for an entry, create an entry and destroy an entry. @@ -48,38 +48,47 @@ typedef unsigned int hashval_t; /* Callback function pointer types. */ /* Calculate hash of a table entry. */ -typedef hashval_t (*htab_hash) PARAMS ((const void *)); +typedef hashval_t (*htab_hash) (const void *); /* Compare a table entry with a possible entry. The entry already in the table always comes first, so the second element can be of a different type (but in this case htab_find and htab_find_slot cannot be used; instead the variants that accept a hash value must be used). */ -typedef int (*htab_eq) PARAMS ((const void *, const void *)); +typedef int (*htab_eq) (const void *, const void *); /* Cleanup function called whenever a live element is removed from the hash table. */ -typedef void (*htab_del) PARAMS ((void *)); +typedef void (*htab_del) (void *); /* Function called by htab_traverse for each live element. The first arg is the slot of the element (which can be passed to htab_clear_slot if desired), the second arg is the auxiliary pointer handed to htab_traverse. Return 1 to continue scan, 0 to stop. */ -typedef int (*htab_trav) PARAMS ((void **, void *)); +typedef int (*htab_trav) (void **, void *); /* Memory-allocation function, with the same functionality as calloc(). Iff it returns NULL, the hash table implementation will pass an error code back to the user, so if your code doesn't handle errors, best if you use xcalloc instead. */ -typedef PTR (*htab_alloc) PARAMS ((size_t, size_t)); +typedef void *(*htab_alloc) (size_t, size_t); /* We also need a free() routine. */ -typedef void (*htab_free) PARAMS ((PTR)); +typedef void (*htab_free) (void *); /* Memory allocation and deallocation; variants which take an extra argument. */ -typedef PTR (*htab_alloc_with_arg) PARAMS ((void *, size_t, size_t)); -typedef void (*htab_free_with_arg) PARAMS ((void *, void *)); +typedef void *(*htab_alloc_with_arg) (void *, size_t, size_t); +typedef void (*htab_free_with_arg) (void *, void *); + +/* This macro defines reserved value for empty table entry. */ + +#define HTAB_EMPTY_ENTRY ((PTR) 0) + +/* This macro defines reserved value for table entry which contained + a deleted element. */ + +#define HTAB_DELETED_ENTRY ((PTR) 1) /* Hash tables are of the following type. The structure (implementation) of this type is not needed for using the hash @@ -99,15 +108,15 @@ struct htab GTY(()) htab_del del_f; /* Table itself. */ - PTR * GTY ((use_param (""), length ("%h.size"))) entries; + void ** GTY ((use_param, length ("%h.size"))) entries; - /* Current size (in entries) of the hash table */ + /* Current size (in entries) of the hash table. */ size_t size; - /* Current number of elements including also deleted elements */ + /* Current number of elements including also deleted elements. */ size_t n_elements; - /* Current number of deleted elements in the table */ + /* Current number of deleted elements in the table. */ size_t n_deleted; /* The following member is used for debugging. Its value is number @@ -123,9 +132,13 @@ struct htab GTY(()) htab_free free_f; /* Alternate allocate/free functions, which take an extra argument. */ - PTR GTY((skip (""))) alloc_arg; + void * GTY((skip)) alloc_arg; htab_alloc_with_arg alloc_with_arg_f; htab_free_with_arg free_with_arg_f; + + /* Current size (in entries) of the hash table, as an index into the + table of primes. */ + unsigned int size_prime_index; }; typedef struct htab *htab_t; @@ -135,44 +148,42 @@ enum insert_option {NO_INSERT, INSERT}; /* The prototypes of the package functions. */ -extern htab_t htab_create_alloc PARAMS ((size_t, htab_hash, - htab_eq, htab_del, - htab_alloc, htab_free)); +extern htab_t htab_create_alloc (size_t, htab_hash, + htab_eq, htab_del, + htab_alloc, htab_free); -extern htab_t htab_create_alloc_ex PARAMS ((size_t, htab_hash, - htab_eq, htab_del, - PTR, htab_alloc_with_arg, - htab_free_with_arg)); +extern htab_t htab_create_alloc_ex (size_t, htab_hash, + htab_eq, htab_del, + void *, htab_alloc_with_arg, + htab_free_with_arg); /* Backward-compatibility functions. */ -extern htab_t htab_create PARAMS ((size_t, htab_hash, htab_eq, htab_del)); -extern htab_t htab_try_create PARAMS ((size_t, htab_hash, htab_eq, htab_del)); - -extern void htab_set_functions_ex PARAMS ((htab_t, htab_hash, - htab_eq, htab_del, - PTR, htab_alloc_with_arg, - htab_free_with_arg)); - -extern void htab_delete PARAMS ((htab_t)); -extern void htab_empty PARAMS ((htab_t)); - -extern PTR htab_find PARAMS ((htab_t, const void *)); -extern PTR *htab_find_slot PARAMS ((htab_t, const void *, - enum insert_option)); -extern PTR htab_find_with_hash PARAMS ((htab_t, const void *, - hashval_t)); -extern PTR *htab_find_slot_with_hash PARAMS ((htab_t, const void *, - hashval_t, - enum insert_option)); -extern void htab_clear_slot PARAMS ((htab_t, void **)); -extern void htab_remove_elt PARAMS ((htab_t, void *)); - -extern void htab_traverse PARAMS ((htab_t, htab_trav, void *)); -extern void htab_traverse_noresize PARAMS ((htab_t, htab_trav, void *)); - -extern size_t htab_size PARAMS ((htab_t)); -extern size_t htab_elements PARAMS ((htab_t)); -extern double htab_collisions PARAMS ((htab_t)); +extern htab_t htab_create (size_t, htab_hash, htab_eq, htab_del); +extern htab_t htab_try_create (size_t, htab_hash, htab_eq, htab_del); + +extern void htab_set_functions_ex (htab_t, htab_hash, + htab_eq, htab_del, + void *, htab_alloc_with_arg, + htab_free_with_arg); + +extern void htab_delete (htab_t); +extern void htab_empty (htab_t); + +extern void * htab_find (htab_t, const void *); +extern void ** htab_find_slot (htab_t, const void *, enum insert_option); +extern void * htab_find_with_hash (htab_t, const void *, hashval_t); +extern void ** htab_find_slot_with_hash (htab_t, const void *, + hashval_t, enum insert_option); +extern void htab_clear_slot (htab_t, void **); +extern void htab_remove_elt (htab_t, void *); +extern void htab_remove_elt_with_hash (htab_t, void *, hashval_t); + +extern void htab_traverse (htab_t, htab_trav, void *); +extern void htab_traverse_noresize (htab_t, htab_trav, void *); + +extern size_t htab_size (htab_t); +extern size_t htab_elements (htab_t); +extern double htab_collisions (htab_t); /* A hash function for pointers. */ extern htab_hash htab_hash_pointer; @@ -181,10 +192,10 @@ extern htab_hash htab_hash_pointer; extern htab_eq htab_eq_pointer; /* A hash function for null-terminated strings. */ -extern hashval_t htab_hash_string PARAMS ((const PTR)); +extern hashval_t htab_hash_string (const void *); /* An iterative hash function for arbitrary data. */ -extern hashval_t iterative_hash PARAMS ((const PTR, size_t, hashval_t)); +extern hashval_t iterative_hash (const void *, size_t, hashval_t); /* Shorthand for hashing something with an intrinsic size. */ #define iterative_hash_object(OB,INIT) iterative_hash (&OB, sizeof (OB), INIT) diff --git a/support/cpp2/libiberty/md5.c b/support/cpp2/libiberty/md5.c new file mode 100644 index 00000000..83e0beb3 --- /dev/null +++ b/support/cpp2/libiberty/md5.c @@ -0,0 +1,430 @@ +/* md5.c - Functions to compute MD5 message digest of files or memory blocks + according to the definition of MD5 in RFC 1321 from April 1992. + Copyright (C) 1995, 1996 Free Software Foundation, Inc. + + NOTE: This source is derived from an old version taken from the GNU C + Library (glibc). + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Written by Ulrich Drepper , 1995. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#if STDC_HEADERS || defined _LIBC +# include +# include +#else +# ifndef HAVE_MEMCPY +# define memcpy(d, s, n) bcopy ((s), (d), (n)) +# endif +#endif + +#include "ansidecl.h" +#include "md5.h" + +#ifdef _LIBC +# include +# if __BYTE_ORDER == __BIG_ENDIAN +# define WORDS_BIGENDIAN 1 +# endif +#endif + +#ifdef WORDS_BIGENDIAN +# define SWAP(n) \ + (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) +#else +# define SWAP(n) (n) +#endif + + +/* This array contains the bytes used to pad the buffer to the next + 64-byte boundary. (RFC 1321, 3.1: Step 1) */ +static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; + + +/* Initialize structure containing state of computation. + (RFC 1321, 3.3: Step 3) */ +void +md5_init_ctx (struct md5_ctx *ctx) +{ + ctx->A = (md5_uint32) 0x67452301; + ctx->B = (md5_uint32) 0xefcdab89; + ctx->C = (md5_uint32) 0x98badcfe; + ctx->D = (md5_uint32) 0x10325476; + + ctx->total[0] = ctx->total[1] = 0; + ctx->buflen = 0; +} + +/* Put result from CTX in first 16 bytes following RESBUF. The result + must be in little endian byte order. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +void * +md5_read_ctx (const struct md5_ctx *ctx, void *resbuf) +{ + ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A); + ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B); + ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C); + ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D); + + return resbuf; +} + +/* Process the remaining bytes in the internal buffer and the usual + prolog according to the standard and write the result to RESBUF. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +void * +md5_finish_ctx (struct md5_ctx *ctx, void *resbuf) +{ + /* Take yet unprocessed bytes into account. */ + md5_uint32 bytes = ctx->buflen; + size_t pad; + + /* Now count remaining bytes. */ + ctx->total[0] += bytes; + if (ctx->total[0] < bytes) + ++ctx->total[1]; + + pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes; + memcpy (&ctx->buffer[bytes], fillbuf, pad); + + /* Put the 64-bit file length in *bits* at the end of the buffer. */ + *(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3); + *(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) | + (ctx->total[0] >> 29)); + + /* Process last bytes. */ + md5_process_block (ctx->buffer, bytes + pad + 8, ctx); + + return md5_read_ctx (ctx, 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. */ +int +md5_stream (FILE *stream, void *resblock) +{ + /* Important: BLOCKSIZE must be a multiple of 64. */ +#define BLOCKSIZE 4096 + struct md5_ctx ctx; + char buffer[BLOCKSIZE + 72]; + size_t sum; + + /* Initialize the computation context. */ + md5_init_ctx (&ctx); + + /* Iterate over full file contents. */ + while (1) + { + /* We read the file in blocks of BLOCKSIZE bytes. One call of the + computation function processes the whole buffer so that with the + next round of the loop another block can be read. */ + size_t n; + sum = 0; + + /* Read block. Take care for partial reads. */ + do + { + n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream); + + sum += n; + } + while (sum < BLOCKSIZE && n != 0); + if (n == 0 && ferror (stream)) + return 1; + + /* If end of file is reached, end the loop. */ + if (n == 0) + break; + + /* Process buffer with BLOCKSIZE bytes. Note that + BLOCKSIZE % 64 == 0 + */ + md5_process_block (buffer, BLOCKSIZE, &ctx); + } + + /* Add the last bytes if necessary. */ + if (sum > 0) + md5_process_bytes (buffer, sum, &ctx); + + /* Construct result in desired memory. */ + md5_finish_ctx (&ctx, resblock); + return 0; +} + +/* 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. */ +void * +md5_buffer (const char *buffer, size_t len, void *resblock) +{ + struct md5_ctx ctx; + + /* Initialize the computation context. */ + md5_init_ctx (&ctx); + + /* Process whole buffer but last len % 64 bytes. */ + md5_process_bytes (buffer, len, &ctx); + + /* Put result in desired memory area. */ + return md5_finish_ctx (&ctx, resblock); +} + + +void +md5_process_bytes (const void *buffer, size_t len, struct md5_ctx *ctx) +{ + /* When we already have some bits in our internal buffer concatenate + both inputs first. */ + if (ctx->buflen != 0) + { + size_t left_over = ctx->buflen; + size_t add = 128 - left_over > len ? len : 128 - left_over; + + memcpy (&ctx->buffer[left_over], buffer, add); + ctx->buflen += add; + + if (left_over + add > 64) + { + md5_process_block (ctx->buffer, (left_over + add) & ~63, ctx); + /* The regions in the following copy operation cannot overlap. */ + memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63], + (left_over + add) & 63); + ctx->buflen = (left_over + add) & 63; + } + + buffer = (const void *) ((const char *) buffer + add); + len -= add; + } + + /* Process available complete blocks. */ + if (len > 64) + { +#if !_STRING_ARCH_unaligned +/* To check alignment gcc has an appropriate operator. Other + compilers don't. */ +# if __GNUC__ >= 2 +# define UNALIGNED_P(p) (((md5_uintptr) p) % __alignof__ (md5_uint32) != 0) +# else +# define UNALIGNED_P(p) (((md5_uintptr) p) % sizeof (md5_uint32) != 0) +# endif + if (UNALIGNED_P (buffer)) + while (len > 64) + { + md5_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx); + buffer = (const char *) buffer + 64; + len -= 64; + } + else +#endif + md5_process_block (buffer, len & ~63, ctx); + buffer = (const void *) ((const char *) buffer + (len & ~63)); + len &= 63; + } + + /* Move remaining bytes in internal buffer. */ + if (len > 0) + { + memcpy (ctx->buffer, buffer, len); + ctx->buflen = len; + } +} + + +/* These are the four functions used in the four steps of the MD5 algorithm + and defined in the RFC 1321. The first function is a little bit optimized + (as found in Colin Plumbs public domain implementation). */ +/* #define FF(b, c, d) ((b & c) | (~b & d)) */ +#define FF(b, c, d) (d ^ (b & (c ^ d))) +#define FG(b, c, d) FF (d, b, c) +#define FH(b, c, d) (b ^ c ^ d) +#define FI(b, c, d) (c ^ (b | ~d)) + +/* Process LEN bytes of BUFFER, accumulating context into CTX. + It is assumed that LEN % 64 == 0. */ + +void +md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx) +{ + md5_uint32 correct_words[16]; + const md5_uint32 *words = (const md5_uint32 *) buffer; + size_t nwords = len / sizeof (md5_uint32); + const md5_uint32 *endp = words + nwords; + md5_uint32 A = ctx->A; + md5_uint32 B = ctx->B; + md5_uint32 C = ctx->C; + md5_uint32 D = ctx->D; + + /* First increment the byte count. RFC 1321 specifies the possible + length of the file up to 2^64 bits. Here we only compute the + number of bytes. Do a double word increment. */ + ctx->total[0] += len; + if (ctx->total[0] < len) + ++ctx->total[1]; + + /* Process all bytes in the buffer with 64 bytes in each round of + the loop. */ + while (words < endp) + { + md5_uint32 *cwp = correct_words; + md5_uint32 A_save = A; + md5_uint32 B_save = B; + md5_uint32 C_save = C; + md5_uint32 D_save = D; + + /* First round: using the given function, the context and a constant + the next context is computed. Because the algorithms processing + unit is a 32-bit word and it is determined to work on words in + little endian byte order we perhaps have to change the byte order + before the computation. To reduce the work for the next steps + we store the swapped words in the array CORRECT_WORDS. */ + +#define OP(a, b, c, d, s, T) \ + do \ + { \ + a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \ + ++words; \ + CYCLIC (a, s); \ + a += b; \ + } \ + while (0) + + /* It is unfortunate that C does not provide an operator for + cyclic rotation. Hope the C compiler is smart enough. */ +#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s))) + + /* Before we start, one word to the strange constants. + They are defined in RFC 1321 as + + T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64 + */ + + /* Round 1. */ + OP (A, B, C, D, 7, (md5_uint32) 0xd76aa478); + OP (D, A, B, C, 12, (md5_uint32) 0xe8c7b756); + OP (C, D, A, B, 17, (md5_uint32) 0x242070db); + OP (B, C, D, A, 22, (md5_uint32) 0xc1bdceee); + OP (A, B, C, D, 7, (md5_uint32) 0xf57c0faf); + OP (D, A, B, C, 12, (md5_uint32) 0x4787c62a); + OP (C, D, A, B, 17, (md5_uint32) 0xa8304613); + OP (B, C, D, A, 22, (md5_uint32) 0xfd469501); + OP (A, B, C, D, 7, (md5_uint32) 0x698098d8); + OP (D, A, B, C, 12, (md5_uint32) 0x8b44f7af); + OP (C, D, A, B, 17, (md5_uint32) 0xffff5bb1); + OP (B, C, D, A, 22, (md5_uint32) 0x895cd7be); + OP (A, B, C, D, 7, (md5_uint32) 0x6b901122); + OP (D, A, B, C, 12, (md5_uint32) 0xfd987193); + OP (C, D, A, B, 17, (md5_uint32) 0xa679438e); + OP (B, C, D, A, 22, (md5_uint32) 0x49b40821); + + /* For the second to fourth round we have the possibly swapped words + in CORRECT_WORDS. Redefine the macro to take an additional first + argument specifying the function to use. */ +#undef OP +#define OP(a, b, c, d, k, s, T) \ + do \ + { \ + a += FX (b, c, d) + correct_words[k] + T; \ + CYCLIC (a, s); \ + a += b; \ + } \ + while (0) + +#define FX(b, c, d) FG (b, c, d) + + /* Round 2. */ + OP (A, B, C, D, 1, 5, (md5_uint32) 0xf61e2562); + OP (D, A, B, C, 6, 9, (md5_uint32) 0xc040b340); + OP (C, D, A, B, 11, 14, (md5_uint32) 0x265e5a51); + OP (B, C, D, A, 0, 20, (md5_uint32) 0xe9b6c7aa); + OP (A, B, C, D, 5, 5, (md5_uint32) 0xd62f105d); + OP (D, A, B, C, 10, 9, (md5_uint32) 0x02441453); + OP (C, D, A, B, 15, 14, (md5_uint32) 0xd8a1e681); + OP (B, C, D, A, 4, 20, (md5_uint32) 0xe7d3fbc8); + OP (A, B, C, D, 9, 5, (md5_uint32) 0x21e1cde6); + OP (D, A, B, C, 14, 9, (md5_uint32) 0xc33707d6); + OP (C, D, A, B, 3, 14, (md5_uint32) 0xf4d50d87); + OP (B, C, D, A, 8, 20, (md5_uint32) 0x455a14ed); + OP (A, B, C, D, 13, 5, (md5_uint32) 0xa9e3e905); + OP (D, A, B, C, 2, 9, (md5_uint32) 0xfcefa3f8); + OP (C, D, A, B, 7, 14, (md5_uint32) 0x676f02d9); + OP (B, C, D, A, 12, 20, (md5_uint32) 0x8d2a4c8a); + +#undef FX +#define FX(b, c, d) FH (b, c, d) + + /* Round 3. */ + OP (A, B, C, D, 5, 4, (md5_uint32) 0xfffa3942); + OP (D, A, B, C, 8, 11, (md5_uint32) 0x8771f681); + OP (C, D, A, B, 11, 16, (md5_uint32) 0x6d9d6122); + OP (B, C, D, A, 14, 23, (md5_uint32) 0xfde5380c); + OP (A, B, C, D, 1, 4, (md5_uint32) 0xa4beea44); + OP (D, A, B, C, 4, 11, (md5_uint32) 0x4bdecfa9); + OP (C, D, A, B, 7, 16, (md5_uint32) 0xf6bb4b60); + OP (B, C, D, A, 10, 23, (md5_uint32) 0xbebfbc70); + OP (A, B, C, D, 13, 4, (md5_uint32) 0x289b7ec6); + OP (D, A, B, C, 0, 11, (md5_uint32) 0xeaa127fa); + OP (C, D, A, B, 3, 16, (md5_uint32) 0xd4ef3085); + OP (B, C, D, A, 6, 23, (md5_uint32) 0x04881d05); + OP (A, B, C, D, 9, 4, (md5_uint32) 0xd9d4d039); + OP (D, A, B, C, 12, 11, (md5_uint32) 0xe6db99e5); + OP (C, D, A, B, 15, 16, (md5_uint32) 0x1fa27cf8); + OP (B, C, D, A, 2, 23, (md5_uint32) 0xc4ac5665); + +#undef FX +#define FX(b, c, d) FI (b, c, d) + + /* Round 4. */ + OP (A, B, C, D, 0, 6, (md5_uint32) 0xf4292244); + OP (D, A, B, C, 7, 10, (md5_uint32) 0x432aff97); + OP (C, D, A, B, 14, 15, (md5_uint32) 0xab9423a7); + OP (B, C, D, A, 5, 21, (md5_uint32) 0xfc93a039); + OP (A, B, C, D, 12, 6, (md5_uint32) 0x655b59c3); + OP (D, A, B, C, 3, 10, (md5_uint32) 0x8f0ccc92); + OP (C, D, A, B, 10, 15, (md5_uint32) 0xffeff47d); + OP (B, C, D, A, 1, 21, (md5_uint32) 0x85845dd1); + OP (A, B, C, D, 8, 6, (md5_uint32) 0x6fa87e4f); + OP (D, A, B, C, 15, 10, (md5_uint32) 0xfe2ce6e0); + OP (C, D, A, B, 6, 15, (md5_uint32) 0xa3014314); + OP (B, C, D, A, 13, 21, (md5_uint32) 0x4e0811a1); + OP (A, B, C, D, 4, 6, (md5_uint32) 0xf7537e82); + OP (D, A, B, C, 11, 10, (md5_uint32) 0xbd3af235); + OP (C, D, A, B, 2, 15, (md5_uint32) 0x2ad7d2bb); + OP (B, C, D, A, 9, 21, (md5_uint32) 0xeb86d391); + + /* Add the starting values of the context. */ + A += A_save; + B += B_save; + C += C_save; + D += D_save; + } + + /* Put checksum in context given as argument. */ + ctx->A = A; + ctx->B = B; + ctx->C = C; + ctx->D = D; +} diff --git a/support/cpp2/md5.h b/support/cpp2/md5.h new file mode 100644 index 00000000..e3578934 --- /dev/null +++ b/support/cpp2/md5.h @@ -0,0 +1,139 @@ +/* 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 + +#if defined HAVE_LIMITS_H || _LIBC +# include +#endif + +/* 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 +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 ) 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 +/* 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 + +/* 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); + +#endif diff --git a/support/cpp2/move-if-change b/support/cpp2/move-if-change index 66d8b8ad..d267e721 100644 --- a/support/cpp2/move-if-change +++ b/support/cpp2/move-if-change @@ -1,11 +1,26 @@ #!/bin/sh -# Like mv $1 $2, but if the files are the same, just delete $1. -# Status is 0 if $2 is changed, 1 otherwise. + +# 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 -s $1 $2 +cmp $1 $2 > /dev/null then echo $2 is unchanged rm -f $1 diff --git a/support/cpp2/opt-functions.awk b/support/cpp2/opt-functions.awk new file mode 100644 index 00000000..f392060c --- /dev/null +++ b/support/cpp2/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/cpp2/opt-gather.awk b/support/cpp2/opt-gather.awk new file mode 100644 index 00000000..87dd37ab --- /dev/null +++ b/support/cpp2/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/cpp2/optc-gen.awk b/support/cpp2/optc-gen.awk new file mode 100644 index 00000000..08232f37 --- /dev/null +++ b/support/cpp2/optc-gen.awk @@ -0,0 +1,168 @@ +# 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 "" + +for (i = 0; i < n_opts; i++) { + name = var_name(flags[i]); + if (name == "") + continue; + + if (flag_set_p("VarExists", flags[i])) + continue; + + init = opt_args("Init", flags[i]) + if (init != "") + init = " = " init; + else if (name in var_seen) + continue; + + print "/* Set by -" opts[i] "." + print " " help[i] " */" + print var_type(flags[i]) name init ";" + 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{" + +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 = quote help[i] quote; + + printf(" { %c-%s%c,\n %s,\n %s, %u,\n", + quote, opts[i], quote, hlp, back_chain[i], len) + 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/cpp2/opth-gen.awk b/support/cpp2/opth-gen.awk new file mode 100644 index 00000000..09d1a9a0 --- /dev/null +++ b/support/cpp2/opth-gen.awk @@ -0,0 +1,185 @@ +# 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 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 ~ ",") + print "#define TARGET_" nth_arg(1, opt) \ + " ((target_flags & 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/cpp2/options_vc_in.c b/support/cpp2/options_vc_in.c deleted file mode 100644 index ab232e73..00000000 --- a/support/cpp2/options_vc_in.c +++ /dev/null @@ -1,221 +0,0 @@ -/* This file is auto-generated by opts.sh. */ - -#include -#include "options.h" -#include "opts.h" - -const char * const lang_names[] = -{ - "SDCPP", - 0 -}; - -const unsigned int cl_options_count = N_OPTS; - -const struct cl_option cl_options[] = -{ - { "--help", - N_("Display this information"), - N_OPTS, 5, CL_COMMON }, - { "--version", - N_("Display the compiler's version"), - N_OPTS, 8, CL_COMMON }, - { "-A", - N_("-A= Assert the to . Putting '-' before disables the to "), - N_OPTS, 1, CL_SDCPP | CL_JOINED | CL_SEPARATE }, - { "-C", - N_("Do not discard comments"), - N_OPTS, 1, CL_SDCPP }, - { "-CC", - N_("Do not discard comments in macro expansions"), - N_OPTS, 2, CL_SDCPP }, - { "-D", - N_("-D[=] Define a with as its value. If just is given, is taken to be 1"), - N_OPTS, 1, CL_SDCPP | CL_JOINED | CL_SEPARATE }, - { "-H", - N_("Print the name of header files as they are used"), - N_OPTS, 1, CL_SDCPP }, - { "-I", - N_("-I Add to the end of the main include path. -I- gives more include path control; see info documentation"), - N_OPTS, 1, CL_SDCPP | CL_JOINED | CL_SEPARATE }, - { "-M", - N_("Generate make dependencies"), - N_OPTS, 1, CL_SDCPP }, - { "-MD", - N_("Generate make dependencies and compile"), - N_OPTS, 2, CL_SDCPP | CL_SEPARATE }, - { "-MF", - N_("-MF Write dependency output to the given file"), - N_OPTS, 2, CL_SDCPP | CL_JOINED | CL_SEPARATE }, - { "-MG", - N_("Treat missing header files as generated files"), - N_OPTS, 2, CL_SDCPP }, - { "-MM", - N_("Like -M but ignore system header files"), - N_OPTS, 2, CL_SDCPP }, - { "-MMD", - N_("Like -MD but ignore system header files"), - N_OPTS, 3, CL_SDCPP | CL_SEPARATE }, - { "-MP", - N_("Generate phony targets for all headers"), - N_OPTS, 2, CL_SDCPP }, - { "-MQ", - N_("-MQ Add a MAKE-quoted target"), - N_OPTS, 2, CL_SDCPP | CL_JOINED | CL_SEPARATE }, - { "-MT", - N_("-MT Add an unquoted target"), - N_OPTS, 2, CL_SDCPP | CL_JOINED | CL_SEPARATE }, - { "-P", - N_("Do not generate #line directives"), - N_OPTS, 1, CL_SDCPP }, - { "-U", - N_("-U Undefine "), - N_OPTS, 1, CL_SDCPP | CL_JOINED | CL_SEPARATE }, - { "-Wall", - N_("Enable most warning messages"), - N_OPTS, 4, CL_SDCPP }, - { "-Wcomment", - N_("Warn about possibly nested block comments, and C++ comments spanning more than one physical line"), - N_OPTS, 8, CL_SDCPP }, - { "-Wcomments", - N_("Synonym for -Wcomment"), - N_OPTS, 9, CL_SDCPP }, - { "-Wdeprecated", - N_("Warn about deprecated compiler features"), - N_OPTS, 11, CL_SDCPP }, - { "-Wendif-labels", - N_("Warn about stray tokens after #elif and #endif"), - N_OPTS, 13, CL_SDCPP }, - { "-Werror", - N_("Treat all warnings as errors"), - N_OPTS, 6, CL_SDCPP }, - { "-Wimport", - N_("Deprecated. This switch has no effect."), - N_OPTS, 7, CL_SDCPP }, - { "-Wsystem-headers", - N_("Do not suppress warnings from system headers"), - N_OPTS, 15, CL_SDCPP }, - { "-Wtrigraphs", - N_("Warn if trigraphs are encountered that might affect the meaning of the program"), - N_OPTS, 10, CL_SDCPP }, - { "-Wundef", - N_("Warn if an undefined macro is used in an #if directive"), - N_OPTS, 6, CL_SDCPP }, - { "-Wunused-macros", - N_("Warn about macros defined in the main file that are not used"), - N_OPTS, 14, CL_SDCPP }, - { "-ansi", - N_("A synonym for -std=c89."), - N_OPTS, 4, CL_SDCPP }, - { "-d", - N_("-d Enable dumps from specific passes of the compiler"), - N_OPTS, 1, CL_SDCPP | CL_JOINED }, - { "-fdollars-in-identifiers", - N_("Permit '$' as an identifier character"), - N_OPTS, 23, CL_SDCPP }, - { "-fexec-charset=", - N_("-fexec-charset= Convert all strings and character constants to character set "), - N_OPTS, 14, CL_SDCPP | CL_JOINED | CL_REJECT_NEGATIVE }, - { "-finput-charset=", - N_("-finput-charset= Specify the default character set for source files."), - N_OPTS, 15, CL_SDCPP | CL_JOINED | CL_REJECT_NEGATIVE }, - { "-fpreprocessed", - N_("Treat the input file as already preprocessed"), - N_OPTS, 13, CL_SDCPP }, - { "-fshow-column", - 0, - N_OPTS, 12, CL_SDCPP }, - { "-fsigned-char", - N_("Make \"char\" signed by default"), - N_OPTS, 12, CL_SDCPP }, - { "-ftabstop=", - N_("-ftabstop= Distance between tab stops for column reporting"), - N_OPTS, 9, CL_SDCPP | CL_JOINED | CL_REJECT_NEGATIVE | CL_UINTEGER }, - { "-funsigned-char", - N_("Make \"char\" unsigned by default"), - N_OPTS, 14, CL_SDCPP }, - { "-fwide-exec-charset=", - N_("-fwide-exec-charset= Convert all wide strings and character constants to character set "), - N_OPTS, 19, CL_SDCPP | CL_JOINED | CL_REJECT_NEGATIVE }, - { "-fworking-directory", - N_("Generate a #line directive pointing at the current working directory"), - N_OPTS, 18, CL_SDCPP }, - { "-idirafter", - N_("-idirafter Add to the end of the system include path"), - N_OPTS, 9, CL_SDCPP | CL_JOINED | CL_SEPARATE }, - { "-imacros", - N_("-imacros Accept definition of macros in "), - N_OPTS, 7, CL_SDCPP | CL_JOINED | CL_SEPARATE }, - { "-include", - N_("-include Include the contents of before other files"), - N_OPTS, 7, CL_SDCPP | CL_JOINED | CL_SEPARATE }, - { "-iprefix", - N_("-iprefix Specify as a prefix for next two options"), - N_OPTS, 7, CL_SDCPP | CL_JOINED | CL_SEPARATE }, - { "-isysroot", - N_("-isysroot Set to be the system root directory"), - N_OPTS, 8, CL_SDCPP | CL_JOINED | CL_SEPARATE }, - { "-isystem", - N_("-isystem Add to the start of the system include path"), - N_OPTS, 7, CL_SDCPP | CL_JOINED | CL_SEPARATE }, - { "-iwithprefix", - N_("-iwithprefix Add to the end of the system include path"), - N_OPTS, 11, CL_SDCPP | CL_JOINED | CL_SEPARATE }, - { "-iwithprefixbefore", - N_("-iwithprefixbefore Add to the end of the main include path"), - OPT_iwithprefix, 17, CL_SDCPP | CL_JOINED | CL_SEPARATE }, - { "-lang-asm", - 0, - N_OPTS, 8, CL_UNDOCUMENTED }, - { "-lang-objc", - 0, - N_OPTS, 9, CL_SDCPP | CL_UNDOCUMENTED }, - { "-nostdinc", - N_("Do not search standard system include directories (those specified with -isystem will still be used)"), - N_OPTS, 8, CL_SDCPP }, - { "-o", - N_("-o Place output into "), - N_OPTS, 1, CL_SDCPP | CL_JOINED | CL_SEPARATE }, - { "-obj-ext=", - N_("-obj-ext= Define object file extension, used for generation of make dependencies"), - OPT_o, 8, CL_SDCPP | CL_JOINED }, - { "-pedantic", - N_("Issue warnings needed for strict compliance to the standard"), - N_OPTS, 8, CL_SDCPP }, - { "-pedantic-errors", - N_("Like -pedantic but issue them as errors"), - N_OPTS, 15, CL_SDCPP }, - { "-pedantic-parse-number", - N_("Pedantic parse number"), - N_OPTS, 21, CL_SDCPP }, - { "-remap", - N_("Remap file names when including files"), - N_OPTS, 5, CL_SDCPP }, - { "-std=c89", - N_("Conform to the ISO 1990 C standard"), - N_OPTS, 7, CL_SDCPP }, - { "-std=c99", - N_("Conform to the ISO 1999 C standard"), - N_OPTS, 7, CL_SDCPP }, - { "-std=iso9899:1990", - N_("Conform to the ISO 1990 C standard"), - N_OPTS, 16, 0 }, - { "-std=iso9899:199409", - N_("Conform to the ISO 1990 C standard as amended in 1994"), - N_OPTS, 18, CL_SDCPP }, - { "-std=iso9899:1999", - N_("Conform to the ISO 1999 C standard"), - N_OPTS, 16, 0 }, - { "-traditional-cpp", - N_("Enable traditional preprocessing"), - N_OPTS, 15, CL_SDCPP }, - { "-trigraphs", - N_("-trigraphs Support ISO C trigraphs"), - N_OPTS, 9, CL_SDCPP }, - { "-v", - N_("Enable verbose output"), - N_OPTS, 1, CL_SDCPP }, - { "-w", - N_("Suppress warnings"), - N_OPTS, 1, CL_SDCPP } -}; diff --git a/support/cpp2/options_vc_in.h b/support/cpp2/options_vc_in.h deleted file mode 100644 index 142b24cd..00000000 --- a/support/cpp2/options_vc_in.h +++ /dev/null @@ -1,76 +0,0 @@ -/* This file is auto-generated by opts.sh. */ - -#define CL_SDCPP (1 << 0) - -enum opt_code -{ - OPT__help, /* --help */ - OPT__version, /* --version */ - OPT_A, /* -A */ - OPT_C, /* -C */ - OPT_CC, /* -CC */ - OPT_D, /* -D */ - OPT_H, /* -H */ - OPT_I, /* -I */ - OPT_M, /* -M */ - OPT_MD, /* -MD */ - OPT_MF, /* -MF */ - OPT_MG, /* -MG */ - OPT_MM, /* -MM */ - OPT_MMD, /* -MMD */ - OPT_MP, /* -MP */ - OPT_MQ, /* -MQ */ - OPT_MT, /* -MT */ - OPT_P, /* -P */ - OPT_U, /* -U */ - OPT_Wall, /* -Wall */ - OPT_Wcomment, /* -Wcomment */ - OPT_Wcomments, /* -Wcomments */ - OPT_Wdeprecated, /* -Wdeprecated */ - OPT_Wendif_labels, /* -Wendif-labels */ - OPT_Werror, /* -Werror */ - OPT_Wimport, /* -Wimport */ - OPT_Wsystem_headers, /* -Wsystem-headers */ - OPT_Wtrigraphs, /* -Wtrigraphs */ - OPT_Wundef, /* -Wundef */ - OPT_Wunused_macros, /* -Wunused-macros */ - OPT_ansi, /* -ansi */ - OPT_d, /* -d */ - OPT_fdollars_in_identifiers, /* -fdollars-in-identifiers */ - OPT_fexec_charset_, /* -fexec-charset= */ - OPT_finput_charset_, /* -finput-charset= */ - OPT_fpreprocessed, /* -fpreprocessed */ - OPT_fshow_column, /* -fshow-column */ - OPT_fsigned_char, /* -fsigned-char */ - OPT_ftabstop_, /* -ftabstop= */ - OPT_funsigned_char, /* -funsigned-char */ - OPT_fwide_exec_charset_, /* -fwide-exec-charset= */ - OPT_fworking_directory, /* -fworking-directory */ - OPT_idirafter, /* -idirafter */ - OPT_imacros, /* -imacros */ - OPT_include, /* -include */ - OPT_iprefix, /* -iprefix */ - OPT_isysroot, /* -isysroot */ - OPT_isystem, /* -isystem */ - OPT_iwithprefix, /* -iwithprefix */ - OPT_iwithprefixbefore, /* -iwithprefixbefore */ - OPT_lang_asm, /* -lang-asm */ - OPT_lang_objc, /* -lang-objc */ - OPT_nostdinc, /* -nostdinc */ - OPT_o, /* -o */ - OPT_obj_ext_, /* -obj-ext= */ - OPT_pedantic, /* -pedantic */ - OPT_pedantic_errors, /* -pedantic-errors */ - OPT_pedantic_parse_number, /* -pedantic-parse-number */ - OPT_remap, /* -remap */ - OPT_std_c89, /* -std=c89 */ - OPT_std_c99, /* -std=c99 */ - OPT_std_iso9899_1990, /* -std=iso9899:1990 */ - OPT_std_iso9899_199409, /* -std=iso9899:199409 */ - OPT_std_iso9899_1999, /* -std=iso9899:1999 */ - OPT_traditional_cpp, /* -traditional-cpp */ - OPT_trigraphs, /* -trigraphs */ - OPT_v, /* -v */ - OPT_w, /* -w */ - N_OPTS -}; diff --git a/support/cpp2/opts.c b/support/cpp2/opts.c index 5323a32a..20e8cb95 100644 --- a/support/cpp2/opts.c +++ b/support/cpp2/opts.c @@ -29,9 +29,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA /* True if we should exit after parsing options. */ bool exit_after_options; -/* Don't print warning messages. -w. */ -bool inhibit_warnings; - /* Treat warnings as errors. -Werror. */ bool warnings_are_errors; @@ -119,14 +116,14 @@ find_opt (const char *input, int lang_mask) { const struct cl_option *opt = &cl_options[mn]; - /* Is this switch a prefix of the input? */ - if (!strncmp (input, opt->opt_text + 1, opt->opt_len)) + /* 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, and the match is exact or the switch - takes a joined argument, return it. */ - if ((opt->flags & lang_mask) - && (input[opt->opt_len] == '\0' || (opt->flags & CL_JOINED))) - return mn; + /* If language is OK, return it. */ + if (opt->flags & lang_mask) + /* If we haven't remembered a prior match, remember this one. Any prior match is necessarily better. */ @@ -199,7 +196,7 @@ complain_wrong_lang (const char *text, const struct cl_option *option, bad_lang = write_langs (lang_mask); /* Eventually this should become a hard error IMO. */ - warning ("command line option \"%s\" is valid for %s but not for %s", + warning (0, "command line option \"%s\" is valid for %s but not for %s", text, ok_langs, bad_lang); free (ok_langs); @@ -220,10 +217,12 @@ handle_option (const char **argv, unsigned int lang_mask) opt = argv[0]; - /* Drop the "no-" from negative switches. */ - if ((opt[1] == 'W' || opt[1] == 'f') + 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 = xmalloc (len + 1); @@ -232,9 +231,9 @@ handle_option (const char **argv, unsigned int lang_mask) memcpy (dup + 2, opt + 5, len - 2 + 1); opt = dup; value = 0; + opt_index = find_opt (opt + 1, lang_mask | CL_COMMON | CL_TARGET); } - opt_index = find_opt (opt + 1, lang_mask | CL_COMMON); if (opt_index == cl_options_count) goto done; @@ -248,6 +247,14 @@ handle_option (const char **argv, unsigned int lang_mask) /* 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 %qs" + " is not supported by this configuration", opt); + goto done; + } + /* Sort out any argument the switch takes. */ if (option->flags & CL_JOINED) { @@ -278,7 +285,7 @@ handle_option (const char **argv, unsigned int lang_mask) /* 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))) + if (!(option->flags & (lang_mask | CL_COMMON | CL_TARGET))) { complain_wrong_lang (argv[0], option, lang_mask); goto done; @@ -286,7 +293,7 @@ handle_option (const char **argv, unsigned int lang_mask) if (arg == NULL && (option->flags & (CL_JOINED | CL_SEPARATE))) { - if (!(*lang_hooks.missing_argument) (opt, opt_index)) + if (!lang_hooks.missing_argument (opt, opt_index)) error ("missing argument to \"%s\"", opt); goto done; } @@ -303,6 +310,34 @@ handle_option (const char **argv, unsigned int lang_mask) } } + 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; @@ -311,12 +346,25 @@ handle_option (const char **argv, unsigned int lang_mask) 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. */ +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. */ @@ -349,15 +397,6 @@ handle_options (unsigned int argc, const char **argv, unsigned int lang_mask) } } -/* Handle FILENAME from the command line. */ -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; -} - /* Parse command line options and set default flag values. Do minimal options processing. */ void @@ -366,7 +405,7 @@ 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); + lang_mask = lang_hooks.init_options (argc, argv); lang_hooks.initialize_diagnostics (global_dc); @@ -377,7 +416,10 @@ decode_options (unsigned int argc, const char **argv) } /* Handle target- and language-independent options. Return zero to - generate an "unknown option" message. */ + 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) @@ -459,7 +501,7 @@ print_filtered_help (unsigned int flag) const char *help, *opt, *tab; static char *printed; - if (flag == CL_COMMON) + if (flag == CL_COMMON || flag == CL_TARGET) { filter = flag; if (!printed) @@ -606,3 +648,65 @@ wrap_help (const char *help, const char *item, unsigned int item_width) } 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/cpp2/opts.h b/support/cpp2/opts.h index eb7c8681..2c2340c3 100644 --- a/support/cpp2/opts.h +++ b/support/cpp2/opts.h @@ -1,5 +1,5 @@ /* Command line option handling. - Copyright (C) 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GCC. @@ -15,14 +15,30 @@ 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. */ +Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301, USA. */ #ifndef GCC_OPTS_H #define GCC_OPTS_H -extern void decode_options (unsigned int argc, const char **argv); -extern void add_input_filename (const char *filename); +/* 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 { @@ -31,12 +47,26 @@ struct cl_option unsigned short back_chain; unsigned char opt_len; 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[]; +#define CL_DISABLED (1 << 21) /* Disabled in this configuration. */ +#define CL_TARGET (1 << 22) /* Target-specific option. */ +#define CL_REPORT (1 << 23) /* Report argument with -fverbose-asm */ #define CL_JOINED (1 << 24) /* If takes joined argument. */ #define CL_SEPARATE (1 << 25) /* If takes a separate argument. */ #define CL_REJECT_NEGATIVE (1 << 26) /* Reject no- form. */ @@ -53,4 +83,8 @@ extern const char **in_fnames; extern unsigned num_in_fnames; +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 *); + #endif diff --git a/support/cpp2/opts.sh b/support/cpp2/opts.sh deleted file mode 100755 index 871c8554..00000000 --- a/support/cpp2/opts.sh +++ /dev/null @@ -1,175 +0,0 @@ -#!/bin/sh -# -# Copyright (C) 2003 Free Software Foundation, Inc. -# Contributed by 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# Usage: opts.sh moveifchange srcdir outfile.c outfile.h file1.opt [ ...] - -# Always operate in the C locale. -LANG=C -LANGUAGE=C -LC_ALL=C -export LANG LANGUAGE LC_ALL - -# Set AWK if environment has not already set it. -AWK=${AWK-awk} - -SORT=sort # Could be /bin/sort or /usr/bin/sort - -MOVEIFCHANGE=$1; shift -C_FILE=$1; shift -H_FILE=$1; shift -TMP_C_FILE=tmp-${C_FILE} -TMP_H_FILE=tmp-${H_FILE} - -${AWK} ' - # Ignore comments and blank lines - /^[ \t]*(;|$)/ { next } - # Note that RS="" falls foul of gawk 3.1.2 bugs - /^[^ \t]/ { record = $0 - do { getline tmp; - if (!(tmp ~ "^[ \t]*(;|$)")) - record = record "\034" tmp - } while (tmp != "") - print record - } -' "$@" | ${SORT} | ${AWK} ' - function switch_flags (flags, result) - { - flags = " " flags " " - result = "0" - for (j = 0; j < n_langs; j++) { - regex = " " langs[j] " " - gsub ( "\\+", "\\+", regex ) - if (flags ~ regex) - result = result " | " macros[j] - } - if (flags ~ " Common ") result = result " | CL_COMMON" - if (flags ~ " Joined ") result = result " | CL_JOINED" - if (flags ~ " JoinedOrMissing ") \ - result = result " | CL_JOINED | CL_MISSING_OK" - if (flags ~ " Separate ") result = result " | CL_SEPARATE" - if (flags ~ " RejectNegative ") result = result " | CL_REJECT_NEGATIVE" - if (flags ~ " UInteger ") result = result " | CL_UINTEGER" - if (flags ~ " Undocumented ") result = result " | CL_UNDOCUMENTED" - sub( "^0 \\| ", "", result ) - return result - } - - BEGIN { - FS = "\034" - n_opts = 0 - n_langs = 0 - } - -# Collect the text and flags of each option into an array - { - if ($1 == "Language") { - langs[n_langs] = $2 - n_langs++; - } else { - opts[n_opts] = $1 - flags[n_opts] = $2 - help[n_opts] = $3 - n_opts++; - } - } - -# Dump out an enumeration into a .h file, and an array of options into a -# C file. Combine the flags of duplicate options. - END { - c_file = "'${TMP_C_FILE}'" - h_file = "'${TMP_H_FILE}'" - realh_file = "'${H_FILE}'" - comma = "," - - print "/* This file is auto-generated by opts.sh. */\n" > c_file - print "#include " >> c_file - print "#include \"" realh_file "\"" >> c_file - print "#include \"opts.h\"\n" >> c_file - print "const char * const lang_names[] =\n{" >> c_file - - print "/* This file is auto-generated by opts.sh. */\n" > h_file - 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 ")" >> h_file - print " \"" langs[i] "\"," >> c_file - } - - print " 0\n};\n" >> c_file - print "const unsigned int cl_options_count = N_OPTS;\n" >> c_file - print "const struct cl_option cl_options[] =\n{" >> c_file - - print "\nenum opt_code\n{" >> h_file - - 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 (flags[i] ~ "Joined") { - 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] "\")"; - - printf(" %s,%s/* -%s */\n", enum, s, opts[i]) >> h_file - printf(" { \"-%s\",\n %s,\n %s, %u, %s }%s\n", - opts[i], hlp, back_chain[i], len, - switch_flags(flags[i]), comma) >> c_file - } - - print " N_OPTS\n};" >> h_file - print "};" >> c_file - } -' - -# Copy the newly generated files back to the correct names only if different. -# This is to prevent a cascade of file rebuilds when not necessary. -${MOVEIFCHANGE} ${TMP_H_FILE} ${H_FILE} -${MOVEIFCHANGE} ${TMP_C_FILE} ${C_FILE} diff --git a/support/cpp2/output.h b/support/cpp2/output.h index 05a37437..3cb091fc 100644 --- a/support/cpp2/output.h +++ b/support/cpp2/output.h @@ -1,7 +1,7 @@ /* 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 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GCC. @@ -17,8 +17,8 @@ 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. */ +Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301, USA. */ #ifndef GCC_OUTPUT_H #define GCC_OUTPUT_H @@ -49,6 +49,10 @@ extern void init_insn_lengths (void); 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); @@ -66,12 +70,12 @@ extern void final_start_function (rtx, FILE *, int); extern void final_end_function (void); /* Output assembler code for some insns: all or part of a function. */ -extern void final (rtx, FILE *, int, int); +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, int *); +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. */ @@ -144,24 +148,17 @@ extern void leaf_renumber_regs_insn (rtx); /* Locate the proper template for the given insn-code. */ extern const char *get_insn_template (int, rtx); -/* Add function NAME to the weak symbols list. VALUE is a weak alias - associated with NAME. */ -extern int add_weak (tree, const char *, const char *); - /* Functions in flow.c */ -extern void allocate_for_life_analysis (void); -extern int regno_uninitialized (unsigned int); extern int regno_clobbered_at_setjmp (int); -extern void find_basic_blocks (rtx, int, FILE *); -extern bool cleanup_cfg (int); -extern bool delete_unreachable_blocks (void); -extern void check_function_return_warnings (void); /* Functions in varasm.c. */ /* Tell assembler to switch to text section. */ extern void text_section (void); +/* Tell assembler to switch to unlikely-to-be-executed text section. */ +extern void unlikely_text_section (void); + /* Tell assembler to switch to data section. */ extern void data_section (void); @@ -172,6 +169,9 @@ extern void readonly_data_section (void); /* Determine if we're in the text section. */ extern int in_text_section (void); +/* Determine if we're in the unlikely-to-be-executed text section. */ +extern int in_unlikely_text_section (void); + #ifdef CTORS_SECTION_ASM_OP extern void ctors_section (void); #endif @@ -213,6 +213,9 @@ extern void named_section (tree, const char *, int); /* Tell assembler to switch to the section for function DECL. */ extern void function_section (tree); +/* Tell assembler to switch to the most recently used text section. */ +extern void current_function_section (tree); + /* Tell assembler to switch to the section for string merging. */ extern void mergeable_string_section (tree, unsigned HOST_WIDE_INT, unsigned int); @@ -281,7 +284,6 @@ extern void assemble_zeros (unsigned HOST_WIDE_INT); /* Assemble an alignment pseudo op for an ALIGN-bit boundary. */ extern void assemble_align (int); -extern void assemble_eh_align (int); /* Assemble a string constant with the specified C string as contents. */ extern void assemble_string (const char *, int); @@ -291,13 +293,17 @@ extern void assemble_external_libcall (rtx); /* Assemble a label named NAME. */ extern void assemble_label (const char *); -extern void assemble_eh_label (const char *); -/* Output to FILE a reference to the assembler name of a C-level name NAME. - If NAME starts with a *, the rest of NAME is output verbatim. - Otherwise NAME is transformed in an implementation-defined way - (usually by the addition of an underscore). - Many macros in the tm file are defined to call this function. */ +/* 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 @@ -318,8 +324,8 @@ 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, abort if we can't output - the constant. */ + 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 @@ -398,11 +404,6 @@ extern const char *weak_global_object_name; extern int current_function_is_leaf; -/* Nonzero if function being compiled doesn't contain any instructions - that can throw an exception. This is set prior to final. */ - -extern int current_function_nothrow; - /* Nonzero if function being compiled doesn't modify the stack pointer (ignoring the prologue and epilogue). This is only valid after life_analysis has run. */ @@ -418,7 +419,7 @@ extern int current_function_uses_only_leaf_regs; /* Default file in which to dump debug output. */ #ifdef BUFSIZ -extern FILE *rtl_dump_file; +extern FILE *dump_file; #endif /* Nonnull if the insn currently being emitted was a COND_EXEC pattern. */ @@ -428,10 +429,38 @@ extern rtx current_insn_predicate; extern rtx current_output_insn; /* Nonzero while outputting an `asm' with operands. - This means that inconsistencies are the user's fault, so don't abort. + 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; + +enum in_section { no_section, in_text, in_unlikely_executed_text, in_data, + in_named +#ifdef BSS_SECTION_ASM_OP + , in_bss +#endif +#ifdef CTORS_SECTION_ASM_OP + , in_ctors +#endif +#ifdef DTORS_SECTION_ASM_OP + , in_dtors +#endif +#ifdef READONLY_DATA_SECTION_ASM_OP + , in_readonly_data +#endif +#ifdef EXTRA_SECTIONS + , EXTRA_SECTIONS +#endif +}; + +extern const char *last_text_section_name; +extern enum in_section last_text_section; +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 (tree, int); @@ -475,17 +504,57 @@ extern void no_asm_to_stream (FILE *); #define SECTION_NOTYPE 0x80000 /* don't output @progbits */ #define SECTION_MACH_DEP 0x100000 /* subsequent bits reserved for target */ -extern unsigned int get_named_section_flags (const char *); +/* 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 +}; + + extern bool set_named_section_flags (const char *, unsigned int); -extern void named_section_flags (const char *, unsigned int); +#define named_section_flags(NAME, FLAGS) \ + named_section_real((NAME), (FLAGS), /*decl=*/NULL_TREE) +extern void named_section_real (const char *, unsigned int, tree); extern bool named_section_first_declaration (const char *); extern unsigned int default_section_type_flags (tree, const char *, int); extern unsigned int default_section_type_flags_1 (tree, const char *, int, int); -extern void default_no_named_section (const char *, unsigned int); -extern void default_elf_asm_named_section (const char *, unsigned int); -extern void default_coff_asm_named_section (const char *, unsigned int); -extern void default_pe_asm_named_section (const char *, unsigned int); +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 (tree, int, 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); @@ -500,6 +569,8 @@ extern void default_elf_select_section_1 (tree, int, unsigned HOST_WIDE_INT, int); extern void default_unique_section (tree, int); extern void default_unique_section_1 (tree, int, int); +extern void default_function_rodata_section (tree); +extern void default_no_function_rodata_section (tree); extern void default_select_rtx_section (enum machine_mode, rtx, unsigned HOST_WIDE_INT); extern void default_elf_select_rtx_section (enum machine_mode, rtx, @@ -509,6 +580,7 @@ extern const char *default_strip_name_encoding (const char *); extern bool default_binds_local_p (tree); extern bool default_binds_local_p_1 (tree, int); extern void default_globalize_label (FILE *, const char *); +extern void default_emit_unwind_label (FILE *, tree, int, int); extern void default_internal_label (FILE *, const char *, unsigned long); extern void default_file_start (void); extern void file_end_indicate_exec_stack (void); @@ -516,4 +588,24 @@ extern bool default_valid_pointer_mode (enum machine_mode); extern int default_address_cost (rtx); +/* 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/cpp2/prefix.c b/support/cpp2/prefix.c index 6204ee92..a559bcd3 100644 --- a/support/cpp2/prefix.c +++ b/support/cpp2/prefix.c @@ -1,5 +1,5 @@ /* Utility to update paths from internal to external forms. - Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GCC. @@ -16,8 +16,8 @@ Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with GCC; see the file COPYING. If not, write to the Free -Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. */ /* This file contains routines to update a path, both to canonicalize the directory format and to handle any prefix translation. @@ -122,6 +122,10 @@ save_string (const char *s, int len) #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 * @@ -155,11 +159,11 @@ lookup_key (char *key) size = 32; dst = xmalloc (size); - res = RegQueryValueExA (reg_key, key, 0, &type, dst, &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, dst, &size); + res = RegQueryValueExA (reg_key, key, 0, &type, (LPBYTE) dst, &size); } if (type != REG_SZ || res != ERROR_SUCCESS) @@ -236,16 +240,20 @@ tr (char *string, int c1, int c2) while (*string++); } -/* Update PATH using KEY if PATH starts with PREFIX. The returned - string is always malloc-ed, and the caller is responsible for - freeing it. */ +/* 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, strlen (std_prefix)) && key != 0) + if (! strncmp (path, std_prefix, len) + && (IS_DIR_SEPARATOR(path[len]) + || path[len] == '\0') + && key != 0) { bool free_key = false; @@ -255,7 +263,7 @@ update_path (const char *path, const char *key) free_key = true; } - result = concat (key, &path[strlen (std_prefix)], NULL); + result = concat (key, &path[len], NULL); if (free_key) free ((char *) key); result = translate_name (result); diff --git a/support/cpp2/prefix.h b/support/cpp2/prefix.h index 25f21159..e6e653ad 100644 --- a/support/cpp2/prefix.h +++ b/support/cpp2/prefix.h @@ -15,8 +15,8 @@ Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with GCC; see the file COPYING. If not, write to the Free -Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. */ #ifndef GCC_PREFIX_H diff --git a/support/cpp2/pretty-print.c b/support/cpp2/pretty-print.c index 9ef12f23..ca8d7a91 100644 --- a/support/cpp2/pretty-print.c +++ b/support/cpp2/pretty-print.c @@ -1,5 +1,5 @@ /* Various declarations for language-independent pretty-print subroutines. - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. Contributed by Gabriel Dos Reis This file is part of GCC. @@ -16,13 +16,14 @@ 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. */ +Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301, USA. */ #include "config.h" #undef FLOAT /* This is for hpux. They should change hpux. */ #undef FFS /* Some systems define this in param.h. */ #include "system.h" +#include "intl.h" #include "pretty-print.h" #define obstack_chunk_alloc xmalloc @@ -30,7 +31,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA /* A pointer to the formatted diagnostic message. */ #define pp_formatted_text_data(PP) \ - ((const char *) obstack_base (&pp_base (PP)->buffer->obstack)) + ((const char *) obstack_base (pp_base (PP)->buffer->obstack)) /* Format an integer given by va_arg (ARG, type-specifier T) where type-specifier is a precision modifier as indicated by PREC. F is @@ -90,7 +91,7 @@ pp_clear_state (pretty_printer *pp) } /* Flush the formatted text of PRETTY-PRINTER onto the attached stream. */ -static inline void +void pp_write_text_to_stream (pretty_printer *pp) { const char *text = pp_formatted_text (pp); @@ -146,7 +147,7 @@ pp_maybe_wrap_text (pretty_printer *pp, const char *start, const char *end) static inline void pp_append_r (pretty_printer *pp, const char *start, int length) { - obstack_grow (&pp->buffer->obstack, start, length); + obstack_grow (pp->buffer->obstack, start, length); pp->buffer->line_length += length; } @@ -163,8 +164,7 @@ pp_base_indent (pretty_printer *pp) pp_space (pp); } -/* Format a message pointed to by TEXT. The following format specifiers are - recognized as being client independent: +/* The following format specifiers are recognized as being client independent: %d, %i: (signed) integer in base ten. %u: unsigned integer in base ten. %o: unsigned integer in base eight. @@ -176,51 +176,250 @@ pp_base_indent (pretty_printer *pp) %s: string. %p: pointer. %m: strerror(text->err_no) - does not consume a value from args_ptr. - %%: `%'. - %.*s: a substring the length of which is specified by an integer. - %H: location_t. */ + %%: '%'. + %<: opening quote. + %>: closing quote. + %': apostrophe (should only be used in untranslated messages; + translations should use appropriate punctuation directly). + %.*s: a substring the length of which is specified by an argument + integer. + %Ns: likewise, but length specified as constant in the format string. + %H: location_t. + %J: a decl tree, from which DECL_SOURCE_LOCATION will be recorded. + Flag 'q': quote formatted text (must come immediately after '%'). + + Arguments can be used sequentially, or through %N$ resp. *N$ + notation Nth argument after the format string. If %N$ / *N$ + notation is used, it must be used for all arguments, except %m, %%, + %<, %> and %', which may not have a number, as they do not consume + an argument. When %M$.*N$s is used, M must be N + 1. (This may + also be written %M$.*s, provided N is not otherwise used.) The + format string must have conversion specifiers with argument numbers + 1 up to highest argument; each argument may only be used once. + A format string can have at most 30 arguments. */ + +/* Formatting phases 1 and 2: render TEXT->format_spec plus + TEXT->args_ptr into a series of chunks in PP->buffer->args[]. + Phase 3 is in pp_base_format_text. */ + void -pp_base_format_text (pretty_printer *pp, text_info *text) +pp_base_format (pretty_printer *pp, text_info *text) { - for (; *text->format_spec; ++text->format_spec) + output_buffer *buffer = pp->buffer; + const char *p; + const char **args; + struct chunk_info *new_chunk_array; + + unsigned int curarg = 0, chunk = 0, argno; + pp_wrapping_mode_t old_wrapping_mode; + bool any_unnumbered = false, any_numbered = false; + const char **formatters[PP_NL_ARGMAX]; + + /* Allocate a new chunk structure. */ + new_chunk_array = XOBNEW (&buffer->chunk_obstack, struct chunk_info); + new_chunk_array->prev = buffer->cur_chunk_array; + buffer->cur_chunk_array = new_chunk_array; + args = new_chunk_array->args; + + /* Formatting phase 1: split up TEXT->format_spec into chunks in + PP->buffer->args[]. Even-numbered chunks are to be output + verbatim, odd-numbered chunks are format specifiers. + %m, %%, %<, %>, and %' are replaced with the appropriate text at + this point. */ + + memset (formatters, 0, sizeof formatters); + + for (p = text->format_spec; *p; ) + { + while (*p != '\0' && *p != '%') + { + obstack_1grow (&buffer->chunk_obstack, *p); + p++; + } + + if (*p == '\0') + break; + + switch (*++p) + { + case '\0': + gcc_unreachable (); + + case '%': + obstack_1grow (&buffer->chunk_obstack, '%'); + p++; + continue; + + case '<': + obstack_grow (&buffer->chunk_obstack, + open_quote, strlen (open_quote)); + p++; + continue; + + case '>': + case '\'': + obstack_grow (&buffer->chunk_obstack, + close_quote, strlen (close_quote)); + p++; + continue; + + case 'm': + { + const char *errstr = xstrerror (text->err_no); + obstack_grow (&buffer->chunk_obstack, errstr, strlen (errstr)); + } + p++; + continue; + + default: + /* Handled in phase 2. Terminate the plain chunk here. */ + obstack_1grow (&buffer->chunk_obstack, '\0'); + gcc_assert (chunk < PP_NL_ARGMAX * 2); + args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *); + break; + } + + if (ISDIGIT (*p)) + { + char *end; + argno = strtoul (p, &end, 10) - 1; + p = end; + gcc_assert (*p == '$'); + p++; + + any_numbered = true; + gcc_assert (!any_unnumbered); + } + else + { + argno = curarg++; + any_unnumbered = true; + gcc_assert (!any_numbered); + } + gcc_assert (argno < PP_NL_ARGMAX); + gcc_assert (!formatters[argno]); + formatters[argno] = &args[chunk]; + do + { + obstack_1grow (&buffer->chunk_obstack, *p); + p++; + } + while (strchr ("qwl+#", p[-1])); + + if (p[-1] == '.') + { + /* We handle '%.Ns' and '%.*s' or '%M$.*N$s' + (where M == N + 1). */ + if (ISDIGIT (*p)) + { + do + { + obstack_1grow (&buffer->chunk_obstack, *p); + p++; + } + while (ISDIGIT (p[-1])); + gcc_assert (p[-1] == 's'); + } + else + { + gcc_assert (*p == '*'); + obstack_1grow (&buffer->chunk_obstack, '*'); + p++; + + if (ISDIGIT (*p)) + { + char *end; + unsigned int argno2 = strtoul (p, &end, 10) - 1; + p = end; + gcc_assert (argno2 == argno - 1); + gcc_assert (!any_unnumbered); + gcc_assert (*p == '$'); + + p++; + formatters[argno2] = formatters[argno]; + } + else + { + gcc_assert (!any_numbered); + formatters[argno+1] = formatters[argno]; + curarg++; + } + gcc_assert (*p == 's'); + obstack_1grow (&buffer->chunk_obstack, 's'); + p++; + } + } + if (*p == '\0') + break; + + obstack_1grow (&buffer->chunk_obstack, '\0'); + gcc_assert (chunk < PP_NL_ARGMAX * 2); + args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *); + } + + obstack_1grow (&buffer->chunk_obstack, '\0'); + gcc_assert (chunk < PP_NL_ARGMAX * 2); + args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *); + args[chunk] = 0; + + /* Set output to the argument obstack, and switch line-wrapping and + prefixing off. */ + buffer->obstack = &buffer->chunk_obstack; + old_wrapping_mode = pp_set_verbatim_wrapping (pp); + + /* Second phase. Replace each formatter with the formatted text it + corresponds to. */ + + for (argno = 0; formatters[argno]; argno++) { int precision = 0; bool wide = false; + bool plus = false; + bool hash = false; + bool quote = false; - /* Ignore text. */ - { - const char *p = text->format_spec; - while (*p && *p != '%') - ++p; - pp_wrap_text (pp, text->format_spec, p); - text->format_spec = p; - } + /* We do not attempt to enforce any ordering on the modifier + characters. */ - if (*text->format_spec == '\0') - break; + for (p = *formatters[argno];; p++) + { + switch (*p) + { + case 'q': + gcc_assert (!quote); + quote = true; + continue; + + case '+': + gcc_assert (!plus); + plus = true; + continue; + + case '#': + gcc_assert (!hash); + hash = true; + continue; + + case 'w': + gcc_assert (!wide); + wide = true; + continue; + + case 'l': + /* We don't support precision beyond that of "long long". */ + gcc_assert (precision < 2); + precision++; + continue; + } + break; + } + + gcc_assert (!wide || precision == 0); - /* We got a '%'. Parse precision modifiers, if any. */ - switch (*++text->format_spec) - { - case 'w': - wide = true; - ++text->format_spec; - break; - - case 'l': - do - ++precision; - while (*++text->format_spec == 'l'); - break; - - default: - break; - } - /* We don't support precision beyond that of "long long". */ - if (precision > 2) - abort(); - - switch (*text->format_spec) + if (quote) + pp_string (pp, open_quote); + + switch (*p) { case 'c': pp_character (pp, va_arg (*text->args_ptr, int)); @@ -228,92 +427,148 @@ pp_base_format_text (pretty_printer *pp, text_info *text) case 'd': case 'i': - if (wide) - pp_wide_integer (pp, va_arg (*text->args_ptr, HOST_WIDE_INT)); - else - pp_integer_with_precision - (pp, *text->args_ptr, precision, int, "d"); + if (wide) + pp_wide_integer (pp, va_arg (*text->args_ptr, HOST_WIDE_INT)); + else + pp_integer_with_precision + (pp, *text->args_ptr, precision, int, "d"); break; case 'o': - if (wide) - pp_scalar (pp, "%" HOST_WIDE_INT_PRINT "o", - va_arg (*text->args_ptr, unsigned HOST_WIDE_INT)); - else - pp_integer_with_precision - (pp, *text->args_ptr, precision, unsigned, "u"); + if (wide) + pp_scalar (pp, "%" HOST_WIDE_INT_PRINT "o", + va_arg (*text->args_ptr, unsigned HOST_WIDE_INT)); + else + pp_integer_with_precision + (pp, *text->args_ptr, precision, unsigned, "o"); break; case 's': pp_string (pp, va_arg (*text->args_ptr, const char *)); break; - case 'p': - pp_pointer (pp, va_arg (*text->args_ptr, void *)); - break; + case 'p': + pp_pointer (pp, va_arg (*text->args_ptr, void *)); + break; case 'u': - if (wide) - pp_scalar (pp, HOST_WIDE_INT_PRINT_UNSIGNED, - va_arg (*text->args_ptr, unsigned HOST_WIDE_INT)); - else - pp_integer_with_precision - (pp, *text->args_ptr, precision, unsigned, "u"); + if (wide) + pp_scalar (pp, HOST_WIDE_INT_PRINT_UNSIGNED, + va_arg (*text->args_ptr, unsigned HOST_WIDE_INT)); + else + pp_integer_with_precision + (pp, *text->args_ptr, precision, unsigned, "u"); break; case 'x': - if (wide) - pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX, - va_arg (*text->args_ptr, unsigned HOST_WIDE_INT)); - else - pp_integer_with_precision - (pp, *text->args_ptr, precision, unsigned, "x"); + if (wide) + pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX, + va_arg (*text->args_ptr, unsigned HOST_WIDE_INT)); + else + pp_integer_with_precision + (pp, *text->args_ptr, precision, unsigned, "x"); break; - case 'm': - pp_string (pp, xstrerror (text->err_no)); + case 'H': + { + location_t *locus = va_arg (*text->args_ptr, location_t *); + gcc_assert (text->locus != NULL); + *text->locus = *locus; + } break; - case '%': - pp_character (pp, '%'); + case 'J': + { + tree t = va_arg (*text->args_ptr, tree); + gcc_assert (text->locus != NULL); + *text->locus = DECL_SOURCE_LOCATION (t); + } break; - case 'H': - { - const location_t *locus = va_arg (*text->args_ptr, location_t *); - pp_string (pp, "file '"); - pp_string (pp, locus->file); - pp_string (pp, "', line "); - pp_decimal_int (pp, locus->line); - } - break; - case '.': { int n; const char *s; - /* We handle no precision specifier but `%.*s'. */ - if (*++text->format_spec != '*') - abort (); - else if (*++text->format_spec != 's') - abort (); - n = va_arg (*text->args_ptr, int); + + /* We handle '%.Ns' and '%.*s' or '%M$.*N$s' + (where M == N + 1). The format string should be verified + already from the first phase. */ + p++; + if (ISDIGIT (*p)) + { + char *end; + n = strtoul (p, &end, 10); + p = end; + gcc_assert (*p == 's'); + } + else + { + gcc_assert (*p == '*'); + p++; + gcc_assert (*p == 's'); + n = va_arg (*text->args_ptr, int); + + /* This consumes a second entry in the formatters array. */ + gcc_assert (formatters[argno] == formatters[argno+1]); + argno++; + } + s = va_arg (*text->args_ptr, const char *); pp_append_text (pp, s, s + n); } break; default: - if (!pp_format_decoder (pp) || !(*pp_format_decoder (pp)) (pp, text)) - { - /* Hmmm. The client failed to install a format translator - but called us with an unrecognized format. Or, maybe, the - translated string just contains an invalid format, or - has formats in the wrong order. Sorry. */ - abort (); - } + { + bool ok; + + gcc_assert (pp_format_decoder (pp)); + ok = pp_format_decoder (pp) (pp, text, p, + precision, wide, plus, hash); + gcc_assert (ok); + } } + + if (quote) + pp_string (pp, close_quote); + + obstack_1grow (&buffer->chunk_obstack, '\0'); + *formatters[argno] = XOBFINISH (&buffer->chunk_obstack, const char *); } + +#ifdef ENABLE_CHECKING + for (; argno < PP_NL_ARGMAX; argno++) + gcc_assert (!formatters[argno]); +#endif + + /* Revert to normal obstack and wrapping mode. */ + buffer->obstack = &buffer->formatted_obstack; + buffer->line_length = 0; + pp_wrapping_mode (pp) = old_wrapping_mode; + pp_clear_state (pp); +} + +/* Format of a message pointed to by TEXT. */ +void +pp_base_output_formatted_text (pretty_printer *pp) +{ + unsigned int chunk; + output_buffer *buffer = pp_buffer (pp); + struct chunk_info *chunk_array = buffer->cur_chunk_array; + const char **args = chunk_array->args; + + gcc_assert (buffer->obstack == &buffer->formatted_obstack); + gcc_assert (buffer->line_length == 0); + + /* This is a third phase, first 2 phases done in pp_base_format_args. + Now we actually print it. */ + for (chunk = 0; args[chunk]; chunk++) + pp_string (pp, args[chunk]); + + /* Deallocate the chunk structure and everything after it (i.e. the + associated series of formatted strings). */ + buffer->cur_chunk_array = chunk_array->prev; + obstack_free (&buffer->chunk_obstack, chunk_array); } /* Helper subroutine of output_verbatim and verbatim. Do the appropriate @@ -321,17 +576,15 @@ pp_base_format_text (pretty_printer *pp, text_info *text) void pp_base_format_verbatim (pretty_printer *pp, text_info *text) { - diagnostic_prefixing_rule_t rule = pp_prefixing_rule (pp); - int line_cutoff = pp_line_cutoff (pp); - /* Set verbatim mode. */ - pp->prefixing_rule = DIAGNOSTICS_SHOW_PREFIX_NEVER; - pp_line_cutoff (pp) = 0; + pp_wrapping_mode_t oldmode = pp_set_verbatim_wrapping (pp); + /* Do the actual formatting. */ - pp_format_text (pp, text); + pp_format (pp, text); + pp_output_formatted_text (pp); + /* Restore previous settings. */ - pp_prefixing_rule (pp) = rule; - pp_line_cutoff (pp) = line_cutoff; + pp_wrapping_mode (pp) = oldmode; } /* Flush the content of BUFFER onto the attached stream. */ @@ -359,7 +612,7 @@ pp_base_set_line_maximum_length (pretty_printer *pp, int length) void pp_base_clear_output_area (pretty_printer *pp) { - obstack_free (&pp->buffer->obstack, obstack_base (&pp->buffer->obstack)); + obstack_free (pp->buffer->obstack, obstack_base (pp->buffer->obstack)); pp->buffer->line_length = 0; } @@ -423,7 +676,9 @@ pp_construct (pretty_printer *pp, const char *prefix, int maximum_length) { memset (pp, 0, sizeof (pretty_printer)); pp->buffer = xcalloc (1, sizeof (output_buffer)); - obstack_init (&pp->buffer->obstack); + obstack_init (&pp->buffer->chunk_obstack); + obstack_init (&pp->buffer->formatted_obstack); + pp->buffer->obstack = &pp->buffer->formatted_obstack; pp->buffer->stream = stderr; pp_line_cutoff (pp) = maximum_length; pp_prefixing_rule (pp) = DIAGNOSTICS_SHOW_PREFIX_ONCE; @@ -454,7 +709,7 @@ pp_base_append_text (pretty_printer *pp, const char *start, const char *end) const char * pp_base_formatted_text (pretty_printer *pp) { - obstack_1grow (&pp->buffer->obstack, '\0'); + obstack_1grow (pp->buffer->obstack, '\0'); return pp_formatted_text_data (pp); } @@ -464,7 +719,7 @@ const char * pp_base_last_position_in_text (const pretty_printer *pp) { const char *p = NULL; - struct obstack *text = &pp->buffer->obstack; + struct obstack *text = pp->buffer->obstack; if (obstack_base (text) != obstack_next_free (text)) p = ((const char *) obstack_next_free (text)) - 1; @@ -491,7 +746,9 @@ pp_printf (pretty_printer *pp, const char *msg, ...) text.err_no = errno; text.args_ptr = ≈ text.format_spec = msg; - pp_format_text (pp, &text); + text.locus = NULL; + pp_format (pp, &text); + pp_output_formatted_text (pp); va_end (ap); } @@ -507,6 +764,7 @@ pp_verbatim (pretty_printer *pp, const char *msg, ...) text.err_no = errno; text.args_ptr = ≈ text.format_spec = msg; + text.locus = NULL; pp_format_verbatim (pp, &text); va_end (ap); } @@ -517,7 +775,7 @@ pp_verbatim (pretty_printer *pp, const char *msg, ...) void pp_base_newline (pretty_printer *pp) { - obstack_1grow (&pp->buffer->obstack, '\n'); + obstack_1grow (pp->buffer->obstack, '\n'); pp->buffer->line_length = 0; } @@ -532,7 +790,7 @@ pp_base_character (pretty_printer *pp, int c) if (ISSPACE (c)) return; } - obstack_1grow (&pp->buffer->obstack, c); + obstack_1grow (pp->buffer->obstack, c); ++pp->buffer->line_length; } @@ -544,4 +802,14 @@ pp_base_string (pretty_printer *pp, const char *str) pp_maybe_wrap_text (pp, str, str + (str ? strlen (str) : 0)); } +/* Maybe print out a whitespace if needed. */ +void +pp_base_maybe_space (pretty_printer *pp) +{ + if (pp_base (pp)->padding != pp_none) + { + pp_space (pp); + pp_base (pp)->padding = pp_none; + } +} diff --git a/support/cpp2/pretty-print.h b/support/cpp2/pretty-print.h index 1691aec2..b2c6772b 100644 --- a/support/cpp2/pretty-print.h +++ b/support/cpp2/pretty-print.h @@ -1,5 +1,5 @@ /* Various declarations for language-independent pretty-print subroutines. - Copyright (C) 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. Contributed by Gabriel Dos Reis This file is part of GCC. @@ -16,8 +16,8 @@ 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. */ +Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301, USA. */ #ifndef GCC_PRETTY_PRINT_H #define GCC_PRETTY_PRINT_H @@ -25,6 +25,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "obstack.h" #include "input.h" +/* Maximum number of format string arguments. */ +#define PP_NL_ARGMAX 30 + /* The type of a text to be formatted according a format specification along with a list of things. */ typedef struct @@ -32,6 +35,7 @@ typedef struct const char *format_spec; va_list *args_ptr; int err_no; /* for %m */ + location_t *locus; } text_info; /* How often diagnostics are prefixed by their locations: @@ -46,12 +50,42 @@ typedef enum DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE = 0x2 } diagnostic_prefixing_rule_t; +/* The chunk_info data structure forms a stack of the results from the + first phase of formatting (pp_base_format) which have not yet been + output (pp_base_output_formatted_text). A stack is necessary because + the diagnostic starter may decide to generate its own output by way + of the formatter. */ +struct chunk_info +{ + /* Pointer to previous chunk on the stack. */ + struct chunk_info *prev; + + /* Array of chunks to output. Each chunk is a NUL-terminated string. + In the first phase of formatting, even-numbered chunks are + to be output verbatim, odd-numbered chunks are format specifiers. + The second phase replaces all odd-numbered chunks with formatted + text, and the third phase simply emits all the chunks in sequence + with appropriate line-wrapping. */ + const char *args[PP_NL_ARGMAX * 2]; +}; + /* The output buffer datatype. This is best seen as an abstract datatype whose fields should not be accessed directly by clients. */ typedef struct { - /* The obstack where the text is built up. */ - struct obstack obstack; + /* Obstack where the text is built up. */ + struct obstack formatted_obstack; + + /* Obstack containing a chunked representation of the format + specification plus arguments. */ + struct obstack chunk_obstack; + + /* Currently active obstack: one of the above two. This is used so + that the text formatters don't need to know which phase we're in. */ + struct obstack *obstack; + + /* Stack of chunk arrays. These come from the chunk_obstack. */ + struct chunk_info *cur_chunk_array; /* Where to output formatted text. */ FILE *stream; @@ -72,11 +106,34 @@ typedef enum pp_none, pp_before, pp_after } pp_padding; +/* Structure for switching in and out of verbatim mode in a convenient + manner. */ +typedef struct +{ + /* Current prefixing rule. */ + diagnostic_prefixing_rule_t rule; + + /* The ideal upper bound of number of characters per line, as suggested + by front-end. */ + int line_cutoff; +} pp_wrapping_mode_t; + +/* Maximum characters per line in automatic line wrapping mode. + Zero means don't wrap lines. */ +#define pp_line_cutoff(PP) pp_base (PP)->wrapping.line_cutoff + +/* Prefixing rule used in formatting a diagnostic message. */ +#define pp_prefixing_rule(PP) pp_base (PP)->wrapping.rule + +/* Get or set the wrapping mode as a single entity. */ +#define pp_wrapping_mode(PP) pp_base (PP)->wrapping + /* The type of a hook that formats client-specific data onto a pretty_pinter. A client-supplied formatter returns true if everything goes well, otherwise it returns false. */ typedef struct pretty_print_info pretty_printer; -typedef bool (*printer_fn) (pretty_printer *, text_info *); +typedef bool (*printer_fn) (pretty_printer *, text_info *, const char *, + int, bool, bool, bool); /* Client supplied function used to decode formats. */ #define pp_format_decoder(PP) pp_base (PP)->format_decoder @@ -85,16 +142,9 @@ typedef bool (*printer_fn) (pretty_printer *, text_info *); formatting. */ #define pp_needs_newline(PP) pp_base (PP)->need_newline -/* Maximum characters per line in automatic line wrapping mode. - Zero means don't wrap lines. */ -#define pp_line_cutoff(PP) pp_base (PP)->ideal_maximum_length - /* True if PRETTY-PTINTER is in line-wrapping mode. */ #define pp_is_wrapping_line(PP) (pp_line_cutoff (PP) > 0) -/* Prefixing rule used in formatting a diagnostic message. */ -#define pp_prefixing_rule(PP) pp_base (PP)->prefixing_rule - /* The amount of whitespace to be emitted when starting a new line. */ #define pp_indentation(PP) pp_base (PP)->indent_skip @@ -116,15 +166,11 @@ struct pretty_print_info account the case of a very very looong prefix. */ int maximum_length; - /* The ideal upper bound of number of characters per line, as suggested - by front-end. */ - int ideal_maximum_length; - /* Indentation count. */ int indent_skip; - /* Current prefixing rule. */ - diagnostic_prefixing_rule_t prefixing_rule; + /* Current wrapping mode. */ + pp_wrapping_mode_t wrapping; /* If non-NULL, this function formats a TEXT into the BUFFER. When called, TEXT->format_spec points to a format code. FORMAT_DECODER should call @@ -158,7 +204,9 @@ struct pretty_print_info #define pp_append_text(PP, B, E) \ pp_base_append_text (pp_base (PP), B, E) #define pp_flush(PP) pp_base_flush (pp_base (PP)) -#define pp_format_text(PP, TI) pp_base_format_text (pp_base (PP), TI) +#define pp_format(PP, TI) pp_base_format (pp_base (PP), TI) +#define pp_output_formatted_text(PP) \ + pp_base_output_formatted_text (pp_base (PP)) #define pp_format_verbatim(PP, TI) \ pp_base_format_verbatim (pp_base (PP), TI) @@ -205,6 +253,7 @@ struct pretty_print_info } while (0) #define pp_maybe_newline_and_indent(PP, N) \ if (pp_needs_newline (PP)) pp_newline_and_indent (PP, N) +#define pp_maybe_space(PP) pp_base_maybe_space (pp_base (PP)) #define pp_separate_with(PP, C) \ do { \ pp_character (PP, C); \ @@ -220,6 +269,8 @@ struct pretty_print_info #define pp_decimal_int(PP, I) pp_scalar (PP, "%d", I) #define pp_wide_integer(PP, I) \ pp_scalar (PP, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) I) +#define pp_widest_integer(PP, I) \ + pp_scalar (PP, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT) I) #define pp_pointer(PP, P) pp_scalar (PP, "%p", P) #define pp_identifier(PP, ID) pp_string (PP, ID) @@ -228,7 +279,7 @@ struct pretty_print_info IDENTIFIER_POINTER (T) + IDENTIFIER_LENGTH (T)) #define pp_unsupported_tree(PP, T) \ - pp_verbatim (pp_base (PP), "#`%s' not supported by %s#", \ + pp_verbatim (pp_base (PP), "#%qs not supported by %s#", \ tree_code_name[(int) TREE_CODE (T)], __FUNCTION__) @@ -247,15 +298,40 @@ extern const char *pp_base_formatted_text (pretty_printer *); extern const char *pp_base_last_position_in_text (const pretty_printer *); extern void pp_base_emit_prefix (pretty_printer *); extern void pp_base_append_text (pretty_printer *, const char *, const char *); -extern void pp_printf (pretty_printer *, const char *, ...) ATTRIBUTE_PRINTF_2; -extern void pp_verbatim (pretty_printer *, const char *, ...); + +/* This header may be included before toplev.h, hence the duplicate + definitions to allow for GCC-specific formats. */ +#if GCC_VERSION >= 3005 +#define ATTRIBUTE_GCC_PPDIAG(m, n) __attribute__ ((__format__ (__gcc_diag__, m ,n))) ATTRIBUTE_NONNULL(m) +#else +#define ATTRIBUTE_GCC_PPDIAG(m, n) ATTRIBUTE_NONNULL(m) +#endif +extern void pp_printf (pretty_printer *, const char *, ...) + ATTRIBUTE_GCC_PPDIAG(2,3); + +extern void pp_verbatim (pretty_printer *, const char *, ...) + ATTRIBUTE_GCC_PPDIAG(2,3); extern void pp_base_flush (pretty_printer *); -extern void pp_base_format_text (pretty_printer *, text_info *); +extern void pp_base_format (pretty_printer *, text_info *); +extern void pp_base_output_formatted_text (pretty_printer *); extern void pp_base_format_verbatim (pretty_printer *, text_info *); extern void pp_base_indent (pretty_printer *); extern void pp_base_newline (pretty_printer *); extern void pp_base_character (pretty_printer *, int); extern void pp_base_string (pretty_printer *, const char *); +extern void pp_write_text_to_stream (pretty_printer *pp); +extern void pp_base_maybe_space (pretty_printer *); + +/* Switch into verbatim mode and return the old mode. */ +static inline pp_wrapping_mode_t +pp_set_verbatim_wrapping_ (pretty_printer *pp) +{ + pp_wrapping_mode_t oldmode = pp_wrapping_mode (pp); + pp_line_cutoff (pp) = 0; + pp_prefixing_rule (pp) = DIAGNOSTICS_SHOW_PREFIX_NEVER; + return oldmode; +} +#define pp_set_verbatim_wrapping(PP) pp_set_verbatim_wrapping_ (pp_base (PP)) #endif /* GCC_PRETTY_PRINT_H */ diff --git a/support/cpp2/sdcpp-opts.c b/support/cpp2/sdcpp-opts.c index 8f8e85e0..56d74399 100644 --- a/support/cpp2/sdcpp-opts.c +++ b/support/cpp2/sdcpp-opts.c @@ -1,5 +1,5 @@ /* C/ObjC/C++ command line option handling. - Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. Contributed by Neil Booth. This file is part of GCC. @@ -16,8 +16,8 @@ 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. */ +Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301, USA. */ #include "config.h" #include "system.h" @@ -27,6 +27,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "c-incpath.h" #include "opts.h" #include "options.h" +#include "mkdeps.h" #ifndef DOLLARS_IN_IDENTIFIERS # define DOLLARS_IN_IDENTIFIERS true @@ -75,6 +76,9 @@ 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; @@ -132,6 +136,7 @@ sdcpp_common_missing_argument (const char *opt, size_t code) case OPT_idirafter: case OPT_isysroot: case OPT_isystem: + case OPT_iquote: error ("missing path after \"%s\"", opt); break; @@ -166,7 +171,7 @@ defer_opt (enum opt_code code, const char *arg) unsigned int sdcpp_common_init_options (unsigned int argc, const char **argv ATTRIBUTE_UNUSED) { - parse_in = cpp_create_reader (CLK_GNUC89, NULL); + parse_in = cpp_create_reader (CLK_GNUC89, NULL, &line_table); cpp_opts = cpp_get_options (parse_in); cpp_opts->dollars_in_ident = DOLLARS_IN_IDENTIFIERS; @@ -176,7 +181,7 @@ sdcpp_common_init_options (unsigned int argc, const char **argv ATTRIBUTE_UNUSED before passing on command-line options to cpplib. */ cpp_opts->warn_dollars = 0; - deferred_opts = xmalloc (argc * sizeof (struct deferred_opt)); + deferred_opts = XNEWVEC (struct deferred_opt, argc); return CL_SDCPP; } @@ -227,13 +232,14 @@ sdcpp_common_handle_option (size_t scode, const char *arg, int value) case OPT_I: if (strcmp (arg, "-")) - add_path (xstrdup (arg), BRACKET, 0); + 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; @@ -309,6 +315,7 @@ sdcpp_common_handle_option (size_t scode, const char *arg, int value) case OPT_Werror: cpp_opts->warnings_are_errors = value; + global_dc->warning_as_error_requested = value; break; case OPT_Wimport: @@ -325,6 +332,10 @@ sdcpp_common_handle_option (size_t scode, const char *arg, int value) cpp_opts->warn_system_headers = value; break; + case OPT_Wtraditional: + cpp_opts->warn_traditional = value; + break; + case OPT_Wtrigraphs: cpp_opts->warn_trigraphs = value; break; @@ -337,6 +348,10 @@ sdcpp_common_handle_option (size_t scode, const char *arg, int value) warn_unused_macros = value; break; + case OPT_Wvariadic_macros: + warn_variadic_macros = value; + break; + case OPT_ansi: set_std_c89 (false, true); break; @@ -361,6 +376,10 @@ sdcpp_common_handle_option (size_t scode, const char *arg, int value) case OPT_fpch_deps: cpp_opts->restore_pch_deps = value; break; + + case OPT_fpch_preprocess: + flag_pch_preprocess = value; + break; #endif case OPT_fpreprocessed: @@ -390,7 +409,7 @@ sdcpp_common_handle_option (size_t scode, const char *arg, int value) break; case OPT_idirafter: - add_path (xstrdup (arg), AFTER, 0); + add_path (xstrdup (arg), AFTER, 0, true); break; case OPT_imacros: @@ -402,12 +421,16 @@ sdcpp_common_handle_option (size_t scode, const char *arg, int value) iprefix = 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); + add_path (xstrdup (arg), SYSTEM, 0, true); break; case OPT_iwithprefix: @@ -459,6 +482,13 @@ sdcpp_common_handle_option (size_t scode, const char *arg, int value) 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; @@ -503,7 +533,7 @@ sdcpp_common_post_options (const char **pfilename) /* Canonicalize the input and output filenames. */ if (in_fnames == NULL) { - in_fnames = xmalloc (sizeof (in_fnames[0])); + in_fnames = XNEWVEC (const char *, 1); in_fnames[0] = ""; } else if (strcmp (in_fnames[0], "-") == 0) @@ -547,8 +577,7 @@ sdcpp_common_post_options (const char **pfilename) cb->dir_change = cb_dir_change; cpp_post_options (parse_in); - saved_lineno = input_line; - input_line = 0; + input_location = UNKNOWN_LOCATION; /* If an error has occurred in cpplib, note it so we fail immediately. */ @@ -563,7 +592,7 @@ sdcpp_common_post_options (const char **pfilename) return false; } - if (flag_working_directory && ! flag_no_line_commands) + if (flag_working_directory && !flag_no_line_commands) pp_dir_change (parse_in, get_src_pwd ()); return 1; @@ -573,8 +602,6 @@ sdcpp_common_post_options (const char **pfilename) bool sdcpp_common_init (void) { - input_line = saved_lineno; - /* 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); @@ -588,6 +615,11 @@ sdcpp_common_init (void) 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 false; @@ -666,6 +698,7 @@ check_deps_environment_vars (void) deps_file = spec; deps_append = 1; + deps_seen = true; } } @@ -674,13 +707,22 @@ 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) - cpp_add_dependency_target (parse_in, opt->arg, opt->code == OPT_MQ); + deps_add_target (deps, opt->arg, opt->code == OPT_MQ); } } @@ -713,6 +755,11 @@ sanitize_cpp_opts (void) 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) @@ -731,12 +778,12 @@ add_prefixed_path (const char *suffix, size_t chain) prefix = iprefix ? iprefix : cpp_GCC_INCLUDE_DIR; prefix_len = iprefix ? strlen (iprefix) : cpp_GCC_INCLUDE_DIR_len; - path = xmalloc (prefix_len + suffix_len + 1); + 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); + add_path (path, chain, 0, false); } /* Handle -D, -U, -A, -imacros, and the first -include. */ @@ -747,7 +794,10 @@ finish_options (void) { size_t i; - cpp_change_file (parse_in, LC_RENAME, _("")); + cb_file_change (parse_in, + linemap_add (&line_table, LC_RENAME, 0, + _(""), 0)); + cpp_init_builtins (parse_in, 0 /*flag_hosted*/); /* We're about to send user input to cpplib, so make it warn for @@ -806,7 +856,7 @@ push_command_line_include (void) { struct deferred_opt *opt = &deferred_opts[include_cursor++]; - if (! cpp_opts->preprocessed && opt->code == OPT_include + if (!cpp_opts->preprocessed && opt->code == OPT_include && cpp_push_include (parse_in, opt->arg)) return; } @@ -817,19 +867,18 @@ push_command_line_include (void) /* -Wunused-macros should only warn about macros defined hereafter. */ cpp_opts->warn_unused_macros = warn_unused_macros; /* Restore the line map from . */ - if (! cpp_opts->preprocessed) - cpp_change_file (parse_in, LC_RENAME, main_input_filename); + 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. */ - cpp_get_line_maps (parse_in)->trace_includes - = cpp_opts->print_include_names; + line_table.trace_includes = cpp_opts->print_include_names; } } /* File change callback. Has to handle -include files. */ static void -cb_file_change (cpp_reader *pfile ATTRIBUTE_UNUSED, +cb_file_change (cpp_reader * ARG_UNUSED (pfile), const struct line_map *new_map) { pp_file_change (new_map); @@ -839,10 +888,10 @@ cb_file_change (cpp_reader *pfile ATTRIBUTE_UNUSED, } void -cb_dir_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const char *dir) +cb_dir_change (cpp_reader * ARG_UNUSED (pfile), const char *dir) { - if (! set_src_pwd (dir)) - warning ("too late for # directive to set debug directory"); + 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 diff --git a/support/cpp2/sdcpp.c b/support/cpp2/sdcpp.c index def45e24..794879ef 100644 --- a/support/cpp2/sdcpp.c +++ b/support/cpp2/sdcpp.c @@ -25,7 +25,7 @@ #include "config.h" #include "system.h" #include "cpplib.h" -#include "cpphash.h" +#include "internal.h" #include "version.h" #include "mkdeps.h" #include "opts.h" @@ -74,10 +74,16 @@ const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; const char *main_input_filename; +#ifndef USE_MAPPED_LOCATION +location_t unknown_location = { NULL, 0 }; +#endif + /* Current position in real source file. */ location_t input_location; +struct line_maps line_table; + /* Stack of currently pending input files. */ struct file_stack *input_file_stack; @@ -137,6 +143,14 @@ static const char *src_pwd; 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) { @@ -292,7 +306,7 @@ decode_d_option (const char *arg) break; default: - warning ("unrecognized gcc debugging option: %c", c); + warning (0, "unrecognized gcc debugging option: %c", c); break; } } diff --git a/support/cpp2/sdcpp.dsp b/support/cpp2/sdcpp.dsp index 5b145663..75aa885a 100644 --- a/support/cpp2/sdcpp.dsp +++ b/support/cpp2/sdcpp.dsp @@ -43,7 +43,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /I "." /I ".\libiberty" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FR /FD /D /GZ "HAVE_CONFIG_H" /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "." /I ".\libiberty" /I ".\win32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "HAVE_CONFIG_H" /FR /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "." /I ".\libiberty" /I ".\win32" /I ".\sdcpp" /I ".\sdcpp\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "HAVE_CONFIG_H" /FR /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" @@ -70,7 +70,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /I "." /I ".\libiberty" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c -# ADD CPP /nologo /W3 /GX /O2 /I "." /I ".\libiberty" /I ".\win32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "HAVE_CONFIG_H" /D "_WIN32" /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "." /I ".\libiberty" /I ".\win32" /I ".\sdcpp" /I ".\sdcpp\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "HAVE_CONFIG_H" /D "_WIN32" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" @@ -90,82 +90,89 @@ LINK32=link.exe # Name "sdcpp - Win32 Release" # Begin Group "Source Files" +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Group "libcpp" + # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File -SOURCE=".\c-incpath.c" +SOURCE=.\libcpp\charset.c # End Source File # Begin Source File -SOURCE=".\c-ppoutput.c" +SOURCE=.\libcpp\directives.c # End Source File # Begin Source File -SOURCE=.\libiberty\concat.c +SOURCE=.\libcpp\errors.c # End Source File # Begin Source File -SOURCE=.\cppcharset.c +SOURCE=.\libcpp\expr.c # End Source File # Begin Source File -SOURCE=.\cppdefault.c +SOURCE=.\libcpp\files.c # End Source File # Begin Source File -SOURCE=.\cpperror.c +SOURCE=.\libcpp\identifiers.c # End Source File # Begin Source File -SOURCE=.\cppexp.c +SOURCE=.\libcpp\init.c # End Source File # Begin Source File -SOURCE=.\cppfiles.c +SOURCE=.\libcpp\internal.h # End Source File # Begin Source File -SOURCE=.\cpphash.c +SOURCE=.\libcpp\lex.c # End Source File # Begin Source File -SOURCE=.\cppinit.c +SOURCE=".\libcpp\line-map.c" # End Source File # Begin Source File -SOURCE=.\cpplex.c +SOURCE=.\libcpp\macro.c # End Source File # Begin Source File -SOURCE=.\cpplib.c +SOURCE=.\libcpp\makeucnid.c # End Source File # Begin Source File -SOURCE=.\cppmacro.c +SOURCE=.\libcpp\mkdeps.c # End Source File # Begin Source File -SOURCE=.\cpptrad.c +SOURCE=.\libcpp\symtab.c # End Source File # Begin Source File -SOURCE=.\diagnostic.c +SOURCE=.\libcpp\system.h # End Source File # Begin Source File -SOURCE=.\win32\dirent.c +SOURCE=.\libcpp\traditional.c # End Source File # Begin Source File -SOURCE=.\libiberty\getpwd.c +SOURCE=.\libcpp\ucnid.h # End Source File +# End Group +# Begin Group "libiberty" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File -SOURCE=.\hashtab.c +SOURCE=.\libiberty\concat.c # End Source File # Begin Source File -SOURCE=.\hashtable.c +SOURCE=.\libiberty\getpwd.c # End Source File # Begin Source File @@ -177,75 +184,92 @@ SOURCE=.\libiberty\lbasename.c # End Source File # Begin Source File -SOURCE=".\line-map.c" +SOURCE=.\libiberty\obstack.c # End Source File # Begin Source File -SOURCE=.\mkdeps.c +SOURCE=".\libiberty\safe-ctype.c" # End Source File # Begin Source File -SOURCE=.\libiberty\obstack.c +SOURCE=".\libiberty\splay-tree.c" # End Source File # Begin Source File -SOURCE=.\options.c +SOURCE=.\libiberty\vasprintf.c # End Source File # Begin Source File -SOURCE=.\opts.c +SOURCE=.\libiberty\xexit.c # End Source File # Begin Source File -SOURCE=.\prefix.c +SOURCE=.\libiberty\xmalloc.c # End Source File # Begin Source File -SOURCE=".\pretty-print.c" +SOURCE=.\libiberty\xmemdup.c # End Source File # Begin Source File -SOURCE=".\libiberty\safe-ctype.c" +SOURCE=.\libiberty\xstrdup.c # End Source File # Begin Source File -SOURCE=".\sdcpp-opts.c" +SOURCE=.\libiberty\xstrerror.c +# End Source File +# End Group +# Begin Group "win32" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\win32\dirent.c # End Source File +# End Group # Begin Source File -SOURCE=.\sdcpp.c +SOURCE=".\c-incpath.c" # End Source File # Begin Source File -SOURCE=".\libiberty\splay-tree.c" +SOURCE=".\c-ppoutput.c" # End Source File # Begin Source File -SOURCE=.\libiberty\vasprintf.c +SOURCE=.\cppdefault.c # End Source File # Begin Source File -SOURCE=.\version.c +SOURCE=.\diagnostic.c # End Source File # Begin Source File -SOURCE=.\libiberty\xexit.c +SOURCE=.\options.c # End Source File # Begin Source File -SOURCE=.\libiberty\xmalloc.c +SOURCE=.\opts.c # End Source File # Begin Source File -SOURCE=.\libiberty\xmemdup.c +SOURCE=.\prefix.c # End Source File # Begin Source File -SOURCE=.\libiberty\xstrdup.c +SOURCE=".\pretty-print.c" # End Source File # Begin Source File -SOURCE=.\libiberty\xstrerror.c +SOURCE=".\sdcpp-opts.c" +# End Source File +# Begin Source File + +SOURCE=.\sdcpp.c +# End Source File +# Begin Source File + +SOURCE=.\version.c # End Source File # End Group # Begin Group "Header Files" diff --git a/support/cpp2/sdcpp.h b/support/cpp2/sdcpp.h index 9f7ece75..8b7e7c8c 100644 --- a/support/cpp2/sdcpp.h +++ b/support/cpp2/sdcpp.h @@ -119,7 +119,6 @@ extern const struct lang_hooks lang_hooks; #ifndef GCC_DIAG_STYLE #define GCC_DIAG_STYLE __gcc_diag__ #endif - /* None of these functions are suitable for ATTRIBUTE_PRINTF, because each language front end can extend them with its own set of format specifiers. We must use custom format checks. */ @@ -128,10 +127,26 @@ extern const struct lang_hooks lang_hooks; #else #define ATTRIBUTE_GCC_DIAG(m, n) ATTRIBUTE_NONNULL(m) #endif -extern void warning (const char *, ...); -extern void error (const char *, ...); +/* None of these functions are suitable for ATTRIBUTE_PRINTF, because + each language front end can extend them with its own set of format + specifiers. We must use custom format checks. */ +#if GCC_VERSION >= 4001 +#define ATTRIBUTE_GCC_DIAG(m, n) __attribute__ ((__format__ (GCC_DIAG_STYLE, m, n))) ATTRIBUTE_NONNULL(m) +#else +#define ATTRIBUTE_GCC_DIAG(m, n) ATTRIBUTE_NONNULL(m) +#endif +extern void internal_error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2) + ATTRIBUTE_NORETURN; +extern void warning0 (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2); +/* Pass one of the OPT_W* from options.h as the first parameter. */ +extern void warning (int, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3); +extern void error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2); extern void fatal_error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2) ATTRIBUTE_NORETURN; +extern void pedwarn (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2); +extern void sorry (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2); +extern void inform (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2); +extern void verbatim (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2); #ifdef BUFSIZ /* N.B. Unlike all the others, fnotice is just gettext+fprintf, and @@ -181,13 +196,10 @@ extern int flag_signed_char; extern int flag_pedantic_errors; -/* Don't print warning messages. -w. */ - -extern bool inhibit_warnings; - /* * From c-common.h */ +#include "hwint.h" #include "cpplib.h" /* Nonzero means don't output line number information. */ diff --git a/support/cpp2/sdcpp.opt b/support/cpp2/sdcpp.opt index fe06f28a..b4d655ad 100644 --- a/support/cpp2/sdcpp.opt +++ b/support/cpp2/sdcpp.opt @@ -1,5 +1,5 @@ ; Options for the SDCPP front end. -; Copyright (C) 2003 Free Software Foundation, Inc. +; Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. ; ; This file is part of GCC. ; @@ -15,47 +15,10 @@ ; ; 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. - - -; This file is processed by the script opts.sh. It is a database of -; command line options, with each record separated by a blank line, -; and each field appearing on its own line. The first field is the -; command-line switch with the leading "-" removed. All options -; beginning with "f" or "W" are implicitly assumed to take a "no-" -; form; this form should not be listed. If you do not want this -; negative form and you want it to be automatically rejected, add -; RejectNegative to the second field. - -; The second field is a space-separated list of which parts of the -; compiler recognize the switch, as declared by "Language" entries. -; If the switch takes an argument, then you should also specify -; "Joined" and/or "Separate" to indicate where the argument can -; appear. If a Joined argument can legitimately be omitted, specify -; "JoinedOrMissing" instead of "Joined". If the argument to a switch -; is a non-negative integer, you can specify "UInteger" and the switch -; decoder will convert the argument for you, or complain to the user -; if the argument is invalid. - -; The third field is the help text to output with --help. This is -; automatically line-wrapped on output. Normally the switch is output -; automatically, with the help text on the right hand side of the -; output. However, if the help text contains a tab character, the -; text to the left of the tab is output instead of the switch, and the -; text to its right forms the help. This is useful for elaborating on -; what type of argument a switch takes, for example. If the second -; field contains "Undocumented" then nothing is output with --help. -; Only do this with good reason like the switch being internal between -; the driver and the front end - it is not an excuse to leave a switch -; undocumented. - -; Comments can appear on their own line anwhere in the file, preceded -; by a semicolon. Whitespace is permitted before the semicolon. - -; For each switch XXX below, an enumeration constant is created by the -; script opts.sh spelt OPT_XXX, but with all non-alphanumeric -; characters replaced with an underscore. +; 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. @@ -165,6 +128,10 @@ Werror SDCPP 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. @@ -177,6 +144,10 @@ Wsystem-headers SDCPP 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 @@ -189,6 +160,10 @@ 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. @@ -263,6 +238,10 @@ isystem SDCPP Joined Separate -isystem Add to the start of the system include path +iquote +SDCPP Joined Separate +-iquote Add to the end of the quote include path + iwithprefix SDCPP Joined Separate -iwithprefix Add to the end of the system include path @@ -290,7 +269,7 @@ SDCPP Joined -obj-ext= Define object file extension, used for generation of make dependencies pedantic -SDCPP +SDCPP Var(pedantic) Issue warnings needed for strict compliance to the standard pedantic-errors @@ -337,8 +316,12 @@ v SDCPP Enable verbose output +;***version +;***SDCPP Var(version_flag) +;***Display the compiler's version + w -SDCPP +SDCPP Var(inhibit_warnings) Suppress warnings ; This comment is to ensure we retain the blank line above. diff --git a/support/cpp2/sdcppa.dsp b/support/cpp2/sdcppa.dsp index fc97e827..6d14bd0a 100644 --- a/support/cpp2/sdcppa.dsp +++ b/support/cpp2/sdcppa.dsp @@ -66,7 +66,7 @@ SOURCE=".\auto-host_vc_in.h" !IF "$(CFG)" == "sdcppa - Win32 Release" # Begin Custom Build -InputPath=.\auto-host_vc_in.h +InputPath=".\auto-host_vc_in.h" "auto-host.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy auto-host_vc_in.h auto-host.h > nul @@ -76,7 +76,7 @@ InputPath=.\auto-host_vc_in.h !ELSEIF "$(CFG)" == "sdcppa - Win32 Debug" # Begin Custom Build -InputPath=.\auto-host_vc_in.h +InputPath=".\auto-host_vc_in.h" "auto-host.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy auto-host_vc_in.h auto-host.h > nul @@ -88,53 +88,40 @@ InputPath=.\auto-host_vc_in.h # End Source File # Begin Source File -SOURCE=.\options_vc_in.c +SOURCE=.\sdcpp.opt !IF "$(CFG)" == "sdcppa - Win32 Release" # Begin Custom Build -InputPath=.\options_vc_in.c +InputPath=.\sdcpp.opt -"options.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - copy options_vc_in.c options.c > nul - -# End Custom Build - -!ELSEIF "$(CFG)" == "sdcppa - Win32 Debug" - -# Begin Custom Build -InputPath=.\options_vc_in.c +BuildCmds= \ + gawk -f opt-gather.awk sdcpp.opt | gawk -f opt-functions.awk -f optc-gen.awk -v header_name="config.h system.h options.h" > options.c \ + gawk -f opt-gather.awk sdcpp.opt | gawk -f opt-functions.awk -f opth-gen.awk > options.h \ + "options.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - copy options_vc_in.c options.c > nul - -# End Custom Build - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\options_vc_in.h - -!IF "$(CFG)" == "sdcppa - Win32 Release" - -# Begin Custom Build -InputPath=.\options_vc_in.h + $(BuildCmds) "options.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - copy options_vc_in.h options.h > nul - + $(BuildCmds) # End Custom Build !ELSEIF "$(CFG)" == "sdcppa - Win32 Debug" # Begin Custom Build -InputPath=.\options_vc_in.h +InputPath=.\sdcpp.opt -"options.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - copy options_vc_in.h options.h > nul +BuildCmds= \ + gawk -f opt-gather.awk sdcpp.opt | gawk -f opt-functions.awk -f optc-gen.awk -v header_name="config.h system.h options.h" > options.c \ + gawk -f opt-gather.awk sdcpp.opt | gawk -f opt-functions.awk -f opth-gen.awk > options.h \ + +"options.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"options.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) # End Custom Build !ENDIF diff --git a/support/cpp2/symcat.h b/support/cpp2/symcat.h index 61ce1e9b..03a12921 100644 --- a/support/cpp2/symcat.h +++ b/support/cpp2/symcat.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SYM_CAT_H #define SYM_CAT_H diff --git a/support/cpp2/system.h b/support/cpp2/system.h deleted file mode 100644 index 7226e38b..00000000 --- a/support/cpp2/system.h +++ /dev/null @@ -1,676 +0,0 @@ -/* Get common system includes and various definitions and declarations based - on autoconf macros. - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 - 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. */ - - -#ifndef GCC_SYSTEM_H -#define GCC_SYSTEM_H - -/* We must include stdarg.h before stdio.h. */ -#include - -#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 -#endif - -#include - -/* Define a generic NULL if one hasn't already been defined. */ -#ifndef NULL -#define NULL 0 -#endif - -/* 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_FPUTC_UNLOCKED -# undef fputc -# define fputc(C, Stream) fputc_unlocked (C, Stream) -# 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_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 int 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 - -#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 . - The last straw is that it varies with the locale. Use libiberty's - replacement instead. */ -#if defined(__APPLE__) && defined(__MACH__) -#include -#else -#include -#endif - -#include - -#include - -#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 -# include -#else -# ifdef HAVE_STRING_H -# include -# else -# ifdef HAVE_STRINGS_H -# include -# endif -# endif -#endif - -#ifdef HAVE_STDLIB_H -# include -#endif - -/* If we don't have an overriding definition, set SUCCESS_EXIT_CODE and - FATAL_EXIT_CODE to EXIT_SUCCESS and EXIT_FAILURE respectively, - or 0 and 1 if those macros are not defined. */ -#ifndef SUCCESS_EXIT_CODE -# ifdef EXIT_SUCCESS -# define SUCCESS_EXIT_CODE EXIT_SUCCESS -# else -# define SUCCESS_EXIT_CODE 0 -# endif -#endif - -#ifndef FATAL_EXIT_CODE -# ifdef EXIT_FAILURE -# define FATAL_EXIT_CODE EXIT_FAILURE -# else -# define FATAL_EXIT_CODE 1 -# endif -#endif - -#ifdef HAVE_UNISTD_H -# include -#endif - -#ifdef HAVE_SYS_PARAM_H -# include -/* We use this identifier later and it appears in some vendor param.h's. */ -# undef PREFETCH -#endif - -#if HAVE_LIMITS_H -# include -#endif - -/* Get definitions of HOST_WIDE_INT and HOST_WIDEST_INT. */ -#include "hwint.h" - -/* 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) - (LOWER)) <= ((UPPER) - (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 -# include -#else -# if HAVE_SYS_TIME_H -# include -# else -# ifdef HAVE_TIME_H -# include -# endif -# endif -#endif - -#ifdef HAVE_FCNTL_H -# include -#else -# ifdef HAVE_SYS_FILE_H -# include -# endif -#endif - -#ifndef SEEK_SET -# define SEEK_SET 0 -# define SEEK_CUR 1 -# define SEEK_END 2 -#endif -#ifndef F_OK -# define F_OK 0 -# define X_OK 1 -# define W_OK 2 -# define R_OK 4 -#endif -#ifndef O_RDONLY -# define O_RDONLY 0 -#endif -#ifndef O_WRONLY -# define O_WRONLY 1 -#endif - -/* Some systems define these in, e.g., param.h. We undefine these names - here to avoid the warnings. We prefer to use our definitions since we - know they are correct. */ - -#undef MIN -#undef MAX -#define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) -#define MAX(X,Y) ((X) > (Y) ? (X) : (Y)) - -/* Returns the least number N such that N * Y >= X. */ -#define CEIL(x,y) (((x) + (y) - 1) / (y)) - -#ifdef HAVE_SYS_WAIT_H -#include -#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 - -/* The HAVE_DECL_* macros are three-state, undefined, 0 or 1. If they - are defined to 0 then we must provide the relevant declaration - here. These checks will be in the undefined state while configure - is running so be careful to test "defined (HAVE_DECL_*)". */ - -#if defined (HAVE_DECL_ATOF) && !HAVE_DECL_ATOF -extern double atof (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_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 - -#ifdef HAVE_MALLOC_H -#include -#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 - -/* If the system doesn't provide strsignal, we get it defined in - libiberty but no declaration is supplied. */ -/* Disabled since it causes errors on solaris -#if !defined (HAVE_STRSIGNAL) \ - || (defined (HAVE_DECL_STRSIGNAL) && !HAVE_DECL_STRSIGNAL) -# ifndef strsignal -extern const 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 - -/* 1 if we have C99 designated initializers. */ -#if !defined(HAVE_DESIGNATED_INITIALIZERS) -#if defined(__APPLE__) && (__MACH__) -#define HAVE_DESIGNATED_INITIALIZERS 0 -#else -#define HAVE_DESIGNATED_INITIALIZERS \ - ((GCC_VERSION >= 2007) || (__STDC_VERSION__ >= 199901L)) -#endif -#endif - -/* 1 if we have _Bool. */ -#ifndef HAVE__BOOL -# define HAVE__BOOL \ - ((GCC_VERSION >= 3000) || (__STDC_VERSION__ >= 199901L)) -#endif - - -#if HAVE_SYS_STAT_H -# include -#endif - -/* Test if something is a normal file. */ -#ifndef S_ISREG -#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -#endif - -/* Test if something is a directory. */ -#ifndef S_ISDIR -#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) -#endif - -/* Test if something is a character special file. */ -#ifndef S_ISCHR -#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) -#endif - -/* Test if something is a block special file. */ -#ifndef S_ISBLK -#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) -#endif - -/* Test if something is a socket. */ -#ifndef S_ISSOCK -# ifdef S_IFSOCK -# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) -# else -# define S_ISSOCK(m) 0 -# endif -#endif - -/* Test if something is a FIFO. */ -#ifndef S_ISFIFO -# ifdef S_IFIFO -# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) -# else -# define S_ISFIFO(m) 0 -# endif -#endif - -/* Approximate O_NONBLOCK. */ -#ifndef O_NONBLOCK -#define O_NONBLOCK O_NDELAY -#endif - -/* Approximate O_NOCTTY. */ -#ifndef O_NOCTTY -#define O_NOCTTY 0 -#endif - -/* Define well known filenos if the system does not define them. */ -#ifndef STDIN_FILENO -# define STDIN_FILENO 0 -#endif -#ifndef STDOUT_FILENO -# define STDOUT_FILENO 1 -#endif -#ifndef STDERR_FILENO -# define STDERR_FILENO 2 -#endif - -/* Some systems have mkdir that takes a single argument. */ -#ifdef MKDIR_TAKES_ONE_ARG -# define mkdir(a,b) mkdir(a) -#endif - -/* Provide a way to print an address via printf. */ -#ifndef HOST_PTR_PRINTF -# ifdef HAVE_PRINTF_PTR -# define HOST_PTR_PRINTF "%p" -# elif SIZEOF_INT == SIZEOF_VOID_P -# define HOST_PTR_PRINTF "%x" -# elif SIZEOF_LONG == SIZEOF_VOID_P -# define HOST_PTR_PRINTF "%lx" -# else -# define HOST_PTR_PRINTF "%llx" -# endif -#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 - -/* Get libiberty declarations. */ -#include "libiberty.h" - -/* Provide a default for the HOST_BIT_BUCKET. - This suffices for POSIX-like hosts. */ - -#ifndef HOST_BIT_BUCKET -#define HOST_BIT_BUCKET "/dev/null" -#endif - -/* Be conservative and only use enum bitfields with GCC. - FIXME: provide a complete autoconf test for buggy enum bitfields. */ - -#if (GCC_VERSION > 2000) -#define ENUM_BITFIELD(TYPE) __extension__ enum TYPE -#else -#define ENUM_BITFIELD(TYPE) unsigned int -#endif - -/* We only use bool bitfields with gcc3. Some supposedly C99 - compilers don't handle them correctly. */ -#if (GCC_VERSION >= 3000) -#define BOOL_BITFIELD _Bool -#else -#define BOOL_BITFIELD unsigned int -#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 - -/* Provide some sort of boolean type. We use stdbool.h if it's - available. 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 - -#ifdef HAVE_STDBOOL_H -# include -#else -# if !HAVE__BOOL -typedef char _Bool; -# endif -# define bool _Bool -# define true 1 -# define false 0 -#endif - -#define TRUE true -#define FALSE false - -/* 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 - -/* 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 \ - SPLIT_COMPLEX_ARGS - -/* 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 \ - ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL ASM_OUTPUT_INTERNAL_LABEL \ - 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 - -/* 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 - -/* 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 */ - -/* 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 /* ! GCC_SYSTEM_H */ diff --git a/support/cpp2/version.c b/support/cpp2/version.c index 1918d696..661dce94 100644 --- a/support/cpp2/version.c +++ b/support/cpp2/version.c @@ -5,7 +5,7 @@ please modify this string to indicate that, e.g. by putting your organization's name in parentheses at the end of the string. */ -const char version_string[] = "3.4.6 + SDCC"; +const char version_string[] = "4.1.1 + SDCC"; /* This is the location of the online document giving instructions for reporting bugs. If you distribute a modified version of GCC, -- 2.47.2